I think you should develop another class: a ValidatorChain, which takes an arbitrary amount of validators, and that aggregates the errormessages of all validators that it has tested
For reference see the docs on Zend Framework's Validator Chain
EDIT
Now that I re-evaluate your question (thanks to Bryan M's comment); why do you want each individual Validator to have access to other Validators' error messages? I would say that collecting each individual Validators' error messages is the responsibility of an object higher in the hierarchy.
If, however, you want individual Validators to be able to act based on context, in other words, based on what the results of other Validators are, then I suppose you could add a $context parameter to the isCorrect
method. This could for instance accept an arbitrary amount of Validators or something similar.
Something like:
interface ValidatorInterface
{
public function isCorrect( array $context );
public function getMessages();
}
abstract class ValidatorContextOptions
{
const SHOULD_BE_PRESENT = 'shouldBePresent';
const SHOULD_NOT_BE_PRESENT = 'shouldNotBePresent';
const SHOULD_BE_VALID = 'shouldBeValid';
}
class EmailValidator implements ValidatorInterface
{
protected $_field;
protected $_contextOptions = array();
protected $_messages = array();
public function __construct( $field, array $contextOptions )
{
$this->_field = $field;
$this->_contextOptions = $contextOptions;
}
public function isCorrect( array $context = null )
{
foreach( $this->_contextOptions as $field => $options )
{
foreach( $options as $option )
{
switch( $option )
{
case ValidatorContextOptions::SHOULD_NOT_BE_PRESENT:
if( isset( $context[ $field ] )
&& $context[ $field ] instanceof ValidatorInterface )
{
$this->_messages[] = $field . ' should not be present';
return false;
}
break;
case ValidatorContextOptions::SHOULD_BE_PRESENT:
if( !isset( $context[ $field ] )
|| !$context[ $field ] instanceof ValidatorInterface )
{
$this->_messages[] = $field . ' should be present';
return false;
}
break;
case ValidatorContextOptions::SHOULD_BE_VALID:
if( !isset( $context[ $field ] )
|| !$context[ $field ] instanceof ValidatorInterface
|| !$context[ $field ]->isCorrect() )
{
$this->_messages[] = $field . ' should be valid';
return false;
}
break;
}
}
}
// some dummy function which you should replace with real validation
return isAnEmailAddress( $this->_field );
}
public function getMessages()
{
return $this->_messages;
}
}
Usage:
$emailValidatorContextOptions = array
(
'phone' => array(
ValidatorContextOptions::SHOULD_BE_PRESENT,
ValidatorContextOptions::SHOULD_BE_VALID
)
);
$phoneValidator = new PhoneValidator( $phoneString );
$emailValidator = new EmailValidator( $emailString, $emailValidatorContextOptions );
if( !$emailValidator->isCorrect( array( 'phone' => $phoneValidator ) ) )
{
print_r( $emailValidator->getMessages() );
}
What I've shown here, needs a lot more thinking (and I really mean A LOT), is buggy as hell and definately not bulletproof. But I hope you catch my drift of where I'm going with this.
Moreover, where do you insert the values in your validator that need to be validated anyway?