You are here

availability_calendar.module in Availability Calendars 7.3

Same filename and directory in other branches
  1. 7.5 availability_calendar.module
  2. 7.4 availability_calendar.module

Availability Calendar module. Defines an availability calendar as a field.

Originally based on the Availability Calendars Module and the availability module. This file contains the hooks and other functions that must be present in the .module file, except for the field hooks. These can be found in availability_calendar.field.inc.

@author Erwin Derksen (http://drupal.org/user/750928)

@todo (This is just a list of features that came up while developing and using this module. This is not a roadmap nor is it complete. More todo's can be found in other places in the code.):

  • Refactor attach behavior code to prevent multiple initializations.
  • Integrate inline javascript (mostly attach code)
  • Separate edit calendar page (reasons: permissions, ease of use)
  • Add documentation using advanced help
  • Orphaned calendars: what to do with them and when (cron or another hook)
  • Changing css class of a state now looses the color style setting (store based on sid instead of css_class )
  • Integrate with API's?:
    • entity
    • search
    • rules
  • New coding standards (about documenting parama ande return types) according to [#711918]
  • Allow multiple blocks for the calendar key (each with a different set of states to show).
  • Allow to hide the name textbox (as you can hide the en/disable checkbox).
  • Allow to define colors for other states like pastdate.
  • Check set of states on saving: not all available, not all not available.
  • Implement hook_date_api_tables and hook_date_api_fields?

File

availability_calendar.module
View source
<?php

/**
 * @file
 * Availability Calendar module. Defines an availability calendar as a field.
 *
 * Originally based on the Availability Calendars Module and the availability
 * module. This file contains the hooks and other functions that must be
 * present in the .module file, except for the field hooks. These can be found
 * in availability_calendar.field.inc.
 *
 * @author Erwin Derksen (http://drupal.org/user/750928)
 *
 * @todo (This is just a list of features that came up while developing and
 * using this module. This is not a roadmap nor is it complete. More todo's can
 * be found in other places in the code.):
 * - Refactor attach behavior code to prevent multiple initializations.
 * - Integrate inline javascript (mostly attach code)
 * - Separate edit calendar page (reasons: permissions, ease of use)
 * - Add documentation using advanced help
 * - Orphaned calendars: what to do with them and when (cron or another hook)
 * - Changing css class of a state now looses the color style setting (store
 *   based on sid instead of css_class )
 * - Integrate with API's?:
 *   - entity
 *   - search
 *   - rules
 * - New coding standards (about documenting parama ande return types) according
 *   to [#711918]
 * - Allow multiple blocks for the calendar key (each with a different set of
 *   states to show).
 * - Allow to hide the name textbox (as you can hide the en/disable checkbox).
 * - Allow to define colors for other states like pastdate.
 * - Check set of states on saving: not all available, not all not available.
 * - Implement hook_date_api_tables and hook_date_api_fields?
 */

// Also defined in Availability Calendars, which can run in parallel.
if (!defined('AC_ISODATE')) {

  /**
   *
   * @const string The date formatter for the ISO 8601 format (date part only).
   */
  define('AC_ISODATE', 'Y-m-d');
}

/**
 * @const string Deanotes that a calendar field is used for a full day rental
 *   or allocation use case.
 */
define('ALLOCATION_TYPE_FULLDAY', 'day');

/**
 * @const string Deanotes that a calendar field is used for an overnight rental
 *   or allocation use case.
 */
define('ALLOCATION_TYPE_OVERNIGHT', 'night');

// Load all Field module hooks for Availability Calendar.
module_load_include('inc', 'availability_calendar', 'availability_calendar.field');

/**
 * Implements hook_views_api().
 */
function availability_calendar_views_api() {
  return array(
    'api' => '3.0-a',
  );
}

/**
 * Implements hook_init().
 * @link http://api.drupal.org/api/drupal/modules--system--system.api.php/function/hook_init/7
 *
 * Adds our css files to all pages.
 */
function availability_calendar_init() {

  // CSS is added to all pages to allow for aggregation.
  // Base css.
  drupal_add_css(drupal_get_path('module', 'availability_calendar') . '/availability_calendar.base.css', array(
    'every_page' => TRUE,
  ));

  // Generated CSS.
  $file = 'public://availability_calendar/availability_calendar.css';
  if (is_readable($file)) {
    drupal_add_css($file, array(
      'every_page' => TRUE,
    ));
  }
}

/**
 * Implements hook_permission().
 * @link http://api.drupal.org/api/drupal/modules--system--system.api.php/function/hook_permission/7
 */
function availability_calendar_permission() {
  return array(
    'administer availability calendar' => array(
      'title' => t('Administer the Availability Calendar field'),
      'description' => t('Define the site wide states that can be used by Availability Calendar fields.'),
    ),
    'style availability calendar' => array(
      'title' => t('Define styles for the Availability Calendar field'),
      'description' => t('Define a number of styles for Availability Calendar fields via the UI'),
    ),
  );
}

/**
 * Implements hook_menu().
 * @link http://api.drupal.org/api/drupal/modules--system--system.api.php/function/hook_menu/7
 */
function availability_calendar_menu() {
  $items = array();
  $items['admin/config/content/availability-calendar'] = array(
    'title' => 'Availability Calendar',
    'description' => 'Configure site-wide settings for availability calendar fields.',
    'page callback' => 'drupal_get_form',
    'page arguments' => array(
      'availability_calendar_admin_settings',
    ),
    'access arguments' => array(
      'administer availability calendar',
    ),
    'file' => 'availability_calendar.admin.inc',
    'type' => MENU_NORMAL_ITEM,
  );
  $items['admin/config/content/availability-calendar/settings'] = array(
    'title' => 'Site-wide settings',
    'type' => MENU_DEFAULT_LOCAL_TASK,
  );
  $items['admin/config/content/availability-calendar/styling'] = array(
    'title' => 'Styling',
    'description' => 'Define CSS styles for availability calendar fields.',
    'page callback' => 'drupal_get_form',
    'page arguments' => array(
      'availability_calendar_styles',
    ),
    'access arguments' => array(
      'style availability calendar',
    ),
    'file' => 'availability_calendar.styles.inc',
    'type' => MENU_LOCAL_TASK,
  );
  return $items;
}

/**
 * Implements hook_theme().
 * @link http://api.drupal.org/api/drupal/modules--system--system.api.php/function/hook_theme/7
 */
function availability_calendar_theme() {
  $file = 'availability_calendar.theme.inc';
  $theme_hook_info = array(
    'file' => $file,
    'variables' => array(
      'cid' => NULL,
      'name' => '',
      'year' => 0,
      'month' => 0,
      'mode' => 'view',
      'settings' => array(),
      'states' => array(),
    ),
  );
  return array(
    'availability_calendar' => $theme_hook_info,
    'availability_calendar_viewport' => $theme_hook_info,
    'availability_calendar_months' => $theme_hook_info,
    'availability_calendar_month' => $theme_hook_info,
    'availability_calendar_viewport_button' => array(
      'file' => $file,
      'variables' => array(
        'direction' => 'forward',
        'scroll' => 6,
      ),
    ),
    'availability_calendar_key' => array(
      'file' => $file,
      'variables' => array(
        'states_to_show' => array(),
      ),
    ),
  );
}

/**
 * Implements hook_date_format_types().
 * @link http://api.drupal.org/api/drupal/modules%21system%21system.api.php/function/hook_date_format_types/7
 */
function availability_calendar_date_format_types() {
  return array(
    'availability_calendar_date_display' => t('Availability Calendar date display'),
    'availability_calendar_date_entry' => t('Availability Calendar date entry'),
    'availability_calendar_month_caption' => t('Availability Calendar month caption'),
  );
}

/**
 * Implements hook_date_formats().
 * @link http://api.drupal.org/api/drupal/modules%21system%21system.api.php/function/hook_date_formats/7
 */
function availability_calendar_date_formats() {
  $formats = array();

  // Some defaults for date display (booking formlet).
  // @todo: locale suggestions are welcome.
  $formats[] = array(
    'type' => 'availability_calendar_date_display',
    'format' => 'l j F Y',
    'locales' => array(),
  );
  $formats[] = array(
    'type' => 'availability_calendar_date_display',
    'format' => 'l F j, Y',
    'locales' => array(
      'en-us',
    ),
  );

  // Some defaults for user entry in date fields (Views).
  // Locales mostly copied from the short format in includes/date.inc.
  $formats[] = array(
    'type' => 'availability_calendar_date_entry',
    'format' => 'Y-n-j',
    'locales' => array(),
  );
  $formats[] = array(
    'type' => 'availability_calendar_date_entry',
    'format' => 'Y/n/j',
    'locales' => array(
      'en-ca',
      'fr-ca',
      'no-no',
      'sv-se',
    ),
  );
  $formats[] = array(
    'type' => 'availability_calendar_date_entry',
    'format' => 'j-n-Y',
    'locales' => array(
      'nl-nl',
    ),
  );
  $formats[] = array(
    'type' => 'availability_calendar_date_entry',
    'format' => 'j/n/Y',
    'locales' => array(
      'en-gb',
      'en-hk',
      'en-ie',
      'el-gr',
      'es-es',
      'fr-be',
      'fr-fr',
      'fr-lu',
      'it-it',
      'nl-be',
      'pt-pt',
    ),
  );
  $formats[] = array(
    'type' => 'availability_calendar_date_entry',
    'format' => 'j.n.Y',
    'locales' => array(
      'de-ch',
      'de-de',
      'de-lu',
      'fi-fi',
      'fr-ch',
      'is-is',
      'pl-pl',
      'ro-ro',
      'ru-ru',
    ),
  );
  $formats[] = array(
    'type' => 'availability_calendar_date_entry',
    'format' => 'n/j/Y',
    'locales' => array(
      'en-us',
    ),
  );

  // A default for the month caption when theming a calendar month.
  $formats[] = array(
    'type' => 'availability_calendar_month_caption',
    'format' => 'F Y',
    'locales' => array(),
  );
  return $formats;
}

/**
* Implements hook_block_info().
* @link http://api.drupal.org/api/drupal/modules--block--block.api.php/function/hook_block_info/7
*/
function availability_calendar_block_info() {
  $blocks = array(
    'key' => array(
      'info' => t('Availability Calendar Key'),
      'cache' => DRUPAL_CACHE_GLOBAL,
    ),
  );
  return $blocks;
}

/**
* Implements hook_block_configure().
* @link http://api.drupal.org/api/drupal/modules--block--block.api.php/function/hook_block_configure/7
*/
function availability_calendar_block_configure($delta = '') {
  module_load_include('inc', 'availability_calendar', 'availability_calendar');
  $form = array();
  if ($delta == 'key') {
    $form['availability_calendar_block_states_to_show'] = array(
      '#type' => 'checkboxes',
      '#title' => t('States to show'),
      '#description' => t('Check the availability states that are to be shown in the key.') . ' ' . t('Checking no states at all will allow all states.'),
      '#default_value' => variable_get('availability_calendar_block_states_to_show', array()),
      '#options' => availability_calendar_get_states('label'),
    );
  }
  return $form;
}

/**
 * Implements hook_block_save().
 * @link http://api.drupal.org/api/drupal/modules--block--block.api.php/function/hook_block_save/7
 */
function availability_calendar_block_save($delta = '', $edit = array()) {

  // Save the settings from the configuration form.
  if ($delta == 'key') {
    variable_set('availability_calendar_block_states_to_show', $edit['availability_calendar_block_states_to_show']);
  }
}

/**
 * Implements hook_block_view().
 * @link http://api.drupal.org/api/drupal/modules--block--block.api.php/function/hook_block_view/7
 */
function availability_calendar_block_view($delta = '') {
  if ($delta == 'key') {
    $block = array(
      'subject' => t('Availability Key'),
      'content' => array(
        '#theme' => 'availability_calendar_key',
        '#states_to_show' => variable_get('availability_calendar_block_states_to_show', array()),
      ),
    );
    return $block;
  }
}

/**
 * Implements hook_js_alter().
 * @link http://api.drupal.org/api/drupal/modules--system--system.api.php/function/hook_js_alter/7
 */
function availability_calendar_js_alter(&$javascript) {
  if (function_exists('availability_calendar_handler_filter_availability_js_alter')) {

    // Alter js for Views that have a filter on availability.
    availability_calendar_handler_filter_availability_js_alter($javascript);
  }
}

/**
* Callback to sync a calendar field:
* - Calendar-id (cid) is synced.
* - Enabled is synced.
* - Order of cid's is synced.
* - Name is kept if already existing, copied otherwise.
*
* @param string $entity_type
* @param object $entity
*   The target entity.
* @param array $field
*   field_info_field() info array.
* @param array $instance
*   field_info_instance() info array.
* @param string $langcode
*   Target language code.
* @param array $items
*   The items to sync. in: source langauge items; out: target language items
* @param object $source_entity
*   The source entity.
* @param string $source_language
*   The source language code
*/
function availability_calendar_i18n_sync_availability_calendar_field($entity_type, $entity, $field, $instance, $langcode, &$items, $source_entity, $source_language) {
  $field_name = $instance['field_name'];

  // Build a copy of the existing calendars in the translation node indexed by
  // cid for easy retrieval in the copy loop below.
  $existing_items = field_get_items($entity_type, $entity, $instance['field_name'], $langcode);
  $existing_calendars = array();
  if ($existing_items !== FALSE) {
    foreach ($existing_items as $delta => $calendar) {
      $existing_calendars[$calendar['cid']] = $calendar;
    }
  }

  // Start creating the translated copy.
  $property = 'name';
  foreach ($items as $delta => &$calendar) {

    // keep name if it already exists.
    if (array_key_exists($calendar['cid'], $existing_calendars)) {
      if (!empty($existing_calendars[$calendar['cid']][$property])) {
        $calendar[$property] = $existing_calendars[$calendar['cid']][$property];
      }
    }
  }
}

Functions

Namesort descending Description
availability_calendar_block_configure Implements hook_block_configure(). @link http://api.drupal.org/api/drupal/modules--block--block.api.php/function/...
availability_calendar_block_info Implements hook_block_info(). @link http://api.drupal.org/api/drupal/modules--block--block.api.php/function/...
availability_calendar_block_save Implements hook_block_save(). @link http://api.drupal.org/api/drupal/modules--block--block.api.php/function/...
availability_calendar_block_view Implements hook_block_view(). @link http://api.drupal.org/api/drupal/modules--block--block.api.php/function/...
availability_calendar_date_formats Implements hook_date_formats(). @link http://api.drupal.org/api/drupal/modules%21system%21system.api.php/funct...
availability_calendar_date_format_types Implements hook_date_format_types(). @link http://api.drupal.org/api/drupal/modules%21system%21system.api.php/funct...
availability_calendar_i18n_sync_availability_calendar_field Callback to sync a calendar field:
availability_calendar_init Implements hook_init(). @link http://api.drupal.org/api/drupal/modules--system--system.api.php/functio...
availability_calendar_js_alter Implements hook_js_alter(). @link http://api.drupal.org/api/drupal/modules--system--system.api.php/functio...
availability_calendar_menu Implements hook_menu(). @link http://api.drupal.org/api/drupal/modules--system--system.api.php/functio...
availability_calendar_permission Implements hook_permission(). @link http://api.drupal.org/api/drupal/modules--system--system.api.php/functio...
availability_calendar_theme Implements hook_theme(). @link http://api.drupal.org/api/drupal/modules--system--system.api.php/functio...
availability_calendar_views_api Implements hook_views_api().

Constants

Namesort descending Description
ALLOCATION_TYPE_FULLDAY @const string Deanotes that a calendar field is used for a full day rental or allocation use case.
ALLOCATION_TYPE_OVERNIGHT @const string Deanotes that a calendar field is used for an overnight rental or allocation use case.