You are here

calendar_systems.module in Calendar Systems 8

Contains Calendar Systems hook implementations and helpers.

File

calendar_systems.module
View source
<?php

require dirname(__FILE__) . '/calendar_systems.helpers.inc';

/**
 * @file
 * Contains Calendar Systems hook implementations and helpers.
 */

/**
 * Implements hook_help().
 */
function calendar_systems_help($path, $arg) {
  switch ($path) {
    case 'admin/help#calendar-systems':

      // Return a line-break version of the module README.txt.
      return check_markup(file_get_contents(dirname(__FILE__) . "/README.txt"));
    case 'admin/config/regionals/calendar-systems':
      $output = '<p>' . t('Using the following form you can assign a different calendar system to each language and also select the default calendar system.') . '</p>';
      return $output;
  }
}

/**
 * Implements hook_perm().
 */
function calendar_systems_permission() {
  return array(
    'administer calendar_systems' => array(
      'title' => t('Administer calendar systems'),
      'description' => t('Administer calendar systems configurations.'),
    ),
  );
}

/**
 * Implements hook_menu().
 */
function calendar_systems_menu() {
  $items = array();

  // Main configuration page:
  $items['admin/config/regional/calendar-systems'] = array(
    'title' => 'Calendar systems',
    'description' => 'Administer calendar systems profiles.',
    'page callback' => 'drupal_get_form',
    'page arguments' => array(
      'calendar_systems_profile_overview',
    ),
    'access arguments' => array(
      'administer calendar_systems',
    ),
    'file' => 'calendar_systems.admin.inc',
  );

  // Configuration profile:
  $items['admin/config/regional/calendar-systems/profile'] = array(
    'title' => 'Calendar systems profiles',
    'description' => 'Assign calendar systems.',
    'type' => MENU_DEFAULT_LOCAL_TASK,
  );

  // Profile removal:
  $items['admin/config/regional/calendar-systems/profile/%/delete'] = array(
    'title' => 'Remove',
    'description' => 'Calendar systems profile removal.',
    'page callback' => 'drupal_get_form',
    'page arguments' => array(
      'calendar_systems_profile_delete_confirm',
      5,
    ),
    'access arguments' => array(
      'administer calendar_systems',
    ),
    'file' => 'calendar_systems.admin.inc',
  );
  return $items;
}

/**
 * Implements hook_theme().
 */
function calendar_systems_theme() {
  return array(
    'calendar_systems_profile_overview' => array(
      'render element' => 'form',
    ),
  );
}

/**
 * Implementation of hook_patch() of patch_manager module
 */
function calendar_systems_patch() {
  $patches = array();
  $patches[] = array(
    'title' => t('Allows drupal format_date function to be altered by other modules'),
    'patch' => 'patch/core_format_date_alter.patch',
    'module' => 'core',
    'issue' => '1178342',
    'description' => t('Allows drupal format_date function to be altered by other modules'),
    'patchdir' => '',
  );
  return $patches;
}

/**
 * Implementation of format_date_alter hook/call
 * Altering out of format_date function
 */
function calendar_systems_format_date_alter(&$formatted_date, &$context) {

  // Calendar systems specific code
  $calendar_name = calendar_systems_get_calendar_system_name();
  if ($calendar_name != 'default' && ($calendar = calendar_systems_get_calendar_instance())) {
    $calendar
      ->setTimeZoneOffset($context['date_time']
      ->getOffset());
    $format = $calendar
      ->timestampToStr($context['format'], $context['date_time']
      ->getTimestamp() + $context['date_time']
      ->getOffset());
    $format = preg_replace('%[-+][0-9]{4}%', $context['date_time']
      ->format('O'), $format);

    // Pass the langcode to _format_date_callback().
    _format_date_callback(NULL, $context['langcode']);

    // Translate the marked sequences.
    $formatted_date = preg_replace_callback('/\\xEF([AaeDlMTF]?)(.*?)\\xFF/', '_format_date_callback', $format);
  }
}

/**
 * Simulating core format_date in case the patch wasn't applied
 * Formats a date, using a date type or a custom date format string.
 *
 * @param $timestamp
 *   A UNIX timestamp to format.
 * @param $type
 *   (optional) The format to use, one of:
 *   - 'short', 'medium', or 'long' (the corresponding built-in date formats).
 *   - The name of a date type defined by a module in hook_date_format_types(),
 *     if it's been assigned a format.
 *   - The machine name of an administrator-defined date format.
 *   - 'custom', to use $format.
 *   Defaults to 'medium'.
 * @param $format
 *   (optional) If $type is 'custom', a PHP date format string suitable for
 *   input to date(). Use a backslash to escape ordinary text, so it does not
 *   get interpreted as date format characters.
 * @param $timezone
 *   (optional) Time zone identifier, as described at
 *   http://php.net/manual/timezones.php Defaults to the time zone used to
 *   display the page.
 * @param $langcode
 *   (optional) Language code to translate to. Defaults to the language used to
 *   display the page.
 *
 * @return
 *   A translated date string in the requested format.
 */
