Reputation: 9442
I am struggling with performing a validation problem, based on a field entity called published
I must apply validation rules:
true
false
(draft feature)I managed to add a callback validator to canonical fields which check my rule and it works fine:
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;
},
),
);
Usage:
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
)
Now I have on some fields which are validated with a ObjectExists
validator:
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
),
The ObjectExists
validator extends 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;
}
}
Problem:
The parent class validator doesn't know the value of published
Even if I change the implementation to check the published
value I will get the value from the DB not from the actual POST
request
Is there a way to check the existence of an entity depending on the published
value from the request?
Is there a way to pass a sibling value when validating another field (in my case pass 'published
when validating a person
)?
Upvotes: 2
Views: 526
Reputation: 44422
Your input-filter has something called a validation group. You could remove the input that you don't want to validate from that validator group when the value for your published
field is false
and then those input elements don't get validated when the input-filter is running.
You don't have to solve this in the validator class itself. It would be better to move this logic to a higher level (so example by setting the validation group inside the init
method of your input-filter class). I don't think the validator class itself should be handling this responsibility.
//pass the input names you want to validate here when published is false
if($published === false){
$inputFilter->setValidationGroup();
}
In such a solution you only have to inject this published
field inside your input-filter class and not inside all the individual validators.
Upvotes: 3
Reputation: 9442
I have found a solution:
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; } }
Upvotes: 0