You are here

availability_calendars.page.inc in Availability Calendars 6.2

Same filename and directory in other branches
  1. 7.2 availability_calendars.page.inc

File

availability_calendars.page.inc
View source
<?php

/**
 * @file
 * Availability Calendars: theming code.
 * - theme calendar
 * - theme 1 month of a calendar
 * - theme key to the calendar
 *
 * @author Dan Karran (geodaniel) <dan at karran dot net>
 * @author Nicholas Alipaz (nicholas.alipaz)
 * @author Erwin Derksen (http://drupal.org/user/750928)
 */
module_load_include('inc', 'availability_calendars', 'availability_calendars');

/**
 * Actual inplementation of D7 hook_node_view.
 * @param object $node
 * @param string $view_mode 'full' or 'teaser'
 */
function availability_calendars_page_node_view($node, $view_mode) {

  // if this is a translated node, use calendar of original node
  $calendar_node = $node->tnid && $node->tnid != $node->nid ? node_load($node->tnid) : $node;
  $settings = availability_calendars_get_settings('node', $calendar_node->nid);
  if ($settings->nodeview === 1 && ($view_mode == 'full' || $view_mode == 'teaser' && $settings->showteaser == 1)) {
    $year = date('Y');
    $month = date('m');

    // if this is a translated node, use calendar of original node
    $node->content['availability_calendars'] = array(
      '#value' => theme('availability_calendars_node', $calendar_node, $year, $month, $settings),
      '#weight' => 10,
    );
  }
}

/**
 * Themes the given number of months of the calendar for the given node.
 *
 * @param object $node
 * @param int $year first year to display
 * @param int $month first month to display
 * @param object $settings
 * @return string
 */
function theme_availability_calendars_node($node, $year = 2008, $month = 01, $settings = NULL) {

  // Calendar code based on example at http://evolt.org/node/60673 :
  $rows = array();
  $day = 1;
  $output = '';

  // Create our key for the availability calendar if the node has it set to do so
  if ($settings->showkey === 1) {
    $output .= theme('availability_calendars_key');
  }
  $monthsremaining = availability_calendars_can_edit($node) ? $settings->editormonthcount : $settings->monthcount;
  while ($monthsremaining > 0) {
    $output .= theme('availability_calendars_month', $node, $year, $month, $settings);
    $monthsremaining--;
    $month++;
    if ($month > 12) {
      $month = 1;
      $year++;
    }
  }
  return $output;
}

/**
 * Themes the calendar for a given month.
 *
 * @param object $node
 * @param int $year
 * @param int $month
 * @param object $settings
 * @return string
 */