function calendar_systems_format_date($timestamp, $type = 'medium', $format = '', $timezone = NULL, $langcode = NULL) {
  if (_calendar_systems_is_patch_applied()) {
    return format_date($timestamp, $type, $format, $timezone, $langcode);
  }

  // Use the advanced drupal_static() pattern, since this is called very often.
  static $drupal_static_fast;
  if (!isset($drupal_static_fast)) {
    $drupal_static_fast['timezones'] =& drupal_static(__FUNCTION__);
  }
  $timezones =& $drupal_static_fast['timezones'];
  if (!isset($timezone)) {
    $timezone = date_default_timezone_get();
  }

  // Store DateTimeZone objects in an array rather than repeatedly
  // constructing identical objects over the life of a request.
  if (!isset($timezones[$timezone])) {
    $timezones[$timezone] = timezone_open($timezone);
  }

  // Use the default langcode if none is set.
  global $language;
  if (empty($langcode)) {
    $langcode = isset($language->language) ? $language->language : 'en';
  }
  switch ($type) {
    case 'short':
      $format = variable_get('date_format_short', 'm/d/Y - H:i');
      break;
    case 'long':
      $format = variable_get('date_format_long', 'l, F j, Y - H:i');
      break;
    case 'custom':

      // No change to format.
      break;
    case 'medium':
    default:

      // Retrieve the format of the custom $type passed.
      if ($type != 'medium') {
        $format = variable_get('date_format_' . $type, '');
      }

      // Fall back to 'medium'.
      if ($format === '') {
        $format = variable_get('date_format_medium', 'D, m/d/Y - H:i');
      }
      break;
  }

  // Create a DateTime object from the timestamp.
  $date_time = date_create('@' . $timestamp);

  // Set the time zone for the DateTime object.
  date_timezone_set($date_time, $timezones[$timezone]);

  // Encode markers that should be translated. 'A' becomes '\xEF\AA\xFF'.
  // xEF and xFF are invalid UTF-8 sequences, and we assume they are not in the
  // input string.
  // Paired backslashes are isolated to prevent errors in read-ahead evaluation.
  // The read-ahead expression ensures that A matches, but not \A.
  $original_format = $format;
  $format = preg_replace(array(
    '/\\\\\\\\/',
    '/(?<!\\\\)([AaeDlMTF])/',
  ), array(
    "",
    "",
  ), $format);

  // Call date_format().
  $formatted_date = date_format($date_time, $format);

  // Pass the langcode to _format_date_callback().
  _format_date_callback(NULL, $langcode);

  // Translate the marked sequences.
  $formatted_date = preg_replace_callback('/\\xEF([AaeDlMTF]?)(.*?)\\xFF/', '_format_date_callback', $formatted_date);

  // Allow modules to alter the result.
  $context = array(
    'date_time' => $date_time,
    'timestamp' => $timestamp,
    'type' => $type,
    'format' => $original_format,
    'timezone' => $timezone,
    'langcode' => $langcode,
  );
  drupal_alter('format_date', $formatted_date, $context);
  return filter_xss_admin($formatted_date);
}

/**
 * hook_module_implements_alter
 * @param $implementations
 * @param $hook
 */
function calendar_systems_module_implements_alter(&$implementations, $hook) {
  if ($hook == 'form_alter') {
    $var = $implementations['calendar_systems'];
    unset($implementations['calendar_systems']);
    $implementations['calendar_systems'] = $var;
  }
}

/**
 * The usage is to improve compatibility when the core patch is not available
 * Implements hook_preprocess_node().
 */
function calendar_systems_preprocess_node(&$variables) {
  if (!_calendar_systems_is_patch_applied()) {
    $calendar = calendar_systems_get_calendar_instance();
    if ($calendar) {
      $format = variable_get('date_format_medium');
      $variables['date'] = $calendar
        ->smartGet($format, $variables['created']);
      if ($variables['display_submitted']) {
        $variables['submitted'] = t('Submitted by !username on !datetime', array(
          '!username' => $variables['name'],
          '!datetime' => $variables['date'],
        ));
      }
    }
  }
}

/**
 * The usage is to improve compatibility when the core patch is not available
 * Implements hook_preprocess_comment().
 */
function calendar_systems_preprocess_comment(&$variables) {
  if (!_calendar_systems_is_patch_applied()) {
    $calendar = calendar_systems_get_calendar_instance();
    if ($calendar) {
      $format = variable_get('date_format_medium');
      $variables['changed'] = $calendar
        ->smartGet($format, $variables['elements']['#comment']->created);
      $variables['created'] = $calendar
        ->smartGet($format, $variables['elements']['#comment']->changed);
      $variables['submitted'] = t('Submitted by !username on !datetime', array(
        '!username' => $variables['author'],
        '!datetime' => $variables['created'],
      ));
    }
  }
}

/**
 * Implements hook_form_alter().
 *
 * @todo
 *   Extend, fix.
 */
