From 1a4e908461ecbfb646b6f4af75f753dd83557b8a Mon Sep 17 00:00:00 2001 From: Eric Lippmann Date: Wed, 3 Sep 2014 14:36:18 +0200 Subject: [PATCH] lib: Let `DateTimeValidator' validate values as defined in HTML5 See http://www.w3.org/TR/html-markup/datatypes.html#common.data.datetime for the specification. refs #6593 --- .../Web/Form/Validator/DateTimeValidator.php | 117 ++++-------------- 1 file changed, 21 insertions(+), 96 deletions(-) diff --git a/library/Icinga/Web/Form/Validator/DateTimeValidator.php b/library/Icinga/Web/Form/Validator/DateTimeValidator.php index f1952f7d4..6b59d5263 100644 --- a/library/Icinga/Web/Form/Validator/DateTimeValidator.php +++ b/library/Icinga/Web/Form/Validator/DateTimeValidator.php @@ -4,127 +4,52 @@ namespace Icinga\Web\Form\Validator; -use Icinga\Util\DateTimeFactory; +use DateTime; use Zend_Validate_Abstract; -use Icinga\Exception\ProgrammingError; /** - * Validator that checks if a textfield contains a correct date format + * Validator for date-and-time input controls + * + * @see \Icinga\Web\Form\Element\DateTimePicker For the date-and-time input control. */ class DateTimeValidator extends Zend_Validate_Abstract { - /** - * Array of allowed patterns for datetime input - * - * @var array - */ - private $patterns = array(); + protected $local; /** - * If the input is not a timestamp this contains the pattern that - * matched the input + * Create a new date-and-time input control validator * - * @var string|bool + * @param bool $local */ - private $validPattern = false; - - /** - * Error templates - * - * @var array - * - * @see Zend_Validate_Abstract::$_messageTemplates - */ - protected $_messageTemplates = array(); - - /** - * Create this validator - * - * @param array $patterns Array containing all allowed patterns as strings - */ - public function __construct(array $patterns) + public function __construct($local) { - $this->patterns = $patterns; - $this->_messageTemplates = array( - 'INVALID_TYPE' => 'Invalid type given. Date/time string or Unix timestamp expected', - 'NO_MATCHING_PATTERN' => 'Invalid format given, valid formats are ' . $this->getAllowedPatternList() - ); + $this->local = (bool) $local; } /** - * Check whether a variable is a Unix timestamp + * Is the date and time valid? + * + * @param string|DateTime $value + * @param mixed $context * - * @param mixed $timestamp * @return bool - */ - public static function isUnixTimestamp($timestamp) - { - return (is_int($timestamp) || ctype_digit($timestamp)) - && ($timestamp <= PHP_INT_MAX) - && ($timestamp >= ~PHP_INT_MAX); - } - - /** - * Returns a printable string containing all configured patterns * - * @return string - */ - private function getAllowedPatternList() - { - return '"' . join('","', $this->patterns) . '"'; - } - - /** - * Validate the input value and set the value of @see validPattern if the input machtes a pattern - * - * @param string $value The format string to validate - * @param null $context The form context (ignored) - * - * @return bool True when the input is valid, otherwise false - * - * @see Zend_Validate_Abstract::isValid() + * @see \Zend_Validate_Interface::isValid() */ public function isValid($value, $context = null) { - $this->validPattern = false; - if (!is_string($value) && !is_int($value)) { - $this->error('INVALID_TYPE'); + if (! $value instanceof DateTime && ! is_string($value)) { + $this->_error(t('Invalid type given. Instance of DateTime or date/time string expected')); return false; } - - if ($this->isUnixTimestamp($value)) { - $dt = DateTimeFactory::create(); - $dt->setTimestamp($value); - } else { - if (!isset($this->patterns)) { - throw new ProgrammingError('There are no allowed timeformats configured'); - } - - $match_found = false; - foreach ($this->patterns as $pattern) { - $dt = DateTimeFactory::parse($value, $pattern); - if ($dt !== false && $dt->format($pattern) === $value) { - $match_found = true; - $this->validPattern = $pattern; - break; - } - } - if (!$match_found) { - $this->_error('NO_MATCHING_PATTERN'); + if (is_string($value)) { + $format = $this->local === true ? 'Y-m-d\TH:i:s' : DateTime::RFC3339; + $dateTime = DateTime::createFromFormat($format, $value); + if ($dateTime === false || $dateTime->format($format) !== $value) { + $this->_error(sprintf(t('Date/time string not in the expected format %s'), $format)); return false; } } - return true; } - - /** - * Return the matched pattern if any or false if input is a timestamp - * - * @return bool|string False if input was a timestamp otherwise string with the dateformat pattern - */ - public function getValidPattern() - { - return $this->validPattern; - } }