Zend Framework 2 Doctrine 2 一对多复选框水合

问题描述 投票:0回答:4

我有一个

ManyToMany
,我闯入了
OneToMany
ManyToOne
关系。我想构建一个具有复选框而不是集合的表单,并且我正在使用“DoctrineObject”水化器,但它不起作用,我不知道出了什么问题。

我从代码中删除了所有其他不相关字段。

角色实体:

/**
 * @orm\Entity
 * @orm\Table(name="roles")
 */
class RolesEntity extends HemisEntity {
    /**
     * @orm\Id
     * @orm\Column(type="integer");
     * @ORM\GeneratedValue(strategy="IDENTITY")
     */
    protected $id;
    
    /**
     * @orm\Column(name="role_code",type="string")
     */
    protected $roleCode;

    /**
     * @orm\OneToMany(targetEntity="RolesPermissionsEntity", mappedBy="role", cascade={"persist"})
     */
    protected $rolePermissions;

    public function __construct()
    {
        $this->rolePermissions = new ArrayCollection();
    }

    public function setRolePermissions($rolePermissions)
    {
        $this->rolePermissions = $rolePermissions;
        return $this;
    }
    
    public function addRolePermissions(Collection $rolePermissions)
    {
        foreach ($rolePermissions as $rolePermission) {
            $rolePermission->setRole($this);
            $this->rolePermissions->add($rolePermission);
        }
    }
    
    public function removeRolePermissions(Collection $rolePermissions)
    {
        foreach ($rolePermissions as $rolePermission) {
            $rolePermission->setRole(null);
            $this->rolePermissions->removeElement($rolePermission);
        }
    }
    
    public function getRolePermissions()
    {
        return $this->rolePermissions;
    }
}

ManyToMany 表实体它有更多字段,所以我破坏了它):

    /**
 * @orm\Entity
 * @orm\Table(name="roles_permissions")
 */
class RolesPermissionsEntity extends HemisEntity {
    /**
     * @orm\Id
     * @orm\Column(type="integer");
     * @ORM\GeneratedValue(strategy="IDENTITY")
     */
    protected $id;
    
    /**
     * @orm\ManyToOne(targetEntity="RolesEntity", inversedBy="rolePermissions")
     * @orm\JoinColumn(name="role_id", referencedColumnName="id")
     **/
    protected $role;
    
    /**
     * @orm\ManyToOne(targetEntity="PermissionsEntity", inversedBy="permissionRoles")
     * @orm\JoinColumn(name="permission_id", referencedColumnName="id")
     **/
    protected $permission;
    
    public function setRole($role)
    {
        $this->role = $role;
        return $this;
    }
    
    public function getRole()
    {
        return $this->role;
    }

    public function setPermission($permission)
    {
        $this->permission = $permission;
        return $this;
    }

    public function getPermission()
    {
        return $this->permission;
    }
}

我的表格看起来像这样

class RoleForm extends Form implements InputFilterProviderInterface
{
    public function __construct(ObjectManager $objectManager)
    {
        parent::__construct('role');

        $this->setHydrator(new DoctrineHydrator($objectManager))
             ->setObject(new RolesEntity());

        $this->add(array(
            'type' => 'Zend\Form\Element\Hidden',
            'name' => 'id'
        ));

        $this->add(array(
            'type'    => 'Zend\Form\Element\Text',
            'name'    => 'roleCode',
            'options' => array(
                'label' => 'Role Code'
            ),
        ));

        $this->add(array(
            'name' => 'rolePermissions',
            'type' => 'DoctrineModule\Form\Element\ObjectMultiCheckbox',
            'options' => array(
                'label' => 'Permissions',
                'object_manager' => $objectManager,
                'target_class'   => 'Hemis\Fnd\PermissionsEntity',
                'property'       => 'permissionDesc'
            ),
        ));
        
        $this->add(array(
            'name' => 'submit',
            'type'  => 'Submit',
            'attributes' => array(
                'value' => 'Submit',
            ),
        ));
    }

    public function getInputFilterSpecification()
    {
        return array(
            'roleCode' => array(
                'required' => false
            ),
            'rolePermissions' => array(
                'required' => true
            )
        );
    }
}

问题是,当我转储

$role
时,它不包含任何
rolePermissions
,即使它们是从表单传递的,它们也没有水合到对象中。

我的代码有什么问题?有没有更好的方法使用复选框来做到这一点?

