2, 'path' => drupal_get_path('module', 'calendar') .'/includes', ); } /** * @file * Adds calendar filtering and displays to Views. */ /** * Implementation of hook_help(). */ function calendar_help($section, $arg) { switch ($section) { case 'admin/help#calendar': return t("

View complete documentation at !link.

", array('!link' => 'http://drupal.org/node/120710')); } } function calendar_init() { drupal_add_css(drupal_get_path('module', 'calendar') .'/calendar.css'); // The css for Farbtastic color picker, painless to add it here // even though it isn't needed everywhere. drupal_add_css('misc/farbtastic/farbtastic.css'); require_once('./'. drupal_get_path('module', 'calendar') .'/theme/theme.inc'); } function calendar_theme() { $path = drupal_get_path('module', 'calendar'); require_once "./$path/theme/theme.inc"; $base = array( 'file' => 'theme.inc', 'path' => "$path/theme", ); return array( 'calendar_day_node' => $base + array( 'template' => 'calendar-day-node', 'arguments' => array('node' => NULL, 'view' => NULL), ), 'calendar_month_node' => $base + array( 'template' => 'calendar-month-node', 'arguments' => array('node' => NULL, 'view' => NULL), ), 'calendar_week_node' => $base + array( 'template' => 'calendar-week-node', 'arguments' => array('node' => NULL, 'view' => NULL), ), 'calendar_datebox' => $base + array( 'template' => 'calendar-datebox', 'arguments' => array( 'date' => NULL, 'view' => NULL, 'items' => NULL, 'selected' => NULL), ), 'calendar_title' => $base + array( 'arguments' => array('date_type' => NULL, 'view' => NULL), ), 'calendar_date_combo' => $base + array( 'arguments' => array('node', 'lable', 'view'), ), 'calendar_empty_day' => $base + array( 'arguments' => array(), ), 'calendar_stripe_legend' => $base + array( 'arguments' => array('stripe_labels'), ), 'calendar_stripe_stripe' => $base + array( 'arguments' => array('node'), ), 'calendar_colorpicker' => $base + array( 'arguments' => array('element'), ), 'calendar_colorfield' => $base + array( 'arguments' => array('element'), ), ); } /** * TODO need to identify type of timezone handling needed for each date field */ function calendar_offset($field_name) { $default_offset = variable_get('date_default_timezone', 0); $configurable_zones = variable_get('configurable_timezones', 1); } /** * A function to test the validity of various date parts */ function calendar_part_is_valid($value, $type) { if ( !preg_match('/^[0-9]*$/', $value) ) { return false; } $value = intval($value); if ($value <= 0) return false; switch ($type) { case 'year': if ($value < DATE_MIN_YEAR) return false; break; case 'month': if ($value < 0 || $value > 12) return false; break; case 'day': if ($value < 0 || $value > 31) return false; break; case 'week': if ($value < 0 || $value > 53) return false; } return true; } /** * implementation of hook_block() */ function calendar_block($op = 'list', $delta = 0) { switch ($op) { case 'list' : $blocks[0]['info'] = t('Calendar Legend.'); return $blocks; break; case 'view' : switch ($delta) { case 0: $block['subject'] = t('Calendar Legend'); $block['content'] = !empty($GLOBALS['calendar_stripe_labels']) ? '
'. theme('calendar_stripe_legend') .'
' : ''; return $block; } } } /** * Calendar display types */ function calendar_display_types() { return array('year' => t('Year'), 'month' => t('Month'), 'day' => t('Day'), 'week' => t('Week')); } /** * Figure out which type of display to use, * based on the current argument. * * @return year, month, day, or week. */ function calendar_current_type($view) { if (!is_object($view) || !isset($view->argument) || !is_array($view->argument)) { if (!empty($view->default_display)) { return $view->default_display; } return FALSE; } $i = 0; $date_handler = new date_sql_handler(); foreach ($view->argument as $argument) { if ($argument['id'] == 'date_argument') { $parts = array_keys($date_handler->arg_parts($view->args[$i])); break; } $i++; } return array_pop($parts); } /** * Identify the base url of the page, * needed when the calendar is embedded so we * don't set the url to the calendar url. */ function calendar_page_url($view) { if ($view->build_type == 'page') { return calendar_real_url($view, $view->real_args); } else { $block_identifier = isset($view->block_identifier) ? $view->block_identifier : 'mini'; return url($_GET['q'], calendar_querystring($view, array($block_identifier => NULL)), NULL, TRUE); } } /** * Pick up filter and sort info from url. */ function calendar_querystring($view, $extra_params = array()) { $query_params = array_merge($_GET, $extra_params); // Allow NULL params to be removed from the query string. foreach ($extra_params AS $key => $value) { if (!isset($value)) { unset($query_params[$key]); } } // Filter the special "q" and "view" variables out of the query string. $exclude = array('q'); // If we don't explicitly add a value for "view", filter it out. if (empty($extra_params['view'])) { $exclude[] = 'view'; } $query = drupal_query_string_encode($query_params, $exclude); // To prevent an empty query string from adding a "?" on to the end of a URL, // we return NULL. return !empty($query) ? $query : NULL; } /** * Create a stripe. * * @param $node - the node object * @param $query_name - the views queryname for this date field * @param $delta - the delta for this field, used to distinguish fields that appear more than once in the calendar * @param $stripe - the hex code for this stripe. * @param $label - the label to give this stripe. * * TODO this is still too hard-wired to node types. * Come back later and make it possible to use taxonomy terms or other * values as stripe keys. * * TODO Need to add in hook so ical and other modules can add things to the legend. * * TODO Reconsider use of $GLOBALS as a method of triggering the legend, there * may be a better way. */ function calendar_node_stripe($view, &$node, $query_name, $delta, $stripe = NULL, $label = '') { $type_names = node_get_types('names'); $colors = isset($view->calendar_colors) ? $view->calendar_colors : array(); if (!$label) { $label = $type_names[$node->type]; } if (!$stripe) { if (array_key_exists($node->type, $colors)) { $stripe = $colors[$node->type]; } else { $stripe = ''; } } $node->stripe = $stripe; $node->stripe_label = $label; $GLOBALS['calendar_stripe_labels'][$node->type] = array('stripe' => $stripe, 'label' => $label); return $stripe; } /** * Helper function to figure out a group gid to use in blocks. * * @return an array of group nodes that are relevant. * @todo this may need more work. */ function calendar_og_groups($view) { if (!$groupnode = og_get_group_context()) { global $user; $groupnodes = array_keys($user->og_groups); } else { $groupnodes = array($groupnode->nid); } return $groupnodes; } /** * A selector to jump to a new date in the calendar. * * @param unknown_type $view * @return unknown */ function calendar_date_select($view) { return '
'. drupal_get_form('calendar_date_select_form', $view) .'
'; } /** * The date selector form. * * @param object $view * @return the form element * * @TODO is the title desired here or does it take up too much space?? */ function calendar_date_select_form($view) { $format = date_limit_format(variable_get('date_format_short', 'm/d/Y - H:i'), array('year', 'month', 'day')); $form['calendar_goto'] = array( //'#title' => t('Calendar date'), '#type' => module_exists('date_popup') ? 'date_popup' : 'date_select', '#default_value' => date_format($view->min_date, 'Y-m-d'), '#date_timezone' => date_default_timezone_name(), '#date_format' => $format, ); $form['date_type'] = array( '#type' => 'hidden', '#value' => $view->date_type, ); $form['submit'] = array( '#type' => 'submit', '#value' => t('Change date'), ); return $form; } /** * Get the url for a calendar node. * * @param $node - a calendar node object * @param $default - a default url to use when nothing specific is provided. */ function calendar_get_node_link($node, $default = NULL) { if (isset($node->url)) { return url($node->url, array('absolute' => TRUE)); } elseif (empty($node->remote) && is_numeric($node->nid)) { return url("node/$node->nid", array('absolute' => TRUE)); } elseif (!empty($default)) { return url($default, array('absolute' => TRUE)); } } /** * Implementation of hook_elements. * * Much of the colorpicker code was adapted from the Colorpicker module. * That module has no stable release yet nor any D6 branch. * * TODO Consider dropping the duplicate code and adding a dependency * when that module is more stable, if calendar module customizations will * work in it. */ function calendar_elements() { // the Farbtastic colorpicker $type['calendar_colorpicker'] = array( '#attributes' => array('class' => 'calendar_colorpicker'), '#input' => TRUE, ); // a textfield to associate with the Farbtastic colorpicker $type['calendar_colorfield'] = array( '#attributes' => array('class' => 'calendar_colorfield'), '#input' => TRUE, '#validate' => array('calendar_validate_hex_color' => array()) ); return $type; } /** * Check to make sure the user has entered a valid 6 digit hex color. */ function calendar_validate_hex_color($element) { if (!$element['#required'] && empty($element['#value'])) { return; } if (!preg_match('/^#(?:(?:[a-f\d]{3}){1,2})$/i', $element['#value'])) { form_error($element, "'". check_plain($element['#value']) ."'". t(' is not a valid hex color')); } else { form_set_value($element, $element['#value']); } } /** * Format calendar_colorpicker. */ function theme_calendar_colorpicker($element) { $output = ''; $output .= '
'; return theme('form_element', $element, $output); } /** * Format calendar_color textfield. */ function theme_calendar_colorfield($element) { $size = isset($element['#size']) ? ' size="' . $element['#size'] . '"' : ''; $maxlength = isset($element['#maxlength']) ? 'maxlength="'.$element['#maxlength'] .'"' : ''; $output = ''; if (isset($element['#calendar_colorpicker'])) { $element['#attributes']['class'] .= ' edit-'. str_replace("_", "-", $element['#calendar_colorpicker']); } $output .= ''; return theme('form_element', $element, $output); }