function calendar_systems_form_alter(&$form, $form_state, $form_id) {
  if (calendar_systems_get_calendar_system_name() != 'default') {

    // Overwrite date field element validate callback:
    if (@isset($form['scheduler_settings']['publish_on'])) {
      $form['scheduler_settings']['publish_on']['#element_validate'] = array_merge(array(
        'calendar_systems_date_validate',
      ), (array) @$form['author']['date']['#element_validate']);
      if (variable_get('calendar_systems_js_date_picker_core_text_date_fields')) {
        $form['scheduler_settings']['publish_on']['#attributes']['class'][] = 'calendar_systems_js_date_picker';
        calendar_systems_attach_js_date_picker($form['scheduler_settings']['publish_on'], 'Y-m-d', 'H:i:s');
      }
    }
    if (@isset($form['scheduler_settings']['unpublish_on'])) {
      $form['scheduler_settings']['unpublish_on']['#element_validate'] = array_merge(array(
        'calendar_systems_date_validate',
      ), (array) @$form['author']['date']['#element_validate']);
      if (variable_get('calendar_systems_js_date_picker_core_text_date_fields')) {
        $form['scheduler_settings']['unpublish_on']['#attributes']['class'][] = 'calendar_systems_js_date_picker';
        calendar_systems_attach_js_date_picker($form['scheduler_settings']['unpublish_on'], 'Y-m-d', 'H:i:s');
      }
    }
    if (isset($form['author']['date'])) {
      $form['author']['date']['#element_validate'] = array_merge(array(
        'calendar_systems_date_validate',
      ), (array) @$form['author']['date']['#element_validate']);
      if (variable_get('calendar_systems_js_date_picker_core_text_date_fields')) {
        $form['author']['date']['#attributes']['class'][] = 'calendar_systems_js_date_picker';
        calendar_systems_attach_js_date_picker($form['author']['date'], 'Y-m-d', 'H:i:s');
      }
    }
    if (isset($form['translation']['created'])) {
      $form['translation']['created']['#element_validate'] = array_merge(array(
        'calendar_systems_date_validate',
      ), (array) @$form['author']['date']['#element_validate']);
      if (variable_get('calendar_systems_js_date_picker_core_text_date_fields')) {
        $form['translation']['created']['#attributes']['class'][] = 'calendar_systems_js_date_picker';
        calendar_systems_attach_js_date_picker($form['translation']['created'], 'Y-m-d', 'H:i:s');
      }
    }
    if (isset($form['admin']['date'])) {
      $form['admin']['date']['#element_validate'] = array_merge(array(
        'calendar_systems_date_validate',
      ), (array) @$form['admin']['date']['#element_validate']);
      if (variable_get('calendar_systems_js_date_picker_core_text_date_fields')) {
        $form['admin']['date']['#attributes']['class'][] = 'calendar_systems_js_date_picker';
        calendar_systems_attach_js_date_picker($form['admin']['date'], 'Y-m-d', 'H:i:s');
      }
    }
    if ($form_id == 'views_exposed_form') {
      $form['#validate'] = array_merge($form['#validate'], array(
        '_calendar_systems_views_exposed_form_validate',
      ));
    }
    if (isset($form['submitted']) && isset($form['#process']) && is_array($form['#process']) && in_array('webform_client_form_includes', $form['#process'])) {
      $form['submitted']['test']['#process'][] = '_calendar_systems_element_date_process';
      $form['submitted']['test']['#element_validate'] = array_merge(array(
        'calendar_systems_date_validate',
      ), (array) $form['submitted']['test']['#element_validate']);
    }
    if (!_calendar_systems_is_patch_applied()) {
      $calendar = calendar_systems_get_calendar_instance();
      $format = variable_get('date_format_medium');
      if (isset($form['scheduler_settings'])) {
        foreach (array(
          'publish_on',
          'unpublish_on',
        ) as $name) {
          if (isset($form['#node']->scheduler[$name]) && !empty($form['scheduler_settings'][$name]['#default_value'])) {
            $form['scheduler_settings'][$name]['#default_value'] = $calendar
              ->smartGet('Y-m-d H:i:s O', $form['#node']->scheduler[$name]);
          }
          $form['scheduler_settings'][$name]['#description'] = t('Format: %date The date format is YYYY-MM-DD and time is H:i:s. Leave blank to disable scheduled.', array(
            '%date' => $now,
          ));
        }
      }
      if (isset($form['author']['date']) && isset($form_state['node'])) {
        $node =& $form_state['node'];
        $form['author']['date']['#description'] = t('Format: %time. The date format is YYYY-MM-DD and %timezone is the time zone offset from UTC. Leave blank to use the time of form submission.', array(
          '%time' => !empty($node->date) ? $calendar
            ->smartGet('Y-m-d H:i:s O', $node->date) : $calendar
            ->smartGet('Y-m-d H:i:s O', $node->created),
          '%timezone' => !empty($node->date) ? $calendar
            ->smartGet('O', $node->date) : $calendar
            ->smartGet('O', $node->created),
        ));
        if (!empty($form['author']['date']['#default_value'])) {
          $form['author']['date']['#default_value'] = $calendar
            ->smartGet('Y-m-d H:i:s O', $form['created']['#value']);
        }
      }
    }
  }
}

/**
 * @param $element
 * @param $form_state
 * @todo supporting month and day only filters and contextual filters
 */
function _calendar_systems_views_exposed_form_validate($element, &$form_state) {
  $position = -1;
  foreach ($form_state['view']->display_handler->handlers['argument'] as $filter_name => $filter) {
    $position++;
    $filter_class = get_class($filter);
    if ($filter_class == 'date_views_argument_handler' || $filter_class == 'date_views_argument_handler_simple' || $filter_class == 'views_handler_filter_date' || $filter_class == 'views_handler_argument_node_created_fulldate' || $filter_class == 'views_handler_argument_node_created_year' || $filter_class == 'views_handler_argument_node_created_year_month') {
      $value =& $form_state['view']->args[$position];
      if (!empty($value)) {
        if ($filter_class == 'views_handler_argument_node_created_fulldate') {
          $convert_option['iso_fixed_position'] = TRUE;
        }
        $date_format = $filter->arg_format;
        $options = array();
        if ($filter_class == 'views_handler_argument_node_created_fulldate' || $filter_class == 'views_handler_argument_node_created_year' || $filter_class == 'views_handler_argument_node_created_year_month') {
          $options['iso_fixed_size_position'] = TRUE;
        }
        $value = _calendar_systems_date_convert($value, $date_format, NULL, $options);
      }
    }
  }
  foreach ($form_state['view']->display_handler->handlers['filter'] as $filter_name => $filter) {
    $filter_class = get_class($filter);
    if ($filter_class == 'date_views_filter_handler' || $filter_class == 'date_views_filter_handler_simple' || $filter_class == 'views_handler_filter_date') {
      if (!empty($form_state['view']->exposed_input[$filter_name]['value'])) {
        foreach (array(
          'value',
          'value2',
          'min',
          'max',
        ) as $index) {
          if (isset($form_state['view']->exposed_input[$filter_name][$index])) {
            if (isset($form_state['view']->exposed_input[$filter_name][$index]['date'])) {
              $orig_date =& $form_state['view']->exposed_input[$filter_name][$index]['date'];
            }
            else {
              $orig_date =& $form_state['view']->exposed_input[$filter_name][$index];
            }
            $value = _calendar_systems_date_convert($orig_date, $element[$filter_name][$index]['#date_format']);
            $is_empty = TRUE;
            if (is_array($value) && class_exists('DateObject')) {
              if (@(!empty($value['year']))) {
                $is_empty = FALSE;
              }
              $date = new DateObject($value);
              $value = $date
                ->format($element[$filter_name][$index]['#date_format']);
            }
            else {
              if (!empty($value)) {
                $is_empty = FALSE;
              }
            }
            $form_state['view']->exposed_input[$filter_name][$index] = $value;
          }
        }
      }
    }
  }
}

/**
 * Element validation callback for date fields.
 *
 * @param $element
 *   Form element.
 * @param $form_state
 *   Known form state array.
 */
