使用插件管理器配置Zend Framework 2输入过滤器

时间:2016-05-30 00:37:46

标签: php zend-framework zend-framework2 zend-inputfilter

我已经关注了zf2专辑的例子。我现在正在尝试集成HTML Purifier。

这是模块 https://github.com/juriansluiman/Soflomo-Purifier#injecting-the-filtermanager

这是我构建输入过滤器的方式 http://framework.zend.com/manual/current/en/user-guide/forms-and-actions.html

namespace Album\Model;

 // Add these import statements
 use Zend\InputFilter\InputFilter;
 use Zend\InputFilter\InputFilterAwareInterface;
 use Zend\InputFilter\InputFilterInterface;

 class Album implements InputFilterAwareInterface
 {
     public $id;
     public $artist;
     public $title;
     protected $inputFilter;                       // <-- Add this variable

     public function exchangeArray($data)
     {
         $this->id     = (isset($data['id']))     ? $data['id']     : null;
         $this->artist = (isset($data['artist'])) ? $data['artist'] : null;
         $this->title  = (isset($data['title']))  ? $data['title']  : null;
     }

     // Add content to these methods:
     public function setInputFilter(InputFilterInterface $inputFilter)
     {
         throw new \Exception("Not used");
     }

     public function getInputFilter()
     {
         if (!$this->inputFilter) {
             $inputFilter = new InputFilter();

             $inputFilter->add(array(
                 'name'     => 'id',
                 'required' => true,
                 'filters'  => array(
                     array('name' => 'Int'),
                 ),
             ));

             $inputFilter->add(array(
                 'name'     => 'artist',
                 'required' => true,
                 'filters'  => array(
                     array('name' => 'StripTags'),
                     array('name' => 'StringTrim'),
                 ),
                 'validators' => array(
                     array(
                         'name'    => 'StringLength',
                         'options' => array(
                             'encoding' => 'UTF-8',
                             'min'      => 1,
                             'max'      => 100,
                         ),
                     ),
                 ),
             ));

             $inputFilter->add(array(
                 'name'     => 'title',
                 'required' => true,
                 'filters'  => array(
                     array('name' => 'StripTags'),
                     array('name' => 'StringTrim'),
                 ),
                 'validators' => array(
                     array(
                         'name'    => 'StringLength',
                         'options' => array(
                             'encoding' => 'UTF-8',
                             'min'      => 1,
                             'max'      => 100,
                         ),
                     ),
                 ),
             ));

             $this->inputFilter = $inputFilter;
         }

         return $this->inputFilter;
     }
 }

我收到以下错误。

因此,您得到ServiceNotFoundException:Zend \ Filter \ FilterPluginManager :: get无法为htmlpurifier获取或创建实例。这意味着过滤器插件管理器被懒惰地实例化,并且不知道htmlpurifier插件。

构建输入过滤器以利用此模块的正确方法是什么。非常感谢, 马特

1 个答案:

答案 0 :(得分:1)

您遇到的问题完全由SoflomoPurifier文档中提到的问题引起: 由于您使用new InputFilter手动实例化,因此该实例永远不会与其他模块提供的配置连接。

为了确保这种接线发生,我建议您创建一个新的InputFilter子类,并将所有InputFilter::add()次调用放入其init()方法中:

use Zend\InputFilter\InputFilter:

class AlbumInputFilter extends InputFilter
{
    public function init()
    {
        $this->add(array(
            'name'     => 'id',
            'required' => true,
            'filters'  => array(
                array('name' => 'Int'),
            ),
         ));

        $this->add(array(
            'name'     => 'artist',
            'required' => true,
            'filters'  => array(
                array('name' => 'StripTags'),
                array('name' => 'StringTrim'),
            ),
            'validators' => array(
                array(
                    'name'    => 'StringLength',
                    'options' => array(
                        'encoding' => 'UTF-8',
                        'min'      => 1,
                        'max'      => 100,
                    ),
                ),
            ),
         ));

        $this->add(array(
            'name'     => 'title',
            'required' => true,
            'filters'  => array(
                array('name' => 'StripTags'),
                array('name' => 'StringTrim'),
            ),
            'validators' => array(
                array(
                    'name'    => 'StringLength',
                    'options' => array(
                        'encoding' => 'UTF-8',
                        'min'      => 1,
                        'max'      => 100,
                    ),
                ),
            ),
         ));
    }
}

更改您的相册模型构造函数以使用构造函数注入:

use Zend\InputFilter\InputFilterInterface;

class Album
{
    // etc etc

    public function __construct(InputFilterInterface $inputFilter)
    {
        $this->inputFilter = $inputFilter;
    }

    // etc etc
}

然后使用工厂注入它:

// in your Module.php

public function getServiceConfig()
{
    return [
        'factories' => [
            'AlbumFactory' => function($serviceManager) {
                $inputFilterManager = $serviceManager->get('InputFilterManager');
                return function() use ($inputFilterManager) {
                    $inputFilter = $inputFilterManager->get(AlbumInputFilter::class);
                    return new Album($inputFilter)
                }
            }
        ]
    ];
}

使用输入过滤器调用InputFilterPluginManager::get() FQCN将自动调用其构造函数,将其与其他模块连接起来,然后调用其init()方法。

现在,您应该使用$album = new Album服务创建专辑,而不是使用AlbumFactory,而是正确注入输入过滤器:

$createAlbum = $serviceManager->get('AlbumFactory');
$album = $createAlbum()

显然,建议您将此工厂注入任何消费者(即控制器),而不是从服务管理器中提取,并可能将匿名功能重构为专用工厂类。