forms - symfony2 validation of child entity prevents editing of parent entity -
i have run problem couple of entities thought try , hang of goes on, , turn best source here (will add bounty question eligible).
my user part of user group. have validator usergroup entity make sure no 2 usergroups have same name.
the problem when go editing user, , try select usergroup user, symfony2 behaving if trying create usergroup same name, when in reality doing trying select usergroup user.
a user entity
<?php // src/biztv/userbundle/entity/user.php namespace biztv\userbundle\entity; use biztv\userbundle\validator\constraints biztvassert; use symfony\component\security\core\user\advanceduserinterface; use fos\userbundle\entity\user baseuser; use doctrine\orm\mapping orm; use biztv\backendbundle\entity\company company; /** * @orm\entity * @orm\table(name="fos_user") */ class user extends baseuser implements advanceduserinterface { /** * @orm\id * @orm\column(type="integer") * @orm\generatedvalue(strategy="auto") */ protected $id; //todo: add constraint on $name * @biztvassert\nameexists (and finish coding constraint) /** * @var object biztv\backendbundle\entity\company * * @orm\manytoone(targetentity="biztv\backendbundle\entity\company") * @orm\joincolumn(name="company", referencedcolumnname="id", nullable=false) */ protected $company; /** * @var object biztv\userbundle\entity\usergroup * @orm\manytoone(targetentity="biztv\userbundle\entity\usergroup") * @orm\joincolumn(name="usergroup", referencedcolumnname="id", nullable=true) */ protected $usergroup; /** * @orm\manytomany(targetentity="biztv\containermanagementbundle\entity\container", inversedby="users") * @orm\jointable(name="access") */ private $access; /** * @var object biztv\containermanagementbundle\entity\container * * applies biztv server user accounts or "screen display accounts". others have null here. * * @orm\manytoone(targetentity="biztv\containermanagementbundle\entity\container") * @orm\joincolumn(name="screen", referencedcolumnname="id", nullable=true) */ protected $screen; /** * @orm\column(type="boolean", nullable=true) */ protected $isserver; public function __construct() { parent::__construct(); $this->access = new \doctrine\common\collections\arraycollection(); } /** * id * * @return integer */ public function getid() { return $this->id; } /** * set company * * @param biztv\backendbundle\entity\company $company */ public function setcompany(\biztv\backendbundle\entity\company $company) { $this->company = $company; } /** * company * * @return biztv\backendbundle\entity\company */ public function getcompany() { return $this->company; } /** * add access * * @param biztv\containermanagementbundle\entity\container $access */ public function addcontainer(\biztv\containermanagementbundle\entity\container $access) { $this->access[] = $access; } /** * access * * @return doctrine\common\collections\collection */ public function getaccess() { return $this->access; } /** * set screen * * @param biztv\containermanagementbundle\entity\container $screen */ public function setscreen(\biztv\containermanagementbundle\entity\container $screen) { $this->screen = $screen; } /** * screen * * @return biztv\containermanagementbundle\entity\container */ public function getscreen() { return $this->screen; } /** * set isserver * * @param boolean $isserver */ public function setisserver($isserver) { $this->isserver = $isserver; } /** * isserver * * @return boolean */ public function getisserver() { return $this->isserver; } /** * set usergroup * * @param biztv\userbundle\entity\usergroup $usergroup */ public function setusergroup(\biztv\userbundle\entity\usergroup $usergroup = null) { $this->usergroup = $usergroup; } /** * usergroup * * @return biztv\userbundle\entity\usergroup */ public function getusergroup() { return $this->usergroup; } } the usergroup entity user linked to:
<?php namespace biztv\userbundle\entity; use biztv\userbundle\validator\constraints biztvassert; use doctrine\orm\mapping orm; use symfony\component\validator\constraints assert; /** * biztv\userbundle\entity\usergroup * * @orm\table() * @orm\entity */ class usergroup { /** * @var integer $id * * @orm\column(name="id", type="integer") * @orm\id * @orm\generatedvalue(strategy="auto") */ private $id; /** * @var string $name * @biztvassert\nameexists * @orm\column(name="name", type="string", length=255) * @assert\notblank(message = "du måste ange ett gruppnamn") */ private $name; /** * @var object biztv\backendbundle\entity\company * * @orm\manytoone(targetentity="biztv\backendbundle\entity\company") * @orm\joincolumn(name="company", referencedcolumnname="id", nullable=false) */ protected $company; /** * id * * @return integer */ public function getid() { return $this->id; } /** * set name * * @param string $name */ public function setname($name) { $this->name = $name; } /** * name * * @return string */ public function getname() { return $this->name; } /** * set company * * @param biztv\backendbundle\entity\company $company */ public function setcompany(\biztv\backendbundle\entity\company $company) { $this->company = $company; } /** * company * * @return biztv\backendbundle\entity\company */ public function getcompany() { return $this->company; } } the nameexistsvalidator
<?php namespace biztv\userbundle\validator\constraints; use symfony\component\validator\constraint; use symfony\component\validator\constraintvalidator; use symfony\component\dependencyinjection\containerinterface container; use doctrine\orm\entitymanager entitymanager; class nameexistsvalidator extends constraintvalidator { private $container; private $em; public function __construct(container $container, entitymanager $em) { $this->container = $container; $this->em = $em; } public function isvalid($value, constraint $constraint) { $em = $this->em; $container = $this->container; $company = $this->container->get('security.context')->gettoken()->getuser()->getcompany(); //fetch entities same name $repository = $em->getrepository('biztvuserbundle:usergroup'); //$repository = $this->getdoctrine()->getrepository('biztvcontainermanagementbundle:container'); $query = $repository->createquerybuilder('c') ->where('c.company = :company') ->setparameter('company', $company) ->orderby('c.name', 'asc') ->getquery(); $groups = $query->getresult(); foreach ($groups $g) { if ($g->getname() == $value) { $this->setmessage('namnet '.$value.' är upptaget, vänligen välj ett annat', array('%string%' => $value)); return false; } } return true; } } user edit form
<?php namespace biztv\userbundle\form; use symfony\component\form\abstracttype; use symfony\component\form\formbuilder; use symfony\component\form\forminterface; use symfony\component\form\callbackvalidator; use symfony\component\form\formvalidatorinterface; use symfony\component\form\formerror; use doctrine\orm\entityrepository; class editusertype extends abstracttype { function __construct($company) { $this->company = $company; } public function buildform(formbuilder $builder, array $options) { $company = $this->company; $builder ->add('locked', 'checkbox', array('label' => 'kontot är låst, användaren kan inte logga in ')) ->add('username', 'text', array('label' => 'användarnamn ')) ; $builder ->add('usergroup', 'entity', array( 'label' => 'användargrupp', 'empty_value' => 'ingen grupptillhörighet', 'property' => 'name', 'class' => 'biztv\userbundle\entity\usergroup', 'query_builder' => function(\doctrine\orm\entityrepository $er) use ($company) { $qb = $er->createquerybuilder('a'); $qb->where('a.company = :company'); $qb->setparameters( array('company' => $company) ); $qb->orderby('a.name', 'asc'); return $qb; } )); $builder ->add('email', 'email', array('label' => 'epost ')) ->add('plainpassword', 'repeated', array('type' => 'password', 'first_name' => 'nytt lösenord ', 'second_name' => 'upprepa lösenord ',)); $builder ->add('roles', 'choice', array( 'label' => 'roller', 'expanded' => true, 'multiple' => true, 'choices' => array( 'role_content' => 'innehåll (användaren kan lägga till, redigera och ta bort innehåll där du nedan beviljar åtkomst)', 'role_layout' => 'skärmlayout (användaren kan skapa ny skärmlayout, redigera befintlig eller ta bort gällande skärmlayout där du nedan beviljar åtkomst)', 'role_video' => 'videouppladdning (användaren har rätt att ladda upp videofiler till företagets mediabibliotek)', 'role_admin' => 'administratör (användaren är administratör med fulla rättigheter till allt precis som det konto du nu är inloggad på, var mycket restriktiv med att tilldela denna behörighet).', ), )) ; $builder ->add('access', 'entity', array( 'label' => 'behörigheter', 'multiple' => true, // multiple selection allowed 'expanded' => true, // render checkboxes 'property' => 'select_label', 'class' => 'biztv\containermanagementbundle\entity\container', 'query_builder' => function(\doctrine\orm\entityrepository $er) use ($company) { $qb = $er->createquerybuilder('a'); $qb->innerjoin('a.containertype', 'ct'); $qb->where('a.containertype in (:containers)', 'a.company = :company'); $qb->setparameters( array('containers' => array(1,2,3,4), 'company' => $company) ); $qb->orderby('ct.id', 'asc'); return $qb; } )); $builder-> addvalidator(new callbackvalidator(function(forminterface $form){ $email = $form->get('email')->getdata(); if (empty( $email )) { $form['email']->adderror(new formerror("du måste ange en epostadress för användaren")); } })); $builder-> addvalidator(new callbackvalidator(function(forminterface $form){ $username = $form->get('username')->getdata(); if (strpos($username,'#') !== false) { $form['username']->adderror(new formerror("användarnamnet får inte innehålla tecknet #")); } })); $builder-> addvalidator(new callbackvalidator(function(forminterface $form){ $username = $form->get('username')->getdata(); if (empty($username)) { $form['username']->adderror(new formerror("du måste ange ett namn för användaren")); } })); //todo check if username exists } public function getname() { return 'biztv_userbundle_newusertype'; } }
your nameexistsvalidator this:
- fail if find any user-group name i'm checking.
but think want this:
- fail if find another user-group name i'm checking.
in other words: validator needs complete usergroup entity (or @ least id , name) check user-group same name different id.
symfony 2 has uniqueentity validator, why don't use it?
using annotations this:
/** * @orm\entity * @assertuniqueentity(fields={"name"}, message="this name exists") */ class usergroup {
Comments
Post a Comment