В Zend Framework 2 Module.php метод getFilterConfig() никогда не вызывается.

У меня есть универсальный модуль в моем приложении Zend Framework 2 с некоторыми фильтрами.

Для своей сущности я создал класс фильтра с InputFilterAwareInterface:

public function getInputFilter()
{
    if (!$this->inputFilter) {
        $inputFilter = new InputFilter();
        $factory     = new InputFactory();
        $inputFilter->add(
            $factory->createInput(
                array(
                    'name'     => 'desc',
                    'required' => false,
                    'filters'  => array(
                        array('name' => 'myfilter'),
                    ),
                )
            )
        );

        $this->inputFilter = $inputFilter;
    }
    return $this->inputFilter;
}

Чтобы загрузить myfilter, я реализовал Generic Module.php с FilterProviderInterface:

public function getFilterConfig()
{
    // Breakpoint at next line
    return array(
        'factories' => array(
            'myfilter' => function($sl) {
                $myfilter = $sl->getServiceLocator()->get('myfilterfactory');
                return new Filter\Filter\MyFilter($myfilter);
            },
        ),
    );
}

Когда я запускаю приложение, выдается исключение:

Zend\ServiceManager\Exception\ServiceNotFoundException
Zend\Filter\FilterPluginManager::get was unable to fetch or create an instance for myfilter

Я запустил отладчик и понял, что метод getFilterConfig() никогда не вызывается, потому что точка останова не срабатывает.

Что мне нужно вставить в свой код, чтобы загрузить конфигурацию фильтра?

РЕДАКТИРОВАТЬ:

Код выполняется, но отладчик не останавливается в точке останова. Когда я вставляю дополнительный оператор и устанавливаю точку останова, выполнение останавливается.

В контроллере я делаю следующее

$serviceManager = $this->getServiceLocator();
$filterManager = $serviceManager->get('FilterManager');

и в диспетчере фильтров у меня есть myfilter в массиве factories. Но все же я получаю исключение.

Как Zend\InputFilter\Factory (как InputFactory) узнает о фабрике фильтров?


person Matthias    schedule 15.08.2013    source источник
comment
была ли у вас фабрика, подобная этой общедоступной функции getServiceConfig() { return array('invokables' => array('myfilterfactory' => 'Application\Filter\MyFilterFactory', )); }   -  person Whisher    schedule 15.08.2013
comment
Да, проблема, похоже, в том, что метод не выполняется, а не в методе ошибка.   -  person Matthias    schedule 15.08.2013
comment
Я сделал тест в своем модуле, и он работает. Попробуйте опубликовать больше кода.   -  person Whisher    schedule 16.08.2013
comment
Фильтр\Фильтр\МойФильтр($мойфильтр); у вас есть модуль под названием Filter? framework.zend.com/manual/2.0/ en/user-guide/ ваш код не вызывает $mymodelentities-›getInputFilter()   -  person Whisher    schedule 16.08.2013
comment
У меня есть общий модуль, так как мне нужен фильтр в большем количестве модулей. Путь: Generic/src/Filter/Filter. Двойной фильтр происходит из реализации фильтра и фабрик, которые должны находиться в отдельной папке Generic/src/Filter/Factory. Может быть, я должен очистить это. Относительно getInputFilter(): Это вызвано, потому что в моем вопросе я написал только часть кода, касающуюся моей проблемы. В нем есть и другие фильтры, которые выполняются корректно. У меня есть отдельный класс фильтров параллельно моей сущности. Но это работает для фильтров Zend Framework. Так что я думаю, что это должно сработать.   -  person Matthias    schedule 16.08.2013


Ответы (2)


Наконец я понял, что пошло не так и как это решить:

В Zend\InputFilter\Factory, который я использовал в качестве InputFactory, с нуля создается defaultFilterChain, который создает новый FilterPluginManager, который не получает фильтры диспетчера служб.

Чтобы решить эту проблему, я вставляю фабрику для фильтра объектов в диспетчер служб, который внедряет defaultFilterChain с фильтрами диспетчера служб:

'EntityFilter' => function($sm) {
    $filterManager = $sm->get('FilterManager');            
    $filterChain = new FilterChain;
    $filterChain->setPluginManager($filterManager);
    return new EntityFilter($filterChain);
 }

В методе getInputFilter класса фильтра EntityFilter это вставляется в InputFactory:

$factory = new InputFactory();
$factory->setDefaultFilterChain($this->defaultFilterChain);

Теперь InputFactory также может использовать эти фильтры диспетчера фильтров менеджера служб, который включает myfilter.

person Matthias    schedule 18.08.2013
comment
Для этой цели можно использовать фабрику услуг. Код и инструкции здесь: gist.github.com/Thinkscape/8418700 - person Artur Bodera; 14.01.2014
comment
+1 Отлично, у меня была такая же проблема, когда фабрика не была найдена, несмотря на реализацию FilterProviderInterface. Вы только что сэкономили мне кучу времени! - person AlexP; 27.06.2014

Проблема, безусловно, в вашем вызове $sl->....->get('myfilterfactory')

Попробуйте использовать die("foo"); перед этим вызовом, и вы увидите, что die() выполняется. И тогда ваш код кажется немного нечистым, или, скорее, вы не знаете, как сделать это лучше.

Вы используете фабрику, так почему бы не использовать настоящую фабрику?

'factories' => array(
    'myfilter' => 'YourNamespace\Filter\MyFilterFactory'
)

class MyFilterFactory implements FactoryInterface 
    public function createService($sl)
        $filterClass = new MyFilter();
        $filterClass->setDependency(
            $sl->getServiceLocator()->get('someDependency')
        )
        return $filterClass
person Sam    schedule 16.08.2013
comment
Я пробовал это с оператором die, но приложение не уничтожается, и я все еще получаю исключение. - person Matthias; 16.08.2013
comment
Вы уверены, что модуль загружен? ^^ Вы также можете проверить объединенную конфигурацию в своем контроллере или где-либо еще и выполнить отладку для $serviceLocator->get('config'), просто чтобы убедиться, что она действительно существует. - person Sam; 16.08.2013