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_elements.inc
1 1
<?php
2

  
2 3
/**
3 4
 * @file
4 5
 * Date forms and form themes and validation.
......
42 43
 *   the local timezone, are converted back to their UTC values and stored.
43 44
 */
44 45
function date_field_widget_form(&$form, &$form_state, $field, $instance, $langcode, $items, $delta, $base) {
45

  
46 46
  $element = $base;
47 47
  $field_name = $field['field_name'];
48 48
  $entity_type = $instance['entity_type'];
49 49

  
50 50
  // If this is a new entity, populate the field with the right default values.
51
  // This happens early so even fields later hidden with #access get those values.
52
  // We should only add default values to new entities, to avoid over-writing
53
  // a value that has already been set. This means we can't just check to see
54
  // if $items is empty, because it might have been set that way on purpose.
55
  // @see date_field_widget_properties_alter() where we flagged if this is a new entity.
56

  
57
  // We check !isset($items[$delta]['value']) because entity translation may create
58
  // a new translation entity for an existing entity and we don't want to clobber
59
  // values that were already set in that case.
51
  // This happens early so even fields later hidden with #access get those
52
  // values. We should only add default values to new entities, to avoid
53
  // over-writing a value that has already been set. This means we can't just
54
  // check to see if $items is empty, because it might have been set that way
55
  // on purpose. In date_field_widget_properties_alter() this is flagged if
56
  // this is a new entity. Check !isset($items[$delta]['value']) because entity
57
  // translation may create a new translation entity for an existing entity and
58
  // we don't want to clobber values that were already set in that case.
59
  // @see date_field_widget_properties_alter()
60 60
  // @see http://drupal.org/node/1478848.
61

  
62 61
  $is_default = FALSE;
63
  if (!empty($instance['widget']['is_new']) && !isset($items[$delta]['value'])) {
64
    $items = date_default_value($field, $instance, $langcode);
65
    $is_default = TRUE;
62
  if (!isset($items[$delta]['value'])) {
63
    if (!empty($instance['widget']['is_new'])) {
64
      // New entity; use default values defined on instance.
65
      $items = date_default_value($field, $instance, $langcode);
66
      $is_default = TRUE;
67
    }
68
    else {
69
      // Date is empty; create array structure for value keys.
70
      $keys = date_process_values($field);
71
      $items[$delta] = array_fill_keys($keys, '');
72
    }
66 73
  }
67 74

  
68
  // @TODO Repeating dates should probably be made into their own field type and completely separated out.
69
  // That will have to wait for a new branch since it may break other things, including other modules
70
  // that have an expectation of what the date field types are.
71

  
72
  // Since repeating dates cannot use the default Add more button, we have to handle our own behaviors here.
73
  // Return only the first multiple value for repeating dates, then clean up the 'Add more' bits in #after_build.
74
  // The repeating values will be re-generated when the repeat widget form is validated.
75
  // At this point we can't tell if this form element is going to be hidden by #access, and we're going to
76
  // lose all but the first value by doing this, so store the original values in case we need to replace them later.
75
  // @todo Repeating dates should probably be made into their own field type
76
  // and completely separated out. That will have to wait for a new branch
77
  // since it may break other things, including other modules that have an
78
  // expectation of what the date field types are. Since repeating dates cannot
79
  // use the default Add more button, we have to handle our own behaviors here.
80
  // Return only the first multiple value for repeating dates, then clean up
81
  // the 'Add more' bits in #after_build. The repeating values will be
82
  // re-generated when the repeat widget form is validated. At this point we
83
  // can't tell if this form element is going to be hidden by #access, and
84
  // we're going to lose all but the first value by doing this, so store the
85
  // original values in case we need to replace them later.
77 86
  if (!empty($field['settings']['repeat']) && module_exists('date_repeat_field')) {
78 87
    if ($delta == 0) {
79 88
      $form['#after_build'][] = 'date_repeat_after_build';
......
101 110
    '#type' => 'date_combo',
102 111
    '#theme_wrappers' => array('date_combo'),
103 112
    '#weight' => $delta,
104
    '#default_value' => isset($items[$delta]) ? $items[$delta] : '',
113
    '#default_value' => isset($items[$delta]) ? $items[$delta] : array(),
105 114
    '#date_timezone' => $timezone,
106 115
    '#element_validate' => array('date_combo_validate'),
107 116
    '#date_is_default' => $is_default,
108 117

  
109 118
    // Store the original values, for use with disabled and hidden fields.
110
    '#date_items' => isset($items[$delta]) ? $items[$delta] : '',
119
    '#date_items' => isset($items[$delta]) ? $items[$delta] : array(),
111 120
  );
112 121

  
113 122
  $element['#title'] = $instance['label'];
......
126 135

  
127 136
  // Make changes if instance is set to be rendered as a regular field.
128 137
  if (!empty($instance['widget']['settings']['no_fieldset'])) {
129
   $element['#title'] = check_plain($instance['label']);
130
   $element['#theme_wrappers'] = ($field['cardinality'] == 1) ? array('date_form_element') : array();
138
    $element['#title'] = check_plain($instance['label']);
139
    $element['#theme_wrappers'] = ($field['cardinality'] == 1) ? array('date_form_element') : array();
131 140
  }
132 141

  
133 142
  return $element;
......
136 145
/**
137 146
 * Create local date object.
138 147
 *
139
 * Create a date object set to local time from the field and
140
 * widget settings and item values. Default values for new entities
141
 * are set by the default value callback, so don't need to be accounted for here.
148
 * Create a date object set to local time from the field and widget settings and
149
 * item values. Default values for new entities are set by the default value
150
 * callback, so don't need to be accounted for here.
142 151
 */
143 152
function date_local_date($item, $timezone, $field, $instance, $part = 'value') {
144

  
145 153
  $value = $item[$part];
146 154

  
147 155
  // If the value is empty, don't try to create a date object because it will
......
150 158
    return NULL;
151 159
  }
152 160

  
153
  // @TODO Figure out how to replace date_fuzzy_datetime() function.
161
  // @todo Figure out how to replace date_fuzzy_datetime() function.
154 162
  // Special case for ISO dates to create a valid date object for formatting.
155 163
  // Is this still needed?
156 164
  // @codingStandardsIgnoreStart
......
200 208
}
201 209

  
202 210
/**
203
 * Helper function for the date default value callback to set either 'value' or 'value2' to its default value.
211
 * Default value callback to set either 'value', 'value2' to its default value.
204 212
 */
205 213
function date_default_value_part($item, $field, $instance, $langcode, $part = 'value') {
206 214
  $timezone = date_get_timezone($field['settings']['tz_handling']);
......
225 233
      return NULL;
226 234
    }
227 235
    else {
228
      // The date stored in 'value' has already been switched to the db timezone.
236
      // The date stored in 'value' has already been switched to the db
237
      // timezone.
229 238
      $date = new DateObject($item[0]['value'], $timezone_db, DATE_FORMAT_DATETIME);
230 239
    }
231 240
  }
232
  // Special case for 'now' when using dates with no timezone,
233
  // make sure 'now' isn't adjusted to UTC value of 'now' .
241
  // Special case for 'now' when using dates with no timezone, make sure 'now'
242
  // isn't adjusted to UTC value of 'now'.
234 243
  elseif ($field['settings']['tz_handling'] == 'none') {
235 244
    $date = date_now();
236 245
  }
......
266 275
  $field = field_widget_field($element, $form_state);
267 276
  $instance = field_widget_instance($element, $form_state);
268 277

  
269
  // Figure out how many items are in the form, including new ones added by ajax.
278
  // Figure out how many items are in the form, including new ones added by
279
  // ajax.
270 280
  $field_state = field_form_get_state($element['#field_parents'], $field_name, $element['#language'], $form_state);
271 281
  $items_count = $field_state['items_count'];
272 282

  
......
280 290
  $offset_field = 'offset';
281 291
  $offset_field2 = 'offset2';
282 292

  
283
  // Convert UTC dates to their local values in DATETIME format,
284
  // and adjust the default values as specified in the field settings.
285

  
286
  // It would seem to make sense to do this conversion when the data
287
  // is loaded instead of when the form is created, but the loaded
288
  // field data is cached and we can't cache dates that have been converted
289
  // to the timezone of an individual user, so we cache the UTC values
290
  // instead and do our conversion to local dates in the form and
291
  // in the formatters.
293
  // Convert UTC dates to their local values in DATETIME format, and adjust the
294
  // default values as specified in the field settings. It would seem to make
295
  // sense to do this conversion when the data is loaded instead of when the
296
  // form is created, but the loaded field data is cached and we can't cache
297
  // dates that have been converted to the timezone of an individual user, so
298
  // we cache the UTC values instead and do our conversion to local dates in
299
  // the form and in the formatters.
292 300
  $process = date_process_values($field, $instance);
293 301
  foreach ($process as $processed) {
294 302
    if (!isset($element['#default_value'][$processed])) {
303
      if (empty($element['#default_value']) || !is_array($element['#default_value'])) {
304
        $element['#default_value'] = array();
305
      }
295 306
      $element['#default_value'][$processed] = '';
296 307
    }
297 308
    $date = date_local_date($element['#default_value'], $element['#date_timezone'], $field, $instance, $processed);
......
299 310
  }
300 311

  
301 312
  // Blank out the end date for optional end dates that match the start date,
302
  // except when this is a new node that has default values that should be honored.
313
  // except when this is a new node that has default values that should be
314
  // honored.
303 315
  if (!$date_is_default && $field['settings']['todate'] != 'required'
304
  && is_array($element['#default_value'])
305
  && !empty($element['#default_value'][$to_field])
306
  && $element['#default_value'][$to_field] == $element['#default_value'][$from_field]) {
316
      && is_array($element['#default_value'])
317
      && !empty($element['#default_value'][$to_field])
318
      && $element['#default_value'][$to_field] == $element['#default_value'][$from_field]) {
307 319
    unset($element['#default_value'][$to_field]);
308 320
  }
309 321

  
......
343 355
    $element['#description'] = $element['value']['#instance']['description'];
344 356
  }
