You are here

datex.module in Datex 7

Same filename and directory in other branches
  1. 8 datex.module
  2. 7.3 datex.module
  3. 7.2 datex.module

Convert output of date_format() to Jalali in a patched drupal installation.

File

datex.module
View source
<?php

/**
 * @file
 * Convert output of date_format() to Jalali in a patched drupal installation.
 */
define('DATEX_PATCHING_METHOD', 'patching mode');
define('DATEX_THEMING_METHOD', 'theming mode');

// ________________________________________________________________________ UI.

/**
 * Implements hook_help().
 */
function datex_help($path, $arg) {
  if ($path == 'admin/help#datex') {
    $output = '<p>';
    $output .= t("By enabling Datex, Gregorian dates generates by drupal function %func will be converted to it's Jalali equivilant.", array(
      '%func' => 'date_format()',
    ));
    $output .= '</p><p>';
    $output .= t('Note that this module requires drupal file %file to be patched.', array(
      '%file' => 'common.inc',
    ));
    $output .= t('The patch is in Datex module directory.');
    $output .= '</p>';
    return $output;
  }
}

/**
 * Implements hook_menu().
 */
function datex_menu() {
  $items['admin/config/regional/date-time/datex'] = array(
    'title' => 'Datex',
    'page callback' => 'drupal_get_form',
    'page arguments' => array(
      'datex_admin_form',
    ),
    'access arguments' => array(
      'administer site configuration',
    ),
    'type' => MENU_LOCAL_TASK,
  );
  return $items;
}

/**
 * Provides administration form for datex module (menu callback).
 */
function datex_admin_form() {
  $options = array(
    DATEX_PATCHING_METHOD => t('Use patching of common.inc file.'),
    DATEX_THEMING_METHOD => t('Use theming layer whenever possible.'),
  );

  // Use PHP-Intl or not.
  $form['datex_integration_method'] = array(
    '#type' => 'radios',
    '#title' => t('Date integration method'),
    '#default_value' => variable_get('datex_integration_method', DATEX_THEMING_METHOD),
    '#description' => t('The method which datex uses to integrate with Drupal. Patching method needs patching a core file, But will support more modules and functionalities, Non patching method (by using theming layer) has a very limited support, It only supports Node authoring date and comment publishing date.'),
    '#options' => $options,
  );
  $options = array();
  foreach (system_get_date_types() as $type) {
    $options[variable_get('date_format_' . $type['type'])] = $type['title'];
  }
  $form['datex_node_format'] = array(
    '#type' => 'radios',
    '#title' => t('Date format for node display pages.'),
    '#default_value' => variable_get('datex_node_format', variable_get('date_format_medium')),
    '#description' => t('Date in node display page will be formatted with this format. Only applicable when selecting "Theming layer" method above.'),
    '#options' => $options,
  );
  $form['datex_comment_format'] = array(
    '#type' => 'radios',
    '#title' => t('Date format for comment display pages.'),
    '#default_value' => variable_get('datex_comment_format', variable_get('date_format_medium')),
    '#description' => t('Date in comment display will be formatted with this format. Only applicable when selecting "Theming layer" method above.'),
    '#options' => $options,
  );
  return system_settings_form($form);
}

// ______________________________________________________________________ MAIN.

/**
 * Implements hook_views_api().
 *
 * In order to get views support of node post date while using non-patching 
 * method.
 */
function datex_views_api() {
  return array(
    'api' => 3,
    'path' => drupal_get_path('module', 'datex'),
  );
}

/**
 * Helper function to determine in which mode datex should work.
 * 
 * For more info, look at the datex_admin_form() description.
 */
function _datex_integration_mode($mode) {
  return $mode === variable_get('datex_integration_method', DATEX_THEMING_METHOD);
}

/**
 * Implements hook_datex_format_alter().
 *
 * This hook is not available unless Drupal core is patched with provided
 * patch in datex module's directory. I tried to keep the patch as small
 * as possible, Just a drupal_alter for date_format function, As we all know
 * patch for core is BAD man, it's bad...
 * Benchmarks were good also, Not much performance difference after appying 
 * patch. More benchmarking needed though.
 */
function datex_datex_format_alter(&$data, $context) {
  if (_datex_skip_language($context['langcode']) || _datex_integration_mode(DATEX_THEMING_METHOD)) {
    return;
  }
  $tz = DatexFormatter::getTzObject($context['timezone']);
  $data = DatexFormatter::format($context['timestamp'], $context['format'], $tz, _datex_intl());
}

/**
 * Implements hook_preprocess_node().
 */
function datex_preprocess_node(&$variables) {
  if (_datex_skip_language() || _datex_integration_mode(DATEX_PATCHING_METHOD)) {
    return;
  }
  $format = variable_get('datex_node_format', variable_get('date_format_medium'));
  $variables['date'] = DatexFormatter::format(intval($variables['created']), $format, drupal_get_user_timezone(), _datex_intl());
  if ($variables['display_submitted']) {
    $variables['submitted'] = t('Submitted by !username on !datetime', array(
      '!username' => $variables['name'],
      '!datetime' => $variables['date'],
    ));
  }
}

