<?php
/**
 * Zend Framework Examples
 *
 * @category  ZfEx
 * @package   TryIt
 * @author    Michel Corne
 * @copyright 2009 Michel Corne
 * @license   http://www.opensource.org/licenses/bsd-license.php The BSD License
 * @see       http://zend-framework-examples.blogspot.com
 */

/*
In this example, we implement text validation.
Validators are chained together. We also implement custom validations.
*/

/*
Loads the autoloader
*/
set_include_path('../ZendFramework/1.9.5/library');
require_once 
'Zend/Loader/Autoloader.php';
$autoloader Zend_Loader_Autoloader::getInstance();

/*
Implementation of the validation process
*/
class MyValidate
{
    
// We define the list of Zend validators.
    // We exclude some validators where parameters are needed.
    // We also exclude the validators for databases.
    
public $zendValidators = array(
        
'Zend_Validate_Alnum',
        
'Zend_Validate_Alpha',
        
// 'Zend_Validate_Barcode',
        
'Zend_Validate_Barcode_Ean13',
        
'Zend_Validate_Barcode_UpcA',
        
'Zend_Validate_Between',
        
'Zend_Validate_Ccnum',
        
'Zend_Validate_Date',
        
// 'Zend_Validate_Db_NoRecordExists',
        // 'Zend_Validate_Db_RecordExists',
        
'Zend_Validate_Digits',
        
'Zend_Validate_EmailAddress',
        
// 'Zend_Validate_File_Count',
        
'Zend_Validate_File_Crc32',
        
// 'Zend_Validate_File_ExcludeExtension',
        // 'Zend_Validate_File_ExcludeMimeType',
        // 'Zend_Validate_File_Exists',
        
'Zend_Validate_File_Extension',
        
'Zend_Validate_File_FilesSize',
        
// 'Zend_Validate_File_Hash',
        // 'Zend_Validate_File_ImageSize',
        // 'Zend_Validate_File_IsCompressed',
        // 'Zend_Validate_File_IsImage',
        
'Zend_Validate_File_Md5',
        
// 'Zend_Validate_File_MimeType',
        // 'Zend_Validate_File_NotExists',
        
'Zend_Validate_File_Sha1',
        
'Zend_Validate_File_Size',
        
// 'Zend_Validate_File_Upload',
        
'Zend_Validate_File_WordCount',
        
'Zend_Validate_Float',
        
'Zend_Validate_GreaterThan',
        
'Zend_Validate_Hex',
        
'Zend_Validate_Hostname',
        
'Zend_Validate_Iban',
        
'Zend_Validate_Identical',
        
// 'Zend_Validate_InArray',
        
'Zend_Validate_Int',
        
'Zend_Validate_Ip',
        
'Zend_Validate_LessThan',
        
'Zend_Validate_NotEmpty',
        
// 'Zend_Validate_Regex',
        // 'Zend_Validate_Sitemap_Changefreq',
        // 'Zend_Validate_Sitemap_Lastmod',
        // 'Zend_Validate_Sitemap_Loc',
        // 'Zend_Validate_Sitemap_Priority',
        // 'Zend_Validate_StringLength',
    
);

    
// We define the list of custom validators.
    
public $customValidators = array(
        
'MyLowerCaseValidator',
        
'MyUpperCaseValidator',
    );

    public 
$min;
    public 
$max;
    public 
$crc32;
    public 
$extension;
    public 
$size;
    public 
$md5;
    public 
$sha1;
    public 
$wordCount;
    public 
$identical;

