ZF2/Doctrine2 - 字段集未验证,数据始终有效
ZF2/Doctrine2 - Fieldsets not validated, data is always valid
我已经使用 Abstract 类 为表单、字段集和 InputFilters 设置了一个结构。表单和字段集有工厂,而 InputFilters 由 FieldsetFactory 在字段集上创建和设置(使用 MutableCreationOptionsInterface
传递选项)
我遇到的问题是 InputFilters 是 为表单加载的,但不用于验证数据。所有输入都被视为有效。
例如 我有一个 Country
实体和 name
属性。 Country 的名称必须至少 3 个字符,最多 255 个字符。当名称为 "ab" 时,它被认为是有效的。
之前有人问:没有抛出错误,数据只是被接受为有效。
在过去的几天里,我一直在为这个问题绞尽脑汁,试图找到我犯错的地方,但找不到。
此外,还有相当多的代码。我将它限制在我认为相关的范围内,尽管如此:如果您需要更多,将会有更多。我删除了很多类型检查、文档块和类型提示以限制代码 lines/reading 时间 ;)
module.config.php
'form_elements' => [
'factories' => [
CountryForm::class => CountryFormFactory::class,
CountryFieldset::class => CountryFieldsetFactory::class,
],
],
Country.php
class Country extends AbstractEntity // Creates $id + getter/setter
{
/**
* @var string
* @ORM\Column(name="name", type="string", length=255, nullable=false)
*/
protected $name;
// Other properties
// Getters/setters
}
CountryController.php - 扩展 AbstractActionController
public function editAction() // Here to show the params used to call function
{
return parent::editAction(
Country::class,
CountryForm::class,
[
'name' => 'country',
'options' => []
],
'id',
'admin/countries/view',
'admin/countries',
['id']
);
}
AbstractActionController.php - (此处出错) - 由 CountryController#editAction()
使用
public function editAction (
$emEntity,
$formName,
$formOptions,
$idProperty,
$route,
$errorRoute, array
$routeParams = []
) {
//Check if form is set
$id = $this->params()->fromRoute($idProperty, null);
/** @var AbstractEntity $entity */
$entity = $this->getEntityManager()->getRepository($emEntity)->find($id);
/** @var AbstractForm $form */
$form = $this->getFormElementManager()->get($formName, (is_null($formOptions) ? [] : $formOptions));
$form->bind($entity);
/** @var Request $request */
$request = $this->getRequest();
if ($request->isPost()) {
$form->setData($request->getPost());
if ($form->isValid()) { // HERE IS WHERE IT GOES WRONG -> ALL IS TRUE
try {
$this->getEntityManager()->flush();
} catch (\Exception $e) {
//Print errors & return (removed, unnecessary)
}
return $this->redirectToRoute($route, $this->getRouteParams($entity, $routeParams));
}
}
return [
'form' => $form,
'validationMessages' => $form->getMessages() ?: '',
];
}
CountryForm.php
class CountryForm extends AbstractForm
{
// This one added for SO, does nothing but call parent#__construct, which would happen anyway
public function __construct($name = null, array $options)
{
parent::__construct($name, $options);
}
public function init()
{
//Call parent initializer.
parent::init();
$this->add([
'name' => 'country',
'type' => CountryFieldset::class,
'options' => [
'use_as_base_fieldset' => true,
],
]);
}
}
CountryFormFactory.php
class CountryFormFactory extends AbstractFormFactory
{
public function createService(ServiceLocatorInterface $serviceLocator)
{
$serviceManager = $serviceLocator->getServiceLocator();
/** @var EntityManager $entityManager */
$entityManager = $serviceManager->get('Doctrine\ORM\EntityManager');
$form = new CountryForm($this->name, $this->options);
$form->setObjectManager($entityManager);
$form->setTranslator($serviceManager->get('translator'));
return $form;
}
}
AbstractFormFactory.php - 使用 MutableCreationOptionsInterface
从控制器函数调用接收选项:$form = $this->getFormElementManager()->get($formName, (is_null($formOptions) ? [] : $formOptions))
abstract class AbstractFormFactory implements FactoryInterface, MutableCreationOptionsInterface
{
protected $name;
protected $options;
/**
* @param array $options
*/
public function setCreationOptions(array $options)
{
// Check presence of required "name" (string) parameter in $options
$this->name = $options['name'];
// Check presence of required "options" (array) parameter in $options
$this->options = $options['options'];
}
}
CountryFieldset.php - 在上面被 CountryForm.php 用作基础字段集
class CountryFieldset extends AbstractFieldset
{
public function init()
{
parent::init();
$this->add([
'name' => 'name',
'required' => true,
'type' => Text::class,
'options' => [
'label' => _('Name'),
],
]);
// Other properties
}
}
AbstractFieldset.php
abstract class AbstractFieldset extends Fieldset
{
use InputFilterAwareTrait;
use TranslatorAwareTrait;
protected $entityManager;
public function __construct(EntityManager $entityManager, $name)
{
parent::__construct($name);
$this->setEntityManager($entityManager);
}
public function init()
{
$this->add([
'name' => 'id',
'type' => Hidden::class,
]);
}
// Getters/setters for $entityManager
}
CountryFieldsetFactory.php - 此处将输入过滤器设置到 FIELDSET
class CountryFieldsetFactory extends AbstractFieldsetFactory
{
public function createService(ServiceLocatorInterface $serviceLocator)
{
parent::createService($serviceLocator);
/** @var CountryRepository $entityRepository */
$entityRepository = $this->getEntityManager()->getRepository(Country::class);
$fieldset = new CountryFieldset($this->getEntityManager(), $this->name);
$fieldset->setHydrator(new DoctrineObject($this->getServiceManager()->get('doctrine.entitymanager.orm_default'), false));
$fieldset->setObject(new Country());
$fieldset->setTranslator($this->getTranslator());
// HERE THE INPUTFILTER IS SET ONTO THE FIELDSET THAT WAS JUST CREATED
$fieldset->setInputFilter(
$this->getServiceManager()->get('InputFilterManager')->get(
CountryInputFilter::class,
[ // These are the options read by the MutableCreationOptionsInterface
'object_manager' => $this->getEntityManager(),
'object_repository' => $entityRepository,
'translator' => $this->getTranslator(),
]
)
);
return $fieldset;
}
}
AbstractFieldsetFactory.php
abstract class AbstractFieldsetFactory implements FactoryInterface, MutableCreationOptionsInterface
{
protected $serviceManager;
protected $entityManager;
protected $translator;
protected $name;
public function setCreationOptions(array $options)
{
$this->name = $options['name'];
}
public function createService(ServiceLocatorInterface $serviceLocator)
{
/** @var ServiceLocator $serviceManager */
$this->serviceManager = $serviceLocator->getServiceLocator();
/** @var EntityManager $entityManager */
$this->entityManager = $this->getServiceManager()->get('Doctrine\ORM\EntityManager');
/** @var Translator $translator */
$this->translator = $this->getServiceManager()->get('translator');
}
// Getters/setters for properties
}
CountryFieldsetInputFilter.php
class CountryInputFilter extends AbstractInputFilter
{
public function init()
{
parent::init();
$this->add([
'name' => 'name',
'required' => true,
'filters' => [
['name' => StringTrim::class],
['name' => StripTags::class],
],
'validators' => [
[
'name' => StringLength::class,
'options' => [
'min' => 3, // This is just completely ignored
'max' => 255,
],
],
],
]);
// More adding
}
}
AbstractFieldsetInputFilter.php - 最后一个! :)
abstract class AbstractInputFilter extends InputFilter
{
use TranslatorAwareTrait;
protected $repository;
protected $objectManager;
public function __construct(array $options)
{
// Check if ObjectManager|EntityManager for InputFilter is set
$this->setObjectManager($options['object_manager']);
// Check if EntityRepository instance for InputFilter is set
$this->setRepository($options['object_repository']);
// Check for presence of translator so as to translate return messages
$this->setTranslator($options['translator']);
}
public function init()
{
$this->add([
'name' => 'id',
'required' => false,
'filters' => [
['name' => ToInt::class],
],
'validators' => [
['name' => IsInt::class],
],
]);
}
//Getters/setters for properties
}
非常感谢任何帮助。希望上面的代码不会让您负担过重。但是我已经反复研究这个问题大约 3-4 天,并没有发现问题所在。
总结一下:
在上面创建了一个 CountryForm
。它使用预加载(在 CountryFieldsetFactory
中)的 CountryFieldset
和 CountryInputFilter
。
在验证数据时,一切都被认为是有效的。例如。 - 国家名称 "ab" 是有效的,尽管 StringLength
验证器将 'min' => 3,
定义为选项。
$fieldset->setInputFilter($inputFilter);
假设 $fieldset
是 Zend\Form\Fieldset
的实例,该方法不存在。这是因为您需要在 表单 上设置输入过滤器 (Zend\Form\Form)
.
如果我要修改您的代码,我会按以下方式进行。修改 CountryForm
以通过表单提供输入过滤器。这可以在不需要为每个表单定义自定义输入过滤器的情况下完成,方法是使用 Zend\InputFilter\InputFilterProviderInterface
并在 type
键下引用您的自定义输入过滤器。
当表单元素管理器创建表单时,它还会注入能够找到自定义 CountryInputFilter
.
的输入过滤器管理器
例如:
use Zend\InputFilter\InputFilterProviderInterface;
class CountryForm extends AbstractForm implements InputFilterProviderInterface
{
public function init()
{
//.. add the country fieldset here
}
/**
* getInputFilterSpecification
*
* Return the form's input filter specification array.
*
* @return array
*/
public function getInputFilterSpecification()
{
return [
// Refers to the country element (happens to be a fieldset)
'country' => [
// Tell the input filter factory what type of input filter.
'type' => 'Country\InputFilter\CountryInputFilter',
// You could even overload/change the default defined in the input filter
// here. This is useful as sometimes the requirements of the FORM are
// different from what the FIELDSET expects.
// [
// 'name' => 'name',
// 'required' => false,
// 'allow_empty' => true,
// ],
],
];
}
}
由于您已经设置了所有 类 ,因此还有另一种方法(来自@AlexP),即构建 Fieldset 的 InputFilters 并将其添加到 Forms InputFilter。而不是使用 InputFilterSpecifications。
因此,将输入过滤器添加到您的 input_filters
配置键中:
'form_elements' => [
'factories' => [
CountryForm::class => CountryFormFactory::class,
CountryFieldset::class => CountryFieldsetFactory::class,
],
],
'input_filters' => [
'factories' => [
CountryInputFilter::class => CountryInputFilterFactory::class,
CountryFieldsetInputFilter::class => CountryFieldsetInputFilterFactory::class,
],
],
工厂类:
class CountryInputFilterFactory implements FactoryInterface
{
public function createService(ServiceLocatorInterface $serviceLocator)
{
$serviceManager = $serviceLocator->getServiceLocator();
$inputFilter = new CountryInputFilter(
$serviceLocator->get(CountryFieldsetInputFilter::class),
$serviceManager()->get('Doctrine\ORM\EntityManager'),
$serviceManager()->get('translator')
);
return $inputFilter;
}
}
class CountryFieldsetInputFilterFactory implements FactoryInterface
{
public function createService(ServiceLocatorInterface $serviceLocator)
{
$serviceManager = $serviceLocator->getServiceLocator();
return new CountryFieldsetInputFilter(
$serviceManager()->get('Doctrine\ORM\EntityManager'),
$serviceManager()->get('translator')
);
}
}
class CountryFormFactory implements AbstractFormFactory
{
public function createService(ServiceLocatorInterface $serviceLocator)
{
$serviceManager = $serviceLocator->getServiceLocator();
$form = new CountryForm($this->name, $this->options);
$form->setObjectManager($serviceManager->get('Doctrine\ORM\EntityManager'));
$form->setTranslator($serviceManager->get('translator'));
$form->setInputFilter($serviceManager->get('InputFilterManager')->get(CountryInputFilterFactory::class));
return $form;
}
}
表格:
class CountryForm extends AbstractForm
{
const COUNTRY_FIELDSET_NAME = 'country';
// This one added for SO, does nothing but call parent#__construct, which would happen anyway
public function __construct($name = null, array $options)
{
parent::__construct($name, $options);
}
public function init()
{
//Call parent initializer.
parent::init();
$this->add([
'name' => self::COUNTRY_FIELDSET_NAME,
'type' => CountryFieldset::class,
'options' => [
'use_as_base_fieldset' => true,
],
]);
}
}
输入过滤器:
class CountryInputFilter extends AbstractInputFilter
{
/** @var CountryFieldsetInputFilter */
protected $countryFieldsetInputFilter;
public function __construct(CountryFieldsetInputFilter $filter, $objectManager, $translator)
{
$this->countryFieldsetInputFilter = $filter;
// other dependencies
}
public function init()
{
$this->add($this->countryFieldsetInputFilter, CountryForm::COUNTRY_FIELDSET_NAME);
}
}
class CountryFieldsetInputFilter extends AbstractInputFilter
{
public function __construct($objectManager, $translator)
{
// dependencies
}
public function init()
{
$this->add([
// configuration
]);
}
}
请注意,我将依赖项按实例而不是包含实例的数组注入到 InputFilters 中。
我已经使用 Abstract 类 为表单、字段集和 InputFilters 设置了一个结构。表单和字段集有工厂,而 InputFilters 由 FieldsetFactory 在字段集上创建和设置(使用 MutableCreationOptionsInterface
传递选项)
我遇到的问题是 InputFilters 是 为表单加载的,但不用于验证数据。所有输入都被视为有效。
例如 我有一个 Country
实体和 name
属性。 Country 的名称必须至少 3 个字符,最多 255 个字符。当名称为 "ab" 时,它被认为是有效的。
之前有人问:没有抛出错误,数据只是被接受为有效。
在过去的几天里,我一直在为这个问题绞尽脑汁,试图找到我犯错的地方,但找不到。
此外,还有相当多的代码。我将它限制在我认为相关的范围内,尽管如此:如果您需要更多,将会有更多。我删除了很多类型检查、文档块和类型提示以限制代码 lines/reading 时间 ;)
module.config.php
'form_elements' => [
'factories' => [
CountryForm::class => CountryFormFactory::class,
CountryFieldset::class => CountryFieldsetFactory::class,
],
],
Country.php
class Country extends AbstractEntity // Creates $id + getter/setter
{
/**
* @var string
* @ORM\Column(name="name", type="string", length=255, nullable=false)
*/
protected $name;
// Other properties
// Getters/setters
}
CountryController.php - 扩展 AbstractActionController
public function editAction() // Here to show the params used to call function
{
return parent::editAction(
Country::class,
CountryForm::class,
[
'name' => 'country',
'options' => []
],
'id',
'admin/countries/view',
'admin/countries',
['id']
);
}
AbstractActionController.php - (此处出错) - 由 CountryController#editAction()
使用public function editAction (
$emEntity,
$formName,
$formOptions,
$idProperty,
$route,
$errorRoute, array
$routeParams = []
) {
//Check if form is set
$id = $this->params()->fromRoute($idProperty, null);
/** @var AbstractEntity $entity */
$entity = $this->getEntityManager()->getRepository($emEntity)->find($id);
/** @var AbstractForm $form */
$form = $this->getFormElementManager()->get($formName, (is_null($formOptions) ? [] : $formOptions));
$form->bind($entity);
/** @var Request $request */
$request = $this->getRequest();
if ($request->isPost()) {
$form->setData($request->getPost());
if ($form->isValid()) { // HERE IS WHERE IT GOES WRONG -> ALL IS TRUE
try {
$this->getEntityManager()->flush();
} catch (\Exception $e) {
//Print errors & return (removed, unnecessary)
}
return $this->redirectToRoute($route, $this->getRouteParams($entity, $routeParams));
}
}
return [
'form' => $form,
'validationMessages' => $form->getMessages() ?: '',
];
}
CountryForm.php
class CountryForm extends AbstractForm
{
// This one added for SO, does nothing but call parent#__construct, which would happen anyway
public function __construct($name = null, array $options)
{
parent::__construct($name, $options);
}
public function init()
{
//Call parent initializer.
parent::init();
$this->add([
'name' => 'country',
'type' => CountryFieldset::class,
'options' => [
'use_as_base_fieldset' => true,
],
]);
}
}
CountryFormFactory.php
class CountryFormFactory extends AbstractFormFactory
{
public function createService(ServiceLocatorInterface $serviceLocator)
{
$serviceManager = $serviceLocator->getServiceLocator();
/** @var EntityManager $entityManager */
$entityManager = $serviceManager->get('Doctrine\ORM\EntityManager');
$form = new CountryForm($this->name, $this->options);
$form->setObjectManager($entityManager);
$form->setTranslator($serviceManager->get('translator'));
return $form;
}
}
AbstractFormFactory.php - 使用 MutableCreationOptionsInterface
从控制器函数调用接收选项:$form = $this->getFormElementManager()->get($formName, (is_null($formOptions) ? [] : $formOptions))
abstract class AbstractFormFactory implements FactoryInterface, MutableCreationOptionsInterface
{
protected $name;
protected $options;
/**
* @param array $options
*/
public function setCreationOptions(array $options)
{
// Check presence of required "name" (string) parameter in $options
$this->name = $options['name'];
// Check presence of required "options" (array) parameter in $options
$this->options = $options['options'];
}
}
CountryFieldset.php - 在上面被 CountryForm.php 用作基础字段集
class CountryFieldset extends AbstractFieldset
{
public function init()
{
parent::init();
$this->add([
'name' => 'name',
'required' => true,
'type' => Text::class,
'options' => [
'label' => _('Name'),
],
]);
// Other properties
}
}
AbstractFieldset.php
abstract class AbstractFieldset extends Fieldset
{
use InputFilterAwareTrait;
use TranslatorAwareTrait;
protected $entityManager;
public function __construct(EntityManager $entityManager, $name)
{
parent::__construct($name);
$this->setEntityManager($entityManager);
}
public function init()
{
$this->add([
'name' => 'id',
'type' => Hidden::class,
]);
}
// Getters/setters for $entityManager
}
CountryFieldsetFactory.php - 此处将输入过滤器设置到 FIELDSET
class CountryFieldsetFactory extends AbstractFieldsetFactory
{
public function createService(ServiceLocatorInterface $serviceLocator)
{
parent::createService($serviceLocator);
/** @var CountryRepository $entityRepository */
$entityRepository = $this->getEntityManager()->getRepository(Country::class);
$fieldset = new CountryFieldset($this->getEntityManager(), $this->name);
$fieldset->setHydrator(new DoctrineObject($this->getServiceManager()->get('doctrine.entitymanager.orm_default'), false));
$fieldset->setObject(new Country());
$fieldset->setTranslator($this->getTranslator());
// HERE THE INPUTFILTER IS SET ONTO THE FIELDSET THAT WAS JUST CREATED
$fieldset->setInputFilter(
$this->getServiceManager()->get('InputFilterManager')->get(
CountryInputFilter::class,
[ // These are the options read by the MutableCreationOptionsInterface
'object_manager' => $this->getEntityManager(),
'object_repository' => $entityRepository,
'translator' => $this->getTranslator(),
]
)
);
return $fieldset;
}
}
AbstractFieldsetFactory.php
abstract class AbstractFieldsetFactory implements FactoryInterface, MutableCreationOptionsInterface
{
protected $serviceManager;
protected $entityManager;
protected $translator;
protected $name;
public function setCreationOptions(array $options)
{
$this->name = $options['name'];
}
public function createService(ServiceLocatorInterface $serviceLocator)
{
/** @var ServiceLocator $serviceManager */
$this->serviceManager = $serviceLocator->getServiceLocator();
/** @var EntityManager $entityManager */
$this->entityManager = $this->getServiceManager()->get('Doctrine\ORM\EntityManager');
/** @var Translator $translator */
$this->translator = $this->getServiceManager()->get('translator');
}
// Getters/setters for properties
}
CountryFieldsetInputFilter.php
class CountryInputFilter extends AbstractInputFilter
{
public function init()
{
parent::init();
$this->add([
'name' => 'name',
'required' => true,
'filters' => [
['name' => StringTrim::class],
['name' => StripTags::class],
],
'validators' => [
[
'name' => StringLength::class,
'options' => [
'min' => 3, // This is just completely ignored
'max' => 255,
],
],
],
]);
// More adding
}
}
AbstractFieldsetInputFilter.php - 最后一个! :)
abstract class AbstractInputFilter extends InputFilter
{
use TranslatorAwareTrait;
protected $repository;
protected $objectManager;
public function __construct(array $options)
{
// Check if ObjectManager|EntityManager for InputFilter is set
$this->setObjectManager($options['object_manager']);
// Check if EntityRepository instance for InputFilter is set
$this->setRepository($options['object_repository']);
// Check for presence of translator so as to translate return messages
$this->setTranslator($options['translator']);
}
public function init()
{
$this->add([
'name' => 'id',
'required' => false,
'filters' => [
['name' => ToInt::class],
],
'validators' => [
['name' => IsInt::class],
],
]);
}
//Getters/setters for properties
}
非常感谢任何帮助。希望上面的代码不会让您负担过重。但是我已经反复研究这个问题大约 3-4 天,并没有发现问题所在。
总结一下:
在上面创建了一个 CountryForm
。它使用预加载(在 CountryFieldsetFactory
中)的 CountryFieldset
和 CountryInputFilter
。
在验证数据时,一切都被认为是有效的。例如。 - 国家名称 "ab" 是有效的,尽管 StringLength
验证器将 'min' => 3,
定义为选项。
$fieldset->setInputFilter($inputFilter);
假设 $fieldset
是 Zend\Form\Fieldset
的实例,该方法不存在。这是因为您需要在 表单 上设置输入过滤器 (Zend\Form\Form)
.
如果我要修改您的代码,我会按以下方式进行。修改 CountryForm
以通过表单提供输入过滤器。这可以在不需要为每个表单定义自定义输入过滤器的情况下完成,方法是使用 Zend\InputFilter\InputFilterProviderInterface
并在 type
键下引用您的自定义输入过滤器。
当表单元素管理器创建表单时,它还会注入能够找到自定义 CountryInputFilter
.
例如:
use Zend\InputFilter\InputFilterProviderInterface;
class CountryForm extends AbstractForm implements InputFilterProviderInterface
{
public function init()
{
//.. add the country fieldset here
}
/**
* getInputFilterSpecification
*
* Return the form's input filter specification array.
*
* @return array
*/
public function getInputFilterSpecification()
{
return [
// Refers to the country element (happens to be a fieldset)
'country' => [
// Tell the input filter factory what type of input filter.
'type' => 'Country\InputFilter\CountryInputFilter',
// You could even overload/change the default defined in the input filter
// here. This is useful as sometimes the requirements of the FORM are
// different from what the FIELDSET expects.
// [
// 'name' => 'name',
// 'required' => false,
// 'allow_empty' => true,
// ],
],
];
}
}
由于您已经设置了所有 类 ,因此还有另一种方法(来自@AlexP),即构建 Fieldset 的 InputFilters 并将其添加到 Forms InputFilter。而不是使用 InputFilterSpecifications。
因此,将输入过滤器添加到您的 input_filters
配置键中:
'form_elements' => [
'factories' => [
CountryForm::class => CountryFormFactory::class,
CountryFieldset::class => CountryFieldsetFactory::class,
],
],
'input_filters' => [
'factories' => [
CountryInputFilter::class => CountryInputFilterFactory::class,
CountryFieldsetInputFilter::class => CountryFieldsetInputFilterFactory::class,
],
],
工厂类:
class CountryInputFilterFactory implements FactoryInterface
{
public function createService(ServiceLocatorInterface $serviceLocator)
{
$serviceManager = $serviceLocator->getServiceLocator();
$inputFilter = new CountryInputFilter(
$serviceLocator->get(CountryFieldsetInputFilter::class),
$serviceManager()->get('Doctrine\ORM\EntityManager'),
$serviceManager()->get('translator')
);
return $inputFilter;
}
}
class CountryFieldsetInputFilterFactory implements FactoryInterface
{
public function createService(ServiceLocatorInterface $serviceLocator)
{
$serviceManager = $serviceLocator->getServiceLocator();
return new CountryFieldsetInputFilter(
$serviceManager()->get('Doctrine\ORM\EntityManager'),
$serviceManager()->get('translator')
);
}
}
class CountryFormFactory implements AbstractFormFactory
{
public function createService(ServiceLocatorInterface $serviceLocator)
{
$serviceManager = $serviceLocator->getServiceLocator();
$form = new CountryForm($this->name, $this->options);
$form->setObjectManager($serviceManager->get('Doctrine\ORM\EntityManager'));
$form->setTranslator($serviceManager->get('translator'));
$form->setInputFilter($serviceManager->get('InputFilterManager')->get(CountryInputFilterFactory::class));
return $form;
}
}
表格:
class CountryForm extends AbstractForm
{
const COUNTRY_FIELDSET_NAME = 'country';
// This one added for SO, does nothing but call parent#__construct, which would happen anyway
public function __construct($name = null, array $options)
{
parent::__construct($name, $options);
}
public function init()
{
//Call parent initializer.
parent::init();
$this->add([
'name' => self::COUNTRY_FIELDSET_NAME,
'type' => CountryFieldset::class,
'options' => [
'use_as_base_fieldset' => true,
],
]);
}
}
输入过滤器:
class CountryInputFilter extends AbstractInputFilter
{
/** @var CountryFieldsetInputFilter */
protected $countryFieldsetInputFilter;
public function __construct(CountryFieldsetInputFilter $filter, $objectManager, $translator)
{
$this->countryFieldsetInputFilter = $filter;
// other dependencies
}
public function init()
{
$this->add($this->countryFieldsetInputFilter, CountryForm::COUNTRY_FIELDSET_NAME);
}
}
class CountryFieldsetInputFilter extends AbstractInputFilter
{
public function __construct($objectManager, $translator)
{
// dependencies
}
public function init()
{
$this->add([
// configuration
]);
}
}
请注意,我将依赖项按实例而不是包含实例的数组注入到 InputFilters 中。