function calendar_systems_date_validate(&$element, &$form_state) {
  if (@$element['#calendar_system'] != 'default') {
    if (!empty($element['#value']) && is_array($element['#value'])) {
      $format = NULL;
      if (isset($element['value']['#date_format'])) {
        $format = $element['value']['#date_format'];
        if ($element['value']['#instance']['widget']['type'] == 'date_popup') {
          $format = preg_replace('%( \\- [a-zA-Z].*)%', '', $format);
        }
      }
      if (isset($element['#name'])) {
        $field_name = $element['#name'];
      }
      elseif (isset($element['#field_name'])) {
        $field_name = $element['#field_name'];
      }
      if (isset($element['#value']['value2']) || preg_match('%value2%', $field_name)) {
        $item_name = 'value2';
      }
      else {
        $item_name = 'value';
      }
      if ($field_name) {
        $field_name = preg_replace('%\\[.*%', '', $field_name);
      }
      $input_exists = NULL;
      $date_format = NULL;
      if (isset($element['#date_format'])) {
        $date_format = $element['#date_format'];
      }
      $value_path = $element['#parents'];
      if (isset($form_state['exposed_form_plugin']) && isset($form_state['view'])) {
        if ($element['#type'] == 'date_popup') {
          $value_path[] = 'date';
          $field_value =& $element['#value']['date'];
          $field_value_in_form_state = drupal_array_get_nested_value($form_state['values'], $value_path, $input_exists);
          $field_value_in_form_input = drupal_array_get_nested_value($form_state['input'], $value_path, $input_exists);
          $field_real_value = $field_value_in_form_input;
        }
        if ($element['#type'] == 'date_select') {
          $field_value =& $element['#value'][$item_name];
          $field_value_in_form_state = drupal_array_get_nested_value($form_state['values'], $element['#parents'], $input_exists);
          $field_value_in_form_input = drupal_array_get_nested_value($form_state['input'], $element['#parents'], $input_exists);
          $field_real_value = $field_value_in_form_input;
          if (@empty($field_real_value['year'])) {
            $field_real_value = NULL;
          }
        }
        if ($element['#type'] == 'date_text') {
          $value_path[] = 'date';
          $field_value =& $element['#value']['date'];
          $field_value_in_form_state = drupal_array_get_nested_value($form_state['values'], $value_path, $input_exists);
          $field_value_in_form_input = drupal_array_get_nested_value($form_state['input'], $value_path, $input_exists);
          $field_real_value = $field_value_in_form_input;
        }
      }
      else {
        if ($element['#type'] == 'date_popup') {
          $field_value =& $element['#value']['date'];
          $value_path[] = 'date';
          $field_value_in_form_state = drupal_array_get_nested_value($form_state['values'], $value_path, $input_exists);
          $field_value_in_form_input = drupal_array_get_nested_value($form_state['input'], $value_path, $input_exists);
          $field_real_value = $field_value_in_form_input;
          $date_format = _calendar_systems_get_format_part('date', $date_format);
        }
        if ($element['#type'] == 'date_select') {
          $field_value =& $element['#value'];
          $field_value_in_form_state = drupal_array_get_nested_value($form_state['values'], $value_path, $input_exists);
          $field_value_in_form_input = drupal_array_get_nested_value($form_state['input'], $value_path, $input_exists);
          $field_real_value = $field_value_in_form_input;
          if (@empty($field_real_value['year'])) {
            $field_real_value = NULL;
          }
        }
        if ($element['#type'] == 'date_text') {
          $value_path[] = 'date';
          $field_value =& $element['#value']['date'];
          $field_value_in_form_state = drupal_array_get_nested_value($form_state['values'], $value_path, $input_exists);
          $field_value_in_form_input = drupal_array_get_nested_value($form_state['input'], $value_path, $input_exists);
          $field_real_value = $field_value_in_form_input;
        }
        if ($element['#type'] == 'date' || $element['#type'] == 'text') {
          $field_value =& $element['#value'];

          //$field_value_second = &$element[$item_name]['date']['value'];
          $field_value_in_form_state = drupal_array_get_nested_value($form_state['values'], $value_path, $input_exists);
          $field_value_in_form_input = drupal_array_get_nested_value($form_state['input'], $value_path, $input_exists);
          $field_real_value = $field_value_in_form_input;
          if (isset($element['#field']) && isset($element['#field']['#translatable'])) {
            $field_real_value_converted = _calendar_systems_date_convert($field_real_value, $date_format, $element['#calendar_system']);
          }
          else {
            $field_real_value_converted = $field_real_value;
          }
        }
      }
      $field_real_value_converted = _calendar_systems_date_convert($field_real_value, $date_format, $element['#calendar_system']);
      if (!empty($field_real_value)) {
        if ($field_real_value_converted) {
          drupal_array_set_nested_value($form_state['values'], $value_path, $field_real_value_converted);
          drupal_array_set_nested_value($form_state['input'], $value_path, $field_real_value_converted);
          if (isset($field_value_second)) {
            $field_value_second = $field_real_value_converted;
          }

          //form_set_value($element, $field_real_value_converted, $form_state);
          if (isset($element['#webform_component']) && $element['#type'] == 'date') {
            $element['#value'] = $field_real_value_converted;
            $element['#calendar_system'] = 'gregorian';
            if (isset($element['year'])) {
              $_value_path = $value_path + array(
                'year',
              );
              $element['year']['#value'] = $field_real_value_converted['year'];
            }
            if (isset($element['month'])) {
              $_value_path = $value_path + array(
                'month',
              );
              $element['month']['#value'] = $field_real_value_converted['month'];
            }
            if (isset($element['day'])) {
              $_value_path = $value_path + array(
                'day',
              );
              $element['day']['#value'] = $field_real_value_converted['day'];
            }
          }
        }
        else {
          form_set_error($element['#name'], t('You have to specify a valid date.'));
        }
      }
    }
    elseif (!empty($element['#value'])) {
      $value = _calendar_systems_date_convert($element['#value']);
      if ($value) {
        form_set_value($element, $value, $form_state);
      }
      else {
        form_set_error($element['#name'], t('You have to specify a valid date.'));
      }
    }
  }
}

/**
 * Load requires libraries for javascript date picker support
 */
function calendar_systems_load_js_date_picker_library() {
  if (module_exists('jquery_calendar')) {

    //Use the default settings configurable by date pickers' provider drupal module
    jquery_calendar_add('picker, picker.ext, persian, islamic, thai');
  }
}

/**
 * @param $element
 * @param $date_format
 * @param null $calendar_system
 * @param null $language
 */
