简体   繁体   English

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

[英]Construct or validation does not work when I embed an entity with sonata_type_admin

I have an entity 'Employee' and I embed an entity 'User' with 'sonata_type_admin' form type (one to one relation). 我有一个实体“ Employee”,并且嵌入了一个具有“ sonata_type_admin”表单类型(一对一关系)的实体“ User”。 When I create a new Employee object I want to set default values to User object, but User __construct() or getNewInstance() method is never called. 创建新的Employee对象时,我想将默认值设置为User对象,但是从未调用User __construct()或getNewInstance()方法。 I also noticed that user validation constraints don't work when I edit an Employee (for instance, if I edit an employee and I try to set an username that already exists, validation constraint is not displayed on username field). 我还注意到,在编辑Employee时,用户验证约束不起作用(例如,如果我编辑一名员工并且尝试设置一个已经存在的用户名,则验证约束不会显示在用户名字段中)。 If I edit an user, __construct(), getNewInstance() and validation constraints works fine. 如果我编辑用户__construct(),getNewInstance()和验证约束,则工作正常。

What can I do? 我能做什么?

I extended my user entity from SonataUserBundle (FOSUserBundle). 我从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>

My Employee entity is in AppBundle. 我的员工实体在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;
...

My configureFormFields. 我的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: 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"

Finally, I found the solution (@anegrea thanks for your help). 最后,我找到了解决方案(@anegrea感谢您的帮助)。

Sonata doesn't call User construct on Employee create because it doesn't know if it's nullable or not (it's different if you create a user because the user is required). Sonata不会在Employee create上调用User构造,因为它不知道它是否可以为空(创建用户是不同的,因为用户是必需的)。 if you want to call User construct on Employee create you have to put data on related field. 如果要在Employee create上调用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()
        ;
    }
...
}

On the other hand, to show errors on User fields when I create or edit an Employee, I had to add Valid constraint on user mapping in Employee entity and add validation groups related to FOSUserBundle in EmployeeAdmin. 另一方面,要在创建或编辑Employee时在User字段上显示错误,我必须在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;
    }
...
}

For the validation you have to add the constraint on the Employee entity for the $user property to be Valid. 为了进行验证,您必须在Employee实体上添加约束,以使$ user属性有效。 http://symfony.com/doc/current/reference/constraints/Valid.html http://symfony.com/doc/current/reference/constraints/Valid.html

If there is a problem with persisting also, it might be because you are having the bidirectional relation that in you employee admin, on preUpdate/prePersist (these are funcitons the admin knows about) you must also link the employee to the user by doing something like: 如果还存在持久性问题,则可能是因为您的员工管理员中存在双向关系,在preUpdate / prePersist(管理员知道的这些功能)上,您还必须通过执行某些操作将员工链接到用户喜欢:

public function prePersist($object) {
    $object->getUser()->setEmployee($object);
}

Or, you can try to have only the user mapped on the employee (without the inversedBy directve). 或者,您可以尝试仅将用户映射到员工(没有反向指令)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM