我正在开发我的自定义用户模块,它基本上使用 ZfcUser 作为基础。由于每个应用程序都是不同的,并且需要有关用户的不同元信息,因此我希望使用配置数组可以轻松地对其进行配置。
在我的模块的全局配置文件中,我定义了自定义表单字段,在模块的 onBootstrap 中,我使用 ZfcUser\Form\Register 的 init 事件扩展了 ZfcUser 注册表单。所以简而言之,我想做这样的事情:
$sharedEvents->attach('ZfcUser\Form\Register',
'init',
function($e) use ($sm)
{
/* @var $form \ZfcUser\Form\Register */
$form = $e->getTarget();
// Get relevant config
$config = $sm->get('config');
if ( array_key_exists('redev_user', $config) && is_array($config['redev_user']) )
{
if ( array_key_exists('custom_fields', $config['redev_user']) && is_array($config['redev_user']['custom_fields']) )
{
foreach ($config['redev_user']['custom_fields'] as $curCustomField)
{
$form->add($curCustomField);
}
}
}
[...]
然后在我的配置文件中定义自定义表单字段,如下所示:
<?php
return array(
'redev_user' => array(
'custom_fields' => array(
// Custom fields which will be added to the registration form
array(
'name' => 'firstname',
'type' => 'text',
'options' => array(
'label' => 'First name',
),
),
我对验证者做同样的事情;它们在配置文件中定义并附加到 onBootstrap 中的表单元素。
这一切都很好,花花公子,除非我需要一个 Doctrine 表单元素。在我的具体情况下,我想使用 DoctrineModule\Form\Element\ObjectSelect 作为国家选择框。在我的配置中,这看起来像这样:
array(
'name' => 'country',
'type' => 'DoctrineModule\Form\Element\ObjectSelect',
'options' => array(
'label' => 'Country',
//'object_manager' => $sm->get('Doctrine\ORM\EntityManager'),
'target_class' => 'RedevUser\Entity\Country',
'property' => 'countryname',
'is_method' => false,
'find_method' => array(
'name' => 'findBy',
'params' => array(
'criteria' => array(),
'orderBy' => array('countryname' => 'ASC'),
),
),
),
),
请注意 object_manager 的注释行。ObjectSelect 元素显然需要 ObjectManager。问题是如何在基于配置呈现表单时注入 ObjectManager。
我正在考虑自己渲染表单元素,然后检查它是否是某个接口的实例或 DoctrineModule\Form\Element 的基类。然而事实证明没有这样的基类或接口。这些元素唯一的共同点是它们都有一个 getProxy。现在我在 onBootstrap 中的代码如下所示:
foreach ($config['redev_user']['custom_fields'] as $curCustomField)
{
$formElemFactory = $form->getFormFactory();
$elem = $formElemFactory->createElement($curCustomField);
if ($elem instanceof \DoctrineModule\Form\Element\ObjectSelect)
{
// Inject ObjectManager
$elem->getProxy()->setObjectmanager($sm->get('Doctrine\ORM\EntityManager'));
}
$form->add($elem);
}
但我真的不想检查不同的 Doctrine 表单元素类型。而且这样做似乎有点脏。关于如何做得更好/更清洁的任何意见或想法?