You are here

datex.module in Datex 7.2

Same filename and directory in other branches
  1. 8 datex.module
  2. 7.3 datex.module
  3. 7 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.
 */

// Modes which datex can operate in, Patching core and get full functionality
// (discouraged) or use altering of dates in theming layer. This does not
// affect date module.
define('DATEX_PATCHING_MODE', 1);

// Theming should have been non-patching, since there are form alters too.
define('DATEX_NONPATCHING_MODE', 2);

// For date module.
require_once 'datex_date.inc';

// ________________________________________________________________________ UI.

/**
 * 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,
    'file' => 'datex.admin.inc',
  );
  $items['admin/config/regional/date-time/datex/edit/%'] = array(
    'title' => 'Datex edit schema',
    'page callback' => 'drupal_get_form',
    'page arguments' => array(
      'datex_schema_edit_form',
      6,
    ),
    'access arguments' => array(
      'administer site configuration',
    ),
    'type' => MENU_CALLBACK,
    'file' => 'datex.admin.inc',
  );
  return $items;
}

// ______________________________________________________________________ MAIN.
// ____________________________ HELPERS.

/**
 * Factory of datex object with some default values.
 */
function _datex_factory_with_defaults($locale = NULL, $mode = NULL) {
  if (!($calendar = _datex_language_calendar($locale, $mode))) {
    return FALSE;
  }
  $tz = drupal_get_user_timezone();
  $intl = _datex_cfg('useintl');
  return datex_factory($calendar, NULL, $tz, '', $intl);
}

/**
 * Factory of datex object.
 */
function _datex_factory($datetime = NULL, $format = NULL, $mode = NULL, $locale = NULL) {
  if (!($calendar = _datex_language_calendar($locale, $mode))) {
    return FALSE;
  }
  $tz = drupal_get_user_timezone();
  $intl = _datex_cfg('useintl');
  return datex_factory($calendar, $datetime, $tz, $format, $intl);
}

/**
 * Default value of various datex config.
 */
function _datex_default_cfg($name) {
  switch ($name) {
    case 'useintl':
      return 0;
      break;
    case 'mode':
      return DATEX_NONPATCHING_MODE;
      break;
    case 'datex_jquery':
      return 0;
      break;
    case 'comment_fmt':
    case 'node_fmt':
      return variable_get('date_format_medium');
      break;
    default:
      throw new Exception('Datex uknown cfg' . $name);
      break;
  }
}

/**
 * Helper function to get datex configuration.
 */
function _datex_cfg($name) {
  $cfg = variable_get('datex_config', array());
  if (!isset($cfg[$name])) {
    $cfg[$name] = _datex_default_cfg($name);
    variable_set('datex_config', $cfg);
  }
  return $cfg[$name];
}

/**
 * Get calendar for a/current language in a mode (if given) from schema.
 */
function _datex_language_calendar($locale = NULL, $mode = NULL, $schema = 'default') {
  if ($mode) {
    if ($mode != _datex_cfg('mode')) {
      return FALSE;
    }
  }
  if (!$locale) {
    $locale = $GLOBALS['language']->language;
  }
  $cfg = variable_get('datex_schema', array());
  if (!isset($cfg[$schema][$locale])) {
    return FALSE;
  }
  return $cfg[$schema][$locale];
}

/**
 * List of available datex schemas
 */
function _datex_schema_list() {
  $cfg = variable_get('datex_schema', array());
  return empty($cfg) ? array(
    'default',
  ) : array_keys($cfg);
}

// ___________________________ HANDLERS.

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

/**
 * 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) {
  $calendar = _datex_language_calendar($context['langcode'], DATEX_PATCHING_MODE);
  if (!$calendar) {
    return;
  }
  $data = datex_format($calendar, $context['timestamp'], $context['format'], $context['timezone']);
}

/**
 * Implements hook_preprocess_node().
 *
 * Localizes 'published on' date in non-patching mode.
 */
function datex_preprocess_node(&$variables) {
  $fmt = _datex_cfg('node_fmt');
  if (!($calendar = _datex_factory($variables['created'], $fmt, DATEX_NONPATCHING_MODE))) {
    return;
  }
  $variables['date'] = $calendar
    ->format();
  if (isset($variables['display_submitted'])) {
    $variables['submitted'] = t('Submitted by !username on !datetime', array(
      '!username' => $variables['name'],
      '!datetime' => $variables['date'],
    ));
  }
}

/**
 * Implements hook_preprocess_comment().
 *
 * Localizes 'published on' date in non-patching mode.
 */
function datex_preprocess_comment(&$variables) {
  $calendar = $variables['elements']['#comment']->created;
  $cfg = _datex_cfg('comment_fmt');
  if (!($calendar = _datex_factory($calendar, $cfg, DATEX_NONPATCHING_MODE))) {
    return;
  }

  // Timestamp set while calling factory.
  $variables['changed'] = $calendar
    ->format();
  $calendar
    ->setTimestamp($variables['elements']['#comment']->created);
  $variables['created'] = $calendar
    ->format();
  $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) {
  $calendar = _datex_factory_with_defaults();

  // Make sure this is a node edit form and date element is present.
  if (!$calendar || !isset($form['#node_edit_form'])) {
    return;
  }
  $calendar
    ->setFormat('o-m-d H:i:s O');
  $now = $calendar
    ->format();
  $validator = array(
    '_datex_node_edit_form_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;
  }
  $nonpatching_mode = _datex_cfg('mode') == DATEX_NONPATCHING_MODE;
  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 ($nonpatching_mode) {
        if (isset($form['#node']->scheduler[$name]) && !empty($form['scheduler_settings'][$name]['#default_value'])) {
          $calendar
            ->setTimestamp($form['#node']->scheduler[$name]);
          $form['scheduler_settings'][$name]['#default_value'] = $calendar
            ->format('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 ($nonpatching_mode && !empty($form['author']['date']['#default_value'])) {
    $calendar
      ->setTimestamp($form['created']['#value']);
    $form['author']['date']['#default_value'] = $calendar
      ->format('Y-m-d H:i:s O');
  }
}

/**
 * Element validation callback for date fields.
 */
function _datex_node_edit_form_date_validate($element, &$form_state, $form) {
  if (empty($element['#value'])) {
    return;
  }
  if (!($calendar = _datex_factory_with_defaults())) {
    form_set_error($element['#name'], t('Invalid site language.'));
  }
  $element['#value'] = $calendar
    ->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);
  if ($ok && count($m) == 8) {
    $date = array(
      'hour' => $m[5],
      'minute' => $m[6],
      'second' => $m[7],
      'year' => $m[1],
      'month' => $m[2],
      'day' => $m[3],
    );
    $calendar
      ->setDatetime($date);
    $calendar
      ->setFormat('Y-m-d H:i:s O');
    $element['#value'] = $calendar
      ->xformat();
    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_datex_format_alter Implements hook_datex_format_alter().
datex_form_alter Implements hook_form_alter().
datex_menu Implements hook_menu().
datex_preprocess_comment Implements hook_preprocess_comment().
datex_preprocess_node Implements hook_preprocess_node().
datex_views_api Implementation of hook_views_api().
_datex_cfg Helper function to get datex configuration.
_datex_default_cfg Default value of various datex config.
_datex_factory Factory of datex object.
_datex_factory_with_defaults Factory of datex object with some default values.
_datex_language_calendar Get calendar for a/current language in a mode (if given) from schema.
_datex_node_edit_form_date_validate Element validation callback for date fields.
_datex_schema_list List of available datex schemas

Constants