Révision 599a39cd
Ajouté par Assos Assos il y a environ 3 ans
drupal7/sites/all/modules/date/date_popup/date_popup.module | ||
---|---|---|
1 | 1 |
<?php |
2 |
|
|
2 | 3 |
/** |
3 | 4 |
* @file |
4 | 5 |
* A module to enable jquery calendar and time entry popups. |
... | ... | |
49 | 50 |
function date_popup_get_wvega_path() { |
50 | 51 |
$path = FALSE; |
51 | 52 |
if (function_exists('libraries_get_path')) { |
53 |
// Try loading the wvega timepicker library. |
|
52 | 54 |
$path = libraries_get_path('wvega-timepicker'); |
53 |
if (!file_exists($path)) { |
|
55 |
// Check if the library actually exists. |
|
56 |
if (empty($path) || !file_exists($path)) { |
|
54 | 57 |
$path = FALSE; |
55 | 58 |
} |
56 | 59 |
} |
... | ... | |
107 | 110 |
* |
108 | 111 |
* @param string $id |
109 | 112 |
* The CSS class prefix to search the DOM for. |
110 |
* TODO : unused ? |
|
111 |
* |
|
113 |
* @todo unused ? |
|
112 | 114 |
* @param string $func |
113 | 115 |
* The jQuery function to invoke on each DOM element |
114 | 116 |
* containing the returned CSS class. |
115 |
* |
|
116 | 117 |
* @param array $settings |
117 | 118 |
* The settings array to pass to the jQuery function. |
118 | 119 |
* |
... | ... | |
127 | 128 |
// Make sure popup date selector grid is in correct year. |
128 | 129 |
if (!empty($settings['yearRange'])) { |
129 | 130 |
$parts = explode(':', $settings['yearRange']); |
130 |
// Set the default date to 0 or the lowest bound if |
|
131 |
// the date ranges do not include the current year.
|
|
132 |
// Necessary for the datepicker to render and select dates correctly.
|
|
131 |
// Set the default date to 0 or the lowest bound if the date ranges do not
|
|
132 |
// include the current year. Necessary for the datepicker to render and
|
|
133 |
// select dates correctly. |
|
133 | 134 |
$default_date = ($parts[0] > 0 || 0 > $parts[1]) ? $parts[0] : 0; |
134 | 135 |
$settings += array('defaultDate' => (string) $default_date . 'y'); |
135 | 136 |
} |
... | ... | |
145 | 146 |
$id_count[$id] = 0; |
146 | 147 |
} |
147 | 148 |
|
148 |
// It looks like we need the additional id_count for this to |
|
149 |
// work correctly when there are multiple values. |
|
150 |
// $return_id = "$id-$func-popup"; |
|
149 |
// It looks like we need the additional id_count for this to work correctly |
|
150 |
// when there are multiple values. |
|
151 | 151 |
$return_id = "$id-$func-popup-" . $id_count[$id]++; |
152 | 152 |
$js_settings['datePopup'][$return_id] = array( |
153 | 153 |
'func' => $func, |
... | ... | |
170 | 170 |
|
171 | 171 |
/** |
172 | 172 |
* Implements hook_element_info(). |
173 |
* |
|
174 |
* Set the #type to date_popup and fill the element #default_value with |
|
175 |
* a date adjusted to the proper local timezone in datetime format |
|
176 |
* (YYYY-MM-DD HH:MM:SS). |
|
177 |
* |
|
178 |
* The element will create two textfields, one for the date and one for the |
|
179 |
* time. The date textfield will include a jQuery popup calendar date picker, |
|
180 |
* and the time textfield uses a jQuery timepicker. |
|
181 |
* |
|
182 |
* NOTE - Converting a date stored in the database from UTC to the local zone |
|
183 |
* and converting it back to UTC before storing it is not handled by this |
|
184 |
* element and must be done in pre-form and post-form processing!! |
|
185 |
* |
|
186 |
* #date_timezone |
|
187 |
* The local timezone to be used to create this date. |
|
188 |
* |
|
189 |
* #date_format |
|
190 |
* Unlike earlier versions of this popup, most formats will work. |
|
191 |
* |
|
192 |
* #date_increment |
|
193 |
* Increment minutes and seconds by this amount, default is 1. |
|
194 |
* |
|
195 |
* #date_year_range |
|
196 |
* The number of years to go back and forward in a year selector, |
|
197 |
* default is -3:+3 (3 back and 3 forward). |
|
198 |
* |
|
199 |
* #datepicker_options |
|
200 |
* An associative array representing the jQuery datepicker options you want |
|
201 |
* to set for this element. Use the jQuery datepicker option names as keys. |
|
202 |
* Hard coded defaults are: |
|
203 |
* - changeMonth => TRUE |
|
204 |
* - changeYear => TRUE |
|
205 |
* - autoPopUp => 'focus' |
|
206 |
* - closeAtTop => FALSE |
|
207 |
* - speed => 'immediate' |
|
208 | 173 |
*/ |
209 | 174 |
function date_popup_element_info() { |
210 | 175 |
$timepicker = date_popup_get_preferred_timepicker(); |
176 |
|
|
177 |
// Set the #type to date_popup and fill the element #default_value with |
|
178 |
// a date adjusted to the proper local timezone in datetime format |
|
179 |
// (YYYY-MM-DD HH:MM:SS). |
|
180 |
// |
|
181 |
// The element will create two textfields, one for the date and one for the |
|
182 |
// time. The date textfield will include a jQuery popup calendar date picker, |
|
183 |
// and the time textfield uses a jQuery timepicker. |
|
184 |
// |
|
185 |
// NOTE - Converting a date stored in the database from UTC to the local zone |
|
186 |
// and converting it back to UTC before storing it is not handled by this |
|
187 |
// element and must be done in pre-form and post-form processing!! |
|
188 |
// |
|
189 |
// #date_timezone |
|
190 |
// The local timezone to be used to create this date. |
|
191 |
// |
|
192 |
// #date_format |
|
193 |
// Unlike earlier versions of this popup, most formats will work. |
|
194 |
// |
|
195 |
// #date_increment |
|
196 |
// Increment minutes and seconds by this amount, default is 1. |
|
197 |
// |
|
198 |
// #date_year_range |
|
199 |
// The number of years to go back and forward in a year selector, |
|
200 |
// default is -3:+3 (3 back and 3 forward). |
|
201 |
// |
|
202 |
// #datepicker_options |
|
203 |
// An associative array representing the jQuery datepicker options you want |
|
204 |
// to set for this element. Use the jQuery datepicker option names as keys. |
|
205 |
// Hard coded defaults are: |
|
206 |
// - changeMonth => TRUE |
|
207 |
// - changeYear => TRUE |
|
208 |
// - autoPopUp => 'focus' |
|
209 |
// - closeAtTop => FALSE |
|
210 |
// - speed => 'immediate' |
|
211 | 211 |
$type['date_popup'] = array( |
212 | 212 |
'#input' => TRUE, |
213 | 213 |
'#tree' => TRUE, |
... | ... | |
222 | 222 |
'#process' => array('date_popup_element_process'), |
223 | 223 |
'#value_callback' => 'date_popup_element_value_callback', |
224 | 224 |
'#theme_wrappers' => array('date_popup'), |
225 |
'#attached' => array('css' => array( |
|
226 |
drupal_get_path('module', 'date_popup'). '/themes/datepicker.1.7.css', |
|
227 |
)), |
|
225 | 228 |
); |
229 |
|
|
226 | 230 |
if (module_exists('ctools')) { |
227 | 231 |
$type['date_popup']['#pre_render'] = array('ctools_dependent_pre_render'); |
228 | 232 |
} |
233 |
|
|
229 | 234 |
return $type; |
230 | 235 |
} |
231 | 236 |
|
... | ... | |
262 | 267 |
/** |
263 | 268 |
* Element value callback for date_popup element. |
264 | 269 |
*/ |
265 |
// @codingStandardsIgnoreStart |
|
266 | 270 |
function date_popup_element_value_callback($element, $input = FALSE, &$form_state) { |
267 | 271 |
$granularity = date_format_order($element['#date_format']); |
268 | 272 |
$has_time = date_has_time($granularity); |
269 | 273 |
$date = NULL; |
270 | 274 |
$return = $has_time ? array('date' => '', 'time' => '') : array('date' => ''); |
271 |
// Normal input from submitting the form element. |
|
272 |
// Check is_array() to skip the string input values created by Views pagers.
|
|
273 |
// Those string values, if present, should be interpreted as empty input.
|
|
275 |
// Normal input from submitting the form element. Check is_array() to skip
|
|
276 |
// the string input values created by Views pagers. Those string values, if
|
|
277 |
// present, should be interpreted as empty input. |
|
274 | 278 |
if ($input !== FALSE && is_array($input)) { |
275 | 279 |
$return = $input; |
276 | 280 |
$date = date_popup_input_date($element, $input); |
... | ... | |
290 | 294 |
return $return; |
291 | 295 |
|
292 | 296 |
} |
293 |
// @codingStandardsIgnoreEnd |
|
294 | 297 |
|
295 | 298 |
/** |
296 | 299 |
* Javascript popup element processing. |
... | ... | |
357 | 360 |
return array(); |
358 | 361 |
} |
359 | 362 |
|
360 |
// The datepicker can't handle zero or negative values like 0:+1 |
|
361 |
// even though the Date API can handle them, so rework the value
|
|
362 |
// we pass to the datepicker to use defaults it can accept (such as +0:+1)
|
|
363 |
// The datepicker can't handle zero or negative values like 0:+1 even though
|
|
364 |
// the Date API can handle them, so rework the value we pass to the
|
|
365 |
// datepicker to use defaults it can accept (such as +0:+1) |
|
363 | 366 |
// date_range_string() adds the necessary +/- signs to the range string. |
364 | 367 |
$this_year = date_format(date_now(), 'Y'); |
365 |
// When used as a Views exposed filter widget, $element['#value'] contains an array instead an string.
|
|
366 |
// Fill the 'date' string in this case. |
|
368 |
// When used as a Views exposed filter widget, $element['#value'] contains an |
|
369 |
// array instead an string. Fill the 'date' string in this case.
|
|
367 | 370 |
$mock = NULL; |
368 | 371 |
$callback_values = date_popup_element_value_callback($element, FALSE, $mock); |
369 | 372 |
if (!isset($element['#value']['date']) && isset($callback_values['date'])) { |
373 |
if (!is_array($element['#value'])) { |
|
374 |
$element['#value'] = array(); |
|
375 |
} |
|
370 | 376 |
$element['#value']['date'] = $callback_values['date']; |
371 | 377 |
} |
372 | 378 |
$date = ''; |
373 | 379 |
if (!empty($element['#value']['date'])) { |
380 |
// @todo If date does not meet the granularity or format condtions, then |
|
381 |
// $date will have error condtions and '#default_value' below will have the |
|
382 |
// global default date (most likely formatted string from 'now'). There |
|
383 |
// will be an validation error message referring to the actual input date |
|
384 |
// but the form element will display formatted 'now'. |
|
374 | 385 |
$date = new DateObject($element['#value']['date'], $element['#date_timezone'], date_popup_date_format($element)); |
386 |
if (!date_is_date($date)) { |
|
387 |
$date = ''; |
|
388 |
} |
|
375 | 389 |
} |
376 | 390 |
$range = date_range_years($element['#date_year_range'], $date); |
377 | 391 |
$year_range = date_range_string($range); |
... | ... | |
401 | 415 |
// Create a unique id for each set of custom settings. |
402 | 416 |
$id = date_popup_js_settings_id($element['#id'], 'datepicker', $settings); |
403 | 417 |
|
404 |
// Manually build this element and set the value - |
|
405 |
// this will prevent corrupting the parent value. |
|
418 |
// Manually build this element and set the value - this will prevent |
|
419 |
// corrupting the parent value. |
|
420 |
// Do NOT set '#input' => FALSE as this prevents the form API from recursing |
|
421 |
// into this element (this was useful when the '#value' property was being |
|
422 |
// overwritten by the '#default_value' property). |
|
406 | 423 |
$parents = array_merge($element['#parents'], array('date')); |
407 | 424 |
$sub_element = array( |
408 | 425 |
'#type' => 'textfield', |
... | ... | |
410 | 427 |
'#title_display' => $element['#date_label_position'] == 'above' ? 'before' : 'invisible', |
411 | 428 |
'#default_value' => date_format_date($date, 'custom', date_popup_date_format($element)), |
412 | 429 |
'#id' => $id, |
413 |
'#input' => FALSE, |
|
414 | 430 |
'#size' => !empty($element['#size']) ? $element['#size'] : 20, |
415 | 431 |
'#maxlength' => !empty($element['#maxlength']) ? $element['#maxlength'] : 30, |
416 | 432 |
'#attributes' => $element['#attributes'], |
417 | 433 |
'#parents' => $parents, |
418 | 434 |
'#name' => array_shift($parents) . '[' . implode('][', $parents) . ']', |
419 | 435 |
'#ajax' => !empty($element['#ajax']) ? $element['#ajax'] : FALSE, |
436 |
'#required' => $element['#required'], |
|
420 | 437 |
); |
421 |
$sub_element['#value'] = $sub_element['#default_value']; |
|
422 |
// TODO, figure out exactly when we want this description. |
|
423 |
// In many places it is not desired. |
|
438 |
// Do NOT overwrite the actual input with the default value. |
|
439 |
// @todo Figure out exactly when this is needed, in many places it is not. |
|
424 | 440 |
$sub_element['#description'] = ' ' . t('E.g., @date', array( |
425 | 441 |
'@date' => date_format_date( |
426 | 442 |
date_example_date(), |
... | ... | |
442 | 458 |
return array(); |
443 | 459 |
} |
444 | 460 |
|
445 |
// When used as a Views exposed filter widget, $element['#value'] contains an array instead an string.
|
|
446 |
// Fill the 'time' string in this case. |
|
461 |
// When used as a Views exposed filter widget, $element['#value'] contains an |
|
462 |
// array instead an string. Fill the 'time' string in this case.
|
|
447 | 463 |
$mock = NULL; |
448 | 464 |
$callback_values = date_popup_element_value_callback($element, FALSE, $mock); |
449 | 465 |
if (!isset($element['#value']['time']) && isset($callback_values['time'])) { |
... | ... | |
464 | 480 |
'spinnerImage' => '', |
465 | 481 |
'fromTo' => isset($fromto), |
466 | 482 |
); |
483 |
|
|
467 | 484 |
if (strpos($element['#date_format'], 'a') !== FALSE) { |
468 | 485 |
// Then we are using lowercase am/pm. |
469 |
$settings['ampmNames'] = array('am', 'pm'); |
|
486 |
$options = date_ampm_options(FALSE, FALSE); |
|
487 |
$settings['ampmNames'] = array($options['am'], $options['pm']); |
|
470 | 488 |
} |
471 |
if (strpos($element['#date_format'], ' A') !== FALSE || strpos($element['#date_format'], ' a') !== FALSE) { |
|
489 |
|
|
490 |
if (strpos($element['#date_format'], 'A') !== FALSE) { |
|
491 |
// Then we are using uppercase am/pm. |
|
492 |
$options = date_ampm_options(FALSE, TRUE); |
|
493 |
$settings['ampmNames'] = array($options['am'], $options['pm']); |
|
472 | 494 |
$settings['ampmPrefix'] = ' '; |
473 | 495 |
} |
474 | 496 |
break; |
... | ... | |
496 | 518 |
default: |
497 | 519 |
$func = ''; |
498 | 520 |
$settings = array(); |
499 |
break; |
|
500 | 521 |
} |
501 | 522 |
|
502 | 523 |
// Create a unique id for each set of custom settings. |
503 | 524 |
$id = date_popup_js_settings_id($element['#id'], $func, $settings); |
504 | 525 |
|
505 |
// Manually build this element and set the value - |
|
506 |
// this will prevent corrupting the parent value.
|
|
526 |
// Manually build this element and set the value - this will prevent
|
|
527 |
// corrupting the parent value. |
|
507 | 528 |
$parents = array_merge($element['#parents'], array('time')); |
508 | 529 |
$sub_element = array( |
509 | 530 |
'#type' => 'textfield', |
... | ... | |
517 | 538 |
'#parents' => $parents, |
518 | 539 |
'#name' => array_shift($parents) . '[' . implode('][', $parents) . ']', |
519 | 540 |
'#ajax' => !empty($element['#ajax']) ? $element['#ajax'] : FALSE, |
541 |
'#required' => $element['#required'], |
|
520 | 542 |
); |
521 | 543 |
|
522 |
$sub_element['#value'] = $sub_element['#default_value'];
|
|
544 |
// Do NOT overwrite the actual input with the default value.
|
|
523 | 545 |
|
524 |
// TODO, figure out exactly when we want this description. |
|
525 |
// In many places it is not desired. |
|
546 |
// @todo Figure out exactly when this is needed, in many places it is not. |
|
526 | 547 |
$example_date = date_now(); |
527 | 548 |
date_increment_round($example_date, $element['#date_increment']); |
528 | 549 |
$sub_element['#description'] = t('E.g., @date', array( |
... | ... | |
543 | 564 |
* contains a string, after submission it contains an array. |
544 | 565 |
*/ |
545 | 566 |
function date_popup_validate($element, &$form_state) { |
546 |
|
|
547 | 567 |
if (date_hidden_element($element)) { |
548 | 568 |
return; |
549 | 569 |
} |
... | ... | |
581 | 601 |
// @codingStandardsIgnoreEnd |
582 | 602 |
$date = date_popup_input_date($element, $input); |
583 | 603 |
|
584 |
// If the date has errors, display them. |
|
585 |
// If something was input but there is no date, the date is invalid.
|
|
586 |
// If the field is empty and required, set error message and return.
|
|
604 |
// If the date has errors, display them. If something was input but there is
|
|
605 |
// no date, the date is invalid. If the field is empty and required, set
|
|
606 |
// error message and return. |
|
587 | 607 |
$error_field = implode('][', $element['#parents']); |
588 | 608 |
if ((empty($element['#value']['date']) && empty($element['#value']['time'])) || !empty($date->errors)) { |
589 | 609 |
if (is_object($date) && !empty($date->errors)) { |
... | ... | |
617 | 637 |
* Useful anytime the time value is optional. |
618 | 638 |
*/ |
619 | 639 |
function date_popup_input_date($element, $input, $auto_complete = FALSE) { |
620 |
if (empty($input) || !is_array($input) || !array_key_exists('date', $input) || empty($input['date'])) { |
|
621 |
//check if there is no time associated in the input variable. This is the exception scenario where the user has entered only time and not date. |
|
622 |
if(empty($input['time'])) |
|
623 |
return NULL; |
|
640 |
if (empty($input) || !is_array($input) || !array_key_exists('date', $input) || (empty($input['date']) && empty($input['time']))) { |
|
641 |
return NULL; |
|
624 | 642 |
} |
625 | 643 |
date_popup_add(); |
626 | 644 |
$granularity = date_format_order($element['#date_format']); |
... | ... | |
629 | 647 |
|
630 | 648 |
$format = date_popup_date_format($element); |
631 | 649 |
$format .= $has_time ? ' ' . date_popup_time_format($element) : ''; |
632 |
//check if date is empty, if yes, then leave it blank. |
|
650 |
// check if date is empty, if yes, then leave it blank.
|
|
633 | 651 |
$datetime = !empty($input['date']) ? trim($input['date']) : ''; |
634 | 652 |
$datetime .= $has_time ? ' ' . trim($input['time']) : ''; |
635 | 653 |
$date = new DateObject($datetime, $element['#date_timezone'], $format); |
636 |
//if the variable is time only then set TimeOnly to TRUE
|
|
637 |
if(empty($input['date']) && !empty($input['time']) ){
|
|
654 |
// if the variable is time only then set TimeOnly to TRUE.
|
|
655 |
if (empty($input['date']) && !empty($input['time'])) {
|
|
638 | 656 |
$date->timeOnly = 'TRUE'; |
639 | 657 |
} |
640 | 658 |
if (is_object($date)) { |
... | ... | |
660 | 678 |
/** |
661 | 679 |
* Format options array. |
662 | 680 |
* |
663 |
* TODO Remove any formats not supported by the widget, if any.
|
|
681 |
* @todo Remove any formats not supported by the widget, if any.
|
|
664 | 682 |
*/ |
665 | 683 |
function date_popup_formats() { |
666 | 684 |
// Load short date formats. |
... | ... | |
684 | 702 |
* A normal date format string, like Y-m-d |
685 | 703 |
* |
686 | 704 |
* @return string |
687 |
* A format string in popup format, like YMD-, for the |
|
688 |
* earlier 'calendar' version, or m/d/Y for the later 'datepicker' |
|
689 |
* version. |
|
705 |
* A format string in popup format, like YMD-, for the earlier 'calendar' |
|
706 |
* version, or m/d/Y for the later 'datepicker' version. |
|
690 | 707 |
*/ |
691 | 708 |
function date_popup_format_to_popup($format) { |
692 | 709 |
if (empty($format)) { |
... | ... | |
754 | 771 |
* input format into one that the given timepicker can support. |
755 | 772 |
* |
756 | 773 |
* @param string $timepicker |
757 |
* The time entry plugin being used: either 'wvega' or 'default'.
|
|
774 |
* The time entry plugin being used: 'wvega', 'timepicker' or 'default'.
|
|
758 | 775 |
* |
759 | 776 |
* @return array |
760 | 777 |
* A map of replacements. |
... | ... | |
765 | 782 |
// The wvega timepicker only supports uppercase AM/PM. |
766 | 783 |
return array('a' => 'A'); |
767 | 784 |
|
785 |
case 'timepicker': |
|
786 |
// The jquery_ui timepicker supports all possible date formats. |
|
787 |
return array(); |
|
788 |
|
|
768 | 789 |
default: |
769 | 790 |
// The default timeEntry plugin requires leading zeros. |
770 | 791 |
return array('G' => 'H', 'g' => 'h'); |
... | ... | |
798 | 819 |
$element = $vars['element']; |
799 | 820 |
$attributes = !empty($element['#wrapper_attributes']) ? $element['#wrapper_attributes'] : array('class' => array()); |
800 | 821 |
$attributes['class'][] = 'container-inline-date'; |
801 |
// If there is no description, the floating date |
|
802 |
// elements need some extra padding below them.
|
|
822 |
// If there is no description, the floating date elements need some extra
|
|
823 |
// padding below them. |
|
803 | 824 |
$wrapper_attributes = array('class' => array('date-padding')); |
804 | 825 |
if (empty($element['date']['#description'])) { |
805 | 826 |
$wrapper_attributes['class'][] = 'clearfix'; |
806 | 827 |
} |
807 |
// Add an wrapper to mimic the way a single value field works, |
|
808 |
// for ease in using #states.
|
|
828 |
// Add an wrapper to mimic the way a single value field works, for ease in
|
|
829 |
// using #states. |
|
809 | 830 |
if (isset($element['#children'])) { |
810 | 831 |
$element['#children'] = '<div id="' . $element['#id'] . '" ' . drupal_attributes($wrapper_attributes) . '>' . $element['#children'] . '</div>'; |
811 | 832 |
} |
... | ... | |
824 | 845 |
* Implements hook_menu(). |
825 | 846 |
*/ |
826 | 847 |
function date_popup_menu() { |
827 |
$items = array(); |
|
828 |
// TODO Fix this later. |
|
848 |
// @todo Fix this later. |
|
829 | 849 |
$items['admin/config/date/date_popup'] = array( |
830 | 850 |
'title' => 'Date Popup', |
831 | 851 |
'description' => 'Configure the Date Popup settings.', |
... | ... | |
836 | 856 |
); |
837 | 857 |
return $items; |
838 | 858 |
} |
859 |
|
|
839 | 860 |
/** |
840 | 861 |
* General configuration form for controlling the Date Popup behaviour. |
841 | 862 |
*/ |
Formats disponibles : Unified diff
Weekly update of contrib modules