Symfony2.7字段使用validation-groups和UniqueEntity验证两次

时间:2015-08-20 08:13:10

标签: symfony-forms symfony-2.7

字段被验证两次,导致2个DB调用和2个相同的错误消息。

我有Subscriber类主要用户,注册类和RegistrationType,它嵌入SubscriberType作为教程How to Implement a simple Registration Form建议。主用户名字段具有UniqueEntity的约束,并且每当输入非唯一用户名时,"用户名已经存在"错误消息弹出两次,检查日志数据库调用以检查现有用户名是否被调用两次。我用谷歌搜索了这个并没有找到与我相同的案例,但是发现了类似的案例。我不知道该怎么办。

数据库是遗留的,所以我无法切换到FOSUserBundle,而且我之所以没有使用@ annotations,而是使用 *。orm.yml validation.yml

real -> real list -> int

自定义class RegistrationType extends AbstractType { public function buildForm(FormBuilderInterface $builder, array $options) { if(!$options['service']){ $builder->add('user', new SubscriberType()); $builder->add('Register', 'submit'); } else { $subscriber = new Subscriber(); $subscriber->setEmail($options['user_information']->getEmail()); $subscriber->setFirstname($options['user_information']->getFirstname()); $subscriber->setLastname($options['user_information']->getLastname()); $subscriber->setUsername($options['user_information']->getEmail()); switch($options['service']){ case 'facebook': $subscriber->setFbEmail($options['user_information']->getEmail()); break; } $builder->add('user', new SubscriberType($subscriber), array('service' => $options['service'], 'user_information' => $options['user_information'], 'data'=> $subscriber)); } $builder->add( 'terms', 'checkbox', array('property_path' => 'termsAccepted') ); } public function configureOptions(OptionsResolver $resolver) { $resolver->setDefaults(array( 'service' => false, 'user_information' => false ,'validation_groups' => array('Default', 'registration') )); } public function getName() { return 'registration'; } } 选项是整合HWIOAuthBundle,整个其他故事。

'service'

和registration.php:

class SubscriberType extends AbstractType
{
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        if(!$options['service']){
            $builder->add('username', 'email');
            $builder->add('plainPassword', 'repeated', array(
               'first_name'  => 'password',
               'second_name' => 'confirm',
               'type'        => 'password',
            ));
        } else {


            $builder->add('email', 'text', array('read_only' => true, ));
            $builder->add('firstname', 'text');
            $builder->add('lastname', 'text');
            $builder->add('username', 'hidden');
            $builder->add('fbEmail', 'hidden');
            $builder->add('gplusEmail', 'hidden');
        }
    }

    public function configureOptions(OptionsResolver $resolver)
    {
        $resolver->setDefaults(array(
            'data_class' => 'AppBundle\Entity\Subscriber',
            'service' => false,
            'user_information' => false
            ,'validation_groups' => array('Default', 'registration')
        ));
    }

    /* DEPRECATED since 2.7
    public function setDefaultOptions(OptionsResolverInterface $resolver)
    {
        $resolver->setDefaults(array(
            'data_class' => 'AppBundle\Entity\Subscriber',
            'service' => false,
            'user_information' => false
        ));
    }
    */

    public function getName()
    {
        return 'subscriber';
    }
}

Subscriber.php //实体:

<?php
// src/AppBundle/Form/Model/Registration

namespace AppBundle\Form\Model;

use Symfony\Component\Validator\Constraints as Assert;
use AppBundle\Entity\Subscriber;

class Registration
{
    /**
     * @Assert\Type(type="AppBundle\Entity\Subscriber")
     * @Assert\Valid()
     */
    protected $user;

    /**
     * @Assert\NotBlank()
     * @Assert\True()
     */
    protected $termsAccepted;

    public function setUser(Subscriber $user)
    {
        $this->user = $user;
    }

    public function getUser()
    {
        return $this->user;
    }

    public function getTermsAccepted()
    {
        return $this->termsAccepted;
    }

    public function setTermsAccepted($termsAccepted)
    {
        $this->termsAccepted = (bool) $termsAccepted;
    }
}

和Subscriber.orm.yml如下:

<?php

namespace AppBundle\Entity;

