calendar_systems.module in Calendar Systems 6.2
Contains Calendar Systems module hooks, helpers and API functions.
@todo
- Drush integration.
- Implement alterers.
- Add Drush make file.
- Add Watchdog loggings.
- Implement the boring hook_help().
- Add date FAPI element integration.
- Procedural and OOP API designation.
- Implement input validation for non-gregorian dates.
- All calnedar internal callbacks should be invoked via calendar_systems_call() API.
- Allow submodules to define their callbacks in their desired path, and set the path in their implementation of hook_calendar_info();
File
calendar_systems.moduleView source
<?php
/**
* @file
* Contains Calendar Systems module hooks, helpers and API functions.
*
* @todo
* - Drush integration.
* - Implement alterers.
* - Add Drush make file.
* - Add Watchdog loggings.
* - Implement the boring hook_help().
* - Add date FAPI element integration.
* - Procedural and OOP API designation.
* - Implement input validation for non-gregorian dates.
* - All calnedar internal callbacks should be invoked
* via calendar_systems_call() API.
* - Allow submodules to define their callbacks in their
* desired path, and set the path in their implementation of
* hook_calendar_info();
*/
/**
* Implements hook_perm().
*/
function calendar_systems_perm() {
return array(
// Authenticated users:
'select different calendar',
// Administerator users:
'administer calendar systems',
);
}
/**
* Implements hook_menu().
*/
function calendar_systems_menu() {
$items = array();
// Calendars listing form.
$items['admin/settings/date-time/calendars'] = array(
'title' => 'Calendars',
'description' => 'Configuration options for all available calendars.',
'page callback' => 'drupal_get_form',
'page arguments' => array(
'calendar_systems_calendars_form',
),
'access arguments' => array(
'administer calendar systems',
),
'file' => 'calendar_systems.admin.inc',
'type' => MENU_LOCAL_TASK,
'weight' => 3,
);
// A calendar configuration form.
$items['admin/settings/date-time/calendars/%'] = array(
'title callback' => 'calendar_systems_calendar_title',
'title arguments' => array(
4,
),
'page callback' => 'drupal_get_form',
'page arguments' => array(
'calendar_systems_calendar_form',
4,
),
'access arguments' => array(
'administer calendar systems',
),
'file' => 'calendar_systems.admin.inc',
'type' => MENU_CALLBACK,
);
return $items;
}
/**
* Implements hook_menu_alter().
*/
function calendar_systems_menu_alter($items) {
// Set the date/time settings page as the default local task.
$items['admin/settings/date-time/date-time'] = $items['admin/settings/date-time'];
$items['admin/settings/date-time/date-time']['type'] = MENU_DEFAULT_LOCAL_TASK;
$items['admin/settings/date-time']['type'] = MENU_NORMAL_ITEM;
}
/**
* Calendar menu title callback.
*
* @param $identifier
* Calendar identifier.
*
* @return
* Calendar menu title.
*/
function calendar_systems_calendar_title($identifier) {
return sprintf('%s Calendar', calendar_systems_calendars('name', $identifier));
}
/**
* Implements hook_patch().
*
* @see http://drupal.org/project/patchdoq
* @see http://doques.net/node/367
*/
function calendar_systems_patch() {
// Include boring patch helpers.
module_load_include('patch.inc', 'calendar_systems');
$patchdoq = array();
$patches = _calendar_systems_patches();
// Build the array as per required by patchdoq.
foreach ($patches as $identifier => $patch) {
$patchdoq[$identifier] = array(
'name' => $patch['title'],
'description' => $patch['description'],
'file' => $patch['path'] . $patch['name'],
'patch arguments' => '-p0',
);
}
return $patchdoq;
}
/**
* Implements hook_format_date().
*
* This is a temporary hook implementation which employs a procedural concept of
* Factory design pattern until we all get a better format_date() function at Drupal core.
* Till those days we need to patch the includes/common.inc file to provide
* the ability to implement hook_format_date().
*
* @param $timestamp
* Unix timestamp to be formatted.
* The proper timezone value has been added to this by format_date().
* @param $timezone
* Timezone offset in seconds.
* @param $format
* PHP date() function format string.
* @param $langcode
* Optional language code to translate to a language other than the default.
*
* @return
* The formatted date or FALSE otherwise.
*
* @see format_date()
* @see calendar_systems_patch()
* @see patch/common.inc-format_date.d6.patch
*/
function calendar_systems_format_date($timestamp, $format, $timezone = NULL, $langcode = NULL) {
// Cherrypick the best-fit calendar for current user/language
// combination and call its formatter callback, if available.
$calendar = calendar_systems_pick();
if (isset($calendar['format callback']) && function_exists($calendar['format callback'])) {
return $calendar['format callback']($timestamp, $format, $timezone, $langcode, $calendar);
}
// Unexpected failure! Falling back to format_date() itself.
return FALSE;
}
/**
* Implements hook_theme().
*/
function calendar_systems_theme() {
return array(
'calendar_systems_calendars_form' => array(
'arguments' => array(
'form' => NULL,
),
'file' => 'calendar_systems.admin.inc',
),
'calendar_systems_languages_overview_form' => array(
'arguments' => array(
'form' => NULL,
),
'file' => 'calendar_systems.admin.inc',
),
);
}
/**
* Implements hook_user().
*
* Adds user specific calendar configuration.
*/
function calendar_systems_user($op, &$edit, &$account, $category = NULL) {
if ($op == 'form' && $category == 'account' && user_access('select different calendar')) {
$form = array();
// Get all avilable calendars names.
$calendars = calendar_systems_calendars('names');
// Add a dropdown widget under timezone
// fieldset, so that she can choose her fave.
// The value of user specific calendar will be
// available in $account->calendar property.
$form['timezone']['calendar'] = array(
'#type' => 'select',
'#title' => t('Default calendar'),
'#description' => t('Selecting a different calendar will change all dates across the site.'),
'#access' => user_access('select different calendar'),
'#options' => $calendars += array(
'default' => t('Site default calendar'),
),
'#default_value' => $account->calendar ? $account->calendar : 'default',
);
// Render.
return $form;
}
}
/**
* Implements hook_form_FORM_ID_alter().
*
* Alters locale_languages_overview_form to inject calendar options.
*/
function calendar_systems_form_locale_languages_overview_form_alter(&$form, $form_state) {
// Get a list of available calendar names.
$calendars = calendar_systems_calendars('names');
// For each language add a dropdown list,
// to let the admin choose her fave calendar.
$form['calendar_systems_languages'] = array(
'#tree' => TRUE,
);
foreach (array_keys($form['enabled']['#options']) as $lang) {
$form['calendar_systems_languages'][$lang] = array(
'#type' => 'select',
'#access' => user_access('administer calendar systems'),
'#options' => $calendars += array(
'default' => t('Default Calendar'),
),
'#default_value' => variable_get('calendar_systems_' . $lang . '_calendar', 'default'),
);
}
// Overwrite the default themer callback.
$form['#theme'] = 'calendar_systems_languages_overview_form';
// And append a submission one.
$form['#submit'][] = 'calendar_systems_languages_overview_form_submit';
}
/**
* Submission callback for Locale language overview form.
*/
function calendar_systems_languages_overview_form_submit($form, &$form_state) {
// Save the choosen calendar for a specific locale in a
// "calendar_systems_{LANGUAGE}_calendar" formatted db variable.
foreach ($form_state['values']['calendar_systems_languages'] as $lang => $calendar) {
variable_set('calendar_systems_' . $lang . '_calendar', $calendar);
}
}
/**
* API function to provide a list of available calendars.
*
* @param $op
* The format of return list. Allowed values are:
* - calendar: Returns information about calendar identified by $identifier.
* - calendars: Returns a list of all available calendar informations.
* - name: Return the name of a calendar identified by $identifier.
* - names: Returns a list of all available calendar names.
* - identifiers: Returns a list of available calendar identifiers.
* @param $identifier
* A calendar identifier to filter the results.
*
* @return
* An array of calendars or a single calendar.
*
* @see _calendar_systems_build()
*/
function calendar_systems_calendars($op = 'calendars', $identifier = NULL) {
list($calendars, $names) = _calendar_systems_build();
switch ($op) {
// Return a array of identifier keyed calendars information.
case 'calendars':
return $calendars;
// Return the information about the calendar specified by $identifier.
case 'calendar':
return is_array($calendars[$identifier]) ? array_merge($calendars[$identifier], array(
'identifier' => $identifier,
)) : NULL;
// Return an array of all available calendar names.
case 'names':
return $names;
// Return the name of the calendar specified by $identifier.
case 'name':
return $names[$identifier];
// Return an array of all available calendar identifiers.
case 'identifiers':
return array_keys($calendars);
}
}
/**
* API function to get current default calendar.
*
* @return
* An array of default calendar information.
*/
function calendar_systems_default() {
// Return the system default calendar, use gregorian calendar as fallback.
return calendar_systems_calendars('calendar', variable_get('calendar_systems_default_calendar', 'gregorian'));
}
/**
* API function which selects the best-fit calendar for the environment.
*
* At the first level it checks current user calendar settings,
* and then the locale specific calendar settings. If there were no
* user/locale specific settings, the default calendar will be chosen.
*
* @return
* Calendar identifier.
*/
function calendar_systems_pick() {
global $user;
global $language;
// Calendar per user.
if (isset($user->calendar) && $user->calendar != 'default' && user_access('select different calendar')) {
return calendar_systems_calendars('calendar', $user->calendar);
}
// Calendar per language.
if ($calendar = variable_get('calendar_systems_' . $language->language . '_calendar', FALSE)) {
return $calendar == 'default' ? calendar_systems_default() : calendar_systems_calendars('calendar', $calendar);
}
// Default calendar.
return calendar_systems_default();
}
/**
* API function to call a calendar's internal routine.
*
* @param $function
* Function "alias" to call.
* @param $pick
* Whether to cherrypick the calendar or just return the
* default one in case that the $calendar is not passed.
* @param $args
* An array of arguments to be passed to $function.
* @param $calendar
* Calendar identifier to call its $function callback.
*
* @retrun
* The returned value of called calendar function or NULL on fail.
*
* @see calendar_systems_pick()
* @see calendar_systems_default()
*/
function calendar_systems_call($function, $pick = TRUE, $args = array(), $calendar = '') {
// Cherrypick the best-fit calendar if requsted so.
$calendar = empty($calendar) ? $pick ? calendar_systems_pick() : calendar_systems_default() : calendar_systems_calendars('calendar', $calendar);
// Call the calendar callback, if available.
if (isset($calendar[$function]) && function_exists($calendar[$function])) {
return call_user_func_array($calendar[$function], $args);
}
// Cry otherwise!
return NULL;
}
/**
* Helper function to build an array of defined calendars.
*
* @return
* A 2D array of available calendars info and names.
*/
function _calendar_systems_build() {
$names = $calendars = array();
$calendars_defined = module_invoke_all('calendar_info');
foreach ($calendars_defined as $identifier => $info) {
// Skip lazy modules without a format callback.
if (!isset($info['format callback']) || !function_exists($info['format callback'])) {
continue;
}
// Loadup the calendar configs.
$info['config'] = variable_get('calendar_systems_settings_' . $identifier, '');
$calendars[$identifier] = $info;
$names[$identifier] = $info['name'];
}
return array(
$calendars,
$names,
);
}
/**
* API function acting as a fallback for 3rdparty Calendar Systems modules.
*
* Modules formatter callbacks that does not define a particular
* format should pass the format to this API function, so the timestamp
* will get formatted by the default formatter.
*
* @param $timestamp
* Unix timestamp to be formatted.
* @param $format
* Date format as required by PHP date().
* @param $timezone
* Time zone offset in seconds.
*
* @return
* Formatted date based on the passed $format.
*
* @todo
* - Pass it through the format_date() once it got improved.
*/
function calendar_systems_formatter($timestamp, $format, $timezone = 0) {
$date = '';
$max = strlen($format);
for ($i = 0; $i < $max; $i++) {
$c = $format[$i];
if (strpos('AaDlM', $c) !== FALSE) {
$date .= t(gmdate($c, $timestamp), array(), $langcode);
}
elseif ($c == 'F') {
$date .= trim(t('!long-month-name ' . gmdate($c, $timestamp), array(
'!long-month-name' => '',
), $langcode));
}
elseif (strpos('BdgGhHiIjLmnsStTUwWYyz', $c) !== FALSE) {
$date .= gmdate($c, $timestamp);
}
elseif ($c == 'r') {
$date .= format_date($timestamp - $timezone, 'custom', 'D, d M Y H:i:s O', $timezone, $langcode);
}
elseif ($c == 'O') {
$date .= sprintf('%s%02d%02d', $timezone < 0 ? '-' : '+', abs($timezone / 3600), abs($timezone % 3600) / 60);
}
elseif ($c == 'Z') {
$date .= $timezone;
}
elseif ($c == '\\') {
$date .= $format[++$i];
}
else {
$date .= date($c, $timestamp);
}
}
return $date;
}
/**
* Implements hook_calendar_info().
*
* This is the calendar_gregorian.module built into the
* calendar_systems.module, So we got a default fake Gregorian calendar.
*
* @return
* An array of Gregorian calendar information.
*/
function calendar_systems_calendar_info() {
$calendar = array();
$calendar['gregorian'] = array(
'name' => t('Gregorian'),
'format callback' => 'calendar_gregorian_formatter',
'month days callback' => 'calendar_gregorian_month_days',
);
return $calendar;
}
/**
* Gregorian calendar (fake) date formatter callback.
*
* @param $timestamp
* Unix timestamp to be formatted.
* The proper timezone value has been added by the native format_date().
* @param $type
* The format to use. Can be "small", "medium" or "large" for the preconfigured
* date formats. If "custom" is specified, then $format is required as well.
* @param $format
* PHP date() function format string.
* @param $langcode
* Optional language code to translate to a language other than the default.
* @param $calendar
* A copy of calendar information.
*
* @return
* The formatted date or FALSE otherwise.
*
* @see format_date()
*/
function calendar_gregorian_formatter($timestamp, $type, $format, $langcode, $calendar) {
return FALSE;
}
/**
* Calendar month days helper. Also acts as a fallback
* for a missing calendar_module_month_days() callback.
*
* @return
* An array of ordered numbers corresponding
* to a Gregorian year monthes length of days.
*/
function calendar_gregorian_month_days() {
return array(
31,
28,
31,
30,
31,
30,
31,
31,
30,
31,
30,
31,
);
}
Functions
Name | Description |
---|---|
calendar_gregorian_formatter | Gregorian calendar (fake) date formatter callback. |
calendar_gregorian_month_days | Calendar month days helper. Also acts as a fallback for a missing calendar_module_month_days() callback. |
calendar_systems_calendars | API function to provide a list of available calendars. |
calendar_systems_calendar_info | Implements hook_calendar_info(). |
calendar_systems_calendar_title | Calendar menu title callback. |
calendar_systems_call | API function to call a calendar's internal routine. |
calendar_systems_default | API function to get current default calendar. |
calendar_systems_formatter | API function acting as a fallback for 3rdparty Calendar Systems modules. |
calendar_systems_format_date | Implements hook_format_date(). |
calendar_systems_form_locale_languages_overview_form_alter | Implements hook_form_FORM_ID_alter(). |
calendar_systems_languages_overview_form_submit | Submission callback for Locale language overview form. |
calendar_systems_menu | Implements hook_menu(). |
calendar_systems_menu_alter | Implements hook_menu_alter(). |
calendar_systems_patch | Implements hook_patch(). |
calendar_systems_perm | Implements hook_perm(). |
calendar_systems_pick | API function which selects the best-fit calendar for the environment. |
calendar_systems_theme | Implements hook_theme(). |
calendar_systems_user | Implements hook_user(). |
_calendar_systems_build | Helper function to build an array of defined calendars. |