[ Index ]

PHP Cross Reference of Drupal 6 (yi-drupal)

title

Body

[close]

/sites/all/modules/calendar/ -> calendar.module (source)

   1  <?php
   2  // $Id: calendar.module,v 1.121.2.43 2010/12/31 16:25:43 karens Exp $
   3  define('CALENDAR_SHOW_ALL', 0);
   4  define('CALENDAR_HIDE_ALL', -1);
   5  
   6  /**
   7   * Implementation of hook_views_api().
   8   *
   9   * This one is used as the base to reduce errors when updating.
  10   */
  11  function calendar_views_api() {
  12    return array(
  13      'api' => 2,
  14      'path' => drupal_get_path('module', 'calendar') .'/includes',
  15    );
  16  }
  17  
  18  /**
  19   * @file
  20   * Adds calendar filtering and displays to Views.
  21   */
  22  /**
  23   * Implementation of hook_help().
  24   */
  25  function calendar_help($section, $arg) {
  26    switch ($section) {
  27      case 'admin/help#calendar':
  28        return t("<p>View complete documentation at !link.</p>", array('!link' => 'http://drupal.org/node/120710'));
  29    }
  30  }
  31  
  32  function calendar_init() {
  33    // If the multiday module is enabled, let it control the css.
  34    if (module_exists('calendar_multiday') || substr($_GET['q'], 0, 24) == 'admin/build/modules/list') {
  35      return;
  36    }
  37    // The css for Farbtastic color picker, painless to add it here 
  38    // even though it isn't needed everywhere.
  39    drupal_add_css('misc/farbtastic/farbtastic.css');
  40    drupal_add_css(drupal_get_path('module', 'calendar') .'/calendar.css');
  41    require_once('./'. drupal_get_path('module', 'calendar') .'/theme/theme.inc');
  42  }
  43  
  44  function calendar_theme() {
  45    if (module_exists('calendar_multiday')) {
  46      return array();
  47    }
  48    $path = drupal_get_path('module', 'calendar');
  49    $base = array(
  50      'file' => 'theme.inc',
  51      'path' => "$path/theme",
  52    );
  53    return array(
  54      'calendar_day_node' => $base + array(
  55         'template' => 'calendar-day-node',
  56         'arguments' => array('node' => NULL, 'view' => NULL),
  57         ),
  58      'calendar_month_node' => $base + array(
  59        'template' => 'calendar-month-node',
  60        'arguments' => array('node' => NULL, 'view' => NULL),
  61        ),
  62      'calendar_week_node' => $base + array(
  63        'template' => 'calendar-week-node',
  64        'arguments' => array('node' => NULL, 'view' => NULL),
  65        ),
  66      'calendar_month_multiple_node' => $base + array(
  67        'template' => 'calendar-month-multiple-node',
  68        'arguments' => array('curday' => NULL, 'count' => NULL, 'view' => NULL, 'types' => NULL),
  69        ),
  70      'calendar_week_multiple_node' => $base + array(
  71        'template' => 'calendar-week-multiple-node',
  72        'arguments' => array('curday' => NULL, 'count' => NULL, 'view' => NULL, 'types' => NULL),
  73        ),
  74      'calendar_datebox' => $base + array(
  75        'template' => 'calendar-datebox',
  76        'arguments' => array(
  77          'date' => NULL, 'view' => NULL, 'items' => NULL, 'selected' => NULL),
  78        ),
  79      'calendar_date_combo' => $base + array(
  80        'arguments' => array('node', 'lable', 'view'),
  81        ),
  82      'calendar_empty_day' => $base + array(
  83        'arguments' => array('curday', 'view'),
  84        ),
  85      'calendar_stripe_legend' => $base + array(
  86        'arguments' => array('stripe_labels'),
  87        ),
  88      'calendar_stripe_stripe' => $base + array(
  89        'arguments' => array('node'),
  90        ),
  91      'calendar_colorpicker' => $base + array(
  92        'arguments' => array('element'),
  93        ),
  94      'calendar_colorfield' => $base + array(
  95        'arguments' => array('element'),
  96        ),
  97      'calendar_time_row_heading' => $base + array(
  98        'arguments' => array('start_time', 'next_start_time', 'curday_date'),
  99        ),
 100    );
 101  }
 102  
 103  /**
 104   *  TODO need to identify type of timezone handling needed for each date field
 105   */
 106  function calendar_offset($field_name) {
 107    $default_offset = variable_get('date_default_timezone', 0);
 108    $configurable_zones = variable_get('configurable_timezones', 1);
 109  }
 110  
 111  /**
 112   *  A function to test the validity of various date parts
 113   */
 114  function calendar_part_is_valid($value, $type) {
 115    if ( !preg_match('/^[0-9]*$/', $value) ) {
 116      return false;
 117    }
 118    $value = intval($value);
 119    if ($value <= 0) return false;
 120    switch ($type) {
 121      case 'year':
 122        if ($value < DATE_MIN_YEAR) return false;
 123        break;
 124      case 'month':
 125        if ($value < 0 || $value > 12) return false;
 126        break;
 127      case 'day':
 128        if ($value < 0 || $value > 31) return false;
 129        break;
 130      case 'week':
 131        if ($value < 0 || $value > 53) return false;
 132    }
 133    return true;
 134  }
 135  
 136  /**
 137   *  implementation of hook_block()
 138   */
 139  function calendar_block($op = 'list', $delta = 0) {
 140    switch ($op) {
 141      case 'list' :
 142        $blocks[0]['info'] = t('Calendar Legend.');
 143        return $blocks;
 144        break;
 145      case 'view' :
 146        switch ($delta) {
 147        case 0:
 148          $block['subject'] = t('Calendar Legend');
 149          $content = theme('calendar_stripe_legend');
 150          $block['content'] = !empty($content) ? '<div class="calendar legend">'. $content .'</div>' : '';
 151          return $block;
 152      }
 153    }
 154  }
 155  
 156  /**
 157   * Calendar display types
 158   */
 159  function calendar_display_types() {
 160    return array('year' => t('Year'), 'month' => t('Month'), 'day' => t('Day'), 'week' => t('Week'));  
 161  }
 162  
 163  /**
 164   * Figure out which type of display to use, 
 165   * based on the current argument.
 166   *
 167   * @return year, month, day, or week.
 168   */
 169  function calendar_current_type($view) {
 170    if (!is_object($view) || !isset($view->argument) || !is_array($view->argument)) {
 171      if (!empty($view->date_info->default_display)) {
 172        return $view->date_info->default_display;
 173      }
 174      return FALSE;
 175    }
 176    $i = 0;
 177    $date_handler = new date_sql_handler();
 178    foreach ($view->argument as $argument) {
 179      if ($argument['id'] == 'date_argument') {
 180        $parts = array_keys($date_handler->arg_parts($view->args[$i]));
 181        break;
 182      }
 183      $i++;
 184    }
 185    return array_pop($parts);
 186  }
 187  
 188  /**
 189   * Create a stripe.
 190   *
 191   * @param $node - the node object
 192   * @param $query_name - the views queryname for this date field
 193   * @param $delta - the delta for this field, used to distinguish fields that appear more than once in the calendar
 194   * @param $stripe - the hex code for this stripe.
 195   * @param $label - the label to give this stripe.
 196   * 
 197   * TODO Reconsider use of $GLOBALS as a method of triggering the legend, there
 198   * may be a better way.
 199   */
 200  function calendar_node_stripe($view, &$node, $query_name, $delta, $stripe = NULL, $label = '') {
 201    $colors = isset($view->date_info->calendar_colors) ? $view->date_info->calendar_colors : array();
 202    if (empty($colors)) {
 203      return;
 204    }
 205  
 206    $type_names = node_get_types('names');
 207    $type = $node->raw->node_type;
 208    if(!(isset($node->stripe))){
 209      $node->stripe = array();
 210      $node->stripe_label = array();
 211    }  
 212    if (!$label && array_key_exists($type, $type_names)) {
 213      $label = $type_names[$type];
 214    }
 215    if (!$stripe) {
 216      if (array_key_exists($type, $colors)) {
 217        $stripe = $colors[$type];
 218      }
 219      else {
 220        $stripe = '';
 221      }
 222    }
 223  
 224    $node->stripe[] = $stripe;
 225    $node->stripe_label[] = $label;
 226    $GLOBALS['calendar_stripe_labels'][][$type] = array('stripe' => $stripe, 'label' => $label);
 227    return $stripe;
 228  }
 229  
 230   /**
 231   * Create a stripe based on a taxonomy term.
 232   *
 233   * @param $node - the node object
 234   * @param $query_name - the views queryname for this date field
 235   * @param $delta - the delta for this field, used to distinguish fields that appear more than once in the calendar
 236   * @param $stripe - the hex code for this stripe.
 237   * @param $label - the label to give this stripe.
 238   * 
 239   * TODO Reconsider use of $GLOBALS as a method of triggering the legend, there
 240   * may be a better way.
 241   */
 242  
 243  function calendar_node_taxonomy_stripe($view, &$node, $query_name, $delta, $stripe = NULL, $label = '') {
 244    $colors_taxonomy = isset($view->date_info->calendar_colors_taxonomy) ? $view->date_info->calendar_colors_taxonomy : array();
 245    if (empty($colors_taxonomy)) {
 246      return;
 247    }
 248    
 249    // Rename the vid added by Views to the normal name that 
 250    // taxonomy will expect, it's in the raw results.
 251    $node->vid = $node->raw->node_vid;
 252    $terms_for_node = taxonomy_node_get_terms($node);
 253    if(!(isset($node->stripe))){
 254      $node->stripe = array();
 255      $node->stripe_label = array();
 256    }
 257    if (count($terms_for_node)){
 258      foreach($terms_for_node as $term_for_node){
 259        if (!array_key_exists($term_for_node->tid, $colors_taxonomy)) {
 260          continue;
 261        }
 262        $stripe = $colors_taxonomy[$term_for_node->tid];
 263        $stripe_label = $term_for_node->name;
 264        $node->stripe[] = $stripe;
 265        $node->stripe_label[] = $stripe_label;
 266        $GLOBALS['calendar_stripe_labels'][][$term_for_node->tid] = array('stripe' => $stripe, 'label' => $stripe_label);
 267      }
 268    }
 269    else {
 270      $node->stripe[] = '';
 271      $node->stripe_label[] = '';
 272    } 
 273    return;
 274  }
 275  
 276  
 277  /**
 278   * Create a stripe based on group.
 279   *
 280   * @param $node - the node object
 281   * @param $query_name - the views queryname for this date field
 282   * @param $delta - the delta for this field, used to distinguish fields that appear more than once in the calendar
 283   * @param $stripe - the hex code for this stripe.
 284   * @param $label - the label to give this stripe.
 285   * 
 286   * TODO Reconsider use of $GLOBALS as a method of triggering the legend, there
 287   * may be a better way.
 288   */
 289  function calendar_node_group_stripe($view, &$node, $query_name, $delta, $stripe = NULL, $label = '') {
 290    $colors_group = isset($view->date_info->calendar_colors_group) ? $view->date_info->calendar_colors_group : array();
 291    if (empty($colors_group)) {
 292      return;
 293    }
 294    if (!function_exists('og_get_node_groups')) {
 295      return;
 296    }
 297  
 298    $groups_for_node = og_get_node_groups($node);
 299    if(!(isset($node->stripe))){
 300      $node->stripe = array();
 301      $node->stripe_label = array();
 302    }
 303    if (count($groups_for_node)){
 304      foreach($groups_for_node as $gid => $group_name){
 305        if (!array_key_exists($gid, $colors_group)) {
 306          continue;
 307        }
 308        $stripe = $colors_group[$gid];
 309        $stripe_label = $group_name;
 310        $node->stripe[] = $stripe;
 311        $node->stripe_label[] = $stripe_label;
 312        $GLOBALS['calendar_stripe_labels'][][$gid] = array('stripe' => $stripe, 'label' => $stripe_label);
 313      }
 314    }
 315    else {
 316      $node->stripe[] = '';
 317      $node->stripe_label[] = '';
 318    } 
 319    return $stripe;
 320  }
 321  
 322  
 323  /**
 324   * Helper function to figure out a group gid to use in blocks.
 325   *
 326   * @return an array of group nodes that are relevant.
 327   * @todo this may need more work.
 328   */
 329  function calendar_og_groups($view) {
 330    if (!$groupnode = og_get_group_context()) {
 331      global $user;
 332      $groupnodes = array_keys($user->og_groups);
 333    }
 334    else {
 335      $groupnodes = array($groupnode->nid);
 336    }
 337    return $groupnodes;
 338  }
 339  
 340  /**
 341   * A selector to jump to a new date in the calendar.
 342   *
 343   * @param unknown_type $view
 344   * @return unknown
 345   */
 346  function calendar_date_select($view) {
 347    return '<div class="calendar-date-select">'. drupal_get_form('calendar_date_select_form', $view) .'</div>';
 348  }
 349  
 350  /**
 351   * The date selector form.
 352   *
 353   * @param object $view
 354   * @return the form element
 355   *
 356   * @TODO is the title desired here or does it take up too much space??
 357   */
 358  function calendar_date_select_form(&$form_state, $view) {
 359    $format = date_limit_format(variable_get('date_format_short', 'm/d/Y - H:i'), array('year', 'month', 'day'));
 360    $form['calendar_goto'] = array(
 361      //'#title' => t('Calendar date'),
 362      '#type' => module_exists('date_popup') ? 'date_popup' : 'date_select',
 363      '#default_value' => date_format($view->date_info->min_date, 'Y-m-d'),
 364      '#date_timezone' => date_default_timezone_name(),
 365      '#date_format' => $format,
 366      );
 367    $form['calendar_type'] = array(
 368      '#type' => 'hidden',
 369      '#value' => $view->date_info->calendar_type,
 370      );
 371    $form['view_name'] = array(
 372      '#type' => 'hidden',
 373      '#value' => $view->name,
 374      );
 375    $form['view_url'] = array(
 376      '#type' => 'hidden',
 377      '#value' => $view->get_url(),
 378      );
 379    $pos = calendar_arg_position($view);  
 380    $form['calendar_previous_arg'] = array(
 381      '#type' => 'hidden',
 382      '#value' => $view->args[$pos],
 383      );
 384    $form['submit'] = array(
 385      '#type' => 'submit',
 386      '#value' => t('Change date'),
 387      );
 388    return $form;
 389  }
 390  
 391  function calendar_arg_position($view) {
 392    $pos = 0;
 393    foreach ($view->argument as $argument) {
 394      if ($argument->definition['handler'] == 'date_api_argument_handler') {
 395        return $pos;
 396      }
 397      $pos++;
 398    }
 399  }
 400  /**
 401   * Get the url for a calendar node.
 402   * 
 403   * @param $node - a calendar node object
 404   * @param $default - a default url to use when nothing specific is provided.
 405   */
 406  function calendar_get_node_link($node, $default = NULL) {
 407    if (isset($node->url)) {
 408      return url($node->url, array('absolute' => TRUE));
 409    }
 410    elseif (empty($node->remote) && is_numeric($node->nid)) {
 411      return url("node/$node->nid", array('absolute' => TRUE));
 412    }
 413    elseif (!empty($default)) {
 414      return url($default, array('absolute' => TRUE));
 415    }
 416  }
 417  
 418  function calendar_groupby_times($type = '') {
 419    $times = array();
 420    switch ($type) {
 421      case 'hour':
 422        for ($i = 0; $i <= 23; $i++) {
 423          $times[] = date_pad($i) .':00:00';
 424        }
 425        break;
 426      case 'half':
 427        for ($i = 0; $i <= 23; $i++) {
 428          $times[] = date_pad($i) .':00:00';
 429          $times[] = date_pad($i) .':30:00';
 430        }
 431        break;
 432      default:
 433        break;
 434    }
 435    return $times;
 436  }
 437  
 438  /**
 439   * Define some error messages.
 440   */
 441  function calendar_errors($error) {
 442    switch ($error) {
 443      case 'missing_argument_default':
 444        return t("The Date argument in this view must be set up to provide a default value set to the current date. Edit the argument, find 'Action to take if argument is not present.', choose 'Provide default argument', then select 'Current date'.");
 445    }
 446  }
 447  /**
 448   * Implementation of hook_elements.
 449   * 
 450   * Much of the colorpicker code was adapted from the Colorpicker module.
 451   * That module has no stable release yet nor any D6 branch.
 452   * 
 453   * TODO Consider dropping the duplicate code and adding a dependency
 454   * when that module is more stable, if calendar module customizations will 
 455   * work in it.
 456   */
 457  function calendar_elements() {
 458    // the Farbtastic colorpicker
 459    $type['calendar_colorpicker'] = array(
 460      '#attributes' => array('class' => 'calendar_colorpicker'), 
 461      '#input' => TRUE,
 462    );
 463    
 464    // a textfield to associate with the Farbtastic colorpicker
 465    $type['calendar_colorfield'] = array(
 466      '#attributes' => array('class' => 'calendar_colorfield'), 
 467        '#input' => TRUE,
 468        '#validate' => array('calendar_validate_hex_color' => array())
 469    );
 470    return $type;
 471  }
 472  
 473  /**
 474   *  Check to make sure the user has entered a valid 6 digit hex color.
 475   */
 476  function calendar_validate_hex_color($element) {
 477    if (!$element['#required'] && empty($element['#value'])) {
 478      return;
 479    }
 480    if (!preg_match('/^#(?:(?:[a-f\d]{3}){1,2})$/i', $element['#value'])) {
 481      form_error($element, "'". check_plain($element['#value']) ."'". t(' is not a valid hex color'));
 482    }
 483    else {
 484      form_set_value($element, $element['#value']);
 485    }
 486  }
 487  
 488  /**
 489   * Format calendar_colorpicker.
 490   */
 491  function theme_calendar_colorpicker($element) {
 492  
 493    $output = '';
 494    $output .= '<div id="'. $element['#id'] .'" '. drupal_attributes($element['#attributes']) .' ></div>';
 495    return theme('form_element', $element, $output);
 496  }
 497  
 498  /**
 499   * Format calendar_color textfield.
 500   */
 501  function theme_calendar_colorfield($element) {
 502    $size = isset($element['#size']) ? ' size="' . $element['#size'] . '"' : '';
 503    $maxlength = isset($element['#maxlength']) ?  'maxlength="'.$element['#maxlength'] .'"' : '';
 504    $output = '';
 505    if (isset($element['#calendar_colorpicker'])) {
 506      $element['#attributes']['class'] .= ' edit-'. str_replace("_", "-", $element['#calendar_colorpicker']);
 507    }
 508    $output .= '<input type="text" name="'. $element['#name'] .'" id="'. $element['#id'] .'" '. $maxlength . $size .' value="'. check_plain($element['#value']) .'"'. drupal_attributes($element['#attributes']) .' />';
 509    return theme('form_element', $element, $output);
 510  }
 511  
 512  /**
 513   * Add link to calendar to nodes.
 514   * 
 515   * Controlled by value of 'calendar_date_link' in the view.
 516   */
 517  function calendar_link($type, $object, $teaser = FALSE) {
 518    if ($type == 'node' && !$teaser) {
 519      $path = variable_get('calendar_date_link_'. $object->type, NULL);
 520      if (!empty($path)) {
 521        return array('calendar_link' => array(
 522          'title' => t('Calendar'),
 523          'href' => $path,
 524          'attributes' => array('title' => t('View the calendar.')),
 525          ));
 526      }
 527    }
 528  }
 529  
 530  /**
 531   * Callback to remove a default calendar from the system.
 532   */
 533  function calendar_remove($view_name) {
 534    // Remove any variable that creates a default view with this name.
 535    $calendar_options = variable_get('calendar_default_view_options', array());
 536    if (array_key_exists($view_name, $calendar_options)) {
 537      unset($calendar_options[$view_name]);
 538    }
 539    variable_set('calendar_default_view_options', $calendar_options);
 540    // Delete it from the database, if stored there.
 541    if ($view = views_get_view($view_name)) {
 542      $view->delete();
 543    }
 544    views_invalidate_cache();
 545  }
 546  
 547  /**
 548   * Formats the weekday information into table header format
 549   *
 550   * @ingroup event_support
 551   * @return array with weekday table header data
 552   */
 553  function calendar_week_header($view) {
 554    $len = isset($view->date_info->style_name_size) ? $view->date_info->style_name_size : (!empty($view->date_info->mini) ? 1 : 3);
 555    $with_week = !empty($view->date_info->style_with_weekno);
 556   
 557    // create week header
 558    $untranslated_days = calendar_untranslated_days();
 559    if ($len == 99) {
 560      $translated_days = date_week_days_ordered(date_week_days(TRUE));
 561    }
 562    else {
 563      $translated_days = date_week_days_ordered(date_week_days_abbr(TRUE));
 564    }
 565    if ($with_week) {
 566      $row[] = array('header' => TRUE, 'class' => "days week", 'data' => '&nbsp;');
 567    }
 568    foreach ($untranslated_days as $delta => $day) {
 569      $label = $len < 3 ? drupal_substr($translated_days[$delta], 0 , $len) : $translated_days[$delta];
 570      $row[] = array('header' => TRUE, 'class' => "days ". $day, 'data' => $label);
 571    }
 572    return $row;
 573  }
 574  /**
 575   * Array of untranslated day name abbreviations, forced to lowercase
 576   * and ordered appropriately for the site setting for the first day of week.
 577   *
 578   * The untranslated day abbreviation is used in css classes.
 579   */
 580  function calendar_untranslated_days() {
 581    $untranslated_days = date_week_days_ordered(date_week_days_untranslated());
 582    foreach ($untranslated_days as $delta => $day) {
 583      $untranslated_days[$delta] = strtolower(substr($day, 0, 3));
 584    }
 585    return $untranslated_days;
 586  }
 587  
 588  /**
 589   * Take the array of items and alter it to an array of
 590   * calendar nodes that the theme can handle.
 591   *
 592   * Iterate through each datefield in the view and each item
 593   * returned by the query, and create pseudo date nodes.
 594   *
 595   * If there is more than one date field in the node, this will create
 596   * multiple nodes, one each with the right calendar date for that
 597   * field's value. If a field value has a date range that covers more than
 598   * one day, separate nodes will be created for each day in the field's
 599   * day range, limited to the minimum and maximum dates for the view.
 600   *
 601   * When we finish, we will have a distinct node for each distinct day
 602   * and date field.
 603   */
 604  function calendar_build_nodes(&$view, &$items) {
 605    if (empty($view->date_info->min_date) || empty($view->date_info->max_date)) {
 606      return $items;
 607    }
 608    // Midnights are determined based on the same timezone as the View uses
 609    $display_timezone = date_timezone_get($view->date_info->min_date);
 610    $display_timezone_name = timezone_name_get($display_timezone);
 611   
 612    // Translate the view min and max dates to UTC values
 613    // so we can compare UTC dates to the view range.
 614    $min_utc = drupal_clone($view->date_info->min_date);
 615    date_timezone_set($min_utc, timezone_open('UTC'));
 616    $max_utc = drupal_clone($view->date_info->max_date);
 617    date_timezone_set($max_utc, timezone_open('UTC'));
 618    $min_zone_string = array(); // Will cache $min_utc-strings in various timezones
 619    $max_zone_string = array();
 620    $view->date_info->nodes_per_page = 0;
 621    $type_names = node_get_types('names');
 622    $datefields = array();
 623    $fields = date_api_fields($view->base_table);
 624    if (!empty($view->filter['date_filter'])) {
 625      $date_filter = $view->filter['date_filter'];
 626      foreach ($view->filter['date_filter']->options['date_fields'] as $name) {
 627        $datefields[] = $fields['name'][$name]['query_name'];
 628      }
 629    }
 630    if (!empty($view->argument['date_argument'])) {
 631      $date_filter = $view->argument['date_argument'];
 632      foreach ($view->argument['date_argument']->options['date_fields'] as $name) {
 633        $datefields[] = $fields['name'][$name]['query_name'];
 634      }
 635    }
 636    $view_fields = date_api_views_fetch_fields('node', 'field');
 637    $field_names = (array) array_keys($fields['name']);
 638    $nodes = array();
 639    $i = 0;
 640    foreach ($date_filter->options['date_fields'] as $name) {
 641      $field        = $fields['name'][$name];
 642      $field_type   = strstr($field['type'], 'string') ? 'string' : 'timestamp';
 643      $alias        = $field['query_name'];
 644      $field_name   = $field['field_name'];
 645      $fromto       = $field['fromto'];
 646      $tz_handling  = $field['tz_handling'];
 647      $label        = isset($view->field[$name]) ? $view->field[$name]['label'] : $field['field_name'];
 648      $tz_alias     = str_replace('.', '_', $field['timezone_field']);
 649      $db_tz        = date_get_timezone_db($field['tz_handling']);
 650      $local_tz     = date_get_timezone($field['tz_handling'], 'date');
 651      $field_name   = $field['field_name'];
 652      $rrule_field  = str_replace(array('_value2', '_value'), '_rrule', $alias);
 653             
 654      // Set a flag to tell us if individual multi-day dates need to be
 655      // split into separate nodes.
 656      $split_dates = TRUE;
 657      if (strstr($view->current_display, '_ical')) {
 658        $split_dates = FALSE;
 659      }
 660     
 661      // If there is no field for this item, just default to the site format.
 662      if (!isset($view->field[$field_name])) {
 663        $format = variable_get('date_format_short', 'm/d/Y - H:i');
 664      }
 665      else {
 666        if (strstr($field['type'], 'cck')) {
 667          $format = $view->field[$field_name]->options['format'];
 668          $cck_field_name = str_replace(array('_value2', '_value'), '', $field_name);
 669          $format = date_formatter_format($format, $cck_field_name);
 670        }
 671        else {
 672          $format = $view->field[$field_name]->options['date_format'];
 673          $cck_field_name = NULL;
 674          switch ($format) {
 675            case 'long':
 676              $format = variable_get('date_format_long',  'l, F j, Y - H:i');
 677              break;
 678            case 'medium':
 679              $format = variable_get('date_format_medium',  'D, m/d/Y - H:i');
 680              break;
 681            case 'custom':
 682              $format = $view->field[$field_name]->options['custom_date_format'];
 683              break;
 684            case 'time ago':
 685              break;
 686            default:
 687              $format = variable_get('date_format_short', 'm/d/Y - H:i');
 688              break;
 689          }
 690        }
 691      }
 692  
 693      // set the domain part of the id
 694      $domain = check_plain($_SERVER['SERVER_NAME']);
 695       
 696      // If there are multiple date fields in this calendar we may get
 697      // duplicate items from the other date fields, so add a way to
 698      // make sure each individual date field only gets added to the
 699      // calendar one time.
 700      $processed = array();
 701      $rrule_processed = array();
 702      foreach ($items as $pos => $item) {
 703        $delta = !empty($field['delta_field']) && !empty($item->{$field['delta_field']}) ? $item->{$field['delta_field']} : 0;
 704        $real_field = $field_name;
 705        if (substr($field['type'], 0, 3) == 'cck') {
 706          $real_field = str_replace(array('_value2', '_value'), '', $field_name);
 707        }
 708        
 709        $id = 'calendar.'. $item->{$view->base_field} .'.'. $real_field .'.'. $delta;
 710        
 711        // When creating iCal feeds for repeating dates we don't want all
 712        // the multiple values, send only the first value.
 713        if (strstr($view->current_display, '_ical')) {
 714          if (!isset($rrule_processed[$item->nid])) {
 715            $rrule_processed[$item->nid] = TRUE;
 716          }
 717          else {
 718            continue;
 719          }
 720        }
 721       
 722        if (!in_array($id, $processed) && !empty($item->calendar_fields->$alias)) {
 723         
 724          // Create from and to date values for each item, adjusted to
 725          // the correct timezone.
 726          $values[0] = !empty($item->calendar_fields->$fromto[0]) ? $item->calendar_fields->$fromto[0] : $item->calendar_fields->$alias;
 727          $values[1] = !empty($item->calendar_fields->$fromto[1]) ? $item->calendar_fields->$fromto[1] : $item->calendar_fields->$alias;
 728                
 729          $db_tz   = date_get_timezone_db($tz_handling, isset($item->$tz_alias) ? $item->$tz_alias : $display_timezone_name);
 730          $to_zone = date_get_timezone($tz_handling, isset($item->$tz_alias) ? $item->$tz_alias : $display_timezone_name);
 731         
 732          // Now $display_timezone determines how $item is split into
 733          // one entry per day, while $to_zone determines how date is displayed.
 734          // For now, use the date fields's timezone for the day splitting.
 735          $display_timezone_name = $to_zone;
 736          $values_display = array();
 737         
 738          // Start date
 739          $date = date_make_date($values[0], $db_tz, $field['sql_type']);
 740          if ($db_tz != $to_zone) {
 741            date_timezone_set($date, timezone_open($to_zone));
 742          }
 743          $values[0] = date_format($date, DATE_FORMAT_DATETIME);
 744             
 745          if ($display_timezone_name != $to_zone) {
 746            date_timezone_set($date, $display_timezone);
 747            $values_display[0] = date_format($date, DATE_FORMAT_DATETIME);
 748          }
 749          else {
 750            $values_display[0] = $values[0];
 751          }
 752             
 753          // End date
 754          $date = date_make_date($values[1], $db_tz, $field['sql_type']);
 755          if ($db_tz != $to_zone) {
 756            date_timezone_set($date, timezone_open($to_zone));
 757          }
 758          $values[1] = date_format($date, DATE_FORMAT_DATETIME);
 759          if ($display_timezone_name != $to_zone) {
 760            date_timezone_set($date, $display_timezone);
 761            $values_display[1] = date_format($date, DATE_FORMAT_DATETIME);
 762          }
 763          else {
 764            $values_display[1] = $values[1];
 765          }
 766                
 767          // Now $values contain start and end date of a node,
 768          // expressed as strings in the display (local) timezone.
 769          // $values_utc does the same in UTC timezone.
 770          // Get calendar min and max day (not time) as strings in the
 771          // $display_timezone. Cache in $min_zone_string and $max_zone_string,
 772          // since many items or fields typically use the samee timezone.
 773          if (!isset($min_zone_string[$display_timezone_name])) {
 774            $date = drupal_clone($view->date_info->min_date);
 775            date_timezone_set($date, $display_timezone);
 776            $min_zone_string[$display_timezone_name] = date_format($date, DATE_FORMAT_DATE);
 777            $date = drupal_clone($view->date_info->max_date);
 778            date_timezone_set($date, $display_timezone);
 779            $max_zone_string[$display_timezone_name] = date_format($date, DATE_FORMAT_DATE);
 780          }
 781         
 782          // Create a node for each date within the field's date range,
 783          // limited to the view's date range (regarding only day, not time).
 784          $now = max($min_zone_string[$display_timezone_name], substr($values_display[0], 0, 10));
 785          $to  = min($max_zone_string[$display_timezone_name], substr($values_display[1], 0, 10));
 786          $next = date_make_date($now, $display_timezone);
 787         
 788          if ($display_timezone_name != $to_zone) {
 789            // Make $start and $end (derived from $node) use the timezone $to_zone, just as $values[..] do
 790            date_timezone_set($next, timezone_open($to_zone));
 791          }
 792          if (empty($to)) {
 793            $to = $now;
 794          }
 795                   
 796          // $now and $next are midnight (in display timezone) on the first day where node will occur.
 797          // $to is midnight on the last day where node will occur.
 798          // All three were limited by the min-max date range of the view.
 799          while ($now <= $to) {
 800            $node = drupal_clone($item);
 801           
 802            // Make sure the pseudo node has the same properties a
 803            // regular node would have.
 804            if (isset($node->node_title) && !isset($node->title)) {
 805              $node->title = $node->node_title;
 806            }
 807            if (isset($node->node_type) && !isset($node->type)) {
 808              $node->type = $node->node_type;
 809            }
 810            $exceptions = array('format_interval', 'time ago');
 811            $node->label = $label;
 812            $node->format = $format;
 813            if (!in_array($node->format, $exceptions)) {
 814              if (!isset($formats[$format])) {
 815                $formats[$format] = date_limit_format($format, array('hour', 'minute', 'second'));
 816                $node->format_time = $formats[$format];
 817              }
 818            }
 819            else {
 820              $node->format_time = '';
 821            }
 822            $node->url = calendar_get_node_link($node);
 823                               
 824            //$node->$fromto[0] = $values[0];
 825            //$node->$fromto[1] = $values[1];
 826           
 827            // Flag which datefield this node is using, in case
 828            // there are multiple date fields in the view.
 829            $node->datefield = $alias;
 830            // If there are other datefields in the View, get rid
 831            // of them in this pseudo node. There should only be one
 832            // date in each calendar node.
 833            foreach ($node as $key => $val) {
 834              if ($key != $alias && in_array($key, $datefields)) {
 835                unset($node->$key);
 836                foreach ($fields['name'] as $other_fields) {
 837                  // If the unused date has other fields, unset them, too.
 838                  if ($other_fields['query_name'] == $key) {
 839                    foreach ($other_fields['related_fields'] as $related_field) {
 840                      $key2 = str_replace('.', '_', $related_field);
 841                      unset($node->$key2);
 842                    }
 843                  }
 844                }
 845              }
 846            }
 847            // If we don't deconstruct dates into individual date parts,
 848            // use date values as-is.
 849            if (!$split_dates) {
 850              $node->calendar_start = $values[0];
 851              $node->calendar_end = $values[1];
 852            }
 853            // Split dates get intersection of current day and the node
 854            // value's duration (as strings in $to_zone timezone)
 855            else {
 856             // Get start and end of current day
 857              $start = date_format($next, DATE_FORMAT_DATETIME);
 858              date_modify($next, '+1 day');
 859              date_modify($next, '-1 second');
 860              $end = date_format($next, DATE_FORMAT_DATETIME);
 861              $node->calendar_start = $values[0] < $start ? $start : $values[0];
 862              $node->calendar_end = !empty($values[1]) ? ($values[1] > $end ? $end : $values[1]) : $node->calendar_start;
 863            }
 864            $node->date_start = date_create($values[0], timezone_open($to_zone));
 865            $node->date_end = date_create(!empty($values[1]) ? $values[1] : $values[0], timezone_open($to_zone));;
 866            
 867            // Make date objects
 868            $node->calendar_start_date = date_create($node->calendar_start, timezone_open($to_zone));
 869            $node->calendar_end_date = date_create($node->calendar_end, timezone_open($to_zone));
 870            
 871            // Change string timezones into
 872            // calendar_start and calendar_end are UTC dates as formatted strings
 873            $node->calendar_start = date_format($node->calendar_start_date, DATE_FORMAT_DATETIME);
 874            $node->calendar_end = date_format($node->calendar_end_date, DATE_FORMAT_DATETIME);
 875            
 876            if (substr($real_field, 0, 9) == 'field_') {
 877              $cck_field = content_fields($cck_field_name);
 878              $granularity = $cck_field['granularity'];
 879              $increment = $cck_field['widget']['increment'];
 880            }
 881            else {
 882              $granularity = 'second';
 883              $increment = 1;
 884            }
 885            $node->calendar_all_day = date_is_all_day($node->calendar_end, $node->calendar_end, $granularity, $increment);
 886           
 887            // Flag all day values specifically set in date.
 888            $all_day_field = str_replace(array('_value2', '_value'), '_all_day', $node->datefield);
 889            if (!empty($all_day_field) && !empty($item->$all_day_field)) {
 890              $node->calendar_all_day = TRUE;
 891            }
 892           
 893            unset($node->calendar_fields);
 894            if (isset($node) && (empty($node->calendar_start))) {
 895              // if no date for the node and no date in the item
 896              // there is no way to display it on the calendar
 897              unset($node);
 898            }
 899            else {
 900              calendar_node_stripe($view, $node, $alias, $alias);
 901              calendar_node_taxonomy_stripe($view, $node, $alias, $alias);
 902              calendar_node_group_stripe($view, $node, $alias, $alias);
 903              $node->date_id = $id .'.'. $pos;
 904  
 905              $nodes[] = $node;
 906              unset($node);
 907            }
 908            $processed[] = $id;
 909            if ($split_dates) {
 910              date_modify($next, '+1 second');
 911              $now = date_format($next, DATE_FORMAT_DATE);
 912            }
 913            else {
 914              break;
 915            }
 916          }
 917        }
 918      }
 919    }
 920    return $nodes;
 921  }


Generated: Mon Jul 9 18:01:44 2012 Cross-referenced by PHPXref 0.7