use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Security\Core\User\UserInterface;
use Doctrine\Common\Collections\ArrayCollection;
//use FOS\UserBundle\Entity\User as BaseUser;
/**
 * Subscriber
 */
class Subscriber implements UserInterface, \Serializable
{
    /**
     * @var integer
     */
    private $id;

    /**
     * @var string
     */
    private $username;

    /**
     * @var string
     */
    private $email;

    /**
     * @var string
     */
    private $gplusEmail;

    /**
     * @var string
     */
    private $fbEmail;

    /**
     * @var string
     */
    private $sha1Password;

    /**
     * @var string
     */
    private $salt;

    /**
     * @var float
     */
    private $unit;

    /**
     * @var string
     */
    private $validate;

    /**
     * @var string
     */
    private $rememberKey;

    /**
     * @var string
     */
    private $firstname = '';

    /**
     * @var string
     */
    private $lastname = '';

    /**
     * @var string
     */
    private $avatar = '';

    /**
     * @var string
     */
    private $countryId = '';

    /**
     * @var string
     */
    private $address;

    /**
     * @var string
     */
    private $phone;

    /**
     * @var string
     */
    private $gender = '';

    /**
     * @var \DateTime
     */
    private $birthdate;

    /**
     * @var \DateTime
     */
    private $lastAttemp;

    /**
     * @var integer
     */
    private $attempCount;

    /**
     * @var \DateTime
     */
    private $lastloginDate;

    /**
     * @var \DateTime
     */
    private $createdAt;

    /**
     * @var \DateTime
     */
    private $updatedAt;

    /**
     * @var \Doctrine\Common\Collections\Collection
     */
    private $groups;


    /**
     * @ORM\Column(type="string", length=255)
     */
    protected $plainPassword;

    /**
     * Constructor
     */
    public function __construct()
    {
        $this->groups = new \Doctrine\Common\Collections\ArrayCollection();
    }

    /**
     * Get id
     *
     * @return integer 
     */
    public function getId()
    {
        return $this->id;
    }

    /**
     * Set username
     *
     * @param string $username
     * @return Subscriber
     */
    public function setUsername($username)
    {
        $this->username = $username;

        return $this;
    }

    /**
     * Get username
     *
     * @return string 
     */
    public function getUsername()
    {
        return $this->username;
    }

    /**
     * Set email
     *
     * @param string $email
     * @return Subscriber
     */
    public function setEmail($email)
    {
        $this->email = $email;

        return $this;
    }

    /**
     * Get email
     *
     * @return string 
     */
    public function getEmail()
    {
        return $this->email;
    }

    /**
     * Set gplusEmail
     *
     * @param string $gplusEmail
     * @return Subscriber
     */
    public function setGplusEmail($gplusEmail)
    {
        $this->gplusEmail = $gplusEmail;

        return $this;
    }

    /**
     * Get gplusEmail
     *
     * @return string 
     */
    public function getGplusEmail()
    {
        return $this->gplusEmail;
    }

    /**
     * Set fbEmail
     *
     * @param string $fbEmail
     * @return Subscriber
     */
    public function setFbEmail($fbEmail)
    {
        $this->fbEmail = $fbEmail;

        return $this;
    }

    /**
     * Get fbEmail
     *
     * @return string 
     */
    public function getFbEmail()
    {
        return $this->fbEmail;
    }

    /**
     * Set sha1Password
     *
     * @param string $sha1Password
     * @return Subscriber
     */
    public function setSha1Password($sha1Password)
    {
        $this->sha1Password = $sha1Password;

        return $this;
    }

    /**
     * Get sha1Password
     *
     * @return string 
     */
    public function getSha1Password()
    {
        return $this->sha1Password;
    }

    /**
     * Set salt
     *
     * @param string $salt
     * @return Subscriber
     */
    public function setSalt($salt)
    {
        $this->salt = $salt;

        return $this;
    }

    /**
     * Get salt
     *
     * @return string 
     */
    public function getSalt()
    {
        return $this->salt;
    }

    /**
     * Set unit
     *
     * @param float $unit
     * @return Subscriber
     */
    public function setUnit($unit)
    {
        $this->unit = $unit;

        return $this;
    }

