Projet

Général

Profil

Paste
Télécharger (13,6 ko) Statistiques
| Branche: | Révision:

root / drupal7 / sites / all / modules / date / date_all_day / date_all_day.module @ b720ea3e

1
<?php
2

    
3
/**
4
 * @file
5
 * Adds All Day functionality to the Date field.
6
 *
7
 * This module implements a number of hooks in the Date field and
8
 * Date api element processing and to add an All Day checkbox to
9
 * date widgets, and also adds an All Day theme and
10
 * All Day information to the formatting.
11
 *
12
 * Keep in mind that the process hooks are fired from the top down,
13
 * first date_combo, then the date_select or date_popup.
14
 *
15
 * Validation fires from the bottom up, first date_select and
16
 * date_popup, then date_combo.
17
 */
18

    
19
/**
20
 * Implements hook_theme().
21
 */
22
function date_all_day_theme() {
23
  $themes = array(
24
    'date_all_day' => array(
25
      'variables' => array(
26
        'field' => NULL,
27
        'instance' => NULL,
28
        'which' => NULL,
29
        'date1' => NULL,
30
        'date2' => NULL,
31
        'format' => NULL,
32
        'entity_type' => NULL,
33
        'entity' => NULL,
34
        'view' => NULL,
35
      ),
36
    ),
37
    'date_all_day_label' => array(
38
      'variables' => array(),
39
    ),
40
  );
41

    
42
  return $themes;
43
}
44

    
45
/**
46
 * Implements hook_date_formatter_dates_alter().
47
 *
48
 * This allows us to alter the $dates array created
49
 * by date_formatter_process.
50
 */
51
function date_all_day_date_formatter_dates_alter(&$dates, $context) {
52

    
53
  $field = $context['field'];
54
  $instance = $context['instance'];
55
  $format = $context['format'];
56
  $entity_type = $context['entity_type'];
57
  $entity = $context['entity'];
58
  $date1 = $dates['value']['local']['object'];
59
  $date2 = $dates['value2']['local']['object'];
60

    
61
  $is_all_day = date_all_day_field($field, $instance, $date1, $date2);
62

    
63
  $all_day1 = '';
64
  $all_day2 = '';
65
  if ($format != 'format_interval' && $is_all_day) {
66
    $all_day1 = theme('date_all_day', array(
67
      'field' => $field,
68
      'instance' => $instance,
69
      'which' => 'date1',
70
      'date1' => $date1,
71
      'date2' => $date2,
72
      'format' => $format,
73
      'entity_type' => $entity_type,
74
      'entity' => $entity));
75
    $all_day2 = theme('date_all_day', array(
76
      'field' => $field,
77
      'instance' => $instance,
78
      'which' => 'date2',
79
      'date1' => $date1,
80
      'date2' => $date2,
81
      'format' => $format,
82
      'entity_type' => $entity_type,
83
      'entity' => $entity));
84
    $dates['value']['formatted_time'] = theme('date_all_day_label');
85
    $dates['value2']['formatted_time'] = theme('date_all_day_label');
86
    $dates['value']['formatted'] = $all_day1;
87
    $dates['value2']['formatted'] = $all_day2;
88
  }
89
}
90

    
91
/**
92
 * Adjust start/end date format to account for 'all day' .
93
 *
94
 * @params array $field
95
 *   The field definition for this date field.
96
 *
97
 * @params string $which
98
 *   Which value to return, 'date1' or 'date2'.
99
 *
100
 * @params object $date1
101
 *   A date/time object for the 'start' date.
102
 *
103
 * @params object $date2
104
 *   A date/time object for the 'end' date.
105
 *
106
 * @params string $format
107
 *   A date/time format
108
 *
109
 * @params object $entity
110
 *   The node this date comes from (may be incomplete, always contains nid).
111
 *
112
 * @params object $view
113
 *   The view this node comes from, if applicable.
114
 *
115
 * @return string
116
 *   Formatted date.
117
 */
