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' => '
',
'#suffix' => '
',
);
}
// 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;
}
}