2017-10-18 24 views
0

Je travaille actuellement sur un projet Symfony v3.3.6. J'ai un formulaire pour la création d'utilisateur. Je voudrais m'assurer que l'email et le nom d'utilisateur (de fos user bundle) sont uniques.Symfony - La contrainte d'entité unique ne fonctionne pas

Je possède actuellement ce modèle (seulement une petite partie):

<?php 

namespace ProjectBundle\Entity\User; 

use Doctrine\ORM\Mapping as ORM; 
use FOS\UserBundle\Model\User as BaseUser; 
use Gedmo\Mapping\Annotation as Gedmo; 
use Gedmo\SoftDeleteable\Traits\SoftDeleteableEntity; 
use Gedmo\Timestampable\Traits\TimestampableEntity; 
use ProjectBundle\Entity\Gender\Gender; 
use ProjectBundle\Entity\Organisation\Organisation; 
use ProjectBundle\Entity\Traits\BlameableEntity; 
use ProjectBundle\Entity\User\Profile; 
use Symfony\Component\Security\Core\User\AdvancedUserInterface; 
use Symfony\Component\Validator\Constraints as Assert; 
use Symfony\Component\Validator\Context\ExecutionContextInterface; 
use Doctrine\Common\Collections\ArrayCollection; 
use Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity; 
use Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntityValidator; 


/** 
* @ORM\Entity(repositoryClass="ProjectBundle\Repository\User\UserRepository") 
* @Gedmo\SoftDeleteable(fieldName="deletedAt") 
* @ORM\Entity 
* @UniqueEntity(fields={"email"}, groups={"registration"}) 
* @UniqueEntity(fields={"username"}, groups={"registration"}) 
* @ORM\Table(name="user") 
*/ 
class User extends BaseUser implements AdvancedUserInterface, \Serializable 
{ 
    use TimestampableEntity; 
    use SoftDeleteableEntity; 
    use BlameableEntity; 

    const ID_ORGA_GC = 1; 

    /** 
    * @var int 
    * 
    * @ORM\Column(name="id", type="integer") 
    * @ORM\Id 
    * @ORM\GeneratedValue(strategy="AUTO") 
    */ 
    protected $id; 


    /** 
    * @Assert\NotBlank() 
    */ 
    protected $username; 

    /** 
    * @Assert\NotBlank(groups={"registration"}) 
    * @Assert\Length(groups={"registration"}, 
    *  min = 2, 
    *  max = 254, 
    *  minMessage = "Votre mot de passe doit comporter au minimum {{ limit }} caractères.", 
    *  maxMessage = "Votre mot de passe doit comporter au maximum {{ limit }} caractères." 
    *) 
    * 
    * @var string 
    */ 
    protected $plainPassword; 


    /** 
    * @Assert\NotBlank() 
    * @Assert\Email(
    *  message = "L'adresse mail '{{ value }}' n'est pas valide.", 
    *  checkMX = true 
    *) 
    * 
    * @var string 
    */ 
    protected $email; 

Comme vous pouvez le voir, j'ajouté attribut 2 « entité unique », nom d'utilisateur et email, également avec une contrainte « NotBlank » sur chaque .

Dans mon contrôleur, je l'appelle ma forme:

$form = $this->createForm('ProjectBundle\Form\User\UserType', $entity,array('organisation' => $organisations, 'validation_groups' => array('Default','registration'))); 

$form->handleRequest($request); 

     if ($form->isSubmitted()) { 
      if ($form->isValid()) { 

Cependant, même si j'écris une adresse e-mail qui existe déjà, je vais dans l'état, et quand vient le temps pour I flush obtenir une grande erreur SQL:

SQLSTATE [23000]: Integrity constraint violation: 1062 Duplicate entry '[email protected]' for key 'UNIQ_8D93D649A0D96FBF' 

Mais remarque intéressante est que la contrainte « NotBlank » fonctionne correctement, et me montre sur mon point de vue « la valeur ne peut pas être vide »

Voici ma forme:

class UserType extends AbstractType 
{ 
    /** 
    * {@inheritdoc} 
    */ 
    public function buildForm(FormBuilderInterface $builder, array $options) 
    { 
     $builder->add('lastname',null,array('required' => true)) 
      ->add('firstname') 
      ->add('gender',null,array('required'=>true)) 
      ->add('organisationMember',null,array(
       'required' => true, 
       'choices' => $options['organisation'], 
       'group_by' => 'type_organisation', 
       'placeholder' => 'Choisissez votre organisation' 
      )) 
      ->add('job') 
      ->add('lang', null, array(
       'required' => true 
      )) 
      ->add('mobile',null, array(
       'required' => false 
      )) 
      ->add('phone', null, array(
       'required' => true 
      )) 
      ->add('enabled') 
      ->add('is_external') 
      ->add('alert_failure') 
      ->add('alert_full') 
      ->add('alert_other') 
      ->add('plainPassword', TextType::class, array('required' => false)) 
      ->add('email') 
      ->add('profile', null, array(
       'required' => true, 
       'placeholder' => 'Choose an organisation !', 
      )); 
    } 

    /** 
    * {@inheritdoc} 
    */ 
    public function configureOptions(OptionsResolver $resolver) 
    { 
     $resolver->setDefaults(array(
      'data_class' => 'ProjectBundle\Entity\User\User', 
      'organisation' => 'ProjectBundle\Entity\Organisation\Organisation', 
      'profiles' => 'ProjectBundle\Entity\User\Profile', 
      'csrf' => true, 
     )); 

    } 
} 

Si quelqu'un a une solution.

Merci d'avance!

+0

Copie possible de [champs Doctrine 2 @Gedmo \ SoftDeleteable et uniques] (https://stackoverflow.com/questions/33533761/doctrine-2-gedmo-softdeleteable-and-unique-fields) –

+0

L'erreur est presque identique mais la solution proposée ne fonctionne pas, j'ai toujours l'exception SQL. –

Répondre

0

Avez-vous essayé comme ceci:

/** 
* @ORM\Entity(repositoryClass="ProjectBundle\Repository\User\UserRepository") 
* @Gedmo\SoftDeleteable(fieldName="deletedAt") 
* @ORM\Entity 
* @UniqueEntity(fields={"email", "username"}, groups={"registration"}) 
* @ORM\Table(name="user") 
*/ 

Mais assurez-vous que vous avez un index unique pour le courrier électronique et nom d'utilisateur.

+0

Votre solution fonctionne uniquement dans DEV. Lorsque je mets à jour les modifications apportées à PROD, l'exception est toujours présente. (La base de données est prête avec un bon index) –

0

Actuellement, la réponse @ CarcaBot ne fonctionne que dans DEV, la mise à jour ne modifie pas mon problème dans PROD tant que les fichiers sont identiques, ainsi que la base de données.

Une idée?