345 357

  
346
  // Give this element the right type, using a Date API
347
  // or a Date Popup element type.
358
  // Give this element the right type, using a Date API or a Date Popup element
359
  // type.
348 360
  $element[$from_field]['#attributes'] = array('class' => array('date-clear'));
349 361
  $element[$from_field]['#wrapper_attributes'] = array('class' => array());
350 362
  $element[$from_field]['#wrapper_attributes']['class'][] = 'date-no-float';
......
360 372
    case 'date_popup':
361 373
      $element[$from_field]['#type'] = 'date_popup';
362 374
      $element[$from_field]['#theme_wrappers'] = array('date_popup');
375
      // Disable autocomplete in browsers.
376
      // @see https://developer.mozilla.org/en-US/docs/Web/Security/Securing_your_site/Turning_off_form_autocompletion
377
      $element[$from_field]['#attributes']['autocomplete'] = 'off';
363 378
      $element[$from_field]['#ajax'] = !empty($element['#ajax']) ? $element['#ajax'] : FALSE;
364 379
      break;
365 380

  
......
367 382
      $element[$from_field]['#type'] = 'date_text';
368 383
      $element[$from_field]['#theme_wrappers'] = array('date_text');
369 384
      $element[$from_field]['#ajax'] = !empty($element['#ajax']) ? $element['#ajax'] : FALSE;
