somejkuser
somejkuser

Reputation: 9040

Set custom filter plugin inside servicemanager config zend framework

I have the following code in my application user form that creates the input filter for the address2 element.

  $inputFilter = new InputFilter();
  $inputFilter->add([
        'name' => 'address2',
        'required' => true,
        'filters' => [
                ['name'=>'StringTrim'],
                ['name'=>'Administration\Filter\Ucwords']
        ]
    ]);

As you can see, I have the class name set as the name of the filter.

I get the following error:

A plugin by the name "Administration\Filter\Ucwords" was not found in the plugin manager Zend\Filter\FilterPluginManager.

How do I get this filter into the servicemanager configuration ?

NOTE

I want to set this using configuration, not executing a call from within the module class so I can say Ucwords instead of the full class name inside the filter config.

Upvotes: 0

Views: 342

Answers (2)

unclexo
unclexo

Reputation: 3941

For ZF3

Assuming that your Ucwords filter is implementing Zend\Filter\FilterInterface. You can then make custom filter available in the specific place in your application by adding it to FilterPluginManager and FilterChain. If any filter that you are attaching to the FilterChain must be known to FilterPluginManager. That is the main point to keep in mind.

N.B. However you can create a factory instead of a closure.

Method 1

Put the following code in the module.config.php.

'service_manager' => [
    'factories' => [
        CustomFilter::class => function($sm){         
            $filterChain = new \Zend\Filter\FilterChain;
            $filterChain->getPluginManager()
                        ->setInvokableClass('Ucwords', \Administration\Filter\Ucwords::class);
            return new CustomFilter($filterChain);
        },
    ],
    'aliases' => [
        'CustomFilter' => CustomFilter::class,
    ],
],

Method 2

Make sure Zend\Filter is enabled via modules.config.php which is located in your application's config directory.

Now put the following code in the module's module.config.php.

'service_manager' => [
    'factories' => [
        CustomFilter::class => function($sm){
            $filterPluginManager = $sm->get('FilterManager');
            $filterChain = new \Zend\Filter\FilterChain();
            $filterChain->setPluginManager($filterPluginManager);

            return new CustomFilter($filterChain);
        },
    ],
    'aliases' => [
        'CustomFilter' => CustomFilter::class,
    ],
],
'filters' => [
    'factories' => [
        Ucwords::class => InvokableFactory::class           
    ],
    'aliases' => [
        'Ucwords' => Ucwords::class,
    ],
], 

Implementation

Now create an instance of Zend\InputFilter\Factory (alias InputFactory here). Set the FilterChain object that you created and passed through the constructor of CustomFilter using a closure in the previous code. Create then input as needed using Zend\InputFilter\Factory's createInput() method. Assign the custom Ucwords filter to where you need, (in this case, I added it to title). See the following code.

<?php
use Zend\Filter\FilterChain;
use Zend\InputFilter\InputFilter;
use Zend\InputFilter\Factory as InputFactory;

class CustomFilter extends InputFilter
{
    protected $filterChain;    

    public function __construct(FilterChain $filterChain)
    { 

        $this->filterChain = $filterChain;

        // Set the FilterChain object
        $factory = new InputFactory();
        $factory->setDefaultFilterChain($this->filterChain);

        $this->add($factory->createInput(array(
            'name' => 'title',
            'required' => true,
            'filters' => array(
                array(
                    // Here we go
                    'name' => 'Ucwords',
                ),  
            ),
        )));

        ...
    }
}

Upvotes: 0

Kristijonas
Kristijonas

Reputation: 151

The configuration looks correct to me. The only issue here is that you have made a typo error when specifying filter name (Administration\Filter\Ucwords). Make sure that such class exists and it can be autoloaded.

I also strongly suggest you to specify the class constant (for fully qualified class name resolution) instead of string, e.g.

...
['name' => Administration\Filter\Ucwords::class]
...

Upvotes: 1

Related Questions