/** * Validates that a value is numeric. * * <code> * class Person extends ActiveRecord\Model { * static $validates_numericality_of = array( * array('salary', 'greater_than' => 19.99, 'less_than' => 99.99) * ); * } * </code> * * Available options: * * <ul> * <li><b>only_integer:</b> value must be an integer (e.g. not a float)</li> * <li><b>even:</b> must be even</li> * <li><b>odd:</b> must be odd"</li> * <li><b>greater_than:</b> must be greater than specified number</li> * <li><b>greater_than_or_equal_to:</b> must be greater than or equal to specified number</li> * <li><b>equal_to:</b> ...</li> * <li><b>less_than:</b> ...</li> * <li><b>less_than_or_equal_to:</b> ...</li> * <li><b>allow_blank:</b> allow blank strings</li> * <li><b>allow_null:</b> allow null strings</li> * </ul> * * @param array $attrs Validation definition */ public function validates_numericality_of($attrs) { $configuration = array_merge(self::$DEFAULT_VALIDATION_OPTIONS, array('only_integer' => false)); // Notice that for fixnum and float columns empty strings are converted to nil. // Validates whether the value of the specified attribute is numeric by trying to convert it to a float with Kernel.Float // (if only_integer is false) or applying it to the regular expression /\A[+\-]?\d+\Z/ (if only_integer is set to true). foreach ($attrs as $attr) { $options = array_merge($configuration, $attr); $attribute = $options[0]; $var = $this->model->{$attribute}; $numericalityOptions = array_intersect_key(self::$ALL_NUMERICALITY_CHECKS, $options); if ($this->is_null_with_option($var, $options)) { continue; } $not_a_number_message = isset($options['message']) ? $options['message'] : Errors::$DEFAULT_ERROR_MESSAGES['not_a_number']; if (true === $options['only_integer'] && !is_integer($var)) { if (!preg_match('/\\A[+-]?\\d+\\Z/', (string) $var)) { $this->record->add($attribute, $not_a_number_message); continue; } } else { if (!is_numeric($var)) { $this->record->add($attribute, $not_a_number_message); continue; } $var = (double) $var; } foreach ($numericalityOptions as $option => $check) { $option_value = $options[$option]; $message = isset($options['message']) ? $options['message'] : Errors::$DEFAULT_ERROR_MESSAGES[$option]; if ('odd' != $option && 'even' != $option) { $option_value = (double) $options[$option]; if (!is_numeric($option_value)) { throw new ValidationsArgumentError("{$option} must be a number"); } $message = str_replace('%d', $option_value, $message); if ('greater_than' == $option && !($var > $option_value)) { $this->record->add($attribute, $message); } elseif ('greater_than_or_equal_to' == $option && !($var >= $option_value)) { $this->record->add($attribute, $message); } elseif ('equal_to' == $option && !($var == $option_value)) { $this->record->add($attribute, $message); } elseif ('less_than' == $option && !($var < $option_value)) { $this->record->add($attribute, $message); } elseif ('less_than_or_equal_to' == $option && !($var <= $option_value)) { $this->record->add($attribute, $message); } } else { if ('odd' == $option && !Utils::is_odd($var) || 'even' == $option && Utils::is_odd($var)) { $this->record->add($attribute, $message); } } } } }