当我使用sonata_type_admin嵌入实体时,构造或验证不起作用

时间:2015-12-08 17:50:08

标签: symfony sonata-admin sonata-user-bundle

我有一个实体'员工'我嵌入了一个实体' 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"

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);
}

或者,您可以尝试仅在用户上映射用户(不使用反向直接)。