    public function 
__construct()
    {
        
// We define hard coded values for some numeric validators.
        
$this->min 10;
        
$this->max 20;

        
// We define hard coded values for the validators for files.
        
$this->crc32 hash_file('CRC32'__FILE__);
        
$info pathinfo(__FILE__);
        
$this->extension $info['extension'];
        
$this->size filesize(__FILE__);
        
$this->md5 hash_file('MD5'__FILE__);
        
$this->sha1 hash_file('SHA1'__FILE__);
        
$this->wordCount str_word_count(file_get_contents(__FILE__));
        
$this->identical 'identical';
    }

    
/* Text validation */
    
public function process()
    {
        
// We get the text and the validators, from the GET request.
        
list($data$validators) = $this->_getParameters();

        try {
            if (empty(
$validators)) {
                
$result 'Please enter some text and select one or more validators!';
            } else {
                
// We instantiate the validator chain.
                
$validatorChain = new Zend_Validate();

                foreach(
$validators as $validator) {
                    switch (
$validator) {
                        
// If the validator is a numeric validator, we instantiate the validator
                        // with one or more target values.
                        
case 'Zend_Validate_GreaterThan':
                        case 
'Zend_Validate_LessThan':
                            
$validatorChain->addValidator(new $validator($this->min));
                            break;

                        case 
'Zend_Validate_Between':
                            
$validatorChain->addValidator(new $validator($this->min$this->maxfalse));
                            break;

                        
// If the validator is a validator for files, we instantiate the validator
                        // and we use this file as a target.
                        
case 'Zend_Validate_File_FilesSize':
                        case 
'Zend_Validate_File_Size':
                        case 
'Zend_Validate_File_WordCount':
                            
// We update the template of the error message for the file size,
                            // because we only validate for the exact size.
                            
$message "Wrong value for file '%value%' but '%size%' detected";
                            
// break;

                        
case 'Zend_Validate_File_Crc32':
                        case 
'Zend_Validate_File_Extension':
                        case 
'Zend_Validate_File_Md5':
                        case 
'Zend_Validate_File_Sha1':
                            
$fileValidator = new $validator($data);
                            empty(
$message) or $fileValidator->setMessage($message);
                            
$validatorChain->addValidator($fileValidator);
                            
// And we perform the validation.
                            
$isValid $validatorChain->isValid(__FILE__);
                            break;

                        case 
'Zend_Validate_Identical':
                            
$validatorChain->addValidator(new $validator($this->identical));
                            break;

                        default:
                            
// If this is another validator, we simply add the validator.
                            
$validatorChain->addValidator(new $validator());
                    }
                }

                
// And we perform the validation if it has not been done yet.
                
isset($isValid) or $isValid $validatorChain->isValid($data);

                if (
$isValid) {
                    
$result 'Your text is valid!';
                } else {
                    
// We return the error message if the validation failed.
                    
$result $validatorChain->getMessages();
                    
$result str_replace(__FILE__basename(__FILE__), $result);
                }
            }

        } catch (
Exception $e) {
            
// If we catch an exception, we return the error message.
            
$result $e->getMessage();
        }

        
$validators array_pad($validators3null);

        return array(
$data$validators$result);
    }

    
/* Extraction of the parameters from the GET request */
    
private function _getParameters()
    {
        
$data = isset($_GET['data'])? $_GET['data'] : null;

        
// We ignore a validator if the validator is invalid.
        
$validators = array();
        if (isset(
$_GET['validators'])) {
            foreach(
$_GET['validators'] as $validator) {
                (
in_array($validator$this->zendValidators) or
                
in_array($validator$this->customValidators)) and
                
$validators[] = $validator;
            }
        }

        return array(
$data$validators);
    }
}

/* Creation of a validator for lower case strings */
class MyLowerCaseValidator extends Zend_Validate_Abstract
{
    const 
LOWER_CASE 'lowerCase';

    protected 
$_messageTemplates = array(
        
self::LOWER_CASE => "'%value%' is not a lower case string",
    );

    public function 
isValid($value)
    {
        
$this->_setValue($value);

        if (
strtolower($value) != $value) {
            
$this->_error();
            return 
false;
        }

        return 
true;
    }
}

/* Creation of a validator for upper case strings */
class MyUpperCaseValidator extends Zend_Validate_Abstract
{
    const 
UPPER_CASE 'upperCase';

    protected 
$_messageTemplates = array(
        
self::UPPER_CASE => "'%value%' is not an upper case string",
    );

    public function 
isValid($value)
    {
        
$this->_setValue($value);

        if (
strtoupper($value) != $value) {
            
$this->_error();
            return 
false;
        }

        return 
true;
    }
}

/* Displaying items */
class MyHtml
{
    
/* Displaying the title of the page based on the file name. */
    
public static function printTitle()
    {
        
$basename basename(__FILE__'.php');
        
$title ucwords(str_replace('-' ' '$basename));
        
$zfVersion Zend_Version::VERSION;
        
$phpVersion phpversion();
        echo 
"ZfEx $title (ZF/$zfVersion PHP/$phpVersion)";
    }

    
/* Displaying the selected option */
    
public static function printSelected($value$target)
    {
        
$value == $target and print 'selected="selected"';
    }

    
/* Displaying a string or an array */
    
public static function display($mixed$isNl2Br true$isStripslashes true)
    {
        
// If the data is an array, we convert the array into a set of lines.
        
is_array($mixed) and $mixed implode("\n"$mixed);
        
$isStripslashes and $mixed stripslashes($mixed);
        
// We converts special characters into HTML entities.
        
$mixed htmlspecialchars($mixedENT_QUOTES'UTF-8');
        
// We convert new-line characters into line breaks.
        
$isNl2Br and $mixed nl2br($mixed);
        echo 
$mixed;
    }
}

