Symfony2,错误:无法自动验证“字符串”类型的值。请提供约束

olg*_*lga 6 php validation annotations symfony

Symfony 2 错误:无法自动验证“字符串”类型的值。请提供约束。

我不明白什么限制以及我必须提供什么?

我正在遵循“扩展 Symfony 2”一书第 4 章中的示例。我尝试制作自定义注释“ValidateUser”并在实体用户属性 $phone 上使用它。我也将“ValidUserListenerCustom”注册为服务,它重定向控制器操作 join4Action 的响应。此操作使用所述自定义注释“@ValidateUser(“join_event”)”进行注释。仅当用户的个人资料中有手机号码时,此操作才应将用户添加到事件中。

C:\Bitnami\wampstack-5.5.30-0\sym_prog\star\src\Yoda\UserBundle\Entity\User.php

/**
 * @ORM\Column(type="string", length=255, name="phone")
 * @Assert\NotBlank(groups={"join_event"})
*/
protected $phone;
Run Code Online (Sandbox Code Playgroud)

C:\Bitnami\wampstack-5.5.30-0\sym_prog\star\src\Yoda\UserBundle\Security\ValidUserListenerCustom.php

<?php

namespace Yoda\UserBundle\Security;

use Doctrine\Common\Annotations\Reader;
use Symfony\Bundle\FrameworkBundle\Routing\Router;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\HttpFoundation\Session\Session;
use Symfony\Component\Security\Core\SecurityContext;
use Symfony\Component\DependencyInjection\Container;
use Symfony\Component\HttpKernel\Event\FilterControllerEvent;


class ValidUserListenerCustom
{
    private $reader;
    private $annotation_name = 'Yoda\UserBundle\Security\Annotation\ValidateUser';

    private $router;
    private $session;
    private $sc;
    private $container;

    public function __construct(Reader $reader, Router $rou, Session $session, SecurityContext $sc, Container $cont)
    {
        /** @var AnnotationReader $reader */
        $this->reader = $reader;

        $this->router = $rou;
        $this->session = $session;
        $this->sc = $sc; //security.context
        $this->container = $cont; //container        
    }

    public function onKernelController(FilterControllerEvent $event)
    {

        $controller = $event->getController();
        if (!is_array($controller)) {
            return;
        }
        $class_name = get_class($event->getController()[0]);
        $method_name = $event->getController()[1];

        dump($class_name); // "Symfony\Bundle\WebProfilerBundle\Controller\ProfilerController"
        dump($method_name);

        $method = new \ReflectionMethod($class_name, $method_name);
        dump('method'); dump($method);

        // Read the annotation
        $annotation = $this->reader->getMethodAnnotation($method, $this->annotation_name);     
        dump($annotation);//null

        if (!is_null($annotation)) {
            // Retrieve the validation group from the annotation, and try to
            // validate the user
            $validation_group = $annotation->getValidationGroup();

            dump($validation_group);

            $user = $this->container->get('security.token_storage')->getToken()->getUser();            
            dump($user);

            $validator = $this->container->get('validator');
            dump($validator);

            $errors = $validator->validate($user);
            dump($errors);
            //original: $errors = $this->validator->validate($user, $validation_group);

            if (count($errors)) {
                $event->setController(function(){
                    $this->session->getFlashBag()->add('warning', 'You must fill in your phone number before joining a meetup.');
                    return new RedirectResponse($this->router->generate(
                            'user_edit',
                            array ('id' => '1') ) );
                });
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

C:\Bitnami\wampstack-5.5.30-0\sym_prog\star\src\Yoda\UserBundle\Security\Annotation\ValidateUser.php

<?php

namespace Yoda\UserBundle\Security\Annotation;

//  Extending Symfony 2
// annotation itself ...\src\Yoda\UserBundle\Security\Annotation\ValidateUSer.php
// used in class ...src\Yoda\UserBundle\Entity\User.php
// readed/analysed by ...src\Yoda\UserBundle\Security\Annotation\AnnotationServices\AnnotationDriver::loadMetadataForClass


/**
 * @Annotation
 */
class ValidateUser
{
    private $validation_group;

    public function __construct(array $parameters)
    {
        $this->validation_group = $parameters['value'];
    }

    public function getValidationGroup()
    {
        return $this->validation_group;
    }
}
Run Code Online (Sandbox Code Playgroud)

C:\Bitnami\wampstack-5.5.30-0\sym_prog\star\src\Yoda\UserBundle\Resources\config\services.yml

yoda.user.security.valid_user_custom:
    class:      Yoda\UserBundle\Security\ValidUserListenerCustom
    arguments:  [@annotation_reader, @router, @session, @security.context, @service_container]
    tags:
        - { name: kernel.event_listener, event: kernel.controller, method: onKernelController }
Run Code Online (Sandbox Code Playgroud)

使用自定义注释“ValidateUser”来检查尝试加入活动的用户的个人资料中是否有手机号码。

网址:http : //127.0.0.1 : 8000/events/5/join4

C:\Bitnami\wampstack-5.5.30-0\sym_prog\star\src\Yoda\UserBundle\Controller\DefaultController.php

<?php ...
class DefaultController extends Controller
{ ...

    /**
     * @Route("/events/{event_id}/join4")
     * @Template()
     * @ValidateUser("join_event")
     */    
public function join4Action($event_id) {

        //Chapter 4
        $reader = $this->get('annotation_reader');
        $method = new \ReflectionMethod(get_class($this), 'join4Action');
        $annotation_name = 'Yoda\UserBundle\Security\Annotation\ValidateUser';
        $annotation = $reader->getMethodAnnotations($method);

        //Chapter 1
        $em = $this->getDoctrine()->getManager();
        $meetup = $em->getRepository('EventBundle:Event')->find($event_id);

        $form = $this->createForm(new JoinEventType(), $meetup, array(
            'action' => '',
            'method' => 'POST',
        ));
        $form->add('submit', 'submit', array('label' => 'Join'));

        $form->handleRequest($this->get('request'));

        //Do not know how to make it to work, chec later
        //$user = $this->get('security.context')->getToken()->getUser();
        $user = $em->getRepository('UserBundle:User')->find('1');

        if ($form->isValid()) {
            $meetup->addAttendee($user);
            $this->get('event_dispatcher')->dispatch(MeetupEvents::MEETUP_JOIN, new MeetupEvent($user, $meetup));
            $em->flush();
        } 

        $form = $form->createView();
        return compact('meetup', 'user', 'form');
    }  
Run Code Online (Sandbox Code Playgroud)