Reputation: 1016
I'm currently struggling with some form validation. I'm working with the class below, which is intended to be a fluent interface.
class Validator implements ValidatorInterface {
protected $_count_validators = 0;
protected $_validators;
protected $errorMsg;
public function __construct($errorMsg = '')
{
$this->errorMsg = $errorMsg;
}
public function addValidator(ValidatorInterface $validator)
{
$this->_count_validators++;
$this->_validators[] = $validator;
return $this;
}
public function validate($value)
{
foreach($this->_validators as $validator) {
if ($validator->validate($value) === false) {
return false;
}
}
return true;
}
public function getError()
{
return $this->errorMsg;
}
}
It actually works 75 % - and I can add validators like this:
$postalcodeValidator = new \Framework\Formular\Validator\Validator();
$validatePostalcode= $postalcodeValidator->addValidator(new \Framework\Formular\Validator\NotEmpty)
->addValidator(new \Framework\Formular\IsNumeric);
$cityValidator = new \Framework\Formular\Validator\Validator();
$validateCity = $lastnameValidator->addValidator(new \Framework\Formular\Validator\NotEmpty);
Now I can just write:
$result = $postalcodeValidator->validate('00000');
- or -
$result = $cityValidator->validate('London');
And I will have a boolean. My problem is, that I need to make it easy to set some errors. In the above example - if I just added a getErrors()-function in the class - I had to get the errors for every new instantiation of the class. I want to make a function for getting all errors.
Can you help me on a solution for that?
Thanks in advance,
denlau
Upvotes: 0
Views: 637
Reputation: 1730
A simple way is to implement a static member in an abstract validator class. All your concrete Validator extends this, and will add automaticly errors to this member. Finally you can get this static member with one call. But this is an anti-pattern and you have to reset this member after getting errors.
A better practice is to use the composite pattern. A class where you can add one or more elements with assigned validators. This composite class will execute all validators on your assigned elements and collect all error messages from each validator. Then you can retrieve all collected error messages from your composite, with one call.
For more information about composite pattern see here on wiki
Here an example..
$elementA = new ElementA; // implements Validable
$elementA->addValidator(new ValidatorA)->addValidator(new ValidatorB);
$elementB = new ElementB; // implements Validable
$elementB->addValidator(new ValidatorC);
$elementA->setValue('any_posted_value_to_validate');
$elementB->setValue('another_any_posted_value_to_validate');
$composite = new Composite; // implements Validable
$composite->addElement($elementA)->addElement($elementB);
if (!composite->isValid()) { // will execute all validators on all elements
$errorMessages = $composite->getErrors();
}
Within your composite..
public function isValid()
{
$isValid = true;
foreach ($this->elements as $element) {
if (!$element->isValid()) { // will execute all assigned validators to this element
$this->addErrors($element->getErrors());
$isValid = false;
}
}
return $isValid;
}
The Validable Interface
interface Validable
{
public function isValid();
public function getErrors();
}
Upvotes: 3