У меня есть Form, FormFactory и и InputFilter. Я хочу создать экземпляр формы и назначить входной фильтр для формы на createService()
метод.
Модуль имеет getFormElementConfig()
метод и getInputFilterConfig()
Когда я пытаюсь получить доступ $serviceManager->get('InputFilterManager')->get('Page\Form\NewsFormInputFilter')
из фабрики форм я получаю следующее сообщение об ошибке
Предоставлена неверная спецификация фильтра; не был ни экземпляром фильтра
ни спецификация массива
модуль / Страница / module.php
<?php
namespace Page;
use Zend\ModuleManager\Feature\AutoloaderProviderInterface;
use Zend\ModuleManager\Feature\ConfigProviderInterface;
class Module implements AutoloaderProviderInterface, ConfigProviderInterface
{
public function getConfig()
{
return include __DIR__ . '/config/module.config.php';
}
public function getFormElementConfig()
{
return array(
'factories' => array(
'Page\Form\NewsForm' => 'Page\Form\NewsFormFactory',
)
);
}
public function getAutoloaderConfig()
{
return array(
'Zend\Loader\StandardAutoloader' => array(
'namespaces' => array(
__NAMESPACE__ => __DIR__ . '/src/' . __NAMESPACE__
)
)
);
}
public function getInputFilterConfig()
{
return array(
'invokables' => array(
'Page\Form\NewsFormInputFilter' => 'Page\Form\NewsFormInputFilter'
)
);
}
}
модуль / Page / SRC / Страница / Форма / NewsFormFactory.php
<?php
namespace Page\Form;
use Zend\ServiceManager\FactoryInterface;
use Zend\ServiceManager\ServiceLocatorInterface;
use Zend\ServiceManager\MutableCreationOptionsInterface;
use Page\Form\NewsForm;class NewsFormFactory implements FactoryInterface, MutableCreationOptionsInterface
{
protected $options;
public function setCreationOptions(array $options)
{
$this->options = $options;
}
public function createService(ServiceLocatorInterface $serviceLocator)
{
$serviceManager = $serviceLocator->getServiceLocator();
$form = new NewsForm();
$form->setTranslator($serviceManager->get('translator'));
$form->setInputFilter($serviceManager->get('InputFilterManager')->get('Page\Form\NewsFormInputFilter'));
return $form;
}
}
модуль / Page / SRC / Страница / Форма / NewsForm.php
<?php
namespace Page\Form;
use Zend\Form\Element;
use Zend\InputFilter;
use Zend\Form\Form;
use Zend\Form\Element\Select;
use Zend\InputFilter\InputFilterInterface;
use Zend\I18n\Translator\TranslatorAwareTrait;
class NewsForm extends Form
{
use TranslatorAwareTrait;
public function __construct($name = null)
{
parent::__construct('News');
}
public function init()
{
$category = new Select('category');
$category->setValueOptions($this->getNewsCategoryList());
$this->add($category);
}
private function getNewsCategoryList()
{
// implementation
}
}
модуль / Page / SRC / Страница / Форма / NewsFormInputFilter.php
<?php
namespace Page\Form;
use Zend\Filter\StringTrim;
use Zend\InputFilter\InputFilterProviderInterface;
use Zend\InputFilter\InputFilter;
use Zend\Form\Element;
class NewsFormInputFilter extends InputFilter
{
public function init()
{
$this->add(
array(
'name' => 'category',
'required' => true,
'filters' => array(
'name' => 'StringTrim'
)
)
);
}
}
В соответствии с Слушатели менеджера модулей, getInputFilterConfig()
доступно в Module.php
Я не уверен, что я делаю неправильно. Любая идея приветствуется.
Редактировать:
В соответствии с InputFilter и объяснил как @Purple Hexagon Я удалил реализацию InputFilterProviderInterface из NewsFormInputFilter и расширил только из InputFilter
Также удалена повторяющаяся реализация свойства $ inputFilter и метода getter из NewsForm
Классы InputFilter не должны реализовывать InputFilterProviderSpecification. Также вам нужно предоставить раздел массива фильтров с массивом для каждого фильтра (как показано ниже). У вас есть ключ имени в разделе фильтров, а не обернутый в массив в NewsFormInputFilter :: init. Следующий код подходит для вашей реализации.
<?php
namespace Page\Form;
use Zend\Filter\StringTrim;
use Zend\InputFilter\InputFilter;
use Zend\Form\Element;class NewsFormInputFilter extends InputFilter
{
public function init()
{
$this->add(
array(
'name' => 'name',
'required' => true,
'filters' => array(
array(
'name' => 'StringTrim'
)
)
)
);
}
}
Я проверил приведенный выше код, и он отлично работает, кроме NewsForm :: getNewsCategoryList не реализуется.
Есть еще несколько моментов, в которых я не совсем уверен, почему вы их делаете:
1: в классе NewsForm вы переопределяете метод setInputFilter и снова определяете свойство. Все это делается для вас в классе Zend \ Form \ Form, который вы расширяете.
2: кажется странным, что в вашей форме определены методы получения и установки для serviceLocator. Они не используются и в любом случае имеют довольно сильный запах кода. У вас уже есть фабрика для внедрения зависимостей. Думаю, вы можете в конечном итоге использовать в getNewsCategoryList, но было бы лучше использовать конструктор / установщик инъекции зависимости.
3: я бы не советовал создавать экземпляры классов Element в вашей форме напрямую. В конечном итоге это будет работать намного лучше, если вы всегда будете использовать спецификации. Подобно:
public function init()
{
$this->add(
array(
'name' => 'title',
'type' => 'Zend\\Form\\Element\\Select',
'options' => array(
'empty_option' => 'Please Select A Value...',
'label' => 'Title',
'value_options' => $this->getNewsCategoryList()
),
'attributes' => array(
'required' => 'required',
)
)
)
}
Скорее всего, у вас есть проблемы с конфигурацией. Я думаю, что эта строка, скорее всего, ничего не возвращает:
$serviceManager->get('InputFilterManager')->get('Page\Form\NewsFormInputFilter');
Я вижу, ты объявил 'Page\Form\NewsFormInputFilter'
в вашем Module.php getInputFilterConfig()
метод. Но я не вижу этого InputFilter
в вашем коде. У вас есть файл для этого класса?
У вас должен быть класс входного фильтра с именем NewsFormInputFilter
в пространстве имен Page\Form
,
Попробуйте один раз удалить getInputFilterSpecification
и не реализуйте InputFilterProviderInterface
, Мне кажется, что вы хотите init
быть названным. Вам не нужен интерфейс и getInputFilterSpecification
метод для этого.
Убедитесь, что ваш класс модуля реализует Zend\ModuleManager\Feature\InputFilterProviderInterface
,
Вы уверены, что ваши файлы находятся в Page
модуль?