php doctrine-orm zend-framework2 zend-form2
4个回答
0
投票
class RoleForm extends Form implements InputFilterProviderInterface
{
    public function __construct(ObjectManager $objectManager)
    {
        // ...

        $this->add(array(
            'name' => 'rolePermissions',
            'type' => 'Zend\Form\Element\Collection',
            'options' => array(
                'label' => 'Role Permissions',
                'count' => 0,
                'should_create_template' => true,
                'allow_add' => true,
                'target_element' => array(
                    'type' => 'Zend\Form\Fieldset',
                    'options' => array(
                        'use_as_base_fieldset' => true
                    ),
                    'elements' => array(
                        // add form fields for the properties of the RolesPermissionsEntity class here
                        array(
                            'name' => 'id',
                            'type' => 'Zend\Form\Element\Hidden',
                        ),
                        array(
                            'name' => 'role',
                            'type' => 'Zend\Form\Element\Checkbox',
                            // other options
                        ),
                        // ...
                    ),
                ),
            ),
        ));

        // ...
    }

    // ...
}

0
投票

您错误地处理了角色权限。使用 DoctrineHydrator 时,您需要确保该字段的属性配置为处理与 RolesPermissionsEntity 的关联

class RoleForm extends Form implements InputFilterProviderInterface
{
    public function __construct(ObjectManager $objectManager)
    {
        parent::__construct('role');

        $this->setHydrator(new DoctrineHydrator($objectManager))
             ->setObject(new RolesEntity());

        $this->add(array(
            'type' => 'Zend\Form\Element\Hidden',
            'name' => 'id'
        ));

        $this->add(array(
            'type'    => 'Zend\Form\Element\Text',
            'name'    => 'roleCode',
            'options' => array(
                'label' => 'Role Code'
            ),
        ));

        $this->add(array(
            'name' => 'rolePermissions',
            'type' => 'DoctrineModule\Form\Element\ObjectMultiCheckbox',
            'options' => array(
                'label' => 'Permissions',
                'object_manager' => $objectManager,
                'target_class'   => 'Hemis\Fnd\RolesPermissionsEntity', // Update the target class to RolesPermissionsEntity
                'property'       => 'permission', // Update the property to permission
                'is_method'      => true, // Add this line
                'find_method'    => array( // Add this line
                    'name'   => 'findPermissionsForRole', // Replace with your custom method name
                    'params' => array(
                        'criteria' => array('role' => $this->getObject()), // Use the getObject() method to get the current RolesEntity object
                    ),
                ),
            ),
        ));

        $this->add(array(
            'name' => 'submit',
            'type'  => 'Submit',
            'attributes' => array(
                'value' => 'Submit',
            ),
        ));
    }

    public function getInputFilterSpecification()
    {
        return array(
            'roleCode' => array(
                'required' => false
            ),
            'rolePermissions' => array(
                'required' => true
            )
        );
    }
}

0
投票

在 Zend Framework 2 (ZF2) 和 Doctrine 2 中,如果您想与复选框建立一对多关系,通常会创建一个表单,允许用户使用复选框选择多个选项(相关实体)。以下是如何设置的总体概述:

  1. 实体设置:

假设您有两个实体:

ParentEntity
ChildEntity
ParentEntity
ChildEntity
具有一对多关系。

  1. 表格设置:

ParentEntity
创建一个表单,其中包含用于选择
ChildEntity
实例的复选框。您通常会使用
Collection
表单元素来处理多个相关实体。

use Zend\Form\Form;
use DoctrineModule\Form\Element\ObjectMultiCheckbox;

class ParentForm extends Form
{
    public function init()
    {
        $this->add([
            'type' => ObjectMultiCheckbox::class,
            'name' => 'children',
            'options' => [
                'object_manager' => $this->getEntityManager(),
                'target_class'   => ChildEntity::class,
                'property'       => 'id', // Property to use as checkbox value
                'label'          => 'Children',
            ],
        ]);
    }
}
  1. 控制器动作:

在控制器操作中,您将处理表单提交并使用选定的

ParentEntity
实例来填充
ChildEntity

use Zend\Mvc\Controller\AbstractActionController;
use YourModule\Form\ParentForm;
use YourModule\Entity\ParentEntity;