function calendar_systems_attach_js_date_picker(&$element, $date_format = NULL, $time_format = NULL, $calendar_system = NULL, $language = NULL) {
  if (module_exists('jquery_calendar')) {
    calendar_systems_load_js_date_picker_library();
    $alignment = 'topLeft';
    if (is_null($language)) {
      $language = _calendar_systems_languages_active();
    }
    $languages = language_list();
    if (isset($languages[$language])) {
      if ($languages[$language]->direction) {
        $alignment = 'topRight';
      }
    }
    if (is_null($calendar_system)) {
      $calendar_system = calendar_systems_get_calendar_system_name($language);
    }
    if ($calendar_system == 'default') {
      $calendar_system = 'gregorian';
    }
    $calendar_system_name_map = array(
      'arabic' => 'islamic',
      'iranian' => 'persian',
      'gregorian' => 'gregorian',
      'thai' => 'thai',
    );
    if (is_null($date_format)) {
      $date_format = 'yyyy-mm-dd';
    }
    $time = '';
    if (!empty($time_format)) {
      $time = calendar_systems_format_date(time(), 'custom', $time_format);
    }
    if (is_null($time_format)) {
      $time_format = '';
    }
    $element['#attributes']['calendar_systems_date_popup'] = 'true';
    $element['#attributes']['calendar_systems_system_name'] = $calendar_system_name_map[$calendar_system];
    $element['#attributes']['calendar_systems_language'] = $language;
    $element['#attributes']['calendar_systems_alignment'] = $alignment;
    $element['#attributes']['calendar_systems_date_format'] = calendar_system_convert_date_format_from_php_to_js($date_format);
    $element['#attributes']['calendar_systems_time_format'] = calendar_system_convert_date_format_from_php_to_js($time_format);
    $element['#attributes']['calendar_systems_time'] = $time;
    $element['#attached']['js'] = array(
      drupal_get_path('module', 'calendar_systems') . '/calendar_systems.js',
    );
  }
}

/**
 * Add javascript date picker for a field or set of fields
 */
function calendar_systems_add_js_date_picker($css_class_id_type, $calendar_system = NULL, $language = NULL) {
  calendar_systems_load_js_date_picker_library();
  static $used_ids;
  if (module_exists('jquery_calendar') && !isset($used_ids[$css_class_id_type])) {
    $alignment = 'topLeft';
    if (is_null($language)) {
      $language = _calendar_systems_languages_active();
    }
    $languages = language_list();
    if (isset($languages[$language])) {
      if ($languages[$language]->direction) {
        $alignment = 'topRight';
      }
    }
    if (is_null($calendar_system)) {
      $calendar_system = calendar_systems_get_calendar_system_name($language);
    }
    if ($calendar_system == 'default') {
      $calendar_system = 'gregorian';
    }
    $calendar_system_name_map = array(
      'arabic' => 'islamic',
      'iranian' => 'persian',
      'gregorian' => 'gregorian',
    );
    $date_format = 'yyyy-mm-dd';
    $time_format = '';
    if ($css_class_id_type == '.calendar_systems_js_date_picker_date_module') {
      $date_format = 'mm/dd/yyyy';
      $time_format = '';
    }
    if ($css_class_id_type == '.calendar_systems_js_date_picker_force_time') {
      $time_format = 'H:i:s';
    }
    $time = '';
    if (!empty($time_format)) {
      $time = calendar_systems_format_date(time(), 'custom', $time_format);
    }
    $calendar_system = $calendar_system_name_map[$calendar_system];
    $js = <<<EOT
(function(\$) {
  \$('{<span class="php-variable">$css_class_id_type</span>}').calendarsPicker({
    calendar: \$.calendars.instance('{<span class="php-variable">$calendar_system</span>}', '{<span class="php-variable">$language</span>}'),
    dateFormat: '{<span class="php-variable">$date_format</span>}',
    alignment: '{<span class="php-variable">$alignment</span>}',
    onShow: function (picker, calendar, inst) {
      if (picker) {
        picker_parts =\$(this).val().split(' ');
      }
    },
    onSelect: function (dates) {
      if (dates) {
        if (picker_parts[1]) {
          dates = dates + ' '  + picker_parts[1];
        } else if ('' != '{<span class="php-variable">$time</span>}') {
          dates = dates + ' ' + '{<span class="php-variable">$time</span>}';
        }
        if ('' != '{<span class="php-variable">$time_format</span>}') {
          if (picker_parts[2]) {
            dates = dates + ' ' + picker_parts[2];
          }
          \$(this).val(dates);
        }
      }
    }
  });
})(jQuery);
EOT;

    //alert(dates);\$('$css_class_id_type').calendarsPicker('setDate', '1350/10/10');

    //onDate: function (date) {alert(date);}

    //altField: function (date) {alert(date);}
    drupal_add_js($js, array(
      'type' => 'inline',
      'scope' => 'footer',
      'weight' => 5,
    ));
    $used_ids[$css_class_id_type] = TRUE;
  }
}

/**
 * For basic integration with views
 * @param $variables
 */
function calendar_systems_preprocess_content_field(&$variables) {

  // Are we called for the right field?
  if ($variables['field_type'] == 'date') {
    foreach ($variables['items'] as $key => $item) {
      $display = 'full';
      if ($variables['teaser']) {
        $display = 'teaser';
      }
      $type_info = date_get_format_types($variables['field']['display_settings'][$display]['format']);
      if (!$type_info) {
        $_format = $variables['field']['default_format'];
      }
      else {
        $_format = $type_info['title'];
      }
      if (!isset($variables['field']['granularity'])) {
        $granularity = FALSE;
      }
      else {
        $granularity = $variables['field']['granularity'];
      }
      if (isset($variables['items'][$key]['value2'])) {
        $format = _calendar_systems_get_format($_format, $granularity);
        $variables['items'][$key]['view'] = calendar_systems_format_date(strtotime($variables['items'][$key]['value']), 'custom', $format) . ' - ' . calendar_systems_format_date(strtotime($variables['items'][$key]['value2']), 'custom', $format);
      }
      else {
        $format = _calendar_systems_get_format($_format, $granularity);
        $variables['items'][$key]['view'] = calendar_systems_format_date(strtotime($variables['items'][$key]['value']), 'custom', $format);
      }
    }
  }
}

