File indexing completed on 2024-12-22 05:37:12
0001 <?php 0002 /** 0003 * Zend Framework 0004 * 0005 * LICENSE 0006 * 0007 * This source file is subject to the new BSD license that is bundled 0008 * with this package in the file LICENSE.txt. 0009 * It is also available through the world-wide-web at this URL: 0010 * http://framework.zend.com/license/new-bsd 0011 * If you did not receive a copy of the license and are unable to 0012 * obtain it through the world-wide-web, please send an email 0013 * to license@zend.com so we can send you a copy immediately. 0014 * 0015 * @category Zend 0016 * @package Zend_Validate 0017 * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) 0018 * @license http://framework.zend.com/license/new-bsd New BSD License 0019 * @version $Id$ 0020 */ 0021 0022 /** 0023 * @see Zend_Validate_Abstract 0024 */ 0025 // require_once 'Zend/Validate/Abstract.php'; 0026 0027 /** 0028 * @category Zend 0029 * @package Zend_Validate 0030 * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) 0031 * @license http://framework.zend.com/license/new-bsd New BSD License 0032 */ 0033 class Zend_Validate_Date extends Zend_Validate_Abstract 0034 { 0035 const INVALID = 'dateInvalid'; 0036 const INVALID_DATE = 'dateInvalidDate'; 0037 const FALSEFORMAT = 'dateFalseFormat'; 0038 0039 /** 0040 * Validation failure message template definitions 0041 * 0042 * @var array 0043 */ 0044 protected $_messageTemplates = array( 0045 self::INVALID => "Invalid type given. String, integer, array or Zend_Date expected", 0046 self::INVALID_DATE => "'%value%' does not appear to be a valid date", 0047 self::FALSEFORMAT => "'%value%' does not fit the date format '%format%'", 0048 ); 0049 0050 /** 0051 * @var array 0052 */ 0053 protected $_messageVariables = array( 0054 'format' => '_format' 0055 ); 0056 0057 /** 0058 * Optional format 0059 * 0060 * @var string|null 0061 */ 0062 protected $_format; 0063 0064 /** 0065 * Optional locale 0066 * 0067 * @var string|Zend_Locale|null 0068 */ 0069 protected $_locale; 0070 0071 /** 0072 * Sets validator options 0073 * 0074 * @param string|array|Zend_Config $options OPTIONAL 0075 */ 0076 public function __construct($options = array()) 0077 { 0078 if ($options instanceof Zend_Config) { 0079 $options = $options->toArray(); 0080 } else if (!is_array($options)) { 0081 $options = func_get_args(); 0082 $temp['format'] = array_shift($options); 0083 if (!empty($options)) { 0084 $temp['locale'] = array_shift($options); 0085 } 0086 0087 $options = $temp; 0088 } 0089 0090 if (array_key_exists('format', $options)) { 0091 $this->setFormat($options['format']); 0092 } 0093 0094 if (!array_key_exists('locale', $options)) { 0095 // require_once 'Zend/Registry.php'; 0096 if (Zend_Registry::isRegistered('Zend_Locale')) { 0097 $options['locale'] = Zend_Registry::get('Zend_Locale'); 0098 } 0099 } 0100 0101 if (array_key_exists('locale', $options)) { 0102 $this->setLocale($options['locale']); 0103 } 0104 } 0105 0106 /** 0107 * Returns the locale option 0108 * 0109 * @return string|Zend_Locale|null 0110 */ 0111 public function getLocale() 0112 { 0113 return $this->_locale; 0114 } 0115 0116 /** 0117 * Sets the locale option 0118 * 0119 * @param string|Zend_Locale $locale 0120 * @return Zend_Validate_Date provides a fluent interface 0121 */ 0122 public function setLocale($locale = null) 0123 { 0124 // require_once 'Zend/Locale.php'; 0125 $this->_locale = Zend_Locale::findLocale($locale); 0126 return $this; 0127 } 0128 0129 /** 0130 * Returns the locale option 0131 * 0132 * @return string|null 0133 */ 0134 public function getFormat() 0135 { 0136 return $this->_format; 0137 } 0138 0139 /** 0140 * Sets the format option 0141 * 0142 * @param string $format 0143 * @return Zend_Validate_Date provides a fluent interface 0144 */ 0145 public function setFormat($format = null) 0146 { 0147 $this->_format = $format; 0148 return $this; 0149 } 0150 0151 /** 0152 * Defined by Zend_Validate_Interface 0153 * 0154 * Returns true if $value is a valid date of the format YYYY-MM-DD 0155 * If optional $format or $locale is set the date format is checked 0156 * according to Zend_Date, see Zend_Date::isDate() 0157 * 0158 * @param string|array|Zend_Date $value 0159 * @return boolean 0160 */ 0161 public function isValid($value) 0162 { 0163 if (!is_string($value) && !is_int($value) && !is_float($value) && 0164 !is_array($value) && !($value instanceof Zend_Date)) { 0165 $this->_error(self::INVALID); 0166 return false; 0167 } 0168 0169 $this->_setValue($value); 0170 0171 if (($this->_format !== null) || ($this->_locale !== null) || is_array($value) || 0172 $value instanceof Zend_Date) { 0173 // require_once 'Zend/Date.php'; 0174 if (!Zend_Date::isDate($value, $this->_format, $this->_locale)) { 0175 if ($this->_checkFormat($value) === false) { 0176 $this->_error(self::FALSEFORMAT); 0177 } else { 0178 $this->_error(self::INVALID_DATE); 0179 } 0180 return false; 0181 } 0182 } else { 0183 if (!preg_match('/^\d{4}-\d{2}-\d{2}$/', $value)) { 0184 $this->_format = 'yyyy-MM-dd'; 0185 $this->_error(self::FALSEFORMAT); 0186 $this->_format = null; 0187 return false; 0188 } 0189 0190 list($year, $month, $day) = sscanf($value, '%d-%d-%d'); 0191 0192 if (!checkdate($month, $day, $year)) { 0193 $this->_error(self::INVALID_DATE); 0194 return false; 0195 } 0196 } 0197 0198 return true; 0199 } 0200 0201 /** 0202 * Check if the given date fits the given format 0203 * 0204 * @param string $value Date to check 0205 * @return boolean False when date does not fit the format 0206 */ 0207 private function _checkFormat($value) 0208 { 0209 try { 0210 // require_once 'Zend/Locale/Format.php'; 0211 $parsed = Zend_Locale_Format::getDate($value, array( 0212 'date_format' => $this->_format, 'format_type' => 'iso', 0213 'fix_date' => false)); 0214 if (isset($parsed['year']) and ((strpos(strtoupper($this->_format), 'YY') !== false) and 0215 (strpos(strtoupper($this->_format), 'YYYY') === false))) { 0216 $parsed['year'] = Zend_Date::getFullYear($parsed['year']); 0217 } 0218 } catch (Exception $e) { 0219 // Date can not be parsed 0220 return false; 0221 } 0222 0223 if (((strpos($this->_format, 'Y') !== false) or (strpos($this->_format, 'y') !== false)) and 0224 (!isset($parsed['year']))) { 0225 // Year expected but not found 0226 return false; 0227 } 0228 0229 if ((strpos($this->_format, 'M') !== false) and (!isset($parsed['month']))) { 0230 // Month expected but not found 0231 return false; 0232 } 0233 0234 if ((strpos($this->_format, 'd') !== false) and (!isset($parsed['day']))) { 0235 // Day expected but not found 0236 return false; 0237 } 0238 0239 if (((strpos($this->_format, 'H') !== false) or (strpos($this->_format, 'h') !== false)) and 0240 (!isset($parsed['hour']))) { 0241 // Hour expected but not found 0242 return false; 0243 } 0244 0245 if ((strpos($this->_format, 'm') !== false) and (!isset($parsed['minute']))) { 0246 // Minute expected but not found 0247 return false; 0248 } 0249 0250 if ((strpos($this->_format, 's') !== false) and (!isset($parsed['second']))) { 0251 // Second expected but not found 0252 return false; 0253 } 0254 0255 // Date fits the format 0256 return true; 0257 } 0258 }