118
function theme_date_all_day($vars) {
119
  $field    = $vars['field'];
120
  $instance = $vars['instance'];
121
  $which    = $vars['which'];
122
  $date1    = $vars['date1'];
123
  $date2    = $vars['date2'];
124
  $format   = $vars['format'];
125
  $entity   = $vars['entity'];
126
  $view     = !empty($vars['view']) ? $vars['view'] : NULL;
127

    
128
  if (empty($date1) || !is_object($date1) || $format == 'format_interval') {
129
    return;
130
  }
131
  if (empty($date2)) {
132
    $date2 = $date1;
133
  }
134

    
135
  $suffix = '';
136
  if (!date_has_time($field['settings']['granularity'])) {
137
    $format = date_limit_format($format, array('year', 'month', 'day'));
138
  }
139
  else {
140
    $format_granularity = date_format_order($format);
141
    $format_has_time = FALSE;
142
    if (in_array('hour', $format_granularity)) {
143
      $format_has_time = TRUE;
144
    }
145
    $all_day = date_all_day_field($field, $instance, $date1, $date2);
146
    if ($all_day && $format_has_time) {
147
      $format = date_limit_format($format, array('year', 'month', 'day'));
148
      $suffix = ' ' . theme('date_all_day_label');
149
    }
150
  }
151

    
152
  return trim(date_format_date($$which, 'custom', $format) . $suffix);
153
}
154

    
155
/**
156
 * Theme the way an 'all day' label will look.
157
 */
158
function theme_date_all_day_label() {
159
  return '(' . t('All day', array(), array('context' => 'datetime')) . ')';
160
}
161

    
162
/**
163
 * Determine if a Start/End date combination qualify as 'All day'.
164
 *
165
 * @param array $field
166
 *   The field definition for this date field.
167
 *
168
 * @param array $instance
169
 *   The field instance for this date field.
170
 *
171
 * @param object $date1
172
 *   A date/time object for the 'Start' date.
173
 *
174
 * @param object $date2
175
 *   A date/time object for the 'End' date.
176
 *
177
 * @return bool
178
 *   TRUE or FALSE.
179
 */
180
function date_all_day_field($field, $instance, $date1, $date2 = NULL) {
181
  if (empty($date1) || !is_object($date1)) {
182
    return FALSE;
183
  }
184
  elseif (!date_has_time($field['settings']['granularity'])) {
185
    return TRUE;
186
  }
187
  if (empty($date2)) {
188
    $date2 = $date1;
189
  }
190

    
191
  $granularity = date_granularity_precision($field['settings']['granularity']);
192
  $increment = isset($instance['widget']['settings']['increment']) ? $instance['widget']['settings']['increment'] : 1;
193
  return date_is_all_day(date_format($date1, DATE_FORMAT_DATETIME), date_format($date2, DATE_FORMAT_DATETIME), $granularity, $increment);
194
}
195

    
196
/**
197
 * Implements hook_date_combo_process_alter().
198
 *
199
 * This hook lets us make changes to the date_combo element.
200
 */
201
function date_all_day_date_combo_process_alter(&$element, &$form_state, $context) {
202

    
203
  $field = $context['field'];
204
  $instance = $context['instance'];
205

    
206
  // Add the all_day checkbox to the combo element.
207
  if (!empty($instance['widget']['settings']['display_all_day'])) {
208

    
209
    $parents = $element['#parents'];
210
    $first_parent = array_shift($parents);
211
    $all_day_id = $first_parent . '[' . implode('][', $parents) . '][all_day]';;
212
    foreach (array('value', 'value2') as $key) {
213
      if (array_key_exists($key, $element)) {
214
        $element[$key]['#date_all_day_id']  = $all_day_id;
215
      }
216
    }
217

    
218
    $from = $element['#default_value']['value'];
219
    $to = !empty($element['#default_value']['value2']) ? $element['#default_value']['value2'] : $element['#default_value']['value'];
220
    $date_is_all_day = date_is_all_day($from, $to);
221
    $all_day = !empty($form_state['values']['all_day']) || $date_is_all_day;
222
    $element['all_day'] = array(
223
      '#title' => t('All Day'),
224
      '#type' => 'checkbox',
225
      '#default_value' => $all_day,
226
      '#weight' => -21,
227
      '#prefix' => '<div class="date-float">',
228
      '#suffix' => '</div>',
229
    );
230
  }
231

    
232
  // Set all_day to 0 for all other date fields.
233
  else {
234
    $form['all_day']['#type'] = 'hidden';
235
    $form['all_day']['#value'] = 0;
236
  }
237
}
238

    
239

    
240
/**
241
 * Implements hook_date_text_process_alter().
242
 *
243
 * This hook lets us make changes to the date_select widget.
244
 */