/**
 * hook_field_formatter_info_alter
 * @param $info
 */
function calendar_systems_field_formatter_info_alter(&$info) {

  // Add a setting to a formatter type.
  if (isset($info['date_default'])) {
    if (!isset($info['date_default']['settings']) || !is_array($info['date_default']['settings'])) {
      $info['date_default']['settings'] = array();
    }
    $info['date_default']['settings'] += array(
      'calendar_system' => '',
    );
  }
  if (isset($info['date_plain'])) {
    if (!isset($info['date_plain']['settings']) || !is_array($info['date_plain']['settings'])) {
      $info['date_plain']['settings'] = array();
    }
    $info['date_plain']['settings'] += array(
      'calendar_system' => '',
    );
  }
}

/**
 * Implements hook_date_field_formatter_settings_form
 */
function calendar_systems_date_field_formatter_settings_form_alter(&$form, &$form_state, &$context) {
  $options = _calendar_systems_profiles_simple(array(
    t('Site\'s default'),
    'same_as_field_settings' => t('Same as field settings'),
  ));
  $settings = $context['instance']['display'][$context['view_mode']]['settings'];
  $form['calendar_system'] = array(
    '#type' => 'select',
    '#title' => t('Calendar system'),
    '#default_value' => empty($settings['calendar_system']) ? '' : $settings['calendar_system'],
    '#options' => $options,
    '#description' => t('Select the calendar system you want to be used regardless of site default calendar system or field settings'),
  );
}

/**
 * Implements date_field_formatter_settings_summary
 */
function calendar_systems_date_field_formatter_settings_summary_alter(&$summary, $context) {
  $settings = $context['instance']['display'][$context['view_mode']]['settings'];
  if ($settings['calendar_system']) {
    $options = _calendar_systems_profiles_simple(array(
      t('Site\'s default'),
      'same_as_field_settings' => t('Same as field settings'),
    ));
    $summary[] = t('Selected calendar system is %s', array(
      '%s' => $options[$settings['calendar_system']],
    ));
  }
}

/**
 * Implements hook_preprocess_date_display_combination().
 * @param $variables
 */
function calendar_systems_preprocess_date_display_combination(&$variables) {
  $instance_settings = $variables['display']['settings']['calendar_system'];
  $calendar_system = calendar_systems_get_calendar_system_name();
  if (empty($instance_settings)) {
  }
  elseif ($instance_settings == 'same_as_field_settings') {
    $calendar_system = $variables['field']['settings']['calendar_system'];
  }
  else {
    $calendar_system = $instance_settings;
  }
  if ($calendar_system != 'default') {
    $format = $variables['dates']['format'];
    $date = $variables['dates']['value']['local']['datetime'];
    $variables['dates']['value']['formatted'] = _calendar_systems_fix_display($date, $format, $calendar_system);
    if (isset($variables['dates']['value2'])) {
      $date = $variables['dates']['value2']['local']['datetime'];
      $variables['dates']['value2']['formatted'] = _calendar_systems_fix_display($date, $format, $calendar_system);
    }
  }
}

/**
 * Implements hook_form_FORM_ID_alter().
 */
function calendar_systems_form_field_ui_field_edit_form_alter(&$form, &$form_state) {
  if ($form['#field']['type'] == 'datetime' || $form['#field']['type'] == 'date' || $form['#field']['type'] == 'datestamp') {
    $options = _calendar_systems_profiles_simple(array(
      t('Site\'s default'),
    ));
    $settings = $form['#field']['settings'];
    $form['field']['settings']['calendar_system'] = array(
      '#type' => 'select',
      '#title' => t('Calendar system'),
      '#default_value' => empty($settings['calendar_system']) ? '' : $settings['calendar_system'],
      '#options' => $options,
      '#description' => t('Select the calendar system you want to be used regardless of site default calendar system'),
    );
  }
}

/**
 * hook_field_info_alter
 * @param $info
 */
function calendar_systems_field_info_alter(&$info) {
  $field_type = 'datetime';
  if (isset($info[$field_type]['settings']) && $info[$field_type]['settings']) {
    $info[$field_type]['settings']['calendar_system'] = '';
  }
  $field_type = 'date';
  if (isset($info[$field_type]['settings']) && $info[$field_type]['settings']) {
    $info[$field_type]['settings']['calendar_system'] = '';
  }
  $field_type = 'datestamp';
  if (isset($info[$field_type]['settings']) && $info[$field_type]['settings']) {
    $info[$field_type]['settings']['calendar_system'] = '';
  }
}

/**
 * @param $type
 */
function calendar_systems_element_info_alter(&$type) {
  if (isset($type['date'])) {
    $type['date']['#process'] = array(
      '_calendar_systems_element_date_process',
    );
    $type['date']['#element_validate'] = array_merge(array(
      'calendar_systems_date_validate',
    ), (array) @$type['#element_validate']);
  }
  if (isset($type['date_popup'])) {
    $type['date_popup']['#element_validate'] = array_merge(array(
      'calendar_systems_date_validate',
    ), (array) @$type['#element_validate']);
  }
  if (isset($type['date_select'])) {
    $type['date_select']['#element_validate'] = array_merge(array(
      'calendar_systems_date_validate',
    ), (array) @$type['#element_validate']);
  }
  if (isset($type['date_text'])) {
    $type['date_text']['#element_validate'] = array_merge(array(
      'calendar_systems_date_validate',
    ), (array) @$type['#element_validate']);
  }
}

/**
 * Supporing date module's date_select element
 *
 * hook_date_select_process_alter
 *
 * @param $element
 * @param $form_state
 * @param $context
 */
