我有一个实体'员工'我嵌入了一个实体' User'使用' sonata_type_admin'表单类型(一对一关系)。 当我创建一个新的Employee对象时,我想将默认值设置为User对象,但从不调用User __construct()或getNewInstance()方法。 我还注意到,当我编辑Employee时,用户验证约束不起作用(例如,如果我编辑员工并且我尝试设置已存在的用户名,则验证约束不会显示在用户名字段上)。如果我编辑用户,__ construct(),getNewInstance()和验证约束工作正常。
我该怎么办?
我从SonataUserBundle(FOSUserBundle)扩展了我的用户实体。
//User.orm.xml
...
<entity name="Application\Sonata\UserBundle\Entity\User" table="fos_user_user">
<id name="id" column="id" type="integer">
<generator strategy="AUTO" />
</id>
<one-to-one field="employee" target-entity="AppBundle\Entity\Employee" mapped-by="user" />
</entity>
</doctrine-mapping>
我的员工实体位于AppBundle。
//Employee.php
namespace AppBundle\Entity;
use Gedmo\Mapping\Annotation as Gedmo;
use Gedmo\Timestampable\Traits\TimestampableEntity;
use Doctrine\ORM\Mapping as ORM;
/**
* Session
*
* @ORM\Table(name="nup_employee")
* @ORM\Entity(repositoryClass="AppBundle\Entity\EmployeeRepository")
*/
class Employee
{
const STATUS_INACTIVE = 0;
const STATUS_ACTIVE = 1;
use TimestampableEntity;
/**
* @var integer
*
* @ORM\Column(name="id", type="integer")
* @ORM\Id
* @ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* @ORM\OneToOne(
* targetEntity="Application\Sonata\UserBundle\Entity\User",
* inversedBy="employee",
* cascade={"persist", "remove"}
* )
* @ORM\JoinColumn(name="user_id", referencedColumnName="id", nullable=true, onDelete="SET NULL")
*/
private $user;
...
我的configureFormFields。
//UserAdmin.php
...
protected function configureFormFields(FormMapper $formMapper)
{
$formMapper
->with('General')
->add('username')
->add('email')
->add('plainPassword', 'text', array(
'required' => (!$this->getSubject() || is_null($this->getSubject()->getId()))
))
->end()
;
$formMapper
->with('Security')
->add('enabled', null, array('required' => false))
->add('locked', null, array('required' => false))
->add('token', null, array('required' => false))
->add('twoStepVerificationCode', null, array('required' => false))
->end()
;
}
...
Composer.json:
...
"symfony/symfony": "2.7.*",
...
"friendsofsymfony/user-bundle": "~1.3",
"sonata-project/admin-bundle": "2.3.*",
"sonata-project/doctrine-orm-admin-bundle": "2.3.*",
"sonata-project/user-bundle": "^2.2"
答案 0 :(得分:1)
最后,我找到了解决方案(@anegrea感谢您的帮助)。
Sonata不会在Employee create上调用User构造,因为它不知道它是否可以为空(如果因为需要用户而创建用户则不同)。如果要在Employee上调用User构造,则必须将数据放在相关字段上。
class EmployeeAdmin extends Admin
{
...
protected function configureFormFields(FormMapper $formMapper)
{
$data = new User();
if ($this->getSubject()->getUser()) {
$data = $this->getSubject()->getUser();
}
$formMapper
->with('General', array('class' => 'col-md-6'))
->add('name')
->add('surnames')
->end()
->with('Access', array('class' => 'col-md-6'))
->add('user', 'sonata_type_admin',
array(
'data' => $data,
'label' => false
),
array(
'admin_code' => 'sonata.user.admin.user',
'edit' => 'inline'
)
)
->end()
;
}
...
}
另一方面,为了在创建或编辑Employee时显示用户字段的错误,我必须在Employee实体中的用户映射中添加Valid约束,并在EmployeeAdmin中添加与FOSUserBundle相关的验证组。
class Employee
{
...
/**
* @ORM\OneToOne(
* targetEntity="Application\Sonata\UserBundle\Entity\User",
* inversedBy="employee",
* cascade={"persist", "remove"}
* )
* @ORM\JoinColumn(name="user_id", referencedColumnName="id", nullable=true, onDelete="SET NULL")
* @Assert\Valid
*/
private $user;
...
}
class EmployeeAdmin extends Admin
{
public function getFormBuilder()
{
$this->formOptions['data_class'] = $this->getClass();
$options = $this->formOptions;
$options['validation_groups'] = array('Default');
array_push($options['validation_groups'], (!$this->getSubject() || is_null($this->getSubject()->getId())) ? 'Registration' : 'Profile');
$formBuilder = $this->getFormContractor()->getFormBuilder($this->getUniqid(), $options);
$this->defineFormBuilder($formBuilder);
return $formBuilder;
}
...
}
答案 1 :(得分:0)
对于验证,您必须将Employee实体上的约束添加为$ user属性为Valid。 http://symfony.com/doc/current/reference/constraints/Valid.html
如果还存在持久性问题,可能是因为您在员工管理员,preUpdate / prePersist(这些是管理员知道的功能)中具有双向关系,您还必须将员工链接到用户做类似的事情:
public function prePersist($object) {
$object->getUser()->setEmployee($object);
}
或者,您可以尝试仅在用户上映射用户(不使用反向直接)。