You are here

weekdays.module in Weekdays field 7

File

weekdays.module
View source
<?php

/**
 * @defgroup weekdays_const Constants to represent week days with bit numbers.
 * @{
 * Used to compound a week byte and operate on it with bit operations.
 *
 * The week byte stores which week days are working days in the calendar.
 */
const WEEKDAYS_SU = 1;

// 00000001
const WEEKDAYS_MO = 2;

// 00000010
const WEEKDAYS_TU = 4;

// 00000100
const WEEKDAYS_WE = 8;

// 00001000
const WEEKDAYS_TH = 16;

// 00010000
const WEEKDAYS_FR = 32;

// 00100000
const WEEKDAYS_SA = 64;

// 01000000

/**
 * @} End of "defgroup weekdays_const".
 */

/**
 * Returns array of iCal day codes and our byte representation.
 */
function weekdays_codes() {
  static $codes;
  if (empty($codes)) {
    foreach (array_keys(date_repeat_dow_day_options()) as $daycode) {
      $codes[$daycode] = constant('WEEKDAYS_' . $daycode);
    }
  }
  return $codes;
}

/**
 * Transform bitwise representation of selected days to an array of day codes.
 */
function weekdays_bitwise_to_array($bitwise) {
  $codes = weekdays_codes();
  $array = array();
  foreach ($codes as $daycode => $code) {
    if ($bitwise & $code) {
      $array[$daycode] = $daycode;
    }
  }
  return $array;
}

/**
 * Transforms selected days to the bitwise representation.
 */
function weekdays_array_to_bitwise($array) {
  $codes = weekdays_codes();
  $bitwise = 0;
  foreach ($array as $daycode => $selected) {
    if ($selected) {
      $bitwise = $bitwise | $codes[$daycode];
    }
  }
  return $bitwise;
}

/**
 * @defgroup weekdays_form_element Implements weekdays form element.
 * @{
 */

/**
 * Implements hook_element_info().
 */
function weekdays_element_info() {
  $types = array();
  $types['weekdays'] = array(
    '#input' => TRUE,
    '#multiple' => TRUE,
    '#process' => array(
      'weekdays_element_process',
    ),
    '#pre_render' => array(
      'form_pre_render_conditional_form_element',
    ),
    '#value_callback' => 'form_type_checkboxes_value',
  );
  return $types;
}

/**
 * Process function to expand the interval element type.
 */
function weekdays_element_process($element, &$form_state, $form) {
  static $options = FALSE;
  if (!$options) {
    $options = date_repeat_dow_day_options(TRUE);
    $options = date_repeat_dow_day_options_ordered($options);
  }
  $element['#options'] = $options;
  if (!empty($element['#ajax'])) {
    $element['#ajax'] += array(
      'trigger_as' => array(
        'name' => $element['#name'],
      ),
      'event' => 'change',
    );
  }
  if ($element['#multiple']) {
    $element['#theme_wrappers'] = array(
      'checkboxes',
    );
    $element = form_process_checkboxes($element);
  }
  else {
    $element['#theme_wrappers'] = array(
      'radios',
    );
    $element = form_process_radios($element);
  }
  return $element;
}

/**
 * @} End of "defgroup weekdays_form_element".
 */

/**
 * @defgroup weekdays_field_hooks Implements field API hooks.
 * @{
 */

/**
 * Implements hook_field_info().
 */
function weekdays_field_info() {
  return array(
    'weekdays' => array(
      'label' => t('Week days'),
      'description' => t('Select week days.'),
      'default_widget' => 'weekdays_default',
      'default_formatter' => 'weekdays_default',
      'property_type' => 'list',
    ),
  );
}

/**
 * Implements hook_field_load().
 */
function weekdays_field_load($entity_type, $entities, $field, $instances, $langcode, &$items) {
  foreach ($entities as $id => $entity) {
    foreach ($items[$id] as $delta => $item) {
      if (is_numeric($item['value'])) {
        $items[$id][$delta]['value'] = weekdays_bitwise_to_array($item['value']);
      }
    }
  }
}

/**
 * Implements hook_field_presave().
 */
function weekdays_field_presave($entity_type, $entity, $field, $instance, $langcode, &$items) {
  foreach ($items as $delta => $item) {
    if (is_array($item['value'])) {
      $items[$delta]['value'] = weekdays_array_to_bitwise($item['value']);
    }
  }
}

/**
 * Implements hook_field_is_empty().
 */
function weekdays_field_is_empty($item, $field) {
  foreach ($item['value'] as $key => $value) {
    if ($value !== 0) {
      return FALSE;
    }
  }
  return TRUE;
}

