ZF2,注册自定义输入过滤器并从表单工厂访问它?

时间:2016-02-01 07:14:41

标签: php configuration module zend-framework2 input-filter

我有一个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'
            )
        );
    }

}

模块/页/ 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;
    }
}

模块/页/ 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
    }
}

模块/页/ 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'
                )
            )
        );
    }
}

根据Module Manager ListenersgetInputFilterConfig()

中提供了Module.php

我不确定我做错了什么。任何想法都是受欢迎的。

修改

根据InputFilter并解释为@Purple Hexagon我已从NewsFormInputFilter中删除了InputFilterProviderInterface实现,并仅从InputFilter

扩展

还从NewsForm

中删除了$ inputFilter属性和getter方法的重复实现

2 个答案:

答案 0 :(得分:1)

您很可能遇到配置问题。我认为这一行很可能不会返回任何内容:

$serviceManager->get('InputFilterManager')->get('Page\Form\NewsFormInputFilter');

我看到您在Module.php 'Page\Form\NewsFormInputFilter'方法中声明了getInputFilterConfig()。但是我的代码中没有看到InputFilter。你有那个班的文件吗?

您应该在命名空间NewsFormInputFilter中有一个名为Page\Form的输入过滤器类。

更新

尝试删除getInputFilterSpecification,不要实施InputFilterProviderInterface。在我看来,你希望调用init。您不需要界面和getInputFilterSpecification方法。

确保您的模块类实现Zend\ModuleManager\Feature\InputFilterProviderInterface

您确定自己的文件位于Page模块中吗?

答案 1 :(得分:1)

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的getter和setter。他们没有被使用,无论如何都是一个非常大的代码味道。你有一个依赖注入工厂。猜猜你最终可能会在getNewsCategoryList中使用,但最好使用构造函数/ setter注入依赖项。

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',
            )
        )
    )
}