我有一个
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
,即使它们是从表单传递的,它们也没有水合到对象中。
我的代码有什么问题?有没有更好的方法使用复选框来做到这一点?
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
),
// ...
),
),
),
));
// ...
}
// ...
}
您错误地处理了角色权限。使用 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
)
);
}
}
在 Zend Framework 2 (ZF2) 和 Doctrine 2 中,如果您想与复选框建立一对多关系,通常会创建一个表单,允许用户使用复选框选择多个选项(相关实体)。以下是如何设置的总体概述:
假设您有两个实体:
ParentEntity
和 ChildEntity
。 ParentEntity
与 ChildEntity
具有一对多关系。
为
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',
],
]);
}
}
在控制器操作中,您将处理表单提交并使用选定的
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 随着时间的推移而不断发展,请考虑参考您正在使用的版本的官方文档,以获得最准确和最新的信息。
当使用 Zend Framework 2 和 Doctrine 2 进行一对多关系和水合复选框时,您可以按照以下步骤操作:
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 ...
}
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;
}
}
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 创建带有用于一对多关系的复选框的表单。