ZF2, зарегистрировать пользовательский фильтр ввода и получить к нему доступ с фабрики форм?

У меня есть 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

0

Решение

Классы 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',
)
)
)
}
1

Другие решения

Скорее всего, у вас есть проблемы с конфигурацией. Я думаю, что эта строка, скорее всего, ничего не возвращает:

$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 модуль?

1

По вопросам рекламы [email protected]