|
1 <?php |
|
2 /** |
|
3 * Zend Framework |
|
4 * |
|
5 * LICENSE |
|
6 * |
|
7 * This source file is subject to the new BSD license that is bundled |
|
8 * with this package in the file LICENSE.txt. |
|
9 * It is also available through the world-wide-web at this URL: |
|
10 * http://framework.zend.com/license/new-bsd |
|
11 * If you did not receive a copy of the license and are unable to |
|
12 * obtain it through the world-wide-web, please send an email |
|
13 * to license@zend.com so we can send you a copy immediately. |
|
14 * |
|
15 * @category Zend |
|
16 * @package Zend_Validate |
|
17 * @copyright Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com) |
|
18 * @license http://framework.zend.com/license/new-bsd New BSD License |
|
19 * @version $Id: Date.php 22668 2010-07-25 14:50:46Z thomas $ |
|
20 */ |
|
21 |
|
22 /** |
|
23 * @see Zend_Validate_Abstract |
|
24 */ |
|
25 require_once 'Zend/Validate/Abstract.php'; |
|
26 |
|
27 /** |
|
28 * @category Zend |
|
29 * @package Zend_Validate |
|
30 * @copyright Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com) |
|
31 * @license http://framework.zend.com/license/new-bsd New BSD License |
|
32 */ |
|
33 class Zend_Validate_Date extends Zend_Validate_Abstract |
|
34 { |
|
35 const INVALID = 'dateInvalid'; |
|
36 const INVALID_DATE = 'dateInvalidDate'; |
|
37 const FALSEFORMAT = 'dateFalseFormat'; |
|
38 |
|
39 /** |
|
40 * Validation failure message template definitions |
|
41 * |
|
42 * @var array |
|
43 */ |
|
44 protected $_messageTemplates = array( |
|
45 self::INVALID => "Invalid type given. String, integer, array or Zend_Date expected", |
|
46 self::INVALID_DATE => "'%value%' does not appear to be a valid date", |
|
47 self::FALSEFORMAT => "'%value%' does not fit the date format '%format%'", |
|
48 ); |
|
49 |
|
50 /** |
|
51 * @var array |
|
52 */ |
|
53 protected $_messageVariables = array( |
|
54 'format' => '_format' |
|
55 ); |
|
56 |
|
57 /** |
|
58 * Optional format |
|
59 * |
|
60 * @var string|null |
|
61 */ |
|
62 protected $_format; |
|
63 |
|
64 /** |
|
65 * Optional locale |
|
66 * |
|
67 * @var string|Zend_Locale|null |
|
68 */ |
|
69 protected $_locale; |
|
70 |
|
71 /** |
|
72 * Sets validator options |
|
73 * |
|
74 * @param string|Zend_Config $options OPTIONAL |
|
75 * @return void |
|
76 */ |
|
77 public function __construct($options = array()) |
|
78 { |
|
79 if ($options instanceof Zend_Config) { |
|
80 $options = $options->toArray(); |
|
81 } else if (!is_array($options)) { |
|
82 $options = func_get_args(); |
|
83 $temp['format'] = array_shift($options); |
|
84 if (!empty($options)) { |
|
85 $temp['locale'] = array_shift($options); |
|
86 } |
|
87 |
|
88 $options = $temp; |
|
89 } |
|
90 |
|
91 if (array_key_exists('format', $options)) { |
|
92 $this->setFormat($options['format']); |
|
93 } |
|
94 |
|
95 if (!array_key_exists('locale', $options)) { |
|
96 require_once 'Zend/Registry.php'; |
|
97 if (Zend_Registry::isRegistered('Zend_Locale')) { |
|
98 $options['locale'] = Zend_Registry::get('Zend_Locale'); |
|
99 } |
|
100 } |
|
101 |
|
102 if (array_key_exists('locale', $options)) { |
|
103 $this->setLocale($options['locale']); |
|
104 } |
|
105 } |
|
106 |
|
107 /** |
|
108 * Returns the locale option |
|
109 * |
|
110 * @return string|Zend_Locale|null |
|
111 */ |
|
112 public function getLocale() |
|
113 { |
|
114 return $this->_locale; |
|
115 } |
|
116 |
|
117 /** |
|
118 * Sets the locale option |
|
119 * |
|
120 * @param string|Zend_Locale $locale |
|
121 * @return Zend_Validate_Date provides a fluent interface |
|
122 */ |
|
123 public function setLocale($locale = null) |
|
124 { |
|
125 require_once 'Zend/Locale.php'; |
|
126 $this->_locale = Zend_Locale::findLocale($locale); |
|
127 return $this; |
|
128 } |
|
129 |
|
130 /** |
|
131 * Returns the locale option |
|
132 * |
|
133 * @return string|null |
|
134 */ |
|
135 public function getFormat() |
|
136 { |
|
137 return $this->_format; |
|
138 } |
|
139 |
|
140 /** |
|
141 * Sets the format option |
|
142 * |
|
143 * @param string $format |
|
144 * @return Zend_Validate_Date provides a fluent interface |
|
145 */ |
|
146 public function setFormat($format = null) |
|
147 { |
|
148 $this->_format = $format; |
|
149 return $this; |
|
150 } |
|
151 |
|
152 /** |
|
153 * Defined by Zend_Validate_Interface |
|
154 * |
|
155 * Returns true if $value is a valid date of the format YYYY-MM-DD |
|
156 * If optional $format or $locale is set the date format is checked |
|
157 * according to Zend_Date, see Zend_Date::isDate() |
|
158 * |
|
159 * @param string|array|Zend_Date $value |
|
160 * @return boolean |
|
161 */ |
|
162 public function isValid($value) |
|
163 { |
|
164 if (!is_string($value) && !is_int($value) && !is_float($value) && |
|
165 !is_array($value) && !($value instanceof Zend_Date)) { |
|
166 $this->_error(self::INVALID); |
|
167 return false; |
|
168 } |
|
169 |
|
170 $this->_setValue($value); |
|
171 |
|
172 if (($this->_format !== null) || ($this->_locale !== null) || is_array($value) || |
|
173 $value instanceof Zend_Date) { |
|
174 require_once 'Zend/Date.php'; |
|
175 if (!Zend_Date::isDate($value, $this->_format, $this->_locale)) { |
|
176 if ($this->_checkFormat($value) === false) { |
|
177 $this->_error(self::FALSEFORMAT); |
|
178 } else { |
|
179 $this->_error(self::INVALID_DATE); |
|
180 } |
|
181 return false; |
|
182 } |
|
183 } else { |
|
184 if (!preg_match('/^\d{4}-\d{2}-\d{2}$/', $value)) { |
|
185 $this->_format = 'yyyy-MM-dd'; |
|
186 $this->_error(self::FALSEFORMAT); |
|
187 $this->_format = null; |
|
188 return false; |
|
189 } |
|
190 |
|
191 list($year, $month, $day) = sscanf($value, '%d-%d-%d'); |
|
192 |
|
193 if (!checkdate($month, $day, $year)) { |
|
194 $this->_error(self::INVALID_DATE); |
|
195 return false; |
|
196 } |
|
197 } |
|
198 |
|
199 return true; |
|
200 } |
|
201 |
|
202 /** |
|
203 * Check if the given date fits the given format |
|
204 * |
|
205 * @param string $value Date to check |
|
206 * @return boolean False when date does not fit the format |
|
207 */ |
|
208 private function _checkFormat($value) |
|
209 { |
|
210 try { |
|
211 require_once 'Zend/Locale/Format.php'; |
|
212 $parsed = Zend_Locale_Format::getDate($value, array( |
|
213 'date_format' => $this->_format, 'format_type' => 'iso', |
|
214 'fix_date' => false)); |
|
215 if (isset($parsed['year']) and ((strpos(strtoupper($this->_format), 'YY') !== false) and |
|
216 (strpos(strtoupper($this->_format), 'YYYY') === false))) { |
|
217 $parsed['year'] = Zend_Date::getFullYear($parsed['year']); |
|
218 } |
|
219 } catch (Exception $e) { |
|
220 // Date can not be parsed |
|
221 return false; |
|
222 } |
|
223 |
|
224 if (((strpos($this->_format, 'Y') !== false) or (strpos($this->_format, 'y') !== false)) and |
|
225 (!isset($parsed['year']))) { |
|
226 // Year expected but not found |
|
227 return false; |
|
228 } |
|
229 |
|
230 if ((strpos($this->_format, 'M') !== false) and (!isset($parsed['month']))) { |
|
231 // Month expected but not found |
|
232 return false; |
|
233 } |
|
234 |
|
235 if ((strpos($this->_format, 'd') !== false) and (!isset($parsed['day']))) { |
|
236 // Day expected but not found |
|
237 return false; |
|
238 } |
|
239 |
|
240 if (((strpos($this->_format, 'H') !== false) or (strpos($this->_format, 'h') !== false)) and |
|
241 (!isset($parsed['hour']))) { |
|
242 // Hour expected but not found |
|
243 return false; |
|
244 } |
|
245 |
|
246 if ((strpos($this->_format, 'm') !== false) and (!isset($parsed['minute']))) { |
|
247 // Minute expected but not found |
|
248 return false; |
|
249 } |
|
250 |
|
251 if ((strpos($this->_format, 's') !== false) and (!isset($parsed['second']))) { |
|
252 // Second expected but not found |
|
253 return false; |
|
254 } |
|
255 |
|
256 // Date fits the format |
|
257 return true; |
|
258 } |
|
259 } |