/** * Validates the length of a value. * * <code> * class Person extends ActiveRecord\Model { * static $validatesLengthOf = array( * array('name', 'within' => array(1,50)) * ); * } * </code> * * Available options: * * <ul> * <li><b>is:</b> attribute should be exactly n characters long</li> * <li><b>in/within:</b> attribute should be within an range array(min,max)</li> * <li><b>maximum/minimum:</b> attribute should not be above/below respectively</li> * <li><b>message:</b> custome error message</li> * <li><b>allowBlank:</b> allow blank strings</li> * <li><b>allowNull:</b> allow null strings. (Even if this is set to false, a null string is always shorter than a maximum value.)</li> * </ul> * * @param array $attrs Validation definition */ public function validatesLengthOf($attrs) { $configuration = array_merge(self::$DEFAULT_VALIDATION_OPTIONS, array('tooLong' => Errors::$DEFAULT_ERROR_MESSAGES['tooLong'], 'tooShort' => Errors::$DEFAULT_ERROR_MESSAGES['tooShort'], 'wrongLength' => Errors::$DEFAULT_ERROR_MESSAGES['wrongLength'])); foreach ($attrs as $attr) { $options = array_merge($configuration, $attr); $rangeOptions = array_intersect(array_keys(self::$ALL_RANGE_OPTIONS), array_keys($attr)); sort($rangeOptions); switch (sizeof($rangeOptions)) { case 0: throw new ValidationsArgumentError('Range unspecified. Specify the [within], [maximum], or [is] option.'); case 1: break; default: throw new ValidationsArgumentError('Too many range options specified. Choose only one.'); } $attribute = $options[0]; $var = $this->model->{$attribute}; if ($this->isNullWithOption($var, $options) || $this->isBlankWithOption($var, $options)) { continue; } if ($rangeOptions[0] == 'within' || $rangeOptions[0] == 'in') { $range = $options[$rangeOptions[0]]; if (!Utils::isA('range', $range)) { throw new ValidationsArgumentError("Range must be an array composing a range of numbers with key [0] being less than key [1]"); } $rangeOptions = array('minimum', 'maximum'); $attr['minimum'] = $range[0]; $attr['maximum'] = $range[1]; } foreach ($rangeOptions as $rangeOption) { $option = $attr[$rangeOption]; if ((int) $option <= 0) { throw new ValidationsArgumentError("{$rangeOption} value cannot use a signed integer."); } if (is_float($option)) { throw new ValidationsArgumentError("{$rangeOption} value cannot use a float for length."); } if (!($rangeOption == 'maximum' && is_null($this->model->{$attribute}))) { $messageOptions = array('is' => 'wrongLength', 'minimum' => 'tooShort', 'maximum' => 'tooLong'); if (isset($options['message'])) { $message = $options['message']; } else { $message = $options[$messageOptions[$rangeOption]]; } $message = str_replace('%d', $option, $message); $attributeValue = $this->model->{$attribute}; $len = strlen($attributeValue); $value = (int) $attr[$rangeOption]; if ('maximum' == $rangeOption && $len > $value) { $this->record->add($attribute, $message); } if ('minimum' == $rangeOption && $len < $value) { $this->record->add($attribute, $message); } if ('is' == $rangeOption && $len !== $value) { $this->record->add($attribute, $message); } } } } }