245
function date_all_day_date_text_process_alter(&$element, &$form_state, $context) {
246
  $all_day_id = !empty($element['#date_all_day_id']) ? $element['#date_all_day_id'] : '';
247
  if ($all_day_id != '') {
248
    // All Day handling on text dates works only
249
    // if the user leaves the time out of the input value.
250
    // There is no element to hide or show.
251
  }
252
}
253

    
254
/**
255
 * Implements hook_date_select_process_alter().
256
 *
257
 * This hook lets us make changes to the date_select widget.
258
 */
259
function date_all_day_date_select_process_alter(&$element, &$form_state, $context) {
260

    
261
  // Hide or show this element in reaction
262
  // to the all_day status for this element.
263
  $all_day_id = !empty($element['#date_all_day_id']) ? $element['#date_all_day_id'] : '';
264
  if ($all_day_id != '') {
265
    foreach (array('hour', 'minute', 'second', 'ampm') as $field) {
266
      if (array_key_exists($field, $element)) {
267
        $element[$field]['#states'] = array(
268
          'visible' => array(
269
            'input[name="' . $all_day_id . '"]' => array('checked' => FALSE),
270
          ));
271
      }
272
    }
273
  }
274
}
275

    
276
/**
277
 * Implements hook_date_popup_process_alter().
278
 *
279
 * This hook lets us make changes to the date_popup element.
280
 */
281
function date_all_day_date_popup_process_alter(&$element, &$form_state, $context) {
282

    
283
  // Hide or show this element in reaction to
284
  // the all_day status for this element.
285
  $all_day_id = !empty($element['#date_all_day_id']) ? $element['#date_all_day_id'] : '';
286
  if ($all_day_id != '' && array_key_exists('time', $element)) {
287
    $element['time']['#states'] = array(
288
      'visible' => array(
289
        'input[name="' . $all_day_id . '"]' => array('checked' => FALSE),
290
      ));
291
  }
292
}
293

    
294
/**
295
 * Implements hook_date_select_pre_validate_alter().
296
 *
297
 * This hook lets us alter the element or the form_state before the rest
298
 * of the date_select validation gets fired.
299
 */
300
function date_all_day_date_text_pre_validate_alter(&$element, &$form_state, &$input) {
301
  // Let Date module massage the format for all day
302
  // values so they will pass validation.
303
  // The All day flag, if used, actually exists on the parent element.
304
  date_all_day_value($element, $form_state);
305
}
306

    
307
/**
308
 * Implements hook_date_select_pre_validate_alter().
309
 *
310
 * This hook lets us alter the element or the form_state before the rest
311
 * of the date_select validation gets fired.
312
 */
313
function date_all_day_date_select_pre_validate_alter(&$element, &$form_state, &$input) {
314
  // Let Date module massage the format for all
315
  // day values so they will pass validation.
316
  // The All day flag, if used, actually exists on the parent element.
317
  date_all_day_value($element, $form_state);
318
}
319

    
320
/**
321
 * Implements hook_date_select_pre_validate_alter().
322
 *
323
 * This hook lets us alter the element or the form_state before the rest
324
 * of the date_popup validation gets fired.
325
 */
326
function date_all_day_date_popup_pre_validate_alter(&$element, &$form_state, &$input) {
327
  // Let Date module massage the format for all
328
  // day values so they will pass validation.
329
  // The All day flag, if used, actually exists on the parent element.
330
  date_all_day_value($element, $form_state);
331
}
332

    
333
/**
334
 * A helper function date_all_day_value().
335
 *
336
 * To check if the all day flag is set on the parent of an
337
 * element, and adjust the date_format accordingly so the missing time will
338
 * not cause validation errors.
339
 */