class SomeController extends AbstractActionController
{
    public function someAction()
    {
        $form = new ParentForm();
        $request = $this->getRequest();

        if ($request->isPost()) {
            $data = $request->getPost();
            $form->setData($data);

            if ($form->isValid()) {
                $parentEntity = new ParentEntity();
                $form->bind($parentEntity);

                $entityManager = $this->getServiceLocator()->get('Doctrine\ORM\EntityManager');
                $entityManager->persist($parentEntity);
                $entityManager->flush();
            }
        }

        return ['form' => $form];
    }
}

在此示例中,提交表单后,所选的

ChildEntity
实例将被合并到
ParentEntity
中并持久保存到数据库中。

请记住,上面的示例提供了使用 Zend Framework 2 和 Doctrine 2 处理一对多关系和复选框的基本结构。您可能需要调整和扩展此代码以满足您的特定应用程序的要求。此外,由于 ZF2 和 Doctrine 2 随着时间的推移而不断发展,请考虑参考您正在使用的版本的官方文档,以获得最准确和最新的信息。


-3
投票

当使用 Zend Framework 2 和 Doctrine 2 进行一对多关系和水合复选框时,您可以按照以下步骤操作:

  1. 定义实体:创建两个实体,例如
    User
    Role
    User
    实体将与
    Role
    实体具有一对多关系。
namespace Application\Entity;

use Doctrine\ORM\Mapping as ORM;
use Doctrine\Common\Collections\ArrayCollection;

/**
 * @ORM\Entity
 * @ORM\Table(name="users")
 */
class User
{
    // ... entity definitions ...

    /**
     * @ORM\OneToMany(targetEntity="Role", mappedBy="user", cascade={"persist", "remove"})
     */
    protected $roles;

    public function __construct()
    {
        $this->roles = new ArrayCollection();
    }

    // ... getters and setters ...
}

/**
 * @ORM\Entity
 * @ORM\Table(name="roles")
 */
class Role
{
    // ... entity definitions ...

    /**
     * @ORM\ManyToOne(targetEntity="User", inversedBy="roles")
     * @ORM\JoinColumn(name="user_id", referencedColumnName="id")
     */
    protected $user;

    // ... getters and setters ...
}
  1. 创建表单:为
    User
    实体创建一个表单,其中包含用于选择角色的复选框。
namespace Application\Form;

use Zend\Form\Form;
use Zend\Form\Element;
use DoctrineModule\Form\Element\ObjectMultiCheckbox;
use DoctrineModule\Persistence\ObjectManagerAwareInterface;
use Doctrine\Common\Persistence\ObjectManager;

class UserForm extends Form implements ObjectManagerAwareInterface
{
    protected $objectManager;

    public function __construct(ObjectManager $objectManager)
    {
        parent::__construct('user-form');
        $this->setObjectManager($objectManager);

        // ... add other form elements ...

        $rolesField = new ObjectMultiCheckbox('roles');
        $rolesField->setOptions([
            'object_manager' => $objectManager,
            'target_class' => 'Application\Entity\Role',
            'property' => 'id',
        ]);
        $this->add($rolesField);
    }

    public function setObjectManager(ObjectManager $objectManager)
    {
        $this->objectManager = $objectManager;
    }

    public function getObjectManager()
    {
        return $this->objectManager;
    }
}
  1. 控制器操作:在控制器操作中,处理表单提交并填充相关实体。
namespace Application\Controller;

use Zend\Mvc\Controller\AbstractActionController;
use Application\Form\UserForm;
use Application\Entity\User;

class UserController extends AbstractActionController
{
    protected $objectManager;

    public function indexAction()
    {
        $form = new UserForm($this->getObjectManager());

        if ($this->getRequest()->isPost()) {
            $user = new User();
            $form->bind($user);
            $form->setData($this->getRequest()->getPost());

            if ($form->isValid()) {
                $this->getObjectManager()->persist($user);
                $this->getObjectManager()->flush();

                // handle successful form submission
                // redirect or display success message
            }
        }

        return ['form' => $form];
    }

    public function setObjectManager(ObjectManager $objectManager)
    {
        $this->objectManager = $objectManager;
    }

    public function getObjectManager()
    {
        return $this->objectManager;
    }
}

确保正确配置 Doctrine 2 和 Zend Framework 2 环境,包括数据库连接、实体映射和实体管理器的依赖注入。

通过这些步骤,您应该能够使用 Zend Framework 2 和 Doctrine 2 创建带有用于一对多关系的复选框的表单。

© www.soinside.com 2019 - 2024. All rights reserved.