    /**
     * Get unit
     *
     * @return float 
     */
    public function getUnit()
    {
        return $this->unit;
    }

    /**
     * Set validate
     *
     * @param string $validate
     * @return Subscriber
     */
    public function setValidate($validate)
    {
        $this->validate = $validate;

        return $this;
    }

    /**
     * Get validate
     *
     * @return string 
     */
    public function getValidate()
    {
        return $this->validate;
    }

    /**
     * Set rememberKey
     *
     * @param string $rememberKey
     * @return Subscriber
     */
    public function setRememberKey($rememberKey)
    {
        $this->rememberKey = $rememberKey;

        return $this;
    }

    /**
     * Get rememberKey
     *
     * @return string 
     */
    public function getRememberKey()
    {
        return $this->rememberKey;
    }

    /**
     * Set firstname
     *
     * @param string $firstname
     * @return Subscriber
     */
    public function setFirstname($firstname)
    {
        $this->firstname = $firstname;

        return $this;
    }

    /**
     * Get firstname
     *
     * @return string 
     */
    public function getFirstname()
    {
        return $this->firstname;
    }

    /**
     * Set lastname
     *
     * @param string $lastname
     * @return Subscriber
     */
    public function setLastname($lastname)
    {
        $this->lastname = $lastname;

        return $this;
    }

    /**
     * Get lastname
     *
     * @return string 
     */
    public function getLastname()
    {
        return $this->lastname;
    }

    /**
     * Set avatar
     *
     * @param string $avatar
     * @return Subscriber
     */
    public function setAvatar($avatar)
    {
        $this->avatar = $avatar;

        return $this;
    }

    /**
     * Get avatar
     *
     * @return string 
     */
    public function getAvatar()
    {
        return $this->avatar;
    }

    /**
     * Set countryId
     *
     * @param string $countryId
     * @return Subscriber
     */
    public function setCountryId($countryId)
    {
        $this->countryId = $countryId;

        return $this;
    }

    /**
     * Get countryId
     *
     * @return string 
     */
    public function getCountryId()
    {
        return $this->countryId;
    }

    /**
     * Set address
     *
     * @param string $address
     * @return Subscriber
     */
    public function setAddress($address)
    {
        $this->address = $address;

        return $this;
    }

    /**
     * Get address
     *
     * @return string 
     */
    public function getAddress()
    {
        return $this->address;
    }

    /**
     * Set phone
     *
     * @param string $phone
     * @return Subscriber
     */
    public function setPhone($phone)
    {
        $this->phone = $phone;

        return $this;
    }

    /**
     * Get phone
     *
     * @return string 
     */
    public function getPhone()
    {
        return $this->phone;
    }

    /**
     * Set gender
     *
     * @param string $gender
     * @return Subscriber
     */
    public function setGender($gender)
    {
        $this->gender = $gender;

        return $this;
    }

    /**
     * Get gender
     *
     * @return string 
     */
    public function getGender()
    {
        return $this->gender;
    }

    /**
     * Set birthdate
     *
     * @param \DateTime $birthdate
     * @return Subscriber
     */
    public function setBirthdate($birthdate)
    {
        $this->birthdate = $birthdate;

        return $this;
    }

    /**
     * Get birthdate
     *
     * @return \DateTime 
     */
    public function getBirthdate()
    {
        return $this->birthdate;
    }

    /**
     * Set lastAttemp
     *
     * @param \DateTime $lastAttemp
     * @return Subscriber
     */
    public function setLastAttemp($lastAttemp)
    {
        $this->lastAttemp = $lastAttemp;

        return $this;
    }

    /**
     * Get lastAttemp
     *
     * @return \DateTime 
     */
    public function getLastAttemp()
    {
        return $this->lastAttemp;
    }

    /**
     * Set attempCount
     *
     * @param integer $attempCount
     * @return Subscriber
     */
    public function setAttempCount($attempCount)
    {
        $this->attempCount = $attempCount;

        return $this;
    }

    /**
     * Get attempCount
     *
     * @return integer 
     */
    public function getAttempCount()
    {
        return $this->attempCount;
    }

