Projet

Général

Profil

Révision 599a39cd

Ajouté par Assos Assos il y a environ 3 ans

Weekly update of contrib modules

Voir les différences:

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