/*
Validating the text
*/
// We apply the validators to the text and we get all the parameters and the result,
// to display in the form.
$validate = new MyValidate();
list(
$data$validators$result) = $validate->process();
?>
<html xmlns="http://www.w3.org/1999/xhtml">
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <title><?php MyHtml::printTitle();?></title>
    <style type="text/css">
      body, td {
          font-family: arial, sans-serif;
          font-size: 0.9em;
      }
      textarea.data {
          height: 3em;
          width: 30em;
      }
    </style>
  </head>

  <body>

    <p>EXAMPLE <?php MyHtml::printTitle();?></p>
    <hr />

    <form name="form">

      <table>

        <tr>
          <td>Text</td>
          <td><textarea class="data" name="data"><?php MyHtml::display($datafalse);?></textarea>
          </td>
        </tr>

        <tr><td>&nbsp;</td></tr>

        <tr>
          <td>Validator Chain</td>
          <td>
            <select name="validators[0]">
              <option></option>
              <optgroup label="Zend Validators">
                <?php foreach($validate->zendValidators as $name) :?>
                    <option value="<?php echo $name;?>"
                            <?php MyHtml::printSelected($validators[0], $name);?>>
                      <?php echo $name;?>
                    </option>
                <?php endforeach;?>
              </optgroup>
              <optgroup label="Custom Validators">
                <?php foreach($validate->customValidators as $name) :?>
                    <option value="<?php echo $name;?>"
                            <?php MyHtml::printSelected($validators[0], $name);?>>
                      <?php echo $name;?>
                    </option>
                <?php endforeach;?>
              </optgroup>
            </select>
          </td>
        </tr>

        <tr>
          <td></td>
          <td>
            <select name="validators[1]">
              <option></option>
              <optgroup label="Zend Validators">
                <?php foreach($validate->zendValidators as $name) :?>
                    <option value="<?php echo $name;?>"
                            <?php MyHtml::printSelected($validators[1], $name);?>>
                      <?php echo $name;?>
                    </option>
                <?php endforeach;?>
              </optgroup>
              <optgroup label="Custom Validators">
                <?php foreach($validate->customValidators as $name) :?>
                    <option value="<?php echo $name;?>"
                            <?php MyHtml::printSelected($validators[1], $name);?>>
                      <?php echo $name;?>
                    </option>
                <?php endforeach;?>
              </optgroup>
            </select>
          </td>
        </tr>

        <tr>
          <td></td>
          <td>
            <select name="validators[2]">
              <option></option>
              <optgroup label="Zend Validators">
                <?php foreach($validate->zendValidators as $name) :?>
                    <option value="<?php echo $name;?>"
                            <?php MyHtml::printSelected($validators[2], $name);?>>
                      <?php echo $name;?>
                    </option>
                <?php endforeach;?>
              </optgroup>
              <optgroup label="Custom Validators">
                <?php foreach($validate->customValidators as $name) :?>
                    <option value="<?php echo $name;?>"
                            <?php MyHtml::printSelected($validators[2], $name);?>>
                      <?php echo $name;?>
                    </option>
                <?php endforeach;?>
              </optgroup>
           </select>
          </td>
        </tr>

        <tr><td>&nbsp;</td></tr>

        <tr>
          <td></td>
          <td>
            <input type="submit" value="Submit" />
            <br /> <br />
            Zend_Validate_Between is hard coded to validate numbers strictly
              between <?php echo $validate->min;?> and <?php echo $validate->max;?>. <br/>
            Zend_Validate_Ccnum validate card numbers,
              for example 4539 9920 4349 1562. <br/>
            Zend_Validate_File_Crc32 is hard coded to validate the CRC32 of this file
              which is <?php echo $validate->crc32;?>.<br>
            Zend_Validate_File_Extension is hard coded to validate the extension of this file
              which is <?php echo $validate->extension;?>.<br>
            Zend_Validate_File_FilesSize is hard coded to validate the size of this file
              which is <?php echo $validate->size;?>.<br>
            Zend_Validate_File_Md5 is hard coded to validate the MD5 of this file
              which is <?php echo $validate->md5;?>.<br>
            Zend_Validate_File_Sha1 is hard coded to validate the SHA1 of this file
              which is <?php echo $validate->sha1;?>.<br>
            Zend_Validate_File_Size is hard coded to validate the size of this file
              which is <?php echo $validate->size;?>.<br>
            Zend_Validate_File_WordCount is hard coded to validate the word count of this file
              which is <?php echo $validate->wordCount;?>.<br>
            Zend_Validate_GreaterThan is hard coded to validate numbers
              greater than <?php echo $validate->min;?>. <br/>
            Zend_Validate_Iban validate International Bank Account Number,
              for example GB35MIDL40253432144670. <br/>
            Zend_Validate_Identical is hard coded to validate
              the word <?php echo $validate->identical;?>. <br/>
            Zend_Validate_LessThan is hard coded to validate numbers
              less than <?php echo $validate->min;?>. <br/>
          </td>
        </tr>

      </table>
    </form>

    <hr />
    RESULT
    <br /> <br />
    <?php MyHtml::display($resulttruefalse);?>

  </body>
</html>