    /**
     * Set lastloginDate
     *
     * @param \DateTime $lastloginDate
     * @return Subscriber
     */
    public function setLastloginDate($lastloginDate)
    {
        $this->lastloginDate = $lastloginDate;

        return $this;
    }

    /**
     * Get lastloginDate
     *
     * @return \DateTime 
     */
    public function getLastloginDate()
    {
        return $this->lastloginDate;
    }

    /**
     * Set createdAt
     *
     * @param \DateTime $createdAt
     * @return Subscriber
     */
    public function setCreatedAt($createdAt)
    {
        $this->createdAt = $createdAt;

        return $this;
    }

    /**
     * Get createdAt
     *
     * @return \DateTime 
     */
    public function getCreatedAt()
    {
        return $this->createdAt;
    }

    /**
     * Set updatedAt
     *
     * @param \DateTime $updatedAt
     * @return Subscriber
     */
    public function setUpdatedAt($updatedAt)
    {
        $this->updatedAt = $updatedAt;

        return $this;
    }

    /**
     * Get updatedAt
     *
     * @return \DateTime 
     */
    public function getUpdatedAt()
    {
        return $this->updatedAt;
    }

    /**
     * Add groups
     *
     * @param \AppBundle\Entity\SubscriberGroup $groups
     * @return Subscriber
     */
    public function addGroup(\AppBundle\Entity\SubscriberGroup $groups)
    {
        $this->groups[] = $groups;

        return $this;
    }

    /**
     * Remove groups
     *
     * @param \AppBundle\Entity\SubscriberGroup $groups
     */
    public function removeGroup(\AppBundle\Entity\SubscriberGroup $groups)
    {
        $this->groups->removeElement($groups);
    }

    /**
     * Get groups
     *
     * @return \Doctrine\Common\Collections\Collection 
     */
    public function getGroups()
    {
        return $this->groups;
    }



    /**
     * Get setPassword
     *
     * @param string 
     */
    public function setPassword($hashed_password)
    {
        return $this->setSha1Password($hashed_password);
    }

    /**
     * Get setPassword
     *
     * @return string 
     */
    public function getPassword()
    {
        return $this->sha1Password;
    }


    ///*
    public function serialize()
    {
        return serialize(array(
            $this->id,
            $this->username,
            $this->sha1Password,
            $this->salt
        ));
    }

    ///*
    public function unserialize($serialized)
    {
        list (
            $this->id,
            $this->username,
            $this->sha1Password,
            $this->salt
        ) = unserialize($serialized);
    }
    //*/

    public function getRoles()
    {
        $roles = array();
        //var_dump($this->getGroups());
        foreach($this->getGroups() as $group){
            $roles[] = $group->getRole();
        }
        $roles[] = "ROLE_SUBSCRIBER";
        return array_unique($roles);
    }

    public function eraseCredentials()
    {
    }

    public function getPlainPassword()
    {
        return $this->plainPassword;
    }

    public function setPlainPassword($password)
    {
        $this->plainPassword = $password;
    }

}

最后验证.yml

