<?php
/**
 * A class for validating strings against regex patterns and minimum/maximum
 * character length constraints.
 */
class validator_string extends validator_pattern
{
    /**
     * @var string The minimum length constraint.
     */
    protected $minimum;
    
    /**
     * @var string The maximum length constraint.
     */
    protected $maximum;
    
    /**
     * @var boolean Whether the minimum/maximum constraint is inclusive or not.
     */
    protected $inclusive;
    
    ////////////////////////////////////////////////////////////////////////////
    // Construct and destruct functions.

    /**
     * @param string (optional) $pattern The regex pattern.
     * @param integer (optional) $minimum The minimum length constraint.
     * @param integer (optional) $maximum The maximum length constraint.
     * @param boolean (optional) $inclusive Whether the minimum/maximum
     * constraint is inclusive or not.
     * @param string (optional) $error The error message.
     * @param boolean (optional) $reverse Whether the validator is in reverse
     * mode or not.
     */
    public function __construct($pattern = '~~', $minimum = null, $maximum = null, $inclusive = true, $error = null, $reverse = false)
    {
        parent::__construct($pattern, $error, $reverse);
        $this->minimum = $minimum;
        $this->maximum = $maximum;
        $this->inclusive = $inclusive;
    }

    ////////////////////////////////////////////////////////////////////////////
    // Overload functions.

    ////////////////////////////////////////////////////////////////////////////
    // Interface functions.

    ////////////////////////////////////////////////////////////////////////////
    // Internal functions.
    
    /**
     * Checks if a value is valid.
     * 
     * @param mixed $value The value.
     * @param string (optional) $pattern The regex pattern.
     * @param integer (optional) $minimum The minimum length constraint.
     * @param integer (optional) $maximum The maximum length constraint.
     * @param boolean (optional) $inclusive Whether the minimum/maximum
     * constraint is inclusive or not.
     * @return boolean True if valid, else false.
     */
    protected function _is_valid($value, $pattern = null, $minimum = null, $maximum = null, $inclusive = null)
    {
        if (!parent::_is_valid($value, $pattern))
        {
            return false;
        }
        
        $length = strlen($value);
        
        if ($inclusive === null)
        {
            $inclusive = $this->inclusive;
        }
        
        if ($minimum === null)
        {
            $minimum = $this->minimum;
        }
        
        if ($minimum !== null)
        {
            if (($length < $minimum) || ($length == $minimum && !$inclusive))
            {
                return false;
            }
        }
        
        if ($maximum === null)
        {
            $maximum = $this->maximum;
        }
        
        if ($maximum !== null)
        {
            if (($length > $maximum) || ($length == $maximum && !$inclusive))
            {
                return false;
            }
        }
        
        return true;
    }
}
