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 calendar_date_week(date_format($date, 'Y-m-d')); } /** * Find the calendar week number for a date. * * @param string $date, in the format Y-m-d * @return int calendar week number. */ function calendar_date_week($date) { $parts = explode('-', $date); $date = date_make_date($date . ' 12:00:00', 'UTC'); $year_date = date_make_date($parts[0] . '-01-01 12:00:00', 'UTC'); $week = intval(date_format($date, 'W')); $year_week = intval(date_format($year_date, 'W')); $date_year = intval(date_format($date, 'o')); // remove the leap week if it's present if ($date_year > intval($parts[0])) { $last_date = drupal_clone($date); date_modify($last_date, '-7 days'); $week = date_format($last_date, 'W') + 1; } else if ($date_year < intval($parts[0])) { $week = 0; } if ($year_week != 1) $week++; // convert to ISO-8601 day number, to match weeks calculated above $iso_first_day = 1 + (variable_get('date_first_day', 0) + 6) % 7; // if it's before the starting day, it's the previous week if (intval(date_format($date, 'N')) < $iso_first_day) $week--; // if the year starts before, it's an extra week at the beginning if (intval(date_format($year_date, 'N')) < $iso_first_day) $week++; return $week; } /** * 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 = calendar_week_range($query); $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'. calendar_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 if (array_key_exists($view->page_type, calendar_view_types())) { if (!$items && $view->build_type == 'page' && $view->year) { $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) { $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'] ? '