tobias/zend-form-doctrine

此包已被弃用且不再维护。未建议替代包。

使用 Zend\Form\Element 与 Doctrine 对象

dev-master 2019-07-01 07:51 UTC

This package is auto-updated.

Last update: 2020-02-01 19:22:55 UTC


README

Build Status

受著名的 DoctrineModule 启发并基于此开发。

此包包含功能,可以自动用来自动填充 Select、MultiCheckbox 或 Radio 表单元素的 ValueOptions 数据,这些数据来自 ObjectRepository

使用方法

Tobias\Zend\Form\Doctrine\Element\ObjectSelectTobias\Zend\Form\Doctrine\Element\ObjectRadioTobias\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',
            ],
        ]);
    }
}

当表单被渲染时,默认情况下将执行 ObjectRepositoryfindAll 方法。

示例 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>