As usual, before I start building the additional strategy class mentioned in the introduction, which as you know will be charged with validating URLs, I'm going to spend a few moments showing the source code of all the sample classes developed so far. This way you can quickly recall the role played by each of them in the implementation of the strategy pattern within a "real" web application. With that being said, here's the first of these classes. It's a basic form helper that takes a group of validator objects through its "addValidator()" method. These objects are used for checking the validity of a given set of data: (FormHelper.php) <?php class FormHelper { protected $_validators = array(); protected $_errors = array();
// add a validator public function addValidator(AbstractValidator $validator) { $this->_validators[] = $validator; return $this; }
// get all the validators public function getValidators() { return !empty($this->_validators) ? $this->_validators : null; }
// validate inputted data public function validate() { $validators = $this->getValidators(); if (null !== $validators) { foreach ($validators as $validator) { if (!$validator->validate()) { $this->_errors[] = $validator->getFormattedError(); } } } return empty($this->_errors) ? true : false; }
// get validation errors as an array public function getErrors() { return $this->_errors; }
// get validation errors as a string public function getErrorString() { $errors = $this->getErrors(); return !empty($errors) ? implode('', $errors) : ''; }
// clear state of the form helper public function clear() { $this->_validators = array(); $this->_errors = array(); } } As you can see, the "FormHelper" class is a simple container that permits you to store different validation objects in an internal array, which is used afterward by the "validate()" method to determine whether or not a supplied value is valid. Since the logic that drives this form helper has been discussed in past articles of the series, I suggest that you move on and take a look at the following abstract class. It defines the generic structure and metadata of the validator objects just mentioned: (AbstractValidator.php) <?php abstract class AbstractValidator { protected $_value = ''; protected $_filter = ''; protected $_options = null; protected $_errorMessage = ''; protected $_errorPrefix = '<p>'; protected $_errorSufix = '</p>';
// constructor public function __construct($value, array $options = null) { $this->_value = $value; if (null !== $options) { $this->setOptions($options); } }
// get supplied value public function getValue() { return $this->_value; }
// set validation options public function setOptions(array $options) { if (empty($options)) { throw new ValidatorException('Invalid options for the validator.'); } $this->_options = $options; }
// get validation options public function getOptions() { return $this->_options; }
// set the validation filter public function setFilter($filter) { if (!is_string($filter)) { throw new ValidatorException('Invalid filter for the validator.'); } $this->_filter = $filter; }
// get the validation filter public function getFilter() { return $this->_filter; }
// set the error message public function setErrorMessage($errorMessage) { if (!is_string($errorMessage)) { throw new ValidatorException('Invalid error message for the validator.'); } $this->_errorMessage = $errorMessage; }
// get error message public function getErrorMessage() { return $this->_errorMessage; }
// get formatted error string public function getFormattedError() { return $this->_errorPrefix . 'The value ' . $this->getValue() . ' is incorrect. ' . $this->getErrorMessage() . $this->_errorSufix; }
// validate the supplied value public function validate() { return filter_var($this->getValue(), $this->getFilter(), $this->getOptions()); } } (ValidatorException.php) <?php class ValidatorException extends Exception{} Well, if I had to say something relevant about the above "AbstractValidator" class, it would be that the driving force of its "validate()" method is the "filter_var()" PHP function. Obviously, this method, along with the corresponding getters and mutators (nice word, right?) allow you to define the logic and structure of a generic validation component, which must be refined by the pertinent subclasses. And speaking of refined implementations, below is the list of concrete subclasses derived from the base "AbstractValidator" class. They come in useful for checking integers, float numbers and email addresses: (IntegerValidator.php) <?php class IntegerValidator extends AbstractValidator { protected $_filter = FILTER_VALIDATE_INT; protected $_errorMessage = 'Please enter an integer value.'; } (FloatValidator.php) <?php class FloatValidator extends AbstractValidator { protected $_filter = FILTER_VALIDATE_FLOAT; protected $_errorMessage = 'Please enter a float value.'; } (EmailValidator.php) <?php class EmailValidator extends AbstractValidator { protected $_filter = FILTER_VALIDATE_EMAIL; protected $_errorMessage = 'Please enter a valid email address.'; } From the previous code samples, it's clear to see how easy it is to create a concrete subclass that permits you to check a specified type of data. In all cases, defining a specific validation component is reduced to overriding the "$_filter" and "$_errorMessage" properties declared by the parent "AbstractValidator" and nothing else. All right, at this point I've shown you all of the strategy classes developed so far, which are more than enough for building a fully-functional validation web application. As I expressed in the introduction, however, it'd be useful to create yet another class that allows us to determine if a supplied value is a valid URL. Doing this is so simple, that experience is really worthwhile. In keeping with this, in the following segment I'm going to create a final strategy class to check URLs, whose definition will look very similar to the ones that you saw before. Now, go ahead and read the next section. It's only one click away.
blog comments powered by Disqus |
|
|
|
|
|
|
|