I have followed the zf2 album example. I am now trying to integrate the HTML Purifier.
This is the Module https://github.com/juriansluiman/Soflomo-Purifier#injecting-the-filtermanager
This is the way I have constructed my inputfilter.
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;
}
}
I am getting the following error.
As such, you get a ServiceNotFoundException: Zend\Filter\FilterPluginManager::get was unable to fetch or create an instance for htmlpurifier. This means the filter plugin manager was lazily instantiated, and does not know about the htmlpurifier plugin.
What is the proper way to construct my input filter to take advantage of this module. Many Thanks, Matt
The problem you're experiencing is caused exactly by what is noted in SoflomoPurifier
documentation:
since you're manually instantiating with new InputFilter
, that instance is never wired with the configuration provided by additional modules.
To ensure this wiring happens, I would suggest to create a new InputFilter
subclass and put your all the InputFilter::add()
calls into its init()
method:
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,
),
),
),
));
}
}
change your Album model constructor to use constructor injection:
use Zend\InputFilter\InputFilterInterface;
class Album
{
// etc etc
public function __construct(InputFilterInterface $inputFilter)
{
$this->inputFilter = $inputFilter;
}
// etc etc
}
and then use a factory to inject it:
// 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)
}
}
]
];
}
invoking InputFilterPluginManager::get()
with an input filter FQCN will automatically invoke its constructor, wire it up with other modules, and then invoke its init()
method.
so now, rather than using $album = new Album
, you should use the AlbumFactory
service to create albums with their input filter correctly injected:
$createAlbum = $serviceManager->get('AlbumFactory');
$album = $createAlbum()
obviously you are advised to inject this factory inside any consumer (i.e. controllers) instead of pulling it from the service manager, and possibly refactor the anonymous function into a dedicated factory class.