zendframework / zend-inputfilter

InputFilter component from Zend Framework
BSD 3-Clause "New" or "Revised" License
64 stars 50 forks source link

Version 2.8.5 broke backward compatibility for apigility #155

Closed ekosogin closed 6 years ago

ekosogin commented 6 years ago

Hi! https://github.com/zendframework/zend-inputfilter/pull/151/files backward compatibility was broken for apigility for file input type where Zend\InputFilter\FileInput specified. It doesn't use custom filters in this case for example "RenameUploadFilter". Everything works in version 2.8.4

Code to reproduce the issue

...
'input_filter_specs' => array(
        'Gateway\\V1\\Rpc\\UploadFile\\Validator' => array(
            ...
            1 => array(
                'required' => true,
                'validators' => array(
                    0 => array(
                        'name' => 'Zend\\Validator\\File\\UploadFile',
                        'options' => array(
                            'breakchainonfailure' => true,
                        ),
                    ),
                    1 => array(
                        'name' => 'Zend\\Validator\\File\\Size',
                        'options' => array(
                            'breakchainonfailure' => true,
                            'max' => '6GB',
                        ),
                    ),
                    2 => array(
                        'name' => 'Zend\\Validator\\File\\Extension',
                        'options' => array(
                            'breakchainonfailure' => true,
                            'extension' => 'csv,zip',
                        ),
                    ),
                ),
                'filters' => array(
                    0 => array(
                        'name' => 'RenameUploadFilter',
                    ),
                ),
                'name' => 'file',
                'type' => 'Zend\\InputFilter\\FileInput',
            ),
        ),
...

Expected results

RenameUploadFilter will be used

Actual results

RenameUploadFilter was not found

weierophinney commented 6 years ago

Okay, confirmed using the following test based on the report above:

    public function testWillUseCustomFiltersWhenProvided()
    {
        $filter = $this->prophesize(Filter\FilterInterface::class)->reveal();

        $filters = new FilterPluginManager($this->services);
        $filters->setService('CustomFilter', $filter);

        $validators = new ValidatorPluginManager($this->services);

        $this->services->setService('FilterManager', $filters);
        $this->services->setService('ValidatorManager', $validators);

        $this->services->setService('config', [
            'input_filter_specs' => [
                'test' => [
                    [
                        'name' => 'a-file-element',
                        'type' => FileInput::class,
                        'required' => true,
                        'validators' => [
                            [
                                'name' => Validator\File\UploadFile::class,
                                'options' => [
                                    'breakchainonfailure' => true,
                                ],
                            ],
                            [
                                'name' => Validator\File\Size::class,
                                'options' => [
                                    'breakchainonfailure' => true,
                                    'max' => '6GB',
                                ],
                            ],
                            [
                                'name' => Validator\File\Extension::class,
                                'options' => [
                                    'breakchainonfailure' => true,
                                    'extension' => 'csv,zip',
                                ],
                            ],
                        ],
                        'filters' => [
                            ['name' => 'CustomFilter'],
                        ],
                    ],
                ],
            ],
        ]);

        $this->services->get('InputFilterManager')
            ->addAbstractFactory(InputFilterAbstractServiceFactory::class);

        $inputFilter = $this->services->get('InputFilterManager')->get('test');
        $this->assertInstanceOf(InputFilterInterface::class, $inputFilter);

        $input = $inputFilter->get('a-file-element');
        $this->assertInstanceOf(FileInput::class, $input);

        $filters = $input->getFilterChain();
        $this->assertCount(1, $filters);

        $received = $filters->getFilters()->top();
        $this->assertSame($filter, $received);
    }

The test fails, with a ServiceNotFoundException indicating "A plugin by the name 'CustomFilter` was not found in the plugin manager Zend\Filter\FilterPluginManager".

weierophinney commented 6 years ago

My test was incorrect. $received in that case is actually [$instance, 'filter'] due to how FilterChain injects filter instances. I needed to modify it to the following in order to run against the pre-2.8.5 release:

$callback = $filters->getFilters()->top();
$this->assertInternalType('array', $callback);
$this->assertSame($filter, $callback[0]);
weierophinney commented 6 years ago

One note: it's 2.7.5, not 2.8.5; we do not have a 2.8 series on this component yet!

Fix is in #156, and will be merged and released shortly.

ekosogin commented 6 years ago

Thank you!