View complete documentation at !link.

", array('!link' => 'http://drupal.org/node/120710')); } } /** * Implementation of hook_menu(). */ function calendar_menu($may_cache) { $items = array(); if (!$may_cache) { drupal_add_css(drupal_get_path('module', 'calendar') .'/calendar.css'); define('CALENDAR_EMPTY_ARG', variable_get('calendar_empty_arg', 'all')); require_once('./'. drupal_get_path('module', 'calendar') .'/calendar_admin.inc'); $first = TRUE; foreach (calendar_info() as $view_name => $view) { if ($first) { $items[] = array( 'path' => 'admin/settings/calendar', 'title' => t('Calendar Setup'), 'description' => t('Customize calendar settings options.'), 'access' => user_access('administer views'), 'type' => MENU_NORMAL_ITEM, 'callback' => 'drupal_get_form', 'callback arguments' => array('_calendar_setup_form', $view_name), ); } $items[] = array( 'path' => 'admin/settings/calendar/'. $view_name, 'title' => $view_name, 'access' => user_access('administer views'), 'callback' => 'drupal_get_form', 'callback arguments' => array('_calendar_setup_form', $view_name), 'type' => $first ? MENU_DEFAULT_LOCAL_TASK : MENU_LOCAL_TASK, ); $items[] = array( 'path' => 'admin/settings/calendar/'. $view_name .'/setup', 'title' => t('Setup'), 'access' => user_access('administer views'), 'callback' => 'drupal_get_form', 'callback arguments' => array('_calendar_setup_form', $view_name), 'type' => MENU_DEFAULT_LOCAL_TASK, 'weight' => -10, ); $items[] = array( 'path' => 'admin/settings/calendar/'. $view_name .'/legend', 'title' => t('Legend'), 'access' => user_access('administer views'), 'callback' => 'drupal_get_form', 'callback arguments' => array('_calendar_legend_form', $view_name), 'type' => MENU_LOCAL_TASK, 'weight' => -5, ); $first = FALSE; } } return $items; } /** * Find the number of calendar weeks for a year. * * @param int $year * @return int number of calendar weeks in selected year. */ function calendar_max_weeks($year) { $date = date_make_date(($year+1) . '-01-01 12:00:00', 'UTC'); date_modify($date, '-1 day'); return date_week(date_format($date, DATE_FORMAT_DATE)); } /** * Implementation of hook_form_alter(). * Make sure calendar_info() and calendar_fields() get updated. */ function calendar_form_alter($form_id, &$form) { if ($form_id == 'views_edit_view') { $form['#submit'] = array_merge($form['#submit'], array('calendar_clear_all' => array())); } } /** * 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); } /** * Custom views handler for all calendar arguments. */ function calendar_handler_arg_type($op, &$query, $argtype, $arg, $field_type) { switch ($op) { case 'summary': case 'link': // The query to do summaries when date ranges can include multiple days, months, and years // is extremely complex and has been omitted, so summary views with these arguments just will not work. // TODO add some kind of validation or warning to keep people from trying to use summary views. break; case 'filter': // Figure out which will be the final calendar argument in this view so we know when to insert the query. $view = $GLOBALS['current_view']; if ($argtype['type'] == calendar_is_last_arg($view)) { $query->calendar_finished = TRUE; //calendar_build_filter($query, $view); } break; case 'title': // Set titles for each argument. $value = intval(str_replace('W', '', $arg ? $arg : $query)); return theme('calendar_arg_title', $field_type, $value, $query); } return; } /** * Custom views handler for the year argument. */ function calendar_handler_arg_year($op, &$query, $argtype, $arg = '') { if ($op == 'filter' && !empty($arg) && $arg != CALENDAR_EMPTY_ARG) { calendar_filter_year($query, $arg); } return calendar_handler_arg_type($op, $query, $argtype, $arg, 'YEAR'); } /** * Callback for year filter. * Build year, month, day, min, and max into query object. * * @param object $query * @param integer $arg */ function calendar_filter_year(&$query, $arg) { $query->calendar_type = 'year'; $query->year = calendar_part_is_valid($arg, 'year') ? $arg : date_format(date_now(), 'Y'); $query->month = CALENDAR_EMPTY_ARG; $query->day = CALENDAR_EMPTY_ARG; } /** * Custom views handler for the month argument. */ function calendar_handler_arg_month($op, &$query, $argtype, $arg = '') { if ($op == 'filter' && !empty($arg) && $arg != CALENDAR_EMPTY_ARG) { calendar_filter_month($query, $arg); } return calendar_handler_arg_type($op, $query, $argtype, $arg, 'MONTH'); } /** * Callback for month filter. * Build year, month, day, min, and max into query object. * * @param object $query * @param integer $arg */ function calendar_filter_month(&$query, $arg) { $now = date_now(); $query->calendar_type = 'month'; if (!isset($query->year)) { calendar_filter_year($query, date_format($now, 'Y')); } $query->month = calendar_part_is_valid($arg, 'month') ? $arg : date_format($now, 'm'); $query->day = CALENDAR_EMPTY_ARG; } /** * Custom views handler for the day argument. */ function calendar_handler_arg_day($op, &$query, $argtype, $arg = '') { if ($op == 'filter' && !empty($arg) && $arg != CALENDAR_EMPTY_ARG) { calendar_filter_day($query, $arg); } return calendar_handler_arg_type($op, $query, $argtype, $arg, 'DAY'); } /** * Callback for day filter. * Build year, month, day, min, and max into query object. * * @param object $query * @param integer $arg */ function calendar_filter_day(&$query, $arg) { $now = date_now(); if (!isset($query->month)) { calendar_filter_month($query, date_format($now, 'm')); } $query->calendar_type = 'day'; $query->day = calendar_part_is_valid($arg, 'day') ? $arg : date_format($now, 'j'); } /** * Custom views handlers for the week argument. */ function calendar_handler_arg_week($op, &$query, $argtype, $arg = '') { if ($op == 'filter' && !empty($arg) && $arg != CALENDAR_EMPTY_ARG) { calendar_filter_week($query, $arg); } return calendar_handler_arg_type($op, $query, $argtype, $arg, 'WEEK'); } /** * Callback for week filter. * Build year, month, day, min, and max into query object. * * @param object $query * @param integer $arg */ function calendar_filter_week(&$query, $arg) { $now = date_now(); if (!isset($query->year)) { calendar_filter_year($query, date_format($now, 'Y')); } $arg = str_replace('W', '', $arg); $query->calendar_type = 'week'; $query->week = calendar_part_is_valid($arg, 'week') ? $arg : NULL; $range = date_week_range($query->week, $query->year); $query->month = date_format($range[0], 'n'); $query->day = date_format($range[0], 'j'); } /** * Implementation of hook_views_query() * Insert filters into the query based on the current calendar view and the selected fields * Used when the actual view arguments don't provide enough info to construct the query. * i.e. on a view with no arguments or one with partial arguments like year or year/month. * * @param object $query * @param object $view */ function calendar_views_query_alter(&$query, &$view) { if (!calendar_has_calendar_args($view) || (empty($view->args) && !calendar_is_calendar_arg($view) && $view->argument[0]['argdefault'] != 2)) { return; } // If there are args before the calendar args and they don't have values // we don't have enough information to create calendar navigation links // so exit here. Except if this is a block because we construct // missing arguments for the block. $pos = calendar_arg_positions($view); if ($pos[0] > count($view->args) && $view->build_type != 'block') { return; } // Check if a new date has been selected and if so redirect. if (isset($_POST['calendar_goto'])) { require_once('./'. drupal_get_path('module', 'date_api') .'/date_api_elements.inc'); $format = date_limit_format(variable_get('date_format_short', 'm/d/Y - H:i'), array('year', 'month', 'day')); $date = date_convert_from_custom($_POST['calendar_goto']['date'], $format); switch ($_POST['calendar_type']) { case 'year': $parts = array( 'year' => date_pad(date_part_extract($date, 'year'), 4), ); break; case 'month': $parts = array( 'year' => date_pad(date_part_extract($date, 'year'), 4), 'month' => date_pad(date_part_extract($date, 'month')), ); break; case 'week': $parts = array( 'year' => date_pad(date_part_extract($date, 'year'), 4), 'week' => 'W'. date_pad(date_week($date)), ); break; default: $parts = array( 'year' => date_pad(date_part_extract($date, 'year'), 4), 'month' => date_pad(date_part_extract($date, 'month')), 'day' => date_pad(date_part_extract($date, 'day')), ); break; } if ($view->build_type == 'page') { // Append the date parts on to the end of the path. drupal_goto($view->url .'/'. implode('/', $parts), calendar_querystring($view)); } else { // Append the date parts on to the end of the block_identifier query param. $block_identifier = isset($view->block_identifier) ? $view->block_identifier : 'mini'; $view->real_url = calendar_real_url($view, $view->args); drupal_goto($view->real_url, calendar_querystring($view, array($block_identifier => $view->real_url .'/'. implode('/', $parts)))); } drupal_exit(); } require_once('./'. drupal_get_path('module', 'calendar') .'/calendar.inc'); require_once('./'. drupal_get_path('module', 'calendar') .'/calendar.theme'); return _calendar_views_query_alter($query, $view); } /** * Implementation of hook_views_pre_view() */ function calendar_views_pre_view(&$view, &$items) { require_once('./'. drupal_get_path('module', 'calendar') .'/calendar.theme'); // Construct a formatted title for the view from the last calendar // argument encountered. $view->subtitle = theme('calendar_nav_title', $view->calendar_type, $view); // If this is a view with calendar arguments but not a calendar view, // add navigation to the top of the view and return. if (!calendar_is_calendar($view) && calendar_has_calendar_args($view)) { return theme('calendar_nav', $view, $view->build_type != 'block'); } // If no part of this view has calendar elements, exit. elseif ((!calendar_is_calendar($view) || !calendar_has_calendar_args($view))) { return; } if ($view->build_type == 'block' || $view->calendar_type == 'year') $view->mini = TRUE; // Don't do anything in summary views. if ($summary = !empty($items) && array_key_exists('num_nodes', $items[0])) { return; } // Don't do anything if this isn't a calendar component. if (!calendar_has_calendar_args($view) || (empty($view->args) && !calendar_is_calendar_arg($view) && $view->argument[0]['argdefault'] != 2)) { return; } require_once('./'. drupal_get_path('module', 'calendar') .'/calendar.inc'); $display_formats = variable_get('calendar_display_format_'. $view->name, array('year' => 'calendar', 'month' => 'calendar', 'week' => 'calendar', 'day' => 'calendar', 'block' => 'calendar')); // Massage the resulting items into formatted calendar items. $items = calendar_build_nodes($view, $items, $display_formats[$view->calendar_type]); // Merge in items from other sources. foreach (module_implements('calendar_add_items') as $module) { $function = $module .'_calendar_add_items'; if (function_exists($function)) { if ($feeds = $function($view)) { foreach ($feeds as $feed) { $items[$feed->calendar_start][] = $feed; } } } } // Sort the results -- sort needed if they are to be displayed // in a list or other non-calendar format, since sorting was // clobbered by adding in feeds and breaking items up into // individual days. $sort = ''; $fields = array_keys(calendar_fields()); foreach ($view->field as $field) { if (in_array($field['field'], $fields)) { foreach ($view->sort as $sort) { if ($sort['field'] = $field['field']) { $sort = $sort['sortorder']; break; } } } } if (!empty($sort)) { if ($sort == 'DESC') { krsort($items); } else { ksort($items); } } $nodes = array(); foreach ($items as $date => $values) { foreach ($values as $node) { $nodes[] = $node; } } $items = $nodes; // If this is a calendar plugin theme view, make sure empty results // will produce blank calendar page if (array_key_exists($view->page_type, calendar_view_types())) { if (!$items && $view->build_type == 'page' && $view->year && $display_formats[$view->calendar_type] == 'calendar') { $view->page_empty = check_markup($view->page_header, $view->page_header_format, FALSE) . check_markup($view->page_empty, $view->page_empty_format, FALSE); } } if (array_key_exists($view->block_type, calendar_view_types())) { if (!$items && $view->build_type == 'block' && $view->year && $display_formats[$view->calendar_type] == 'calendar') { $view->block_empty = check_markup($view->block_header, $view->block_header_format, FALSE) . check_markup($view->block_empty, $view->block_empty_format, FALSE); } } } /** * Implementation of hook_views_post_view(). * * Views automatically sets the page title to the value of the last argument. * The calendar module has already created a proper title within the * calendar, so override Views to set the page title to match the View title. */ function calendar_views_post_view(&$view, $items, $output) { // If no part of this view has calendar elements, exit. if ($view->build_type != 'page' || !calendar_is_calendar($view) || !calendar_has_calendar_args($view)) { return; } require_once('./'. drupal_get_path('module', 'calendar') .'/calendar.inc'); $title = theme('calendar_page_title', $view, $items, $output); drupal_set_title($title); } /** * 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.'); $blocks[1]['info'] = t('Switch Calendar.'); return $blocks; break; case 'view' : switch ($delta) { case 0: $block['subject'] = t('Calendar Legend'); $content = theme('calendar_stripe_legend'); $block['content'] = !empty($content) ? '
'. $content .'
' : ''; return $block; case 1: $block['subject'] = t('Switch Calendar'); $block['content'] = $GLOBALS['calendar_is_calendar'] ? drupal_get_form('calendar_switch_view') : ''; return $block; } } } /** * A block with a drop-down list that allows the user to switch between * views of the current period */ function calendar_switch_view() { $options[''] = t('Calendar'); $options['list'] = t('List'); $options['teasers'] = t('Teasers'); $options['nodes'] = t('Nodes'); $options['table'] = t('Table'); $form = array( '#method' => 'GET', 'view' => array( '#type' => 'select', '#default_value' => $_GET['view'], '#options' => $options, ), 'q' => array( '#type' => 'hidden', '#value' => $_GET['q'], ), 'submit' => array('#type' => 'submit', '#value' => t('Switch')), ); return $form; } /** * Valid calendar arguments. */ function calendar_args() { return array('calendar_year', 'calendar_week', 'calendar_month', 'calendar_day'); } /** * 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); } } /** * Figure out what the URL of the calendar view we're currently looking at is. */ function calendar_real_url($view, $args) { if (empty($args)) { return $view->url; } // Add non-calendar arguments to the base url. $parts = explode('/', $view->url); $bump = 0; foreach ($parts as $delta => $part) { // If one of the args is buried in the url, add it here and adjust // the delta values we'll compare the calendar arg positions to. if (substr($part, 0, 1) == '$') { $parts[$delta] = array_shift($args); $bump++; } } foreach ($args as $delta => $arg) { if (!in_array($delta + $bump, calendar_arg_positions($view)) && !empty($arg)) { array_push($parts, $arg); } } return implode('/', $parts); } /** * Count the args in the url * * Looking for a pattern like '/$'. */ function calendar_args_in_url($view) { ereg('\/\$', $view->url, $regs); return count($regs); } /** * 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; } /** * An alternative to views_get_url() * that will correctly substitute replacement * values like $group or $node. */ function calendar_get_url($view, $args, $as_array = FALSE) { // build an array of the current path and its parts $real_url = calendar_real_url($view, $view->real_args); $buried_args = calendar_args_in_url($view); $i = 0; $path[0] = array( 'path' => $real_url, 'type' => 'url', ); $start_calendar = FALSE; foreach ($view->argument as $delta => $arg) { if ($delta < $buried_args) { continue; } if (in_array($arg['type'], calendar_args())) { $start_calendar = TRUE; $pathtype = str_replace('calendar_', '', $arg['type']); $path[$delta + 1] = array( 'path' => $args[$delta] != CALENDAR_EMPTY_ARG ? $args[$delta] : CALENDAR_EMPTY_ARG, 'type' => $pathtype, ); } // Args prior to the calendar arg are already reflected in the $real_url. elseif ($start_calendar) { $path[$delta + 1] = array( 'path' => $args[$delta], 'type' => '', ); } } if ($as_array) { return $path; } else { $string = ''; $first = TRUE; foreach ($path as $part) { if (!$first) { $string .= '/'; } $string .= $part['path']; $first = FALSE; } return $string; } } /** * Substitute a calendar argument with a wildcard. */ function calendar_wildcard($arg, $value) { if (empty($value) && substr($arg['type'], 0, 8) == 'calendar') { $value = CALENDAR_EMPTY_ARG; } elseif (!empty($arg['wildcard_substitution']) && !empty($arg['wildcard']) && !empty($value) && $value == $arg['wildcard']) { $value = $arg['wildcard_substitution']; } return $value; } /** * Function to test whether this is a view that uses the calendar plugin theme. */ function calendar_is_calendar($view) { $calendar_info = calendar_info(); if (!empty($calendar_info) && !empty($calendar_info[$view->name])) { return $calendar_info[$view->name][$view->build_type]; } return FALSE; } /** * Function to test whether any calendar args are used in this view. */ function calendar_has_calendar_args($view, $reset = FALSE) { $calendar_info = calendar_info(); if (!empty($calendar_info) && !empty($calendar_info[$view->name]) && count($calendar_info[$view->name]['args']) > 0) { return TRUE; } else { return FALSE; } } /** * The positions in the view that hold calendar arguments. */ function calendar_arg_positions($view) { $calendar_info = calendar_info(); if (array_key_exists($view->name, $calendar_info)) { return array_keys($calendar_info[$view->name]['args']); } else { return array(); } } /** * Is the current argument a calendar argument. * Used to sort out whether or not to display the calendar at each point. */ function calendar_is_calendar_arg($view) { if (empty($view->real_args)) { $delta = 0; } else { $delta = max(array_keys($view->real_args)); } if (in_array($delta, calendar_arg_positions($view))) { return TRUE; } return FALSE; } /** * Identify the final calendar argument in this view. * Needed because we can't construct a query until we know all the calendar elements. * Used to tell when to add the filter to the query object. * * @param object $view * @return string $argtype */ function calendar_is_last_arg($view, $reset = FALSE) { foreach ($view->argument as $argument) { if (in_array($argument['id'], calendar_args())) { $calendar_arg = $argument['id']; } $max = $argument['id']; } return $max < $calendar_arg; } /** * Helper function to find the display formats * for each part of this view. */ function calendar_get_formats($view) { return variable_get('calendar_display_format_'. $view->name, array( 'year' => 'calendar', 'month' => 'calendar', 'week' => 'calendar', 'day' => 'calendar', 'block' => 'calendar')); } /** * 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 = variable_get('calendar_color_'. $view->name, 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; } /** * Moved the following infrequently-used functions to separate file * so the code is not parsed on every page. */ /** * Implementation of hook_views_style_plugins() */ function calendar_views_style_plugins() { require_once('./'. drupal_get_path('module', 'calendar') .'/calendar_admin.inc'); return _calendar_views_style_plugins(); } /** * Implementation of hook_views_default_views() */ function calendar_views_default_views() { require_once('./'. drupal_get_path('module', 'calendar') .'/calendar_admin.inc'); return _calendar_views_default_views(); } /** * Implementation of hook_views_arguments() */ function calendar_views_arguments() { require_once('./'. drupal_get_path('module', 'calendar') .'/calendar_admin.inc'); return _calendar_views_arguments(); } /** * Function to return all possible calendar views page display types. */ function calendar_view_types($reset = FALSE) { require_once('./'. drupal_get_path('module', 'calendar') .'/calendar_admin.inc'); return _calendar_view_types($reset); } /** * Function to get information about all views that have calendar components. */ function calendar_info($reset = FALSE) { static $calendar_views; if (empty($calendar_views) || $reset) { $cid = 'calendar_views'; if (!$reset && $cached = cache_get($cid, 'cache_views')) { $calendar_views = unserialize($cached->data); } else { require_once('./'. drupal_get_path('module', 'calendar') .'/calendar_admin.inc'); $calendar_views = _calendar_info(); } } return $calendar_views; } /** * Identify all potential date/timestamp fields */ function calendar_fields($reset = FALSE) { static $fields; if (empty($fields) || $reset) { $cid = 'calendar_fields'; if (!$reset && $cached = cache_get($cid, 'cache_views')) { $fields = unserialize($cached->data); } else { require_once('./'. drupal_get_path('module', 'calendar') .'/calendar_admin.inc'); $fields = _calendar_fields(); } } return $fields; } /** * Validate a view during Views administration. */ function calendar_views_validate($type, $view, $form) { require_once('./'. drupal_get_path('module', 'calendar') .'/calendar_admin.inc'); return _calendar_views_validate($type, $view, $form); } /** * Setup Calendar parameters in the Setup Tab. */ function calendar_setup_form($view_name) { require_once('./'. drupal_get_path('module', 'calendar') .'/calendar_admin.inc'); return _calendar_setup_form($view_name); } /** * Save Setup values. */ function calendar_setup_form_submit($form_id, $form_values) { require_once('./'. drupal_get_path('module', 'calendar') .'/calendar_admin.inc'); return _calendar_setup_form_submit($form_id, $form_values); } /** * Save Setup values. */ function calendar_legend_form_submit($form_id, $form_values) { require_once('./'. drupal_get_path('module', 'calendar') .'/calendar_admin.inc'); return _calendar_legend_form_submit($form_id, $form_values); } /** * Empty or reset cached values. * * @param $remove * whether or not to completely remove the caches. */ function calendar_clear_all($remove = FALSE) { if ($remove) { cache_clear_all('calendar_views', 'cache_views'); cache_clear_all('calendar_fields', 'cache_views'); } else { calendar_fields(TRUE); calendar_info(TRUE); } } /** * 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, DATE_FORMAT_DATE), '#date_timezone' => date_default_timezone_name(), '#date_format' => $format, ); $form['calendar_type'] = array( '#type' => 'hidden', '#value' => $view->calendar_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, NULL, NULL, TRUE); } elseif (empty($node->remote) && is_numeric($node->nid)) { return url("node/$node->nid", NULL, NULL, TRUE); } elseif (!empty($default)) { return url($default, NULL, NULL, TRUE); } } /** * Get the absolute minimum and maxium allowable years for a view. */ function calendar_year_range($view) { $year_range = explode(':', variable_get('calendar_year_range_'. $view->name, '-3:+3')); if (substr(variable_get('calendar_year_range_'. $view->name, '-3:+3'), 0, 1) == '-' || $year_range[0] < 0) { $this_year = date_format(date_now(), 'Y'); $year_range[0] = $this_year + $year_range[0]; $year_range[1] = $this_year + $year_range[1]; } return $year_range; } /** * Trim a post to a certain number of characters, removing all HTML. */ function calendar_trim_text($text, $length = 128) { $original_text = $text; // remove any HTML or line breaks so these don't appear in the text $text = trim(str_replace(array("\n", "\r"), ' ', strip_tags($text))); $text = trim(substr($text, 0, $length)); // only truncate if original text is longer than the length we want if (strlen($original_text) > $length) { $lastchar = substr($text, -1, 1); // check to see if the last character in the title is a non-alphanumeric character, except for ? or ! // if it is strip it off so you don't get strange looking titles if (preg_match('/[^0-9A-Za-z\!\?]/', $lastchar)) { $text = substr($text, 0, -1); } // ? and ! are ok to end a title with since they make sense if ($lastchar != '!' and $lastchar != '?') { $text .= '...'; } } return $text; } /** * 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) { $path = drupal_get_path('module', 'calendar'); // Add Farbtastic color picker drupal_add_css('misc/farbtastic/farbtastic.css'); drupal_add_js('misc/farbtastic/farbtastic.js'); // Add our custom js and css for our calendar_color drupal_add_js($path . '/js/calendar_colorpicker.js'); $output = ''; $output .= '
'; return theme('form_element', $element, $output); } /** * Format calendar_color textfield. */ function theme_calendar_colorfield($element) { $size = $element['#size'] ? ' size="' . $element['#size'] . '"' : ''; $output = ''; if (isset($element['#calendar_colorpicker'])) { $element['#attributes']['class'] .= ' edit-'. str_replace("_", "-", $element['#calendar_colorpicker']); } $output .= ''; return theme('form_element', $element, $output); }