370
      break;
371 385
  }
372 386

  
373
  // If this field uses the 'End', add matching element
374
  // for the 'End' date, and adapt titles to make it clear which
375
  // is the 'Start' and which is the 'End' .
376

  
387
  // If this field uses the 'End', add matching element for the 'End' date, and
388
  // adapt titles to make it clear which is the 'Start' and which is the 'End' .
377 389
  if (!empty($field['settings']['todate'])) {
378 390
    $element[$to_field] = $element[$from_field];
379 391
    $element[$from_field]['#title_display'] = 'none';
......
423 435
  }
424 436

  
425 437
  $context = array(
426
    'field'     => $field,
427
    'instance'  => $instance,
428
    'form'      => $form,
438
    'field' => $field,
439
    'instance' => $instance,
440
    'form' => $form,
429 441
  );
430 442
  drupal_alter('date_combo_process', $element, $form_state, $context);
431 443

  
......
438 450
function date_element_empty($element, &$form_state) {
439 451
  $item = array();
440 452
  $item['value'] = NULL;
441
  $item['value2']   = NULL;
442
  $item['timezone']   = NULL;
453
  $item['value2'] = NULL;
454
  $item['timezone'] = NULL;
443 455
  $item['offset'] = NULL;
444 456
  $item['offset2'] = NULL;
445 457
  $item['rrule'] = NULL;
......
453 465
 * Don't try this if there were errors before reaching this point.
454 466
 */
455 467
function date_combo_validate($element, &$form_state) {
456

  
457
  // Disabled and hidden elements won't have any input and don't need validation,
458
  // we just need to re-save the original values, from before they were processed into
459
  // widget arrays and timezone-adjusted.
468
  // Disabled and hidden elements won't have any input and don't need
469
  // validation, we just need to re-save the original values, from before they
470
  // were processed into widget arrays and timezone-adjusted.
460 471
  if (date_hidden_element($element) || !empty($element['#disabled'])) {
461 472
    form_set_value($element, $element['#date_items'], $form_state);
462 473
    return;
......
504 515
  $offset_field = 'offset';
505 516
  $offset_field2 = 'offset2';
506 517

  
507
  // Check for empty 'Start date', which could either be an empty
508
  // value or an array of empty values, depending on the widget.
518
  // Check for empty 'Start date', which could either be an empty value or an
519
  // array of empty values, depending on the widget.
509 520
  $empty = TRUE;
510 521
  if (!empty($item[$from_field])) {
511 522
    if (!is_array($item[$from_field])) {
......
567 578

  
568 579
    // Neither the start date nor the end date should be empty at this point
569 580
    // unless they held values that couldn't be evaluated.
570

  
571 581
    if (!$instance['required'] && (!date_is_date($from_date) || !date_is_date($to_date))) {
572 582
      $item = date_element_empty($element, $form_state);
573 583
      $errors[] = t('The dates are invalid.');
......
577 587
      $errors[] = t('The End date must be greater than the Start date.');
578 588
    }
579 589
    else {
580
      // Convert input dates back to their UTC values and re-format to ISO
581
      // or UNIX instead of the DATETIME format used in element processing.
590
      // Convert input dates back to their UTC values and re-format to ISO or
591
      // UNIX instead of the DATETIME format used in element processing.
582 592
      $item[$tz_field] = $timezone;
583 593

  
584 594
      // Update the context for changes in the $item, and allow other modules to
......
587 597
      // We can only pass two additional values to drupal_alter, so $element
588 598
      // needs to be included in $context.
589 599
      $context['element'] = $element;
600

  
601
      // Trigger hook_date_combo_validate_date_start_alter().
590 602
      drupal_alter('date_combo_validate_date_start', $from_date, $form_state, $context);
603

  
604
      // Trigger hook_date_combo_validate_date_end_alter().
591 605
      drupal_alter('date_combo_validate_date_end', $to_date, $form_state, $context);
592 606

  
593 607
      $item[$offset_field] = date_offset_get($from_date);
......
604 618
        $item['rrule'] = $form_values[$field['field_name']]['rrule'];
605 619
      }
606 620

  
607
      // If the db timezone is not the same as the display timezone
608
      // and we are using a date with time granularity,
609
      // test a roundtrip back to the original timezone to catch
610
      // invalid dates, like 2AM on the day that spring daylight savings
611
      // time begins in the US.
621
      // If the db timezone is not the same as the display timezone and we are
622
      // using a date with time granularity, test a roundtrip back to the
623
      // original timezone to catch invalid dates, like 2AM on the day that
624
      // spring daylight savings time begins in the US.
612 625
      $granularity = date_format_order($element[$from_field]['#date_format']);
613 626
      if ($timezone != $timezone_db && date_has_time($granularity)) {
614 627
        date_timezone_set($from_date, timezone_open($timezone));
......
626 639
      }
627 640
    }
628 641
  }
629
  // Don't show further errors if errors are already flagged
630
  // because otherwise we'll show errors on the nested elements
631
  // more than once.
642

  
643
  // Don't show further errors if errors are already flagged because otherwise
644
  // we'll show errors on the nested elements more than once.
632 645
  if (!form_get_errors() && !empty($errors)) {
633 646
    if ($field['cardinality']) {
634 647
      form_error($element, t('There are errors in @field_name value #@delta:', array('@field_name' => $instance['label'], '@delta' => $delta + 1)) . theme('item_list', array('items' => $errors)));
......
652 665
  return variable_get('date_format_short', 'm/d/Y - H:i');
653 666
}
654 667

  
655

  
656 668
/**
657 669
 * Implements hook_date_select_pre_validate_alter().
658 670
 */
......
678 690
 * Helper function to clear out end date when not being used.
679 691
 */
680 692
function date_empty_end_date(&$element, &$form_state, &$input) {
681
  // If this is the end date and the option to show an end date has not been selected,
682
  // empty the end date to surpress validation errors and stop further processing.
693
  // If this is the end date and the option to show an end date has not been
694
  // selected, empty the end date to surpress validation errors and stop
695
  // further processing.
683 696
  $parents = $element['#parents'];
684 697
  $parent = array_pop($parents);
685 698
  if ($parent == 'value2') {

Formats disponibles : Unified diff