/**
 * Implements hook_field_widget_info().
 */
function weekdays_field_widget_info() {
  return array(
    'weekdays_default' => array(
      'label' => t('Weekdays'),
      'field types' => array(
        'weekdays',
      ),
    ),
  );
}

/**
 * Implements hook_field_widget_form().
 */
function weekdays_field_widget_form(&$form, &$form_state, $field, $instance, $langcode, $items, $delta, $element) {
  $element['value'] = $element + array(
    '#type' => 'weekdays',
    '#default_value' => isset($items[$delta]['value']) ? $items[$delta]['value'] : array(),
  );
  return $element;
}

/**
 * Implements of hook_field_formatter_info().
 */
function weekdays_field_formatter_info() {
  return array(
    'weekdays_default' => array(
      'label' => t('Weekdays default'),
      'field types' => array(
        'weekdays',
      ),
    ),
  );
}

/**
 * Implements hook_field_formatter_view().
 */
function weekdays_field_formatter_view($entity_type, $entity, $field, $instance, $langcode, $items, $display) {
  $days = date_repeat_dow_day_options(TRUE);
  $element = array();
  foreach ($items as $delta => $item) {
    $value = array();
    foreach (array_filter($item['value']) as $daycode) {
      $value[] = $days[$daycode];
    }
    $element[$delta] = array(
      '#markup' => implode(', ', $value),
    );
  }
  return $element;
}

/**
 * @} End of "defgroup weekdays_field_hooks".
 */

/**
 * Reverse week days.
 */
function weekdays_reverse($weekdays) {
  $reversed = array();
  foreach (array_keys(date_repeat_dow_day_options()) as $daycode) {
    if (!isset($weekdays[$daycode])) {
      $reversed[$daycode] = $daycode;
    }
  }
  return $reversed;
}

/**
 * Checks if a date's week day matches the allowed weekdays.
 */
function weekdays_valid_date($date, $weekdays) {
  $dow = array_keys(date_repeat_dow_day_options(TRUE));
  $wday = $dow[date_day_of_week($date)];
  return in_array($wday, $weekdays);
}

/**
 * Computes dates corresponding to the weekdays in a given date range.
 *
 * @param DateObject $start
 * @param DateObject $end
 * @param array $weekdays array of weekdays in iCal format.
 * @param array $include dates to include, in DATE_FORMAT_DATE format.
 * @param array $exclude dates to exclude, in DATE_FORMAT_DATE format.
 * @return array array of dates in DATE_FORMAT_DATE format.
 */
function weekdays_days_in_date_range(DateObject $start, DateObject $end, array $weekdays, array $include = array(), array $exclude = array()) {

  // It may happen that week day of $start is not part of $weekdays.
  // In that case we need to increase $start until it matches a weekday.
  // This is a workaround to https://drupal.org/node/1365516
  $dow = array_keys(date_repeat_dow_day_options(TRUE));
  $wday = $dow[date_day_of_week($start)];
  while (!in_array($wday, $weekdays) && $start < $end) {
    $start
      ->modify('+1 day');
    $wday = $dow[date_day_of_week($start)];
  }
  if (!empty($weekdays)) {
    $rrule = 'RRULE:FREQ=WEEKLY;INTERVAL=1;BYDAY=' . implode(',', $weekdays) . ';';
    $dates = date_repeat_calc($rrule, (string) $start, (string) $end);
  }
  else {
    $dates = array();
  }

  // Strip hours from dates.
  foreach ($dates as $date) {
    $date = substr($date, 0, 10);
    if (!in_array($date, $exclude)) {
      $include[] = $date;
    }
  }
  return $include;
}

Functions

Namesort descending Description
weekdays_array_to_bitwise Transforms selected days to the bitwise representation.
weekdays_bitwise_to_array Transform bitwise representation of selected days to an array of day codes.
weekdays_codes Returns array of iCal day codes and our byte representation.
weekdays_days_in_date_range Computes dates corresponding to the weekdays in a given date range.
weekdays_element_info Implements hook_element_info().
weekdays_element_process Process function to expand the interval element type.
weekdays_field_formatter_info Implements of hook_field_formatter_info().
weekdays_field_formatter_view Implements hook_field_formatter_view().
weekdays_field_info Implements hook_field_info().
weekdays_field_is_empty Implements hook_field_is_empty().
weekdays_field_load Implements hook_field_load().
weekdays_field_presave Implements hook_field_presave().
weekdays_field_widget_form Implements hook_field_widget_form().
weekdays_field_widget_info Implements hook_field_widget_info().
weekdays_reverse Reverse week days.
weekdays_valid_date Checks if a date's week day matches the allowed weekdays.

Constants