Squiz Matrix  4.12.2
 All Data Structures Namespaces Functions Variables Pages
form_question_type_datetime.inc
1 <?php
18 require_once dirname(__FILE__).'/../../form_question/form_question.inc';
19 require_once SQ_FUDGE_PATH.'/datetime_field/datetime_field.inc';
20 require_once SQ_FUDGE_PATH.'/general/datetime.inc';
21 
35 {
36 
37 
45  function Form_Question_Type_Datetime($assetid=0,$data=Array())
46  {
47  $this->Form_Question($assetid,$data);
48 
49  }//end constructor
50 
51 
59  function _getAllowedLinks()
60  {
61  return Array();
62 
63  }//end _getAllowedLinks()
64 
65 
72  function getHtmlField()
73  {
74  $name = 'q'.$this->id;
75  $html = '';
76  $value = $this->getValue();
77 
78  $elements = Array('day' => 'd', 'month' => 'm', 'year' => 'y', 'hour' => 'h', 'min' => 'i', 'sec' => 's');
79 
80  $parameters = Array();
81  $parameters['show'] = Array();
82  $parameters['null'] = Array();
83  $parameters['style'] = Array();
84  $parameters['min'] = $this->attr('minimum');
85 
86  if (($parameters['min'] == '---------- --:--:--') || ($parameters['min'] == '0001------ --:--:--')) {
87  $parameters['min'] = '1900-01-01 00:00:00';
88  }
89  $parameters['max'] = $this->attr('maximum');
90 
91  if (($parameters['max'] == '---------- --:--:--') || ($parameters['max'] == '0001------ --:--:--')) {
92  $parameters['max'] = '2099-12-31 23:59:59';
93  }
94  $parameters['extras'] = $this->attr('extras');
95 
96  if ($this->attr('tabindex')) {
97  $tabindex = ' tabindex="'.$this->attr('tabindex').'"';
98  foreach ($parameters['extras'] as $key => $extra) {
99  $parameters['extras'][$key] .= $tabindex;
100  }
101  }
102 
103  $show_params = $this->attr('show');
104  $text_params = $this->attr('text');
105  $null_params = $this->attr('null');
106 
107  $parameters['allow_circa'] = $show_params['c'];
108  if (!empty($show_params['a'])) $parameters['show'][] = 'a';
109 
110  foreach ($elements as $attr => $t) {
111  $parameters['style'][$t] = ($text_params[$t] ? 't' : 's');
112  if ($show_params[$t]) $parameters['show'][] = $t;
113  // we will allow null if this field is required then check for blank value
114  $parameters['null'][] = $t;
115  }
116 
117  $dt_field = new Datetime_Field($name, $value, $parameters);
118 
119  ob_start();
120  $dt_field->printField();
121  $html .= ob_get_contents();
122  ob_end_clean();
123 
124  // so we need to convert them back to proper php tags
125  return $html;
126 
127  }//end getHtmlField()
128 
129 
137  {
138  $elements = Array('day' => 'd', 'month' => 'm', 'year' => 'y', 'hour' => 'h', 'min' => 'i', 'sec' => 's');
139 
140  $parameters = Array();
141  $parameters['show'] = Array();
142  $parameters['null'] = Array();
143  $parameters['style'] = Array();
144  $parameters['min'] = '01-00-1970 00:00:00';
145  $parameters['max'] = '31-12-2035 23:59:59';
146  $parameters['show']['c'] = 0;
147  $parameters['show']['a'] = 0;
148 
149  foreach ($elements as $attr => $t) {
150  $parameters['style'][$t] = 's';
151  $parameters['show'][] = $t;
152  $parameters['null'][$t] = 1;
153  }
154 
155  return $parameters;
156 
157  }//end getDefaultParameters()
158 
159 
168  function getAllowedRules()
169  {
170  return Array();
171 
172  }//end getAllowedRules()
173 
174 
190  function hasValidValue($answer=NULL, $mute_errors=FALSE)
191  {
192  if (is_null($answer)) $answer = $this->getValue();
193 
194  $required_fields = $this->attr('null');
195  $show_params = $this->attr('show');
196 
197  $custom_error = $this->attr('cust_required_error');
198  if (empty($custom_error)) {
199  $custom_error = translate('core_form_datetime_invalid_date_time');
200  }
201 
202  $this->failed_rules[] = $custom_error;
203 
204  if (!is_iso8601($answer)) return FALSE;
205 
206  // Ensure that required fields are filled in
207  foreach ($required_fields as $field => $required) {
208  if ($required != '1' && $show_params[$field] == '1') {
209  if ($field == 'y' && (substr($answer, 0, 2) == '--')) {
210  return FALSE;
211 
212  } else if ($field == 'm' && (substr($answer, 5, 2) == '--')) {
213  return FALSE;
214 
215  } else if ($field == 'd' && (substr($answer, 8, 2) == '--')) {
216  return FALSE;
217 
218  } else if ($field == 'h' && (substr($answer, 11, 2) == '--')) {
219  return FALSE;
220 
221  } else if ($field == 'i' && (substr($answer, 14, 2) == '--')) {
222  return FALSE;
223 
224  } else if ($field == 's' && (substr($answer, 17, 2) == '--')) {
225  return FALSE;
226 
227  }
228  }
229  }
230 
231  // At this stage the date is in ISO 8601 format, however we still need to check value limits (eg; to avoid 30th Feb)
232  $date = Array();
233  list($date['y'], $date['m'], $date['d']) = sscanf($answer, '%04s-%02s-%02s');
234 
235  // For checking purposes, set year, month, and day defaults for each value if they were not mandatory and were not specified. Feb 29th will be allowed if the year is not specified
236  foreach ($required_fields as $field => $required) {
237  if ($required == '1' || $show_params[$field] != '1') {
238  if ((($field == 'y') || ($field == 'm') || ($field == 'd')) && (substr($date[$field], 0, 2) == '--')) {
239  if ($field == 'y') {
240  $date['y'] = 2000;
241  } else {
242  $date[$field] = 1;
243  }
244  }
245  }
246  }
247  $is_valid_date = checkdate($date['m'], $date['d'], $date['y']);
248 
249  if (!$is_valid_date) return FALSE;
250 
251  return parent::hasValidValue($answer, $mute_errors);
252 
253  }//end hasValidValue()
254 
255 
262  function getSummary()
263  {
264 
265 
266  $allow_circa = FALSE;
267  $show_params = $this->attr('show');
268  if ($show_params['c']) $allow_circa = TRUE;
269 
270  if ($allow_circa) {
271  list($date, $time, $circa) = explode(' ', $this->getValue());
272  } else {
273  list($date, $time) = explode(' ', $this->getValue());
274  $circa = 0;
275  }
276  $val = Array();
277 
278  // break apart the date into correct portions
279  list($val['y'], $val['m'], $val['d']) = sscanf($date, '%04s-%02s-%02s');
280  list($val['h'], $val['i'], $val['s']) = sscanf($time, '%02s:%02s:%02s');
281 
282  $matches = Array();
283  $new_format = $this->attr('print_format');
284 
285  $required_fields = $this->attr('null');
286 
287  // if blank, then fill date up (using bits and pieces from the date
288  // 2000-01-01 00:00:00 - year 2000 so leap year dates appear properly)
289  $non_empty_date = TRUE;
290 
291  foreach ($val as $val_key => $val_time) {
292  $preg_match_result = preg_match('|^-*$|', $val[$val_key]);
293  if ($required_fields[$val_key] != '1' || !$preg_match_result) {
294  $non_empty_date = FALSE;
295  }//end if
296  if ($preg_match_result) {
297  switch ($val_key) {
298  case 'y':
299  // If Year is allowed empty, set new_format to [empty],xx,xx
300  if ($required_fields[$val_key] == 1) {
301  $new_format = $this->replaceDateFormat($new_format, $val_key);
302  }
303  $val[$val_key] = 2000;
304  break;
305 
306  case 'm':
307  // If Month is allowed empty, set new_format to xxxx,[empty],xx
308  case 'd':
309  // If Date is allowed empty, set new_format to xxxx,xx,[empty]
310  if ($required_fields[$val_key] == 1) {
311  $new_format = $this->replaceDateFormat($new_format, $val_key);
312  }
313  $val[$val_key] = 1;
314  break;
315 
316  case 'h':
317  case 'i':
318  case 's':
319  if ($required_fields[$val_key] == 1) {
320  $new_format = $this->replaceDateFormat($new_format, $val_key);
321  }
322  $val[$val_key] = 0;
323  break;
324  }
325  }//end if preg_match_result
326  }//end foreach
327 
328  // If all six date fields is allow blank and they are blank, then return blank string.
329  if ($non_empty_date === TRUE) return '';
330 
331  // Flag set when supplied year is out of range 1970 - 2038 range
332  $invalid_year = FALSE;
333  $temp_date = mktime($val['h'], $val['i'], $val['s'], $val['m'], $val['d'], $val['y']);
334 
335  // If the supplied year doesn't returns the timestamp or date is not within range, use the year 2000
336  if ($temp_date === FALSE || $val['y'] < 1970 || $val['y'] > 2038) {
337  $temp_date = mktime($val['h'], $val['i'], $val['s'], $val['m'], $val['d'], 2000);
338  $invalid_year = TRUE;
339  }
340 
341  // Extra operation is required to handle UNIX Timestamp issues of mktime() function.
342  // Simply we don't want to pass the year to calculate the UNIX timestamp when year is not within range
343 
344  preg_match_all('/y|Y/', $new_format, $matches, PREG_OFFSET_CAPTURE);
345  if (!empty($matches) && $invalid_year) {
346  $matches = array_reverse(array_pop($matches));
347  foreach ($matches as $match) {
348  $pos = $match[1];
349  $year_str = ($match[0] == 'Y') ? $val['y'] : substr($val['y'], -2);
350  if ($pos == 0) {
351  $new_format = $year_str.substr($new_format, 1);
352  } else if (($pos > 0) && (substr($new_format, ($pos - 1), 1) != '\\')) {
353  $new_format = substr($new_format, 0, $pos).$year_str.substr($new_format, $pos + 1);
354  }
355  }
356  }
357 
358  return ($circa ? 'circa ' : '').date($new_format, $temp_date);
359 
360  }//end getSummary()
361 
362 
370  function replaceDateFormat($original_format, $element)
371  {
372  $replacement_mapping = Array (
373  'y' => Array ('y', 'Y'),
374  'm' => Array ('m', 'n', 'F', 'M'),
375  'd' => Array ('d', 'j', 'S', 'D', 'l'),
376  'h' => Array ('h', 'H', 'g', 'G'),
377  'i' => Array ('i'),
378  's' => Array ('s'),
379  );
380  // Replace with blank string
381  if (isset($replacement_mapping[$element])) {
382  foreach ($replacement_mapping[$element] as $replace_string) {
383  $original_format = str_replace($replace_string, '', $original_format);
384  }//end foreach
385  }//end if
386 
387  return $original_format;
388 
389  }//end replaceDateFormat()
390 
391 
400  function getXML($answer)
401  {
402  ob_start();
403 
404  $allow_circa = FALSE;
405 
406  $show_params = $this->attr('show');
407  if ($show_params['c']) $allow_circa = TRUE;
408 
409  if ($allow_circa) {
410  list($date, $time, $circa) = explode(' ', $answer);
411  } else {
412  list($date, $time) = explode(' ', $answer);
413  $circa = 0;
414  }
415 
416  echo '<datetime_q id="'.addslashes($this->id).'" name="'.htmlspecialchars($this->attr('name')).'"'.($circa ? ' circa="1"' : '').'>';
417 
418  $iso = $date.'T'.$time;
419  echo $iso;
420 
421  echo '</datetime_q>';
422 
423  $contents = ob_get_contents();
424  ob_end_clean();
425 
426  return $contents;
427 
428  }//end getXML()
429 
430 
437  function populate()
438  {
439  $val = '';
440  $name = 'q'.$this->id;
441  $value = array_get_index($_POST, $name.'value', '');
442  $show = array_get_index($_POST, $name.'show', '');
443 
444  if (strpos($show, 'y') === FALSE) {
445  $val .= '----';
446  } else {
447  $val .= str_pad($_POST[$name.'value']['y'], 4, '-', STR_PAD_LEFT);
448  }
449 
450  $val .= '-';
451 
452  if ((isset($_POST[$name.'value']['m']) && empty($_POST[$name.'value']['m'])) || strpos($show, 'm') === FALSE) {
453  $val .= '--';
454  } else {
455  $val .= str_pad($_POST[$name.'value']['m'], 2, '0', STR_PAD_LEFT);
456  }
457 
458  $val .= '-';
459 
460  if ((isset($_POST[$name.'value']['d']) && empty($_POST[$name.'value']['d'])) || strpos($show, 'd') === FALSE) {
461  $val .= '--';
462  } else {
463  $val .= str_pad($_POST[$name.'value']['d'], 2, '0', STR_PAD_LEFT);
464  }
465 
466  $val .= ' ';
467 
468  if ((isset($_POST[$name.'value']['h']) && empty($_POST[$name.'value']['h'])) || strpos($show, 'h') === FALSE) {
469  if (isset($_POST[$name.'value']['h']) && (string) $_POST[$name.'value']['h'] === '0') {
470  $val .= '00';
471  } else {
472  $val .= '--';
473  }
474  } else {
475  $hour = str_pad($_POST[$name.'value']['h'], 2, '0', STR_PAD_LEFT);
476  if (!empty($_POST[$name.'value']['a']) && strpos($show, 'a') !== FALSE && $hour != '--'){
477  $hour = date('H', strtotime($hour.' '.$_POST[$name.'value']['a']));
478  }
479  $val .= $hour;
480  }
481 
482  $val .= ':';
483 
484  if ((isset($_POST[$name.'value']['i']) && empty($_POST[$name.'value']['i'])) || strpos($show, 'i') === FALSE) {
485  if (isset($_POST[$name.'value']['i']) && (string) $_POST[$name.'value']['i'] === '0') {
486  $val .= '00';
487  } else {
488  $val .= '--';
489  }
490  } else {
491  $val .= str_pad($_POST[$name.'value']['i'], 2, '0', STR_PAD_LEFT);
492  }
493 
494  $val .= ':';
495 
496  if ((isset($_POST[$name.'value']['s']) && empty($_POST[$name.'value']['s'])) || strpos($show, 's') === FALSE) {
497  if (isset($_POST[$name.'value']['s']) && (string) $_POST[$name.'value']['s'] === '0') {
498  $val .= '00';
499  } else {
500  $val .= '--';
501  }
502  } else {
503  $val .= str_pad($_POST[$name.'value']['s'], 2, '0', STR_PAD_LEFT);
504  }
505 
506  $this->setValue($val);
507 
508  return TRUE;
509 
510  }//end populate()
511 
512 
513 }//end class
514 ?>