我正在努力执行验证问题,基于名为published
的字段实体我必须应用验证规则:
true
false
(草稿功能)我设法在规范字段中添加了一个回调验证器来检查我的规则并且它有效 细:
Validator definition
$emptyValidatorOnPublish = array(
'name' => 'Callback',
'options' => array(
'messages' => array(
\Zend\Validator\Callback::INVALID_VALUE => 'This field cannot be empty',
),
'callback' => function($value, $context=array()) {
if($context['published']){//Here I know the POST value
return !empty($value); //it must not be empty
}
return true;
},
),
);
用法:
array(
'name' => 'title',
'description' => 'Title of the interview',
'required' => true,
'filters' => array(
0 => array(
'name' => 'Zend\\Filter\\StringTrim',
'options' => array()
),
1 => array(
'name' => 'Zend\\Filter\\StripTags',
'options' => array()
)
),
'validators' => array($emptyValidatorOnPublish),
'error_message' => 'title is required',
'allow_empty' => true,
'continue_if_empty' => true
)
现在,我已经使用ObjectExists
验证器验证了一些字段:
array(
'name' => 'person',
'description' => 'Person link',
'required' => true,
'filters' => array(),
'validators' => array(
0 => array(
'name' => 'MyApp\\Validators\\ObjectExists',
'options' => array(
'fields' => 'ref',
'message' => 'This person does not exist',
'object_manager' => 'doctrine.entitymanager.orm_default',
'object_repository' => 'MyApp\\Person'
)
)
),
'allow_empty' => true,
'continue_if_empty' => true
),
ObjectExists
验证程序扩展DoctrineModule\Validator\ObjectExists
。
class ObjectExists extends BaseObjectExists
{
/**
* {@inheritDoc}
*/
public function isValid($value)
{
if (! is_array($value)) {
return parent::isValid($value);
}
$isValid = null;
foreach ($value as $oneValue) {
$isValid = false === $isValid ? $isValid : parent::isValid($oneValue);
}
return $isValid;
}
}
问题:
父类验证员不知道published
的价值
即使我更改实施以检查published
值,我也会从数据库中获取值而不是实际的POST
请求
是否有办法根据请求中的published
值检查实体是否存在?
有没有办法在验证另一个字段时传递一个兄弟值(在我的情况下,在验证'published
时传递person
)?
答案 0 :(得分:3)
您的输入过滤器有一个叫validation group的东西。当published
字段的值为false
时,您可以删除不希望从该验证程序组验证的输入,然后在输入过滤器为时,这些输入元素不会得到验证运行
您无需在验证程序类本身中解决此问题。将此逻辑移动到更高级别会更好(例如,通过在输入过滤器类的init
方法中设置验证组)。我认为验证者类本身不应该处理这个责任。
//pass the input names you want to validate here when published is false
if($published === false){
$inputFilter->setValidationGroup();
}
在这样的解决方案中,您只需要在输入过滤器类中注入此published
字段,而不是在所有单独的验证器中注入。
答案 1 :(得分:0)
我找到了一个解决方案:
class ObjectExistsIfPublishedFactory implements FactoryInterface,MutableCreationOptionsInterface { /** * @var array */ protected $options = array(); public function setCreationOptions(array $options) { $this->options = $options; } public function createService(ServiceLocatorInterface $serviceLocator) { $services = $serviceLocator->getServiceLocator(); $application = $services->get('Application'); $mvcEvent = $application->getMvcEvent(); $dataContainer = $mvcEvent->getParam('ZFContentNegotiationParameterData', false); $data = $dataContainer->getBodyParams(); //Get request parameters $this->options['isPublished'] = $data['published']?true:false; //Add to the options of the validator $objectManager = $serviceLocator->getServiceLocator()->get($this->options['object_manager']); $this->options['object_repository'] = $objectManager->getRepository($this->options['object_repository']); return new ObjectExistsIfPublished($this->options); } }
use DoctrineModule\Validator\ObjectExists as BaseObjectExists; class ObjectExistsIfPublished extends BaseObjectExists { /** * {@inheritDoc} */ public function isValid($value) { $isValid = true; if($this->getOption('isPublished')){ if (! is_array($value)) { return parent::isValid($value); } $isValid = null; foreach ($value as $oneValue) { $isValid = false === $isValid ? $isValid : parent::isValid($oneValue); } } return $isValid; } }