AppBundle\Entity\Subscriber:
    type: entity
    table: w_subscriber
    repositoryClass: AppBundle\Entity\SubscriberRepository
    id:
        id:
            type: bigint
            nullable: false
            unsigned: false
            comment: ''
            id: true
            generator:
                strategy: IDENTITY
    fields:
        username:
            type: string
            nullable: false
            length: 50
            fixed: false
            comment: ''
        email:
            type: string
            nullable: false
            length: 150
            fixed: false
            comment: ''
        gplusEmail:
            type: string
            nullable: true
            length: 150
            fixed: false
            comment: ''
            column: gplus_email
        fbEmail:
            type: string
            nullable: true
            length: 150
            fixed: false
            comment: ''
            column: fb_email
        sha1Password:
            type: string
            nullable: true
            length: 40
            fixed: false
            comment: ''
            column: sha1_password
        salt:
            type: string
            nullable: true
            length: 32
            fixed: false
            comment: ''
        unit:
            type: float
            nullable: true
            precision: 18
            scale: 2
            comment: ''
            default: '0.00'
        validate:
            type: string
            nullable: true
            length: 10
            fixed: false
            comment: ''
        rememberKey:
            type: string
            nullable: true
            length: 50
            fixed: false
            comment: ''
            column: remember_key
        firstname:
            type: string
            nullable: false
            length: 200
            fixed: false
            comment: ''
        lastname:
            type: string
            nullable: true
            length: 200
            fixed: false
            comment: ''
        avatar:
            type: string
            nullable: false
            length: 200
            fixed: false
            comment: ''
        countryId:
            type: string
            nullable: false
            length: 5
            fixed: false
            comment: ''
            default: MN
            column: country_id
        address:
            type: text
            nullable: true
            length: null
            fixed: false
            comment: ''
        phone:
            type: string
            nullable: true
            length: 50
            fixed: false
            comment: ''
        gender:
            type: string
            nullable: false
            length: 1
            fixed: false
            comment: ''
            default: M
        birthdate:
            type: date
            nullable: true
            comment: ''
        lastAttemp:
            type: datetime
            nullable: true
            comment: ''
            column: last_attemp
        attempCount:
            type: bigint
            nullable: true
            unsigned: false
            comment: ''
            default: '0'
            column: attemp_count
        lastloginDate:
            type: datetime
            nullable: true
            comment: ''
            column: lastlogin_date
        createdAt:
            type: datetime
            nullable: false
            comment: ''
            column: created_at
            gedmo:
                timestampable:
                  on: create
        updatedAt:
            type: datetime
            nullable: false
            comment: ''
            column: updated_at
            gedmo:
                timestampable:
                    on: update
    lifecycleCallbacks: {  }
    manyToMany:
        groups:
          targetEntity: SubscriberGroup
          joinTable:
            name: w_subscriber_credential
            joinColumns:
              subscriber_id:
                referencedColumnName: id
            inverseJoinColumns:
              group_id:
                referencedColumnName: id

控制器:

# src/AppBundle/Resources/config/validation.yml
AppBundle\Entity\Subscriber:
    constraints:
      - \Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity:
          fields: [ username ]
          groups: [ registration ]
          message: 'this email is already registered'
    properties:
        email:
            - Email: ~

请注意,用户名也是电子邮件字段,我还没有发布模板,因为它也相当大,我相信它与验证无关,但如果有人想看到它,我很乐意发布它。< / p>

也有配置 <?php // src/AppBundle/Controller/SecurityController.php namespace AppBundle\Controller; use Symfony\Component\HttpFoundation\Request; use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route; use Symfony\Bundle\FrameworkBundle\Controller\Controller; use AppBundle\Form\Type\RegistrationType; use AppBundle\Form\Model\Registration; class SecurityController extends Controller { /** * @Route("/register", name="register") */ public function registerAction() { $form = $this->createForm(new RegistrationType(), new Registration(), array( 'action' => $this->generateUrl('register_create'), )); return $this->render( 'security/register.html.twig', array('form' => $form->createView()) ); } /** * @Route("/register/create", name="register_create") */ public function createAction(Request $request) { $em = $this->getDoctrine()->getManager(); $form = $this->createForm(new RegistrationType(), new Registration()); $form->handleRequest($request); if ($form->isValid()) { $registration = $form->getData(); $user = $registration->getUser(); $user->setEmail($user->getUsername()); $this->get('my.oauth_aware.user_provider.service')->setUserPassword($user, $user->getPlainPassword()); $em->persist($registration->getUser()); $em->flush(); //return $this->redirectToRoute('homepage'); } return $this->render( 'security/register.html.twig', array('form' => $form->createView()) ); } /** * @Route("/login_check", name="login_check") */ public function loginCheckAction() { // this controller will not be executed, // as the route is handled by the Security system } }

1 个答案:

答案 0 :(得分:0)

我很遗憾浪费每个人的时间。错误发生在主AppBundle的声明中,或者实际上在1个包文件层次结构中声明了2个不同的束。

为了覆盖HWIOAuthBundle的模板和控制器,我在AppBundle中声明了一个新的包,出于某种原因我认为需要一个新的声明。傻我。

因此,symfony加载validation.yml两次预先对bundle进行单独的声明。

通过将getParent函数移动到AppBundle声明中,并从AppKernel中删除第二个Bundle类声明及其初始化解决了这个问题。