123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451 |
- <?php
- /**
- * @file
- * Adds All Day functionality to the Date field.
- *
- * This module implements a number of hooks in the Date field and
- * Date api element processing and to add an All Day checkbox to
- * date widgets, and also adds an All Day theme and
- * All Day information to the formatting.
- *
- * Keep in mind that the process hooks are fired from the top down,
- * first date_combo, then the date_select or date_popup.
- *
- * Validation fires from the bottom up, first date_select and
- * date_popup, then date_combo.
- */
- /**
- * Implements hook_theme().
- */
- function date_all_day_theme() {
- $themes = array(
- 'date_all_day' => array(
- 'variables' => array(
- 'field' => NULL,
- 'instance' => NULL,
- 'which' => NULL,
- 'date1' => NULL,
- 'date2' => NULL,
- 'format' => NULL,
- 'entity_type' => NULL,
- 'entity' => NULL,
- 'view' => NULL,
- ),
- ),
- 'date_all_day_label' => array(
- 'variables' => array(),
- ),
- );
- return $themes;
- }
- /**
- * Implements hook_date_formatter_dates_alter().
- *
- * This allows us to alter the $dates array created
- * by date_formatter_process.
- */
- function date_all_day_date_formatter_dates_alter(&$dates, $context) {
- $field = $context['field'];
- $instance = $context['instance'];
- $format = $context['format'];
- $entity_type = $context['entity_type'];
- $entity = $context['entity'];
- $date1 = $dates['value']['local']['object'];
- $date2 = $dates['value2']['local']['object'];
- $is_all_day = date_all_day_field($field, $instance, $date1, $date2);
- $all_day1 = '';
- $all_day2 = '';
- if ($format != 'format_interval' && $is_all_day) {
- $all_day1 = theme('date_all_day', array(
- 'field' => $field,
- 'instance' => $instance,
- 'which' => 'date1',
- 'date1' => $date1,
- 'date2' => $date2,
- 'format' => $format,
- 'entity_type' => $entity_type,
- 'entity' => $entity));
- $all_day2 = theme('date_all_day', array(
- 'field' => $field,
- 'instance' => $instance,
- 'which' => 'date2',
- 'date1' => $date1,
- 'date2' => $date2,
- 'format' => $format,
- 'entity_type' => $entity_type,
- 'entity' => $entity));
- $dates['value']['formatted_time'] = theme('date_all_day_label');
- $dates['value2']['formatted_time'] = theme('date_all_day_label');
- $dates['value']['formatted'] = $all_day1;
- $dates['value2']['formatted'] = $all_day2;
- }
- }
- /**
- * Adjust start/end date format to account for 'all day' .
- *
- * @params array $field
- * The field definition for this date field.
- *
- * @params string $which
- * Which value to return, 'date1' or 'date2'.
- *
- * @params object $date1
- * A date/time object for the 'start' date.
- *
- * @params object $date2
- * A date/time object for the 'end' date.
- *
- * @params string $format
- * A date/time format
- *
- * @params object $entity
- * The node this date comes from (may be incomplete, always contains nid).
- *
- * @params object $view
- * The view this node comes from, if applicable.
- *
- * @return string
- * Formatted date.
- */
- function theme_date_all_day($vars) {
- $field = $vars['field'];
- $instance = $vars['instance'];
- $which = $vars['which'];
- $date1 = $vars['date1'];
- $date2 = $vars['date2'];
- $format = $vars['format'];
- $entity = $vars['entity'];
- $view = !empty($vars['view']) ? $vars['view'] : NULL;
- if (empty($date1) || !is_object($date1) || $format == 'format_interval') {
- return;
- }
- if (empty($date2)) {
- $date2 = $date1;
- }
- $suffix = '';
- if (!date_has_time($field['settings']['granularity'])) {
- $format = date_limit_format($format, array('year', 'month', 'day'));
- }
- else {
- $format_granularity = date_format_order($format);
- $format_has_time = FALSE;
- if (in_array('hour', $format_granularity)) {
- $format_has_time = TRUE;
- }
- $all_day = date_all_day_field($field, $instance, $date1, $date2);
- if ($all_day && $format_has_time) {
- $format = date_limit_format($format, array('year', 'month', 'day'));
- $suffix = ' ' . theme('date_all_day_label');
- }
- }
- return trim(date_format_date($$which, 'custom', $format) . $suffix);
- }
- /**
- * Theme the way an 'all day' label will look.
- */
- function theme_date_all_day_label() {
- return '(' . t('All day', array(), array('context' => 'datetime')) . ')';
- }
- /**
- * Determine if a Start/End date combination qualify as 'All day'.
- *
- * @param array $field
- * The field definition for this date field.
- *
- * @param array $instance
- * The field instance for this date field.
- *
- * @param object $date1
- * A date/time object for the 'Start' date.
- *
- * @param object $date2
- * A date/time object for the 'End' date.
- *
- * @return bool
- * TRUE or FALSE.
- */
- function date_all_day_field($field, $instance, $date1, $date2 = NULL) {
- if (empty($date1) || !is_object($date1)) {
- return FALSE;
- }
- elseif (!date_has_time($field['settings']['granularity'])) {
- return TRUE;
- }
- if (empty($date2)) {
- $date2 = $date1;
- }
- $granularity = date_granularity_precision($field['settings']['granularity']);
- $increment = isset($instance['widget']['settings']['increment']) ? $instance['widget']['settings']['increment'] : 1;
- return date_is_all_day(date_format($date1, DATE_FORMAT_DATETIME), date_format($date2, DATE_FORMAT_DATETIME), $granularity, $increment);
- }
- /**
- * Implements hook_date_combo_process_alter().
- *
- * This hook lets us make changes to the date_combo element.
- */
- function date_all_day_date_combo_process_alter(&$element, &$form_state, $context) {
- $field = $context['field'];
- $instance = $context['instance'];
- // Add the all_day checkbox to the combo element.
- if (!empty($instance['widget']['settings']['display_all_day'])) {
- $parents = $element['#parents'];
- $first_parent = array_shift($parents);
- $all_day_id = $first_parent . '[' . implode('][', $parents) . '][all_day]';;
- foreach (array('value', 'value2') as $key) {
- if (array_key_exists($key, $element)) {
- $element[$key]['#date_all_day_id'] = $all_day_id;
- }
- }
- $from = $element['#default_value']['value'];
- $to = !empty($element['#default_value']['value2']) ? $element['#default_value']['value2'] : $element['#default_value']['value'];
- $date_is_all_day = date_is_all_day($from, $to);
- $all_day = !empty($form_state['values']['all_day']) || $date_is_all_day;
- $element['all_day'] = array(
- '#title' => t('All Day'),
- '#type' => 'checkbox',
- '#default_value' => $all_day,
- '#weight' => -21,
- '#prefix' => '<div class="date-float">',
- '#suffix' => '</div>',
- );
- }
- // Set all_day to 0 for all other date fields.
- else {
- $form['all_day']['#type'] = 'hidden';
- $form['all_day']['#value'] = 0;
- }
- }
- /**
- * Implements hook_date_text_process_alter().
- *
- * This hook lets us make changes to the date_select widget.
- */
- function date_all_day_date_text_process_alter(&$element, &$form_state, $context) {
- $all_day_id = !empty($element['#date_all_day_id']) ? $element['#date_all_day_id'] : '';
- if ($all_day_id != '') {
- // All Day handling on text dates works only
- // if the user leaves the time out of the input value.
- // There is no element to hide or show.
- }
- }
- /**
- * Implements hook_date_select_process_alter().
- *
- * This hook lets us make changes to the date_select widget.
- */
- function date_all_day_date_select_process_alter(&$element, &$form_state, $context) {
- // Hide or show this element in reaction
- // to the all_day status for this element.
- $all_day_id = !empty($element['#date_all_day_id']) ? $element['#date_all_day_id'] : '';
- if ($all_day_id != '') {
- foreach (array('hour', 'minute', 'second', 'ampm') as $field) {
- if (array_key_exists($field, $element)) {
- $element[$field]['#states'] = array(
- 'visible' => array(
- 'input[name="' . $all_day_id . '"]' => array('checked' => FALSE),
- ));
- }
- }
- }
- }
- /**
- * Implements hook_date_popup_process_alter().
- *
- * This hook lets us make changes to the date_popup element.
- */
- function date_all_day_date_popup_process_alter(&$element, &$form_state, $context) {
- // Hide or show this element in reaction to
- // the all_day status for this element.
- $all_day_id = !empty($element['#date_all_day_id']) ? $element['#date_all_day_id'] : '';
- if ($all_day_id != '' && array_key_exists('time', $element)) {
- $element['time']['#states'] = array(
- 'visible' => array(
- 'input[name="' . $all_day_id . '"]' => array('checked' => FALSE),
- ));
- }
- }
- /**
- * Implements hook_date_select_pre_validate_alter().
- *
- * This hook lets us alter the element or the form_state before the rest
- * of the date_select validation gets fired.
- */
- function date_all_day_date_text_pre_validate_alter(&$element, &$form_state, &$input) {
- // Let Date module massage the format for all day
- // values so they will pass validation.
- // The All day flag, if used, actually exists on the parent element.
- date_all_day_value($element, $form_state);
- }
- /**
- * Implements hook_date_select_pre_validate_alter().
- *
- * This hook lets us alter the element or the form_state before the rest
- * of the date_select validation gets fired.
- */
- function date_all_day_date_select_pre_validate_alter(&$element, &$form_state, &$input) {
- // Let Date module massage the format for all
- // day values so they will pass validation.
- // The All day flag, if used, actually exists on the parent element.
- date_all_day_value($element, $form_state);
- }
- /**
- * Implements hook_date_select_pre_validate_alter().
- *
- * This hook lets us alter the element or the form_state before the rest
- * of the date_popup validation gets fired.
- */
- function date_all_day_date_popup_pre_validate_alter(&$element, &$form_state, &$input) {
- // Let Date module massage the format for all
- // day values so they will pass validation.
- // The All day flag, if used, actually exists on the parent element.
- date_all_day_value($element, $form_state);
- }
- /**
- * A helper function date_all_day_value().
- *
- * To check if the all day flag is set on the parent of an
- * element, and adjust the date_format accordingly so the missing time will
- * not cause validation errors.
- */
- function date_all_day_value(&$element, $form_state) {
- if (!empty($element['#date_all_day_id'])) {
- $parents = $element['#parents'];
- array_pop($parents);
- $parent_element = drupal_array_get_nested_value($form_state['values'], $parents);
- if (!empty($parent_element) && !empty($parent_element['all_day'])) {
- $element['#date_format'] = date_part_format('date', $element['#date_format']);
- return $parent_element['all_day'];
- }
- }
- return FALSE;
- }
- /**
- * Implements hook_date_combo_pre_validate_alter().
- *
- * This hook lets us alter the element or the form_state before the rest
- * of the date_combo validation gets fired.
- */
- function date_all_day_date_combo_pre_validate_alter(&$element, &$form_state, $context) {
- if (!empty($context['item']['all_day'])) {
- $field = $context['field'];
- // If we have an all day flag on this date and the time is empty,
- // change the format to match the input value
- // so we don't get validation errors.
- $element['#date_is_all_day'] = TRUE;
- $element['value']['#date_format'] = date_part_format('date', $element['value']['#date_format']);
- if (!empty($field['settings']['todate'])) {
- $element['value2']['#date_format'] = date_part_format('date', $element['value2']['#date_format']);
- }
- }
- }
- /**
- * Implements hook_date_combo_validate_date_start_alter().
- *
- * This hook lets us alter the local date objects
- * created by the date_combo validation before they are
- * converted back to the database timezone and stored.
- */
- function date_all_day_date_combo_validate_date_start_alter(&$date, &$form_state, $context) {
- // If this is an 'All day' value, set the time to midnight.
- if (!empty($context['element']['#date_is_all_day'])) {
- $date->setTime(0, 0, 0);
- }
- }
- /**
- * Implements hook_date_combo_validate_date_end_alter().
- *
- * This hook lets us alter the local date objects
- * created by the date_combo validation before
- * they are converted back to the database timezone and stored.
- */
- function date_all_day_date_combo_validate_date_end_alter(&$date, &$form_state, $context) {
- // If this is an 'All day' value, set the time to midnight.
- if (!empty($context['element']['#date_is_all_day'])) {
- $date->setTime(0, 0, 0);
- }
- }
- /**
- * Implements hook_field_widget_info_alter().
- *
- * This Field API hook lets us add a new setting to the widgets.
- */
- function date_all_day_field_widget_info_alter(&$info) {
- // Add a setting to a widget type.
- $info['date_select']['settings'] += array(
- 'display_all_day' => 0,
- );
- $info['date_text']['settings'] += array(
- 'display_all_day' => 0,
- );
- if (module_exists('date_popup')) {
- $info['date_popup']['settings'] += array(
- 'display_all_day' => 0,
- );
- }
- }
- /**
- * Implements hook_date_field_widget_settings_form_alter().
- *
- * This hook lets us alter the field settings form by adding a place
- * to set the value added above.
- */
- function date_all_day_date_field_widget_settings_form_alter(&$form, $context) {
- $field = $context['field'];
- $instance = $context['instance'];
- $settings = $instance['widget']['settings'];
- $form['display_all_day'] = array(
- '#type' => 'checkbox',
- '#title' => t('Display all day checkbox'),
- '#default_value' => $settings['display_all_day'],
- '#description' => t("Determines whether to display the 'All Day' checkbox to the user."),
- '#weight' => 8,
- '#fieldset' => 'date_format',
- );
- // Hide the option to use the all day checkbox for dates with no time.
- if (!date_has_time($field['settings']['granularity'])) {
- $form['display_all_day']['#type'] = 'hidden';
- $form['display_all_day']['#value'] = 0;
- }
- }
|