tobias / zend-form-doctrine
使用 Zend\Form\Element 与 Doctrine 对象
Requires
- php: ^7.3
- doctrine/collections: ^1.6
- doctrine/inflector: ^1.2
- doctrine/persistence: ^1.0
- zendframework/zend-form: ^2.14
Requires (Dev)
- phpunit/phpunit: ^8.2
- squizlabs/php_codesniffer: ^3.4
- zendframework/zend-servicemanager: ^2.7.5 || ^3.0.3
This package is auto-updated.
Last update: 2020-02-01 19:22:55 UTC
README
受著名的 DoctrineModule 启发并基于此开发。
此包包含功能,可以自动用来自动填充 Select、MultiCheckbox 或 Radio 表单元素的 ValueOptions
数据,这些数据来自 ObjectRepository
。
使用方法
将 Tobias\Zend\Form\Doctrine\Element\ObjectSelect
、Tobias\Zend\Form\Doctrine\Element\ObjectRadio
或 Tobias\Zend\Form\Doctrine\Element\ObjectMultiCheckbox
添加到您的表单中。为此,您需要指定至少一个 object_manager
、要使用的 target_class
以及用作标签的类的 property
。
示例 1:简单示例
namespace Module\Form; use Zend\Form\Form; use Doctrine\Common\Persistence\ObjectManager; class MyForm extends Form { protected $objectManager; public function init() { $this->add([ 'type' => 'Tobias\Zend\Form\Doctrine\Element\ObjectSelect', 'name' => 'name', 'options' => [ 'object_manager' => $this->getObjectManager(), 'target_class' => 'Module\Entity\SomeEntity', 'property' => 'property', ], ]); } }
当表单被渲染时,默认情况下将执行 ObjectRepository
的 findAll
方法。
示例 2:修改标签
当您想更改标签的显示时,您需要使用 label_generator
选项。此选项允许您根据需要修改标签。在下面的简单示例中,我将使用连字符连接两个属性。
$this->add([ 'type' => 'Tobias\Zend\Form\Doctrine\Element\ObjectSelect', 'name' => 'name', 'options' => [ 'object_manager' => $this->getObjectManager(), 'target_class' => 'Module\Entity\SomeEntity', 'label_generator' => function ($targetEntity) { return $targetEntity->getId() . ' - ' . $targetEntity->getTitle(); }, ], ]);
可调用的函数将始终接收目标实体作为参数,因此您可以使用实体提供的所有功能。另一个示例是在您的网站有特定选项以提供更易于访问的标签时,完全切换标签。
$this->add([ 'type' => 'Tobias\Zend\Form\Doctrine\Element\ObjectSelect', 'name' => 'name', 'options' => [ 'object_manager' => $this->getObjectManager(), 'target_class' => 'Module\Entity\SomeEntity', 'label_generator' => function ($targetEntity) use ($someSession) { if ('accessible' === $someSession->getCurrentMode()) { return $targetEntity->getAccessibleLabel(); } return $targetEntity->getLabel(); }, ], ]);
示例 3:扩展版本
如果您不需要或不需要整个存储库,可以指定一个要使用的 find_method
。此方法必须在存储库中存在。以下示例执行 findBy
方法并传递指定参数,但使用自定义存储库时,可以进行更复杂的查询!您还可以将方法指定为属性,通过将 is_method
设置为 true 来实现。
$this->add([ 'type' => 'Tobias\Zend\Form\Doctrine\Element\ObjectSelect', 'name' => 'name', 'options' => [ 'object_manager' => $this->getObjectManager(), 'target_class' => 'Module\Entity\User', 'property' => 'ComposedOfSeveralProperties', 'is_method' => true, 'find_method' => [ 'name' => 'findBy', 'params' => [ 'criteria' => ['active' => 1], // Use key 'orderBy' if using ORM 'orderBy' => ['lastname' => 'ASC'], // Use key 'sort' if using ODM 'sort' => ['lastname' => 'ASC'], ], ], ], ]);
示例 4:包括空选项
如果您想在顶部包括一个空选项,请将 display_empty_item
设置为 true。您还可以指定 empty_item_label
设置,默认为空字符串。
$this->add([ 'type' => 'Tobias\Zend\Form\Doctrine\Element\ObjectSelect', 'name' => 'name', 'options' => [ 'object_manager' => $this->getObjectManager(), 'target_class' => 'Module\Entity\SomeEntity', 'property' => 'property', 'display_empty_item' => true, 'empty_item_label' => '---', ], ]);
示例 5:向元素添加 HTML 属性
要为每个 valueOption
设置自定义 HTML 属性,您可以使用 option_attributes
设置来指定键值对数组,其中键代表有效的 HTML 属性(data-,aria-,onEvent 等)。
值必须是 string
类型或 callable
类型(在这种情况下,需要返回 string
或可转换为字符串的东西)。请参阅以下示例
$this->add([ 'type' => 'Tobias\Zend\Form\Doctrine\Element\ObjectSelect', 'name' => 'test', 'options' => [ 'object_manager' => $this->getObjectManager(), 'target_class' => 'Module\Entity\SomeEntity', 'property' => 'property', 'option_attributes' => [ 'class' => 'styledOption', 'data-id' => function (\Module\Entity\SomeEntity $entity) { return $entity->getId(); }, ], ], ]);
上面的示例将生成带有 data-key 属性的 HTML 选项
<select name="test"> <option value="1" class="styledOption" data-id="1">property one</option> <option value="2" class="styledOption" data-id="2">property two</option> </select>
值得注意的是,当使用类型为 callable
的 option_attribute 值时,你不需要在函数中定义完全限定的类名。传递给函数的对象将始终与你在 target_class
键上定义的类型相同。
示例 6:实现 <optgroup>
支持
当列表变得更大时,使用 html 属性对列表进行分组将带来巨大的用户体验提升。此软件包通过 optgroup_identifier
提供此功能。
然而,此软件包的假设是,你的数据结构已经考虑了 optgroup 分组。请参见以下示例
按照如下方式添加 Select 列表
$this->add([ 'type' => 'Tobias\Zend\Form\Doctrine\Element\ObjectSelect', 'name' => 'name', 'options' => [ 'object_manager' => $this->getObjectManager(), 'target_class' => 'Module\Entity\SomeEntity', 'property' => 'property', 'optgroup_identifier' => 'category', ], ]);
使用如下数据结构
id | property | category
1 | Football | sports
2 | Basketball | sports
3 | Spaghetti | food
将创建如下 HTML Select 列表
<select name="name"> <optgroup label="sports"> <option value="1">Football</option> <option value="2">Basketball</option> </optgroup> <optgroup label="food"> <option value="3">Spaghetti</option> </optgroup> </select>
示例 7:在空 optgroups 上的格式化
如果你定义了 optgroup_identifier
并且该列中的数据为空或 null
,你有两种方式来渲染这些情况。从用户体验的角度来看,你应该将所有“松散”条目分组在一个名为“其他”或类似的组中。但你也可以选择不进行任何分组。以下是两种示例
7.1:无默认组渲染
要无默认组渲染,你不需要做任何更改。这是默认行为
按照如下方式添加 Select 列表
$this->add([ 'type' => 'Tobias\Zend\Form\Doctrine\Element\ObjectSelect', 'name' => 'name', 'options' => [ 'object_manager' => $this->getObjectManager(), 'target_class' => 'Module\Entity\SomeEntity', 'property' => 'property', 'optgroup_identifier' => 'category', ], ]);
使用如下数据结构
id | property | category
1 | Football | sports
2 | Basketball |
3 | Spaghetti | food
将创建如下 HTML Select 列表
<select name="name"> <optgroup label="sports"> <option value="1">Football</option> </optgroup> <optgroup label="food"> <option value="3">Spaghetti</option> </optgroup> <option value="2">Basketball</option> </select>
注意“篮球”的值没有被 <optgroup>
元素包裹。
7.2:使用默认组渲染
要将所有松散值分组到一个统一的组中,只需将 optgroup_default
参数添加到选项中。
按照如下方式添加 Select 列表
$this->add([ 'type' => 'Tobias\Zend\Form\Doctrine\Element\ObjectSelect', 'name' => 'name', 'options' => [ 'object_manager' => $this->getObjectManager(), 'target_class' => 'Module\Entity\SomeEntity', 'property' => 'property', 'optgroup_identifier' => 'category', 'optgroup_default' => 'Others', ], ]);
使用如下数据结构
id | property | category
1 | Football | sports
2 | Basketball |
3 | Spaghetti | food
将创建如下 HTML Select 列表
<select name="name"> <optgroup label="sports"> <option value="1">Football</option> </optgroup> <optgroup label="others"> <option value="2">Basketball</option> </optgroup> <optgroup label="food"> <option value="3">Spaghetti</option> </optgroup> </select>