340
function date_all_day_value(&$element, $form_state) {
341
  if (!empty($element['#date_all_day_id'])) {
342
    $parents = $element['#parents'];
343
    array_pop($parents);
344
    $parent_element = drupal_array_get_nested_value($form_state['values'], $parents);
345
    if (!empty($parent_element) && !empty($parent_element['all_day'])) {
346
      $element['#date_format'] = date_part_format('date', $element['#date_format']);
347
      return $parent_element['all_day'];
348
    }
349
  }
350
  return FALSE;
351
}
352

    
353
/**
354
 * Implements hook_date_combo_pre_validate_alter().
355
 *
356
 * This hook lets us alter the element or the form_state before the rest
357
 * of the date_combo validation gets fired.
358
 */
359
function date_all_day_date_combo_pre_validate_alter(&$element, &$form_state, $context) {
360

    
361
  if (!empty($context['item']['all_day'])) {
362

    
363
    $field = $context['field'];
364

    
365
    // If we have an all day flag on this date and the time is empty,
366
    // change the format to match the input value
367
    // so we don't get validation errors.
368
    $element['#date_is_all_day'] = TRUE;
369
    $element['value']['#date_format'] = date_part_format('date', $element['value']['#date_format']);
370
    if (!empty($field['settings']['todate'])) {
371
      $element['value2']['#date_format'] = date_part_format('date', $element['value2']['#date_format']);
372
    }
373
  }
374
}
375

    
376
/**
377
 * Implements hook_date_combo_validate_date_start_alter().
378
 *
379
 * This hook lets us alter the local date objects
380
 * created by the date_combo validation before they are
381
 * converted back to the database timezone and stored.
382
 */
383
function date_all_day_date_combo_validate_date_start_alter(&$date, &$form_state, $context) {
384
  // If this is an 'All day' value, set the time to midnight.
385
  if (!empty($context['element']['#date_is_all_day'])) {
386
    $date->setTime(0, 0, 0);
387
  }
388
}
389

    
390
/**
391
 * Implements hook_date_combo_validate_date_end_alter().
392
 *
393
 * This hook lets us alter the local date objects
394
 * created by the date_combo validation before
395
 * they are converted back to the database timezone and stored.
396
 */
397
function date_all_day_date_combo_validate_date_end_alter(&$date, &$form_state, $context) {
398
  // If this is an 'All day' value, set the time to midnight.
399
  if (!empty($context['element']['#date_is_all_day'])) {
400
    $date->setTime(0, 0, 0);
401
  }
402
}
403

    
404
/**
405
 * Implements hook_field_widget_info_alter().
406
 *
407
 * This Field API hook lets us add a new setting to the widgets.
408
 */
409
function date_all_day_field_widget_info_alter(&$info) {
410
  // Add a setting to a widget type.
411
  $info['date_select']['settings'] += array(
412
    'display_all_day' => 0,
413
  );
414
  $info['date_text']['settings'] += array(
415
    'display_all_day' => 0,
416
  );
417
  if (module_exists('date_popup')) {
418
    $info['date_popup']['settings'] += array(
419
      'display_all_day' => 0,
420
    );
421
  }
422
}
423

    
424
/**
425
 * Implements hook_date_field_widget_settings_form_alter().
426
 *
427
 * This hook lets us alter the field settings form by adding a place
428
 * to set the value added above.
429
 */
430
function date_all_day_date_field_widget_settings_form_alter(&$form, $context) {
431

    
432
  $field = $context['field'];
433
  $instance = $context['instance'];
434

    
435
  $settings = $instance['widget']['settings'];
436

    
437
  $form['display_all_day'] = array(
438
    '#type' => 'checkbox',
439
    '#title' => t('Display all day checkbox'),
440
    '#default_value' => $settings['display_all_day'],
441
    '#description' => t("Determines whether to display the 'All Day' checkbox to the user."),
442
    '#weight' => 8,
443
    '#fieldset' => 'date_format',
444
  );
445

    
446
  // Hide the option to use the all day checkbox for dates with no time.
447
  if (!date_has_time($field['settings']['granularity'])) {
448
    $form['display_all_day']['#type'] = 'hidden';
449
    $form['display_all_day']['#value'] = 0;
450
  }
451
}