1 <?php
2 require_once 'Zend/Date.php';
3
4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47
48 class DateField extends TextField {
49
50 51 52
53 protected $config = array(
54 'showcalendar' => false,
55 'dateformat' => null,
56 'datavalueformat' => 'yyyy-MM-dd',
57 'min' => null,
58 'max' => null
59 );
60
61 62 63
64 protected $locale = null;
65
66 67 68 69 70
71 protected $valueObj = null;
72
73 function __construct($name, $title = null, $value = null, $form = null, $rightTitle = null) {
74 if(!$this->locale) {
75 $this->locale = i18n::get_locale();
76 }
77
78 if(!$this->getConfig('dateformat')) {
79 $this->setConfig('dateformat', Zend_Locale_Format::getDateFormat($this->locale));
80 }
81 if ($this->useHTML5()) {
82 $this->setConfig('dateformat', 'yyyy-MM-dd');
83 }
84
85 parent::__construct($name, $title, $value, $form, $rightTitle);
86 }
87
88 function Field() {
89 if ($this->useHTML5()) {
90 $this->setHTML5Attribute('type', 'date');
91 $this->setConfig('dateformat', 'yyyy-MM-dd');
92 if ($min = $this->getConfig('min'))
93 $this->setHTML5Attribute('min', date('Y-m-d', strtotime($min)));
94 if ($max = $this->getConfig('max'))
95 $this->setHTML5Attribute('max', date('Y-m-d', strtotime($max)));
96 }
97 $attributes = array(
98 'type' => 'text',
99 'class' => 'text ' . $this->class . ($this->extraClass() ? $this->extraClass() : ''),
100 'id' => $this->id(),
101 'name' => $this->Name(),
102 'value' => $this->Value(),
103 'tabindex' => $this->getTabIndex(),
104 'maxlength' => ($this->maxLength) ? $this->maxLength : null,
105 'size' => ($this->maxLength) ? min( $this->maxLength, 30 ) : null
106 );
107 108 109 110 111 112
113 return $this->createTag('input', $attributes);
114
115
116 return $html;
117 }
118
119 function ShowCalendar() {
120 return !$this->useHTML5() && $this->getConfig('showcalendar');
121 }
122
123 function getCalendarLang() {
124 if($this->ShowCalendar()) {
125 $lang = i18n::get_lang_from_locale($this->getLocale());
126 return $lang;
127 }
128 return false;
129 }
130
131 132 133 134 135
136 function setValue($val) {
137 if(empty($val)) {
138 $this->value = null;
139 $this->valueObj = null;
140 } else {
141
142
143
144
145 if(!empty($val) && Zend_Date::isDate($val, $this->getConfig('dateformat'), $this->locale)) {
146 $this->valueObj = new Zend_Date($val, $this->getConfig('dateformat'), $this->locale);
147 $this->value = $this->valueObj->get($this->getConfig('dateformat'));
148 }
149
150 else if(!empty($val) && Zend_Date::isDate($val, $this->getConfig('datavalueformat'))) {
151 $this->valueObj = new Zend_Date($val, $this->getConfig('datavalueformat'));
152 $this->value = $this->valueObj->get($this->getConfig('dateformat'));
153 }
154 else {
155 $this->value = $val;
156 $this->valueObj = null;
157 }
158 }
159 }
160
161 162 163
164 function dataValue() {
165 if($this->valueObj) {
166 return $this->valueObj->toString($this->getConfig('datavalueformat'));
167 } else {
168 return null;
169 }
170 }
171
172 function performReadonlyTransformation() {
173 $field = new DateField_Disabled($this->name, $this->title, $this->value);
174 $field->setForm($this->form);
175 $field->readonly = true;
176
177 return $field;
178 }
179
180 function jsValidation() {
181
182 }
183
184 185 186
187 function validate($validator) {
188 $valid = true;
189
190
191 if(empty($this->value)) return true;
192
193
194 $valid = (Zend_Date::isDate($this->value, $this->getConfig('dateformat'), $this->locale));
195 if(!$valid) {
196 $validator->validationError(
197 $this->name,
198 _t('DateField.VALIDDATEFORMAT', "Please enter a valid date format (DD/MM/YYYY)."),
199 "validation",
200 false
201 );
202 return false;
203 }
204
205
206 if($min = $this->getConfig('min')) {
207
208 if(Zend_Date::isDate($min, $this->getConfig('datavalueformat'))) {
209 $minDate = new Zend_Date($min, $this->getConfig('datavalueformat'));
210 } else {
211 $minDate = new Zend_Date(strftime('%Y-%m-%d', strtotime($min)), $this->getConfig('datavalueformat'));
212 }
213 if(!$this->valueObj->isLater($minDate) && !$this->valueObj->equals($minDate)) {
214 $validator->validationError(
215 $this->name,
216 sprintf(
217 _t('DateField.VALIDDATEMINDATE', "Your date has to be newer or matching the minimum allowed date (%s)"),
218 $minDate->toString($this->getConfig('dateformat'))
219 ),
220 "validation",
221 false
222 );
223 return false;
224 }
225 }
226 if($max = $this->getConfig('max')) {
227
228 if(Zend_Date::isDate($min, $this->getConfig('datavalueformat'))) {
229 $maxDate = new Zend_Date($max, $this->getConfig('datavalueformat'));
230 } else {
231 $maxDate = new Zend_Date(strftime('%Y-%m-%d', strtotime($max)), $this->getConfig('datavalueformat'));
232 }
233 if(!$this->valueObj->isEarlier($maxDate) && !$this->valueObj->equals($maxDate)) {
234 $validator->validationError(
235 $this->name,
236 sprintf(
237 _t('DateField.VALIDDATEMAXDATE', "Your date has to be older or matching the maximum allowed date (%s)"),
238 $maxDate->toString($this->getConfig('dateformat'))
239 ),
240 "validation",
241 false
242 );
243 return false;
244 }
245 }
246
247 return true;
248 }
249
250 251 252
253 function getLocale() {
254 return $this->locale;
255 }
256
257 258 259 260 261
262 function setLocale($locale) {
263 $this->locale = $locale;
264 }
265
266 267 268 269
270 function setConfig($name, $val) {
271 switch($name) {
272 case 'min':
273 $format = $this->getConfig('datavalueformat');
274 if($val && !Zend_Date::isDate($val, $format) && !strtotime($val)) {
275 throw new InvalidArgumentException('Date "%s" is not a valid minimum date format (%s) or strtotime() argument', $val, $format);
276 }
277 break;
278 case 'max':
279 $format = $this->getConfig('datavalueformat');
280 if($val && !Zend_Date::isDate($val, $format) && !strtotime($val)) {
281 throw new InvalidArgumentException('Date "%s" is not a valid maximum date format (%s) or strtotime() argument', $val, $format);
282 }
283 break;
284 }
285
286 $this->config[$name] = $val;
287 }
288
289 290 291 292
293 function getConfig($name) {
294 return $this->config[$name];
295 }
296 }
297
298 299 300 301 302 303
304 class DateField_Disabled extends DateField {
305
306 protected $disabled = true;
307
308 function Field() {
309 if($this->valueObj) {
310 if($this->valueObj->isToday()) {
311 $val = Convert::raw2xml($this->valueObj->toString($this->getConfig('dateformat')) . ' ('._t('DateField.TODAY','today').')');
312 } else {
313 $df = new Date($this->name);
314 $df->setValue($this->dataValue());
315 $val = Convert::raw2xml($this->valueObj->toString($this->getConfig('dateformat')) . ', ' . $df->Ago());
316 }
317 } else {
318 $val = '<i>('._t('DateField.NOTSET', 'not set').')</i>';
319 }
320
321 return "<span class=\"readonly\" id=\"" . $this->id() . "\">$val</span>";
322 }
323
324 function Type() {
325 return "date_disabled readonly";
326 }
327
328 function jsValidation() {
329 return null;
330 }
331
332 function validate($validator) {
333 return true;
334 }
335 }
336
[Raise a SilverStripe Framework issue/bug](https://github.com/silverstripe/silverstripe-framework/issues/new)
- [Raise a SilverStripe CMS issue/bug](https://github.com/silverstripe/silverstripe-cms/issues/new)
- Please use the
Silverstripe Forums to ask development related questions.
-