function theme_availability_calendars_month($node, $year, $month, $settings) {
  $month_meta = availability_calendars_month_meta($year, $month, $settings);

  /**
   * Here we list all the days of the week, an array of 14 (two full weeks) so
   * that if users select monday as the first day we still get a full week in
   * our following loop.
   */
  $days = array(
    13 => t('Mon'),
    12 => t('Tue'),
    11 => t('Wed'),
    10 => t('Thu'),
    9 => t('Fri'),
    8 => t('Sat'),
    7 => t('Sun'),
    6 => t('Mon'),
    5 => t('Tue'),
    4 => t('Wed'),
    3 => t('Thu'),
    2 => t('Fri'),
    1 => t('Sat'),
    0 => t('Sun'),
  );
  $counter = -$month_meta['firstday'];
  for ($j = 0; $j < $month_meta['weeksinmonth']; $j++) {
    for ($i = 0; $i < 7; $i++) {
      $counter++;
      $week[$j][$i] = $counter;

      // Offset the days.
      if ($week[$j][$i] < 1 || $week[$j][$i] > $month_meta['daysinmonth']) {
        $week[$j][$i] = "";
      }
    }
  }

  // #1093408: Summer/winter time offsets: don't use midnight sharp
  $month_title = format_date(mktime(12, 0, 0, $month, 1, $year), 'custom', 'F Y');
  if (availability_calendars_can_edit($node)) {

    // add edit link to month_title.
    $month_title .= ' ' . l(t('edit'), 'availability-calendars/' . $node->nid . '/' . date('Y/m', mktime(12, 0, 0, $month, 1, $year)) . '/edit', array(
      'query' => array(
        'destination' => 'node/' . $node->nid,
      ),
    ));
  }
  $headers = array();

  // container for header row
  if ($settings->showweeknotes) {
    array_push($headers, array(
      'data' => '&nbsp;',
      'class' => 'calempty',
    ));

    // Add one empty cell for the notes column
  }

  // Add a header row showing the day of the week, we do some odd backwards looping through this...
  // Because the options in the node's form are set in a way that requires it.
  for ($i = $settings->startofweek + 7; $i > $settings->startofweek && $i <= 7 + $settings->startofweek; $i--) {
    $day = $settings->firstletter == 0 ? $days[$i] : drupal_substr($days[$i], 0, 1);
    array_push($headers, array(
      'data' => $day,
      'class' => 'dayofweek',
    ));
  }

  // Find all entries in database for this month ($availability, $notes) and pre-populate.
  $notes = availability_calendars_get_node_notes($node->nid, $year, $month);
  $states = availability_calendars_get_node_states($node->nid, $year, $month, $settings);
  $today = date(AC_ISODATE);
  $rows = array();

  // our container for rows
  $cells = array();

  // our container for cells
  foreach ($week as $key => $val) {
    $weeknumber = $key + 1;

    // Add the week note cell to the cells array.
    if ($settings->showweeknotes) {
      $note = !empty($notes[$weeknumber]) ? '<div>' . filter_xss($notes[$weeknumber]) . '</div>' : '<div class="calweeknote-empty"></div>';
      array_push($cells, array(
        'data' => $note,
        'class' => 'calweeknote',
      ));

      // Add the week note cell to the cells array
    }
    for ($i = 0; $i < 7; $i++) {
      $day = $week[$key][$i];

      // if there's a date, it's part of this month.
      if ($day) {
        $daystamp = date(AC_ISODATE, mktime(0, 0, 0, $month, $day, $year));
        $status = $states[$daystamp];
        $classes = array();
        if ($daystamp < $today) {
          $classes[] = 'calpastdate';

          // show or hide old states?
          if ($settings->hideold != 1) {
            $classes[] = $status;
          }
        }
        else {
          if ($today == $daystamp) {
            $classes[] = 'caltoday';

            // today
          }
          $classes[] = $status;
        }
        $day_cell = availability_calenders_day($day, $settings);
        $classes = implode(' ', $classes);
        array_push($cells, array(
          'data' => $day_cell,
          'class' => $classes,
        ));
      }
      else {

        // Empty day, beginning of row 1 or end of row 5/6 in a month.
        array_push($cells, array(
          'data' => '<span></span>',
          'class' => 'calother',
        ));
      }
    }
    array_push($rows, array(
      'data' => $cells,
      'class' => 'calweek',
    ));
    $cells = array();

    // clear out our $cells array before running the next week
  }
  if ($weeknumber == 5) {
    if ($settings->showweeknotes) {
      $note = '<div class="calweeknote-empty"></div>';
      array_push($cells, array(
        'data' => $note,
        'class' => 'calweeknote',
      ));

      // Add the week note cell to the cells array
    }
    for ($i = 0; $i < 7; $i++) {
      array_push($cells, array(
        'data' => '<span></span>',
        'class' => 'calother',
      ));
    }
    array_push($rows, array(
      'data' => $cells,
    ));
  }
  $output = theme('table', $headers, $rows, array(
    'class' => 'cal',
  ), $month_title);

  // Our final table
  // Wrap the table to allow for better styling
  return '<div class="calmonth-wrapper">' . $output . '</div>';
}

/**
 * Helper function that returns the html for 1 day.
 *
 * @param int $day The day number.
 * @param object $settings settings (for the current node).
 */
function availability_calenders_day($day, $settings) {
  if (!$settings->splitday) {

    // Whole day
    $result = "<span>{$day}</span>";
  }
  else {

    // Split day: the inner span will be positioned absolute and will take care of the background.
    // However, to be able to position it absolute, it needs to be within another positioned element.
    // That's why we use an outer span: td's are not and cannot be positioned.
    // Choice between span and div: span is used less often than div in Drupal, so styles that end with "... > span > span"
    // are more specific.
    $result = "<span>{$day}<span></span></span>";
  }
  return $result;
}

/**
 * Themes the key for our calendars.
 *
 * @return string
 */
function theme_availability_calendars_key() {

  // @todo: use caption instead of a non-related div tag (key-title)

  //use all the same classes for cells and table, so it styles the same as the calendars
  $keytitle = t('Key');
  $headers = array(
    t('Availability'),
  );
  $rows = array();
  $states = availability_calendars_get_states();
  foreach ($states as $class => $state) {
    $rows[] = array(
      array(
        'data' => '<span>' . check_plain(t($state['label'])) . '</span>',
        'class' => "{$class} keystatus",
      ),
    );
  }
  $rows[] = array(
    array(
      'data' => '<span>' . t('Current Day') . '</span>',
      'class' => 'caltoday keystatus',
    ),
  );
  $key = theme('table', $headers, $rows, array(
    'class' => 'cal',
  ), $keytitle);
  return '<div class="calmonth-wrapper key-wrapper">' . $key . '</div>';
}

Functions

Namesort descending Description
availability_calendars_page_node_view Actual inplementation of D7 hook_node_view.
availability_calenders_day Helper function that returns the html for 1 day.
theme_availability_calendars_key Themes the key for our calendars.
theme_availability_calendars_month Themes the calendar for a given month.
theme_availability_calendars_node Themes the given number of months of the calendar for the given node.