function calendar_systems_date_select_process_alter(&$element, &$form_state, $context) {
  if (!isset($element['#calendar_system'])) {
    if (!empty($element['#field']['settings']['calendar_system'])) {
      $element['#calendar_system'] = $element['#field']['settings']['calendar_system'];
    }
    else {
      $element['#calendar_system'] = calendar_systems_get_calendar_system_name();
    }
  }
  if ($element['#calendar_system'] != 'default') {
    $calendar = calendar_systems_get_calendar_instance($element['#calendar_system']);
    $date_array = array();
    $value_path = $element['#parents'];

    //$value_path[] = 'year';
    $submitted_value = drupal_array_get_nested_value($form_state['input'], $value_path);
    $element_value = $element['#value'];
    if (@empty($element['#value']['year'])) {
      $element_value = $element['#default_value'];
    }
    else {
      $date_array = $element['#value'];
    }
    if (!empty($element_value) && empty($submitted_value)) {
      if (is_string($element_value)) {
        $date = new DateObject($element_value);
      }
      else {
        $date = date_select_input_date($element, $element_value);
      }
      if ($date) {
        $timestamp = $date
          ->format("U");
        $element['#default_value'] = $calendar
          ->smartGet(DATE_FORMAT_ISO, $timestamp);
        $date_array = $calendar
          ->timestampToInfoArray($timestamp);
        $element['#value'] = $date_array;
      }
    }
    if (isset($element['year'])) {
      if ($element['#date_year_range']) {
        if ($date_array) {
          $element['year']['#default_value'] = $date_array['year'];
        }
        list($from, $to) = explode(':', $element['#date_year_range']);
        $from = intval($from);
        $to = intval($to);
        $current_year = $calendar
          ->date('Y');
        $from_year = $current_year + $from;
        if ($element['year']['#default_value'] < $from_year && !empty($element['year']['#default_value'])) {
          $from_year = $element['year']['#default_value'];
        }
        $to_year = $current_year + $to;
        if ($element['year']['#default_value'] > $to_year && !empty($element['year']['#default_value'])) {
          $to_year = $element['year']['#default_value'];
        }
        $years = array();
        if (isset($element['year']['#options'][''])) {
          $years[''] = $element['year']['#options'][''];
        }
        foreach (range($from_year, $to_year) as $year) {
          $years[$year] = $year;
        }
        $element['year']['#options'] = $years;
      }
    }
    if (isset($element['month'])) {
      if ($date_array) {
        $element['month']['#default_value'] = $date_array['month'];
      }
      $months = array();
      if (isset($element['month']['#options'][''])) {
        $months[''] = $element['month']['#options'][''];
      }
      $_months = $calendar
        ->getOption('monthsName');
      foreach ($_months as $n => $month) {
        $months[$n] = html_entity_decode($month, ENT_QUOTES, 'UTF-8');
      }
      $element['month']['#options'] = $months;
    }
    if (isset($element['day'])) {
      if ($date_array) {
        $element['day']['#default_value'] = $date_array['day'];
      }
    }

    //$element['day']['#options'] = ;
  }
}

/**
 * Supporing date module's date_popup element
 * hook_date_popup_process_alter
 *
 * @param $element
 * @param $form_state
 * @param $context
 */
function calendar_systems_date_popup_process_alter(&$element, &$form_state, $context) {
  if (!isset($element['#calendar_system'])) {
    if (!empty($element['#field']['settings']['calendar_system'])) {
      $element['#calendar_system'] = $element['#field']['settings']['calendar_system'];
    }
    else {
      $element['#calendar_system'] = calendar_systems_get_calendar_system_name();
    }
  }
  if ($element['#calendar_system'] != 'default') {
    $calendar = calendar_systems_get_calendar_instance($element['#calendar_system']);
    $date_format = $element['#date_format'];
    $granularity = _calendar_systems_get_granularity_from_format($date_format);
    $date_value = $element['#default_value'];
    $date_value = $element['#value']['date'];
    if (isset($element['date'])) {
      $element['date']['#description'] = ' ' . t('E.g., @date', array(
        '@date' => calendar_systems_format_date(time(), 'custom', date_popup_date_format($element)),
      ));
    }
    $value_path = $element['#parents'];
    $value_path[] = 'date';
    $submitted_value = drupal_array_get_nested_value($form_state['input'], $value_path);
    if (!empty($element['#value']) && empty($submitted_value)) {
      $date = date_popup_input_date($element, $element['#value']);
      if ($date) {
        $timestamp = $date
          ->format("U");
        $element['#value']['date'] = $calendar
          ->smartGet(DATE_FORMAT_ISO, $timestamp);
        $date_format = date_part_format('date', $date_format);
        $date_value = $calendar
          ->smartGet($date_format, $timestamp);
      }
    }
    $date_granularity = _calendar_systems_get_granularity_part('date', $granularity);
    $granularity_css = 'granularity_' . implode('_', $date_granularity);
    $class_name = 'calendar_systems_js_date_picker_date_module';
    if (empty($element['date']['#attributes']['class'])) {
      $element['date']['#attributes']['class'] = array();
    }
    $date_format_considering_granularity = date_limit_format($date_format, $date_granularity);
    $element['date']['#description'] = str_replace(date($date_format_considering_granularity), $calendar
      ->smartGet($date_format_considering_granularity), $element['date']['#description']);
    $element['date']['#attributes']['class'] = array_merge(@$element['date']['#attributes']['class'], array(
      $class_name,
    ));
    $element['date']['#attributes']['class'][] = $granularity_css;
    $element['date']['#id'] = $element['#id'] . '_calendar_systems';
    if ($date_value) {
      $element['date']['#value'] = $date_value;
    }
    calendar_systems_attach_js_date_picker($element['date'], $date_format_considering_granularity);
  }
}

/**
 * Supporing date module's date_text element
 * hook_date_text_process_alter
 *
 * @param $element
 * @param $form_state
 * @param $context
 */
