Validator.php 5.26 KB
Newer Older
doctrine's avatar
doctrine committed
1
<?php
2 3
/**
 * Doctrine_Validator
4 5 6 7 8
 * Doctrine_Session uses this class for transaction validation
 *
 * @package     Doctrine ORM
 * @url         www.phpdoctrine.com
 * @license     LGPL
9
 */
doctrine's avatar
doctrine committed
10
class Doctrine_Validator {
11 12 13 14 15
    /**
     * ERROR CONSTANTS
     */

    /**
doctrine's avatar
doctrine committed
16
     * constant for length validation error
17
     */
doctrine's avatar
doctrine committed
18
    const ERR_LENGTH    = 0;
19
    /**
doctrine's avatar
doctrine committed
20
     * constant for type validation error
21
     */
doctrine's avatar
doctrine committed
22
    const ERR_TYPE      = 1;
23 24 25
    /**
     * constant for general validation error
     */
doctrine's avatar
doctrine committed
26
    const ERR_VALID     = 2;
27
    /**
doctrine's avatar
doctrine committed
28
     * constant for unique validation error
29
     */
doctrine's avatar
doctrine committed
30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53
    const ERR_UNIQUE    = 3;
    /**
     * constant for blank validation error
     */
    const ERR_BLANK     = 4;
    /**
     * constant for date validation error
     */
    const ERR_DATE      = 5;
    /**
     * constant for null validation error
     */
    const ERR_NULL      = 6;
    /**
     * constant for enum validation error
     */
    const ERR_ENUM      = 7;
    /**
     * constant for range validation error
     */
    const ERR_RANGE     = 8;



doctrine's avatar
doctrine committed
54 55
    
    /**
56
     * @var array $stack            error stack
doctrine's avatar
doctrine committed
57 58 59
     */
    private $stack      = array();
    /**
60
     * @var array $validators       an array of validator objects
doctrine's avatar
doctrine committed
61 62 63
     */
    private static $validators = array();
    /**
64 65
     * returns a validator object
     *
doctrine's avatar
doctrine committed
66
     * @param string $name
67
     * @return Doctrine_Validator_Interface
doctrine's avatar
doctrine committed
68 69 70 71 72 73 74 75 76 77 78 79 80 81
     */
    public static function getValidator($name) {
        if( ! isset(self::$validators[$name])) {
            $class = "Doctrine_Validator_".ucwords(strtolower($name));
            if(class_exists($class)) {
                self::$validators[$name] = new $class;
            } elseif(class_exists($name."Validator")) {
                self::$validators[$name] = new $name."Validator";
            } else 
                throw new Doctrine_Exception("Validator named '$name' not availible.");
        }
        return self::$validators[$name];
    }
    /**
82 83 84
     * validates a given record and saves possible errors
     * in Doctrine_Validator::$stack
     *
doctrine's avatar
doctrine committed
85 86 87 88 89 90 91 92 93 94 95 96 97 98 99
     * @param Doctrine_Record $record
     * @return void
     */
    public function validateRecord(Doctrine_Record $record) {
        $modified = $record->getModified();
        $columns  = $record->getTable()->getColumns();
        $name     = $record->getTable()->getComponentName();

        $err      = array();
        foreach($modified as $key => $value) {
            $column = $columns[$key];

            if(strlen($value) > $column[1]) {
                $err[$key] = Doctrine_Validator::ERR_LENGTH;
                continue;
doctrine's avatar
doctrine committed
100
            }
doctrine's avatar
doctrine committed
101 102 103 104 105 106 107 108 109

            if(self::gettype($value) !== $column[0]) {
                $err[$key] = Doctrine_Validator::ERR_TYPE;
                continue;
            }

            $e = explode("|",$column[2]);

            foreach($e as $k => $arg) {
doctrine's avatar
doctrine committed
110
                if(empty($arg) || $arg == "primary" || $arg == "protected" || $arg == "autoincrement")
doctrine's avatar
doctrine committed
111 112
                    continue;

doctrine's avatar
doctrine committed
113 114 115 116 117 118 119
                $args = explode(":",$arg);
                if( ! isset($args[1])) 
                    $args[1] = '';

                $validator = self::getValidator($args[0]);
                if( ! $validator->validate($record, $key, $value, $args[1])) {
                    switch(strtolower($args[0])):
doctrine's avatar
doctrine committed
120 121 122
                        case "unique":
                            $err[$key] = Doctrine_Validator::ERR_UNIQUE;
                        break;
doctrine's avatar
doctrine committed
123 124 125 126 127 128 129 130 131
                        case "notnull":
                            $err[$key] = Doctrine_Validator::ERR_NULL;
                        break;
                        case "notblank":
                            $err[$key] = Doctrine_Validator::ERR_BLANK;
                        break;
                        case "enum":
                            $err[$key] = Doctrine_Validator::ERR_VALID;
                        break;
doctrine's avatar
doctrine committed
132 133 134 135 136
                        default:
                            $err[$key] = Doctrine_Validator::ERR_VALID;
                        break;
                    endswitch;
                }
doctrine's avatar
doctrine committed
137 138
                
                // errors found quit validation looping for this column
doctrine's avatar
doctrine committed
139 140 141 142 143 144 145 146 147 148 149 150 151
                if(isset($err[$key]))
                    break;
            }
        }

        if( ! empty($err)) {
            $this->stack[$name][] = $err;
            return false;
        }
        
        return true;
    }
    /**
152
     * whether or not this validator has errors
153
     *
doctrine's avatar
doctrine committed
154 155 156 157 158 159
     * @return boolean
     */
    public function hasErrors() {
        return (count($this->stack) > 0);
    }
    /**
160 161
     * returns the error stack
     *
doctrine's avatar
doctrine committed
162 163 164 165 166 167
     * @return array
     */
    public function getErrorStack() {
        return $this->stack;
    }
    /**
168
     * returns the type of loosely typed variable
169
     *
doctrine's avatar
doctrine committed
170
     * @param mixed $var
171
     * @return string
doctrine's avatar
doctrine committed
172 173 174 175 176
     */
    public static function gettype($var) {
        $type = gettype($var);
        switch($type):
            case "string":
doctrine's avatar
doctrine committed
177
                if(preg_match("/^[0-9]+$/",$var)) return "integer";
doctrine's avatar
doctrine committed
178 179 180 181 182 183 184 185 186
                elseif(is_numeric($var)) return "float";
                else return $type;
            break;
            default:
            return $type;
        endswitch;
    }
}
?>