Как применить фильтр к элементу поля с содержимым массива?
Например:
$this->add( "name" => "tags", "type" => "text", "filter" => array( array("name" => "StripTags"), array("name" => "StringTrim") ) ); $tags[0] = "PHP"; $tags[1] = "CSS";
Если я пытаюсь фильтровать, я получаю сообщение об ошибке, скажем, что скалярный объект исключен, заданный массив.
В настоящее время это невозможно. Лучше всего использовать фильтр обратного вызова и фильтровать каждый элемент по отдельности. Что-то вроде этого
$this->add( "name" => "tags", "type" => "text", "filter" => array( array("name" => "Callback", "options" => array( "callback" => function($tags) { $strip = new \Zend\Filter\StripTags(); $trim = new \Zend\Filter\StringTrim(); foreach($tags as $key => $tag) { $tag = $strip->filter($tag); $tag = $trim->filter($tag); $tags[$key] = $tag; } return $tags; })) ) );
Я понимаю, что это старо, но вы можете указать тип ввода, поскольку ArrayInput
и InputFilter
будут обрабатывать его, как ожидалось:
"name" => "tags", "type" => "Zend\\InputFilter\\ArrayInput", // Treat this field as an array of inputs "filter" => array( array("name" => "StripTags"), array("name" => "StringTrim") )
Я создал CollectionValidator, который применяет существующий валидатор ко всем элементам массива.
Я использую его с Apigility как таковым:
'input_filter_specs' => [ 'Api\\Contact\\Validator' => [ [ 'name' => 'addresses', 'required' => false, 'filters' => [], 'validators' => [ [ 'name' => 'Application\\Validator\\CollectionValidator', 'options' => ['validator' => 'Api\\Address\\Validator'] ] ], 'description'=> 'List of addresses for contact' ], [ 'name' => 'birthdate', # ... ] ], ]
Я не уверен, что именно так вы будете использовать валидатор внутри контроллера, но, вероятно, что-то вроде этого:
new Collection(array('validator' => 'Zend\Validator\CreditCard'))
Он возвращает validation_messages
каждого индекса. Предположим, что для создания контакта был запросом REST POST, он указывает, что второй адрес содержит ошибку в поле zipcode.
{ "detail": "Failed Validation", "status": 422, "title": "Unprocessable Entity", "type": "http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html", "validation_messages": { "addresses": { "1": { "zipcode": { "notAlnum": "The input contains characters which are non alphabetic and no digits" } } }, "birthdate": { "dateInvalidDate": "The input does not appear to be a valid date" } } }
Валидатор коллекции:
<?php namespace Application\Validator; class Collection extends \Zend\Validator\AbstractValidator implements \Zend\ServiceManager\ServiceLocatorAwareInterface { protected $serviceLocator; protected $em; protected $messages; protected $options = array( 'validator' => null ); public function setServiceLocator(\Zend\ServiceManager\ServiceLocatorInterface $serviceLocator) { $this->serviceLocator = $serviceLocator->getServiceLocator(); } public function getServiceLocator() { return $this->serviceLocator; } public function isValid($array) { $inputFilterManager = $this->getServiceLocator()->get('inputfiltermanager'); $validatorName = $this->getOption('validator'); $this->messages = []; $isvalid = true; foreach($array as $index => $item) { $inputFilter = $inputFilterManager->get($validatorName); $inputFilter->setData($item); $isvalid = $isvalid && $inputFilter->isValid($item); foreach($inputFilter->getMessages() as $field => $errors) { foreach($errors as $key => $string) { $this->messages[$index][$field][$key] = $string; } } } return $isvalid; } public function getMessages() { return $this->messages; } }
Текущие ограничения: