Projet

Général

Profil

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

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

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
 * @param array $field, the field definition for this date field.
95
 * @param string $which, which value to return, 'date1' or 'date2' .
96
 * @param object $date1, a date/time object for the 'start' date.
97
 * @param object $date2, a date/time object for the 'end' date.
98
 * @param string $format
99
 * @param object $entity, the node this date comes from (may be incomplete, always contains nid).
100
 * @param object $view, the view this node comes from, if applicable.
101
 * @return formatted date.
102
 */
103
function theme_date_all_day($vars) {
104
  $field    = $vars['field'];
105
  $instance = $vars['instance'];
106
  $which    = $vars['which'];
107
  $date1    = $vars['date1'];
108
  $date2    = $vars['date2'];
109
  $format   = $vars['format'];
110
  $entity   = $vars['entity'];
111
  $view     = !empty($vars['view']) ? $vars['view'] : NULL;
112

    
113
  if (empty($date1) || !is_object($date1) || $format == 'format_interval') {
114
    return;
115
  }
116
  if (empty($date2)) {
117
    $date2 = $date1;
118
  }
119

    
120
  $suffix = '';
121
  if (!date_has_time($field['settings']['granularity'])) {
122
    $format = date_limit_format($format, array('year', 'month', 'day'));
123
  }
124
  else {
125
    $format_granularity = date_format_order($format);
126
    $format_has_time = FALSE;
127
    if (in_array('hour', $format_granularity)) {
128
      $format_has_time = TRUE;
129
    }
130
    $all_day = date_all_day_field($field, $instance, $date1, $date2);
131
    if ($all_day && $format_has_time) {
132
      $format = date_limit_format($format, array('year', 'month', 'day'));
133
      $suffix = ' ' . theme('date_all_day_label');
134
    }
135
  }
136

    
137
  return trim(date_format_date($$which, 'custom', $format) . $suffix);
138

    
139
}
140

    
141
/**
142
 * Theme the way an 'all day' label will look.
143
 */
144
function theme_date_all_day_label() {
145
  return '(' . t('All day', array(), array('context' => 'datetime')) .')';
146
}
147

    
148
/**
149
 * Determine if a Start/End date combination qualify as 'All day'.
150
 *
151
 * @param array $field, the field definition for this date field.
152
 * @param object $date1, a date/time object for the 'Start' date.
153
 * @param object $date2, a date/time object for the 'End' date.
154
 * @return TRUE or FALSE.
155
 */
156
function date_all_day_field($field, $instance, $date1, $date2 = NULL) {
157
  if (empty($date1) || !is_object($date1)) {
158
    return FALSE;
159
  }
160
  elseif (!date_has_time($field['settings']['granularity'])) {
161
    return TRUE;
162
  }
163
  if (empty($date2)) {
164
    $date2 = $date1;
165
  }
166

    
167
  $granularity = date_granularity_precision($field['settings']['granularity']);
168
  $increment = isset($instance['widget']['settings']['increment']) ? $instance['widget']['settings']['increment'] : 1;
169
  return date_is_all_day(date_format($date1, DATE_FORMAT_DATETIME), date_format($date2, DATE_FORMAT_DATETIME), $granularity, $increment);
170

    
171
}
172

    
173
/**
174
 * Implements hook_date_combo_process_alter().
175
 *
176
 * This hook lets us make changes to the date_combo element.
177
 */
178
function date_all_day_date_combo_process_alter(&$element, &$form_state, $context) {
179

    
180
  $field = $context['field'];
181
  $instance = $context['instance'];
182

    
183
  // Add the all_day checkbox to the combo element.
184
  if (!empty($instance['widget']['settings']['display_all_day'])) {
185

    
186
    $parents = $element['#parents'];
187
    $first_parent = array_shift($parents);
188
    $all_day_id = $first_parent . '[' . implode('][', $parents) . '][all_day]';;
189
    foreach (array('value', 'value2') as $key) {
190
      if (array_key_exists($key, $element)) {
191
        $element[$key]['#date_all_day_id']  = $all_day_id;
192
      }
193
    }
194

    
195
    $from = $element['#default_value']['value'];
196
    $to = !empty($element['#default_value']['value2']) ? $element['#default_value']['value2'] : $element['#default_value']['value'];
197
    $date_is_all_day = date_is_all_day($from, $to);
198
    $all_day = !empty($form_state['values']['all_day']) || $date_is_all_day;
199
    $element['all_day'] = array(
200
      '#title' => t('All Day'),
201
      '#type' => 'checkbox',
202
      '#default_value' => $all_day,
203
      '#weight' => -21,
204
      '#prefix' => '<div class="date-float">',
205
      '#suffix' => '</div>',
206
    );
207
  }
208

    
209
  // Set all_day to 0 for all other date fields.
210
  else {
211
    $form['all_day']['#type'] = 'hidden';
212
    $form['all_day']['#value'] = 0;
213
  }
214
}
215

    
216

    
217
/**
218
 * Implements hook_date_text_process_alter().
219
 *
220
 * This hook lets us make changes to the date_select widget.
221
 */
222
function date_all_day_date_text_process_alter(&$element, &$form_state, $context) {
223
  $all_day_id = !empty($element['#date_all_day_id']) ? $element['#date_all_day_id'] : '';
224
  if ($all_day_id != '') {
225
    // All Day handling on text dates works only if the user leaves the time out of the input value.
226
    // There is no element to hide or show.
227
  }
228
}
229

    
230
/**
231
 * Implements hook_date_select_process_alter().
232
 *
233
 * This hook lets us make changes to the date_select widget.
234
 */
235
function date_all_day_date_select_process_alter(&$element, &$form_state, $context) {
236

    
237
  // Hide or show this element in reaction to the all_day status for this element.
238
  $all_day_id = !empty($element['#date_all_day_id']) ? $element['#date_all_day_id'] : '';
239
  if ($all_day_id != '') {
240
    foreach(array('hour', 'minute', 'second', 'ampm') as $field) {
241
      if (array_key_exists($field, $element)) {
242
        $element[$field]['#states'] = array(
243
          'visible' => array(
244
            'input[name="' . $all_day_id . '"]' => array('checked' => FALSE),
245
          ));
246
      }
247
    }
248
  }
249
}
250

    
251
/**
252
 * Implements hook_date_popup_process_alter().
253
 *
254
 * This hook lets us make changes to the date_popup element.
255
 */
256
function date_all_day_date_popup_process_alter(&$element, &$form_state, $context) {
257

    
258
  // Hide or show this element in reaction to the all_day status for this element.
259
  $all_day_id = !empty($element['#date_all_day_id']) ? $element['#date_all_day_id'] : '';
260
  if ($all_day_id != '' && array_key_exists('time', $element)) {
261
    $element['time']['#states'] = array(
262
      'visible' => array(
263
        'input[name="' . $all_day_id . '"]' => array('checked' => FALSE),
264
      ));
265
  }
266
}
267

    
268
/**
269
 * Implements hook_date_select_pre_validate_alter().
270
 *
271
 * This hook lets us alter the element or the form_state before the rest
272
 * of the date_select validation gets fired.
273
 */
274
function date_all_day_date_text_pre_validate_alter(&$element, &$form_state, &$input) {
275
  // Let Date module massage the format for all day values so they will pass validation.
276
  // The All day flag, if used, actually exists on the parent element.
277
  date_all_day_value($element, $form_state);
278
}
279

    
280
/**
281
 * Implements hook_date_select_pre_validate_alter().
282
 *
283
 * This hook lets us alter the element or the form_state before the rest
284
 * of the date_select validation gets fired.
285
 */
286
function date_all_day_date_select_pre_validate_alter(&$element, &$form_state, &$input) {
287
  // Let Date module massage the format for all day values so they will pass validation.
288
  // The All day flag, if used, actually exists on the parent element.
289
  date_all_day_value($element, $form_state);
290
}
291

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

    
304
/**
305
 * A helper function to check if the all day flag is set on the parent of an
306
 * element, and adjust the date_format accordingly so the missing time will
307
 * not cause validation errors.
308
 */
309
function date_all_day_value(&$element, $form_state) {
310
  if (!empty($element['#date_all_day_id'])) {
311
    $parents = $element['#parents'];
312
    array_pop($parents);
313
    $parent_element = drupal_array_get_nested_value($form_state['values'], $parents);
314
    if (!empty($parent_element) && !empty($parent_element['all_day'])) {
315
      $element['#date_format'] = date_part_format('date', $element['#date_format']);
316
      return $parent_element['all_day'];
317
    }
318
  }
319
  return FALSE;
320
}
321

    
322
/**
323
 * Implements hook_date_combo_pre_validate_alter().
324
 *
325
 * This hook lets us alter the element or the form_state before the rest
326
 * of the date_combo validation gets fired.
327
 */
328
function date_all_day_date_combo_pre_validate_alter(&$element, &$form_state, $context) {
329

    
330
  if (!empty($context['item']['all_day'])) {
331

    
332
    $field = $context['field'];
333

    
334
    // If we have an all day flag on this date and the time is empty,
335
    // change the format to match the input value so we don't get validation errors.
336
    $element['#date_is_all_day'] = TRUE;
337
    $element['value']['#date_format'] = date_part_format('date', $element['value']['#date_format']);
338
    if (!empty($field['settings']['todate'])) {
339
      $element['value2']['#date_format'] = date_part_format('date', $element['value2']['#date_format']);
340
    }
341
  }
342
}
343

    
344
/**
345
 * Implements hook_date_combo_validate_date_start_alter().
346
 *
347
 * This hook lets us alter the local date objects created by the date_combo validation
348
 * before they are converted back to the database timezone and stored.
349
 */
350
function date_all_day_date_combo_validate_date_start_alter(&$date, &$form_state, $context) {
351

    
352
   // If this is an 'All day' value, set the time to midnight.
353
   if (!empty($context['element']['#date_is_all_day'])) {
354
     $date->setTime(0, 0, 0);
355
   }
356
}
357

    
358
/**
359
 * Implements hook_date_combo_validate_date_end_alter().
360
 *
361
 * This hook lets us alter the local date objects created by the date_combo validation
362
 * before they are converted back to the database timezone and stored.
363
 */
364
function date_all_day_date_combo_validate_date_end_alter(&$date, &$form_state, $context) {
365

    
366
   // If this is an 'All day' value, set the time to midnight.
367
   if (!empty($context['element']['#date_is_all_day'])) {
368
     $date->setTime(0, 0, 0);
369
   }
370
}
371

    
372
/**
373
 * Implements hook_field_widget_info_alter().
374
 *
375
 * This Field API hook lets us add a new setting to the widgets.
376
 */
377
function date_all_day_field_widget_info_alter(&$info) {
378
  // Add a setting to a widget type.
379
  $info['date_select']['settings'] += array(
380
    'display_all_day' => 0,
381
  );
382
  $info['date_text']['settings'] += array(
383
    'display_all_day' => 0,
384
  );
385
  if (module_exists('date_popup')) {
386
    $info['date_popup']['settings'] += array(
387
      'display_all_day' => 0,
388
    );
389
  }
390
}
391

    
392
/**
393
 * Implements hook_date_field_widget_settings_form_alter().
394
 *
395
 * This hook lets us alter the field settings form by adding a place
396
 * to set the value added above.
397
 */
398
function date_all_day_date_field_widget_settings_form_alter(&$form, $context) {
399

    
400
  $field = $context['field'];
401
  $instance = $context['instance'];
402

    
403
  $settings = $instance['widget']['settings'];
404

    
405
  $form['display_all_day'] = array(
406
    '#type' => 'checkbox',
407
    '#title' => t('Display all day checkbox'),
408
    '#default_value' => $settings['display_all_day'],
409
    '#description' => t("Determines whether to display the 'All Day' checkbox to the user."),
410
    '#weight' => 8,
411
    '#fieldset' => 'date_format',
412
  );
413

    
414
  // Hide the option to use the all day checkbox for dates with no time.
415
  if (!date_has_time($field['settings']['granularity'])) {
416
    $form['display_all_day']['#type'] = 'hidden';
417
    $form['display_all_day']['#value'] = 0;
418
  }
419
}