/**
 * Implements hook_preprocess_comment().
 */
function datex_preprocess_comment(&$variables) {
  if (_datex_skip_language() || _datex_integration_mode(DATEX_PATCHING_METHOD)) {
    return;
  }
  $format = variable_get('datex_node_format', variable_get('date_format_medium'));
  $variables['changed'] = DatexFormatter::format($variables['elements']['#comment']->created, $format, drupal_get_user_timezone(), _datex_intl());
  $variables['created'] = DatexFormatter::format($variables['elements']['#comment']->changed, $format, drupal_get_user_timezone(), _datex_intl());
  $variables['submitted'] = t('Submitted by !username on !datetime', array(
    '!username' => $variables['author'],
    '!datetime' => $variables['created'],
  ));
}

// ____________________________________________________________ NODE EDIT FORM.

/**
 * Implements hook_form_alter().
 *
 * Looks for node editing forms and adds a Jalali calendar to author information
 * editing field in vertical tabs.
 */
function datex_form_alter(&$form, &$form_state, $form_id) {

  // Make sure this is a node edit form and date element is present.
  if (_datex_skip_language() || !isset($form['#node_edit_form'])) {
    return;
  }

  // Add a nice datepicker and an small jQuery file which attaches that
  // datepicker to node_edit_form form element.
  if (variable_get('datex_jquery', FALSE)) {
    _datex_jquery_add_libraries('jquery.datetimeentry', 'fa');
    drupal_add_js(drupal_get_path('module', 'datex') . '/datex_jquery.js');
  }
  $now = datex_format(time(), 'o-m-d H:i:s O');
  $validator = array(
    '_datex_node_edit_form_author_date_validate',
  );
  if (isset($form['author']['date'])) {
    $t_args = array(
      '%date' => $now,
    );
    $form['author']['date']['#description'] = t('Format: %date The date format is YYYY-MM-DD and time is H:i:s. Leave blank to use the time of form submission.', $t_args);
    $form['author']['date']['#element_validate'] = $validator;
  }
  $mode = _datex_integration_mode(DATEX_THEMING_METHOD);
  if (isset($form['scheduler_settings'])) {
    foreach (array(
      'publish_on',
      'unpublish_on',
    ) as $name) {
      if (isset($form['scheduler_settings'][$name])) {
        $form['scheduler_settings'][$name]['#element_validate'] = $validator;
      }
      if ($mode) {
        if (isset($form['#node']->scheduler[$name]) && !empty($form['scheduler_settings'][$name]['#default_value'])) {
          $form['scheduler_settings'][$name]['#default_value'] = datex_format($form['#node']->scheduler[$name], 'Y-m-d H:i:s O');
        }
        $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 ($mode && !empty($form['author']['date']['#default_value'])) {
    $form['author']['date']['#default_value'] = datex_format($form['created']['#value'], 'Y-m-d H:i:s O');
  }
}

/**
 * Element validation callback for date fields.
 */
function _datex_node_edit_form_author_date_validate($element, &$form_state, $form) {
  if (_datex_skip_language() || empty($element['#value'])) {
    return;
  }
  $element['#value'] = DatexFormatter::decor($element['#value'], FALSE);
  $m = array();
  $ok = preg_match('#^([0-9]{2,4})[-\\/\\\\]([0-9]{1,2})[-\\/\\\\]([0-9]{1,2})( {1,}([0-9]{1,2})\\:([0-9]{1,2})\\:([0-9]{1,2}))?#', $element['#value'], $m);

  // 1969: It's a dirty hack: If entered year is less than EPOCH limit, Then
  // probably is it Jalali otherwise it is Gregorian.
  if ($ok && count($m) == 8 && (int) $m[1] < 1969) {
    $date = array(
      'hour' => $m[5],
      'minute' => $m[6],
      'second' => $m[7],
      'year' => $m[1],
      'month' => $m[2],
      'day' => $m[3],
    );
    $date = new DatexObject($date, DATEX_JALALI, date_default_timezone_get());
    $element['#value'] = $date
      ->xformat('Y-m-d H:i:s O');
    form_set_value($element, $element['#value'], $form_state);
  }
  else {
    form_set_error($element['#name'], t('You have to specify a valid date.'));
  }
}

Functions

Namesort descending Description
datex_admin_form Provides administration form for datex module (menu callback).
datex_datex_format_alter Implements hook_datex_format_alter().
datex_form_alter Implements hook_form_alter().
datex_help Implements hook_help().
datex_menu Implements hook_menu().
datex_preprocess_comment Implements hook_preprocess_comment().
datex_preprocess_node Implements hook_preprocess_node().
datex_views_api Implements hook_views_api().
_datex_integration_mode Helper function to determine in which mode datex should work.
_datex_node_edit_form_author_date_validate Element validation callback for date fields.

Constants

Namesort descending Description
DATEX_PATCHING_METHOD @file Convert output of date_format() to Jalali in a patched drupal installation.
DATEX_THEMING_METHOD