function calendar_systems_date_text_process_alter(&$element, &$form_state, $context) {
  if (!isset($element['#calendar_system'])) {
    if (!empty($element['#field']['settings']['calendar_system'])) {
      $element['#calendar_system'] = $element['#field']['settings']['calendar_system'];
    }
    else {
      $element['#calendar_system'] = calendar_systems_get_calendar_system_name();
    }
  }
  if ($element['#calendar_system'] != 'default') {
    $calendar = calendar_systems_get_calendar_instance($element['#calendar_system']);
    $date_format = $element['#date_format'];
    $granularity = _calendar_systems_get_granularity_from_format($date_format);
    if (isset($element['date'])) {
      $element['date']['#description'] = ' ' . t('Format: @date', array(
        '@date' => calendar_systems_format_date(time(), 'custom', $date_format),
      ));
    }
    $value_path = $element['#parents'];
    $value_path[] = 'date';
    $submitted_value = drupal_array_get_nested_value($form_state['input'], $value_path);
    if (!empty($element['#value']) && empty($submitted_value)) {
      $date = date_text_input_date($element, $element['#value']);
      if ($date) {
        $timestamp = $date
          ->format("U");
        $element['#value']['date'] = $calendar
          ->smartGet(DATE_FORMAT_ISO, $timestamp);
        $date_format = date_limit_format($date_format, $granularity);
        $date_value = $calendar
          ->smartGet($date_format, $timestamp);
      }
    }
    if (isset($date_value)) {
      $element['date']['#value'] = $date_value;
    }
  }
}

/**
 * Support drupal's core date field
 * @param $element
 * @return array
 */
function _calendar_systems_element_date_process(&$element, &$form_state) {
  $element = form_process_date($element);
  $year_range = '-100:+100';
  if (isset($element['#webform_component']) && isset($element['#webform_component']['extra']) && isset($element['#webform_component']['extra']['start_date'])) {
    $start = str_replace(' years', '', $element['#webform_component']['extra']['start_date']);
    $end = str_replace(' years', '', $element['#webform_component']['extra']['end_date']);
    $year_range = "{$start}:{$end}";
  }
  if (!isset($element['#calendar_system'])) {
    $element['#calendar_system'] = calendar_systems_get_calendar_system_name();
  }
  if ($element['#calendar_system'] != 'default') {
    $calendar = calendar_systems_get_calendar_instance($element['#calendar_system']);
    $date_array = array();
    $value_path = $element['#parents'];
    $submitted_value = drupal_array_get_nested_value($form_state['input'], $value_path);
    $element_value = $element['#value'];
    if (@empty($element['#value']['year'])) {
      $element_value = $element['#default_value'];
    }
    else {
      $date_array = $element['#value'];
    }
    if (!empty($element_value) && empty($submitted_value) && !isset($element['#webform_component'])) {
      if (is_array($element_value)) {
        $element_value = "{$element_value['year']}-{$element_value['month']}-{$element_value['day']}";
      }
      $date = new DateTime($element_value);
      if ($date) {
        $timestamp = $date
          ->format("U");
        $element['#default_value'] = $calendar
          ->smartGet("Y-m-d\\TH:i:s", $timestamp);
        $date_array = $calendar
          ->timestampToInfoArray($timestamp);
        $element['#value'] = $date_array;
      }
    }
    else {
      $date_array = $element['#value'];
    }
    if (isset($element['year'])) {
      if ($year_range) {
        if ($date_array) {
          $element['year']['#value'] = $date_array['year'];
        }
        list($from, $to) = explode(':', $year_range);
        $from = intval($from);
        $to = intval($to);
        $current_year = $calendar
          ->date('Y');
        $from_year = $current_year + $from;
        if ($element['year']['#value'] < $from_year) {
          $from_year = $element['year']['#value'];
        }
        $to_year = $current_year + $to;
        if ($element['year']['#value'] > $to_year) {
          $to_year = $element['year']['#value'];
        }
        $years = array();
        foreach (range($from_year, $to_year) as $year) {
          $years[$year] = $year;
        }
        $element['year']['#options'] = $years;
      }
    }
    if (isset($element['month'])) {
      if ($date_array) {
        $element['month']['#value'] = $date_array['month'];
      }
      $months = array();
      $_months = $calendar
        ->getOption('monthsName');
      foreach ($_months as $n => $month) {
        $months[$n] = html_entity_decode($month, ENT_QUOTES, 'UTF-8');
      }
      $element['month']['#options'] = $months;
    }
    if (isset($element['day'])) {
      if ($date_array) {
        $element['day']['#value'] = $date_array['day'];
      }
    }
  }
  return $element;
}

Functions

Namesort descending Description
calendar_systems_add_js_date_picker Add javascript date picker for a field or set of fields
calendar_systems_attach_js_date_picker
calendar_systems_date_field_formatter_settings_form_alter Implements hook_date_field_formatter_settings_form
calendar_systems_date_field_formatter_settings_summary_alter Implements date_field_formatter_settings_summary
calendar_systems_date_popup_process_alter Supporing date module's date_popup element hook_date_popup_process_alter
calendar_systems_date_select_process_alter Supporing date module's date_select element
calendar_systems_date_text_process_alter Supporing date module's date_text element hook_date_text_process_alter
calendar_systems_date_validate Element validation callback for date fields.
calendar_systems_element_info_alter
calendar_systems_field_formatter_info_alter hook_field_formatter_info_alter
calendar_systems_field_info_alter hook_field_info_alter
calendar_systems_format_date Simulating core format_date in case the patch wasn't applied Formats a date, using a date type or a custom date format string.
calendar_systems_format_date_alter Implementation of format_date_alter hook/call Altering out of format_date function
calendar_systems_form_alter Implements hook_form_alter().
calendar_systems_form_field_ui_field_edit_form_alter Implements hook_form_FORM_ID_alter().
calendar_systems_help Implements hook_help().
calendar_systems_load_js_date_picker_library Load requires libraries for javascript date picker support
calendar_systems_menu Implements hook_menu().
calendar_systems_module_implements_alter hook_module_implements_alter
calendar_systems_patch Implementation of hook_patch() of patch_manager module
calendar_systems_permission Implements hook_perm().
calendar_systems_preprocess_comment The usage is to improve compatibility when the core patch is not available Implements hook_preprocess_comment().
calendar_systems_preprocess_content_field For basic integration with views
calendar_systems_preprocess_date_display_combination Implements hook_preprocess_date_display_combination().
calendar_systems_preprocess_node The usage is to improve compatibility when the core patch is not available Implements hook_preprocess_node().
calendar_systems_theme Implements hook_theme().
_calendar_systems_element_date_process Support drupal's core date field
_calendar_systems_views_exposed_form_validate @todo supporting month and day only filters and contextual filters