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')); include_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, ); $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, 'Y-m-d')); } /** * 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; } // Check if a new date has been selected and if so redirect. if (isset($_POST['calendar_goto'])) { $parts = explode('/', $_POST['calendar_goto']['date']); $type = $_POST['calendar_type']; if ($type == 'year') { unset($parts[1], $parts[2]); } elseif ($type == 'month') { unset($parts[2]); } elseif ($type == 'week') { $date = implode('-', $parts); $parts[1] = 'W'. date_week($date); unset($parts[2]); } drupal_goto($view->url .'/'. implode('/', $parts)); drupal_exit(); } include_once('./'. drupal_get_path('module', 'calendar') .'/calendar.inc'); include_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) { include_once('./'. drupal_get_path('module', 'calendar') .'/calendar.theme'); // If no part of this view has calendar elements, exit. if ((!calendar_is_calendar($view) || !calendar_has_calendar_args($view))) { return; } if (!calendar_is_calendar_arg($view)) { return; } include_once('./'. drupal_get_path('module', 'calendar') .'/calendar.inc'); // Massage the resulting items into formatted calendar items. $items = calendar_build_nodes($view, $items); // 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; } } } } if ($view->build_type == 'block' || $view->calendar_type == 'year') $view->mini = TRUE; // 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_show_nav', $view, $view->build_type == 'block', calendar_is_calendar($view)); } // If this is a calendar plugin theme view, make sure empty results // will produce blank calendar page $display_format = variable_get('calendar_display_format_'. $view->name, array('year' => 'calendar', 'month' => 'calendar', 'week' => 'calendar', 'day' => 'calendar', 'block' => 'calendar')); if (array_key_exists($view->page_type, calendar_view_types())) { if (!$items && $view->build_type == 'page' && $view->year && $display_format[$view->calendar_type] == 'calendar') { $view->page_empty = check_markup($view->page_header, $view->page_header_format) . check_markup($view->page_empty, $view->page_empty_format) . theme('calendar_display', $view, array(), 'page') . check_markup($view->page_footer, $view->page_footer_format); $view->page_empty_format = 3; } } if (array_key_exists($view->block_type, calendar_view_types())) { if (!$items && $view->build_type == 'block' && $view->year && $display_format[$view->calendar_type] == 'calendar') { $view->block_empty = check_markup($view->block_header, $view->block_header_format) . check_markup($view->block_empty, $view->block_empty_format) . theme('calendar_display', $view, array(), 'block') . check_markup($view->block_footer, $view->block_footer_format); $view->block_empty_format = 3; } } } /** * 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; } include_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'); $block['content'] = $GLOBALS['calendar_stripe_labels'] ? '