calendar.module in Calendar 5
Same filename and directory in other branches
Adds calendar filtering and displays to Views.
File
calendar.moduleView source
<?php
/**
* @file
* Adds calendar filtering and displays to Views.
*/
/**
* Implementation of hook_help().
*/
function calendar_help($section) {
switch ($section) {
case 'admin/help#calendar':
return t("<p>View complete documentation at !link.</p>", array(
'!link' => 'http://drupal.org/node/120710',
));
}
}
/**
* Implementation of hook_menu().
*/
function calendar_menu($may_cache) {
$items = array();
if (!$may_cache) {
include_once './' . drupal_get_path('module', 'calendar') . '/calendar.theme';
drupal_add_css(drupal_get_path('module', 'calendar') . '/calendar.css');
define('CALENDAR_EMPTY_ARG', variable_get('calendar_empty_arg', 'all'));
foreach (calendar_info() as $view_name => $view) {
$parts = explode('/', $view['url']);
foreach ($parts as $delta => $part) {
if (in_array($part, array(
'$arg',
'$node',
'$user',
'$group',
))) {
$parts[$delta] = arg($delta);
}
}
$items[] = array(
'path' => implode('/', $parts) . '/setup',
'title' => t('Setup'),
'description' => t('Calendar setup.'),
'access' => user_access('administer views'),
'callback' => 'drupal_get_form',
'callback arguments' => array(
'calendar_setup_form',
$view_name,
),
'type' => MENU_LOCAL_TASK,
'weight' => 5,
);
}
}
return $items;
}
/**
* 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(),
));
}
}
/**
* Implementation of hook_views_tabs().
*/
function calendar_views_tabs($op) {
switch ($op) {
case 'names':
return array(
'setup',
);
}
}
/**
* Helper function for loading date_api.
*/
function calendar_load_date_api() {
include_once drupal_get_path('module', 'date_api') . '/date.inc';
include_once drupal_get_path('module', 'date_api') . '/date_timezones.inc';
}
/**
* Helper function for loading calendar_api.
*/
function calendar_load_calendar_api() {
include_once './' . drupal_get_path('module', 'calendar') . '/calendar_api.inc';
}
/**
* Call hooks in other modules to add other items to a calendar view.
*
* @param object $view
* @param string $type - display type, 'table', 'teasers', 'nodes', 'list', 'calendar'
* @return array of additional items to add.
*/
function calendar_add_items($view, $type) {
$new_items = array();
foreach (module_implements('calendar_add_items') as $module) {
$function = $module . '_calendar_add_items';
if (function_exists($function)) {
$feeds = $function($view);
// Calendar items are just added as objects, themeing will be done by the calendar api.
// For other types, theme the items and add them.
foreach ($feeds as $feed) {
if ($type == 'calendar') {
$new_items[] = $feed;
}
else {
switch ($type) {
case 'table':
$output = array(
'data' => array(
theme('calendar_node_month', $feed),
),
);
break;
case 'nodes':
case 'teasers':
case 'list':
$output = theme('calendar_node_day', $feed);
break;
}
if (!empty($output)) {
$new_items[] = $output;
}
}
}
}
}
return $new_items;
}
/**
* The workhorse function that takes the beginning array of items and alters it
* to an array of calendar nodes that the theme can handle.
*/
function calendar_get_nodes(&$view, &$items, $type) {
calendar_load_calendar_api();
calendar_load_date_api();
$view->nodes_per_page = 0;
$type_names = node_get_types('names');
unset($params['limit']);
if ($type == 'block' || $view->calendar_type == 'year') {
$params['mini'] = TRUE;
}
$fields = calendar_fields();
$calendar_fields = (array) array_keys($fields);
$nodes = array();
$i = 0;
$items_in = $items;
// explode out field and format info from the view
foreach ($view->field as $delta => $data) {
if (in_array($data['field'], $calendar_fields)) {
$option = $fields[$data['field']];
$field_type = strstr($option['type'], 'string') ? 'string' : 'timestamp';
$field_function = strstr($option['type'], 'cck') ? 'content_format' : $data['handler'];
$field_formatter = $data['options'];
$field_field = $option['query_name'];
$field_end = $field_field . '2';
$field_field_name = $option['field_name'];
$timestamp_fromto = $option['timestamp_fromto'];
$string_fromto = $option['string_fromto'];
$field_id = $delta;
$tz_handling = $option['tz_handling'];
$offset_field = str_replace('.', '_', $option['offset_field']);
$label = $data['label'];
$granularity = $option['granularity'];
$view_fields = _views_get_fields();
// iterate through the $items array returned by the query and create date or pseudo date nodes
foreach ($items as $delta => $item) {
// we have to serialize and unserialize to force a completely new copy of $item when duplicate fields use the same node
// without doing this, values added to the item in later iterations get applied to earlier ones
$node = unserialize(serialize($item));
$node->title = $node->node_title;
$node->label = $label;
foreach ($view->field as $field) {
if (!in_array($field['field'], $calendar_fields) && $field['field'] != 'title') {
if ($view_fields[$field['id']]['visible'] !== FALSE) {
$node->fields[$field['queryname']] = views_theme_field('views_handle_field', $field['queryname'], $view_fields, $field, $node, $view);
}
}
}
// If we're dealing with an event node, join the start and to dates together in one node and get rid of the other
if (module_exists('event') && ($field_field == 'event_event_start' || $field_field == 'event_event_end') && !$event_field_processed[$item->nid]) {
if ($node->event_event_start > 0) {
$node->calendar_start = $node->event_event_start;
$node->calendar_end = $node->event_event_end;
$event_field_processed[$item->nid] = TRUE;
}
}
elseif (module_exists('event') && ($field_field == 'event_event_start' || $field_field == 'event_event_end') && $event_field_processed[$item->nid]) {
// if more than one event field was added to the view (like start and end dates)
// don't process it more than once
unset($node);
}
if (isset($node) && !isset($node->calendar_start) && !isset($item->{$field_field})) {
// if no date for the node and no date in the item
// there is no way to display it on the calendar
unset($node);
}
if (isset($node) && !$node->calendar_start && $item->{$field_field}) {
// if calendar_start field holds a numeric value, treat it as a unix timestamp
// if string, convert to timestamp
if ($field_type == 'timestamp') {
$node->calendar_start = $item->{$field_field};
$node->calendar_end = $item->{$field_end} ? $item->{$field_end} : $item->{$field_field};
}
else {
// get the timestamp value for this date, use UTC to make sure no timezone conversion gets done on it
$node->calendar_start = date_iso2unix($item->{$field_field});
$node->calendar_end = $item->{$field_end} ? date_iso2unix($item->{$field_end}) : date_iso2unix($item->{$field_field});
}
}
if (isset($node)) {
// get appropriate timezone offset
switch ($tz_handling) {
case 'user':
global $user;
$node->start_offset = $node->end_offset = $user->timezone;
break;
case 'none':
case 'GMT':
$node->start_offset = $node->end_offset = 0;
break;
case 'date':
$node->start_offset = $node->end_offset = $node->{$offset_field};
break;
case 'event':
$node->start_offset = date_get_offset($node->event_timezone, $node->event_event_start);
$node->end_offset = date_get_offset($node->event_timezone, $node->event_event_end);
break;
default:
$timezone = variable_get('date_default_timezone_name', 'UTC');
$node->start_offset = date_offset(date_unix2array($node->calendar_start), $timezone);
$node->end_offset = date_offset(date_unix2array($node->calendar_end), $timezone);
break;
}
}
if (isset($node) && function_exists($field_function) && $node->calendar_start && $item->{$field_field}) {
if ($field_function == 'content_format') {
// force the original value for this field into the array that content_format expects
$node->start_format = content_format($field_field_name, array(
'value' => $item->{$field_field},
'value2' => $item->{$field_field},
), $field_formatter);
if ($node->calendar_end) {
$node->end_format = content_format($field_field_name, array(
'value' => $item->{$field_end},
'value2' => $item->{$field_end},
), $field_formatter);
}
}
else {
// or call date format function
if (!$node->start_format) {
$node->start_format = $field_function(NULL, NULL, $item->{$field_field}, NULL);
if ($node->calendar_end && !$node->end_format) {
$node->end_format = $field_function(NULL, NULL, $node->calendar_end, NULL);
}
}
}
// format a time-only display for the month calendar for dates that have time elements
if (array_intersect($granularity, array(
'H',
'N',
'S',
))) {
$node->start_time_format = date_format_date(variable_get('calendar_time_format_' . $view->name, 'H:i'), intval($node->calendar_start + $node->start_offset));
if ($node->calendar_end) {
$node->end_time_format = date_format_date(variable_get('calendar_time_format_' . $view->name, 'H:i'), intval($node->calendar_end + $node->end_offset));
}
}
else {
$node->start_time_format = $node->start_format;
$node->end_time_format = $node->end_format;
}
if ($node) {
// we can have multiple representations with the same nid, like multi-day values
// or different fields that refer to the same node
// create a unique id so it gets displayed in the calendar
// Add delta to key to make multiple value CCK fields display as separate items.
if (strstr($option['type'], 'cck')) {
$id = $item->nid . ':' . $delta . ':' . $field_field;
}
else {
$id = $item->nid . ':0:' . $field_field;
}
$node->nid = $id;
if ($view->build_type == 'page' && $view->calendar_type != 'year') {
$node->stripe = calendar_node_stripe($view, $node, $option['query_name'], $field_field);
}
$nodes[$id] = $node;
unset($node);
}
}
}
}
}
// make sure there is at least one item in $nodes to force the calendar to display
// set the hour to 12 to minimize timezone adjustments that might push it to previous or next day
if ($view->calendar_type == 'year') {
// for the year view to work, must have at least one node in each month
for ($i = 1; $i < 13; $i++) {
$nodes[] = _calendar_make_node(NULL, NULL, _views_get_timezone(), $view->year, $i, 1, 12, 0);
}
}
elseif ($view->calendar_type == 'week') {
// make sure at least one node is created for the current week
// add both start and end of week in case week crosses from one month to next
$week_range = calendar_week_range($view->year, $view->week);
$nodes[] = _calendar_make_node(NULL, NULL, _views_get_timezone(), date_format_date('Y', $week_range[0]), date_format_date('m', $week_range[0]), date_format_date('j', $week_range[0]), 12, 0);
$nodes[] = _calendar_make_node(NULL, NULL, _views_get_timezone(), date_format_date('Y', $week_range[1]), date_format_date('m', $week_range[1]), date_format_date('j', $week_range[1]), 12, 0);
}
elseif (sizeof($nodes) == 0) {
// otherwise add a blank node for the current day
$nodes = array(
_calendar_make_node(NULL, NULL, _views_get_timezone(), $view->year, $view->month, $view->day, 12, 0),
);
}
if (calendar_part_is_valid($view->year, 'year')) {
// valid year is a test that indicates if arguments were available to establish a date for the calendar
// a full view with an argument date will display a single month, day or week calendar page
// with navigation that mimics regular calendar
// trim off date values that are outside the selected range to prevent display of incomplete extra calendars
$params['limit'] = _calendar_limit_nodes($nodes, $view->calendar_type, $view->year, $view->month, $view->day, $view->week, _views_get_timezone());
// hide the intermediate header rows created by the event api and
// push title and navigation into calendar header
$params['hide_header'] = $view->calendar_type == 'week' ? false : true;
//$title = theme('calendar_nav_wrapper', calendar_nav($view, $params['mini']), array());
// standard api displays a whole month instead of a single week
// adjust here for single week display
if ($view->calendar_type == 'week' && $view->week) {
$params['force_week'] = $view->week;
}
}
// use calendar_get_calendar api to draw the calendar
$params['url'] = calendar_real_url($view, $view->args);
$params['append'] = calendar_url_append($view);
$params['stripe'] = 'stripe';
$params['with_weekno'] = $view->build_type == 'block' || $view->calendar_type == 'year' || $view->year < 1970 ? FALSE : TRUE;
return array(
'nodes' => $nodes,
'params' => $params,
);
}
/**
* Function to construct back and next navigation from views arguments
*/
function calendar_nav($view, $mini = FALSE) {
if (!calendar_part_is_valid($view->year, 'year')) {
return array(
$view->subtitle,
);
}
calendar_load_date_api();
if ($view->calendar_type == 'week' && calendar_part_is_valid($view->week, 'week')) {
$range = calendar_week_range($view->year, $view->week + 1);
$cur_stamp = $range[0];
}
else {
$cur_stamp = date_gmmktime(array(
'mon' => $view->month ? $view->month : 1,
'mday' => $view->day ? $view->day : 1,
'year' => $view->year ? $view->year : date_format_date("Y", date_time()),
));
}
// make the navigation into a header, with prev and next links
// use the calendar_nav themes to mimic standard calendar navigation
$paths = calendar_get_paths($cur_stamp, $view);
$prev_path = implode('/', array_reverse($paths[0]));
$next_path = implode('/', array_reverse($paths[1]));
$prev_query = $next_query = array();
if ($_GET['view']) {
$prev_query[] = 'view=' . $_GET['view'];
$next_query[] = 'view=' . $_GET['view'];
}
// for the mini calendar in a block, treat the url as a querystring to avoid actually changing the page
if ($mini && $view->calendar_type == 'month') {
$prev_query[] = 'mini=' . $prev_path;
$prev_path = $_GET['q'];
$next_query[] = 'mini=' . $next_path;
$next_path = $_GET['q'];
}
$prev_query[] = calendar_url_append($view);
$next_query[] = calendar_url_append($view);
$header = array();
$header[] = array(
'data' => theme('calendar_nav_prev', $prev_path, $mini ? FALSE : TRUE, implode('&', $prev_query)),
'class' => 'prev',
);
$header[] = array(
'data' => $view->subtitle,
'class' => 'heading',
'colspan' => 5,
);
$header[] = array(
'data' => theme('calendar_nav_next', $next_path, $mini ? FALSE : TRUE, implode('&', $next_query)),
'class' => 'next',
);
return $header;
}
function calendar_get_paths($cur_stamp, $view) {
calendar_load_date_api();
$path = array();
// build an array of the current path and its parts
$i = 0;
$path[$i] = array(
'path' => $view->real_url,
'type' => 'url',
);
foreach ($view->argument as $delta => $arg) {
if ($view->args[$delta]) {
$i++;
$pathtype = str_replace('calendar_', '', $arg['type']);
$path[$i] = array(
'path' => $view->args[$delta] != CALENDAR_EMPTY_ARG ? $view->{$pathtype} : CALENDAR_EMPTY_ARG,
'type' => $pathtype,
);
}
}
// if there are other arguments after the view arguments, add them to the navigation links
while ($i < sizeof($view->args)) {
$i++;
$path[$i] = array(
'path' => $view->args[intval($i - 1)],
'type' => '',
);
}
// reverse through the path, creating a $nextpath and $prevpath arrays
for ($x = $i; $x >= 0; $x--) {
if ($path[$x]['path'] != CALENDAR_EMPTY_ARG) {
switch ($path[$x]['type']) {
case 'day':
$day = $path[$x]['path'];
$next_stamp = $cur_stamp + 86400;
$prev_stamp = $cur_stamp - 86400;
$nextpath[$x] = date_format_date('j', $next_stamp);
$prevpath[$x] = date_format_date('j', $prev_stamp);
break;
case 'week':
$week = $path[$x]['path'];
$year = $view->year;
if (!$next_stamp) {
$cal_range = calendar_week_range($year, $week);
$next_stamp = $cal_range[1] + 1;
$prev_stamp = $cal_range[0] - 1;
}
$week_year = calendar_week_year($next_stamp);
$next_year = $week_year[1];
$nextpath[$x] = 'W' . sprintf("%02d", $week_year[0]);
$week_year = calendar_week_year($prev_stamp);
$prev_year = $week_year[1];
$prevpath[$x] = 'W' . sprintf("%02d", $week_year[0]);
break;
case 'month':
$month = $path[$x]['path'];
$year = $view->year;
$next_year = $month < 12 ? $year : $year + 1;
$prev_year = $month > 1 ? $year : $year - 1;
if (!$next_stamp) {
$next_stamp = date_gmmktime(array(
'mon' => $month < 12 ? $month + 1 : 1,
'mday' => 1,
'year' => $next_year,
));
$prev_stamp = date_gmmktime(array(
'mon' => $month > 1 ? $month - 1 : 12,
'mday' => 1,
'year' => $prev_year,
));
}
$nextpath[$x] = date_format_date('n', $next_stamp);
$prevpath[$x] = date_format_date('n', $prev_stamp);
break;
case 'year':
$year = $view->year;
if (!$next_stamp) {
$next_stamp = date_gmmktime(array(
'mon' => 1,
'mday' => 1,
'year' => $next_year ? $next_year : $year + 1,
));
$prev_stamp = date_gmmktime(array(
'mon' => 12,
'mday' => 1,
'year' => $prev_year ? $prev_year : $year - 1,
));
}
$nextpath[$x] = date_format_date('Y', $next_stamp);
$prevpath[$x] = date_format_date('Y', $prev_stamp);
break;
default:
// all other arguments are just passed through
if ($path[$x]['path']) {
$nextpath[$x] = $path[$x]['path'];
$prevpath[$x] = $path[$x]['path'];
}
break;
}
}
else {
$nextpath[$x] = $path[$x]['path'];
$prevpath[$x] = $path[$x]['path'];
}
}
return array(
$prevpath,
$nextpath,
);
}
/**
* A function to create a blank date to force a calendar display when there is no data
*/
function _calendar_make_node($node = NULL, $timestamp = NULL, $offset = NULL, $year = NULL, $month = NULL, $day = NULL, $hour = NULL, $minute = NULL) {
calendar_load_date_api();
$offset = $offset ? $offset : _views_get_timezone();
if (!$timestamp) {
$year = calendar_part_is_valid($year, 'year') ? $year : date_format_date('Y', date_time());
$month = calendar_part_is_valid($month, 'month') ? $month : date_format_date('m', date_time());
$day = calendar_part_is_valid($day, 'day') ? $day : date_format_date('j', date_time());
$hour = calendar_part_is_valid($hour, 'hour') ? $hour : date_format_date('H', date_time());
$minute = calendar_part_is_valid($minute, 'minute') ? $minute : date_format_date('i', date_time());
while (!checkdate($month, $day, $year)) {
$day--;
}
// Account for days that don't exist
$timestamp = date_gmmktime(array(
'hours' => $hour,
'minutes' => $minute,
'mon' => $month,
'mday' => $day,
'year' => $year,
));
}
if (!$node) {
$node = new stdClass();
$node->nid = 0;
}
$node->calendar_start = $timestamp;
$node->start_offset = $offset;
$node->calendar_end = $timestamp;
$node->end_offset = $offset;
return $node;
}
/**
* A function to adjust node values to slice off times before and after the selected view
* used for calendars that span days, months, or years since the calendar api
* automatically creates additional calendars for calendars that extend into another time period
* and the additional calendars will be incomplete (only containing cross-over calendars)
*/
function _calendar_limit_nodes($nodes, $type, $year, $month, $day, $week, $offset) {
calendar_load_date_api();
if (!calendar_part_is_valid($day, 'day')) {
$day = 1;
}
if (!calendar_part_is_valid($month, 'month')) {
$month = date_format_date('m', date_time());
}
if (!calendar_part_is_valid($year, 'year')) {
$year = date_format_date('Y', date_time());
}
switch ($type) {
case 'day':
$min_date = date_gmmktime(array(
'mon' => $month,
'mday' => $day,
'year' => $year,
));
$max_date = $min_date + 86400 - 1;
break;
case 'week':
return calendar_week_range($year, $week);
case 'month':
$min_date = date_gmmktime(array(
'mon' => $month,
'mday' => 1,
'year' => $year,
));
// find the first day of the next month and subtract one day
if (intval($month) < 12) {
$max_date = date_gmmktime(array(
'mon' => intval($month + 1),
'day' => 1,
'year' => $year,
'hours' => 23,
'minutes' => 59,
'seconds' => 59,
));
}
else {
$max_date = date_gmmktime(array(
'mon' => 1,
'mday' => 1,
'year' => intval($year + 1),
'hours' => 23,
'minutes' => 59,
'seconds' => 59,
));
}
$max_date -= 86400;
break;
case 'year':
$min_date = date_gmmktime(array(
'hours' => 0,
'minutes' => 0,
'seconds' => 0,
'mon' => 1,
'mday' => 1,
'year' => $year,
));
$max_date = date_gmmktime(array(
'hours' => 23,
'minutes' => 59,
'seconds' => 59,
'mon' => 12,
'mday' => 31,
'year' => $year,
));
}
return array(
$min_date,
$max_date,
);
}
/**
* 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 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) {
calendar_load_calendar_api();
$query->calendar_type = 'year';
$query->year = calendar_part_is_valid($arg, 'year') ? $arg : calendar_user_date('year');
$query->month = CALENDAR_EMPTY_ARG;
$query->day = CALENDAR_EMPTY_ARG;
$query->min = $query->year;
$query->max = $query->year;
}
/**
* 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) {
calendar_load_calendar_api();
$query->calendar_type = 'month';
if (!isset($query->year)) {
calendar_filter_year($query, calendar_user_date('year'));
}
$query->month = calendar_part_is_valid($arg, 'month') ? $arg : calendar_user_date('month');
$query->day = CALENDAR_EMPTY_ARG;
$query->min .= '-' . sprintf('%02d', $query->month);
$query->max .= '-' . sprintf('%02d', $query->month);
}
/**
* 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) {
calendar_load_calendar_api();
if (!isset($query->month)) {
calendar_filter_month($query, calendar_user_date('month'));
}
$query->calendar_type = 'day';
$query->day = calendar_part_is_valid($arg, 'day') ? $arg : calendar_user_date('day');
$query->min .= '-' . sprintf('%02d', $query->day);
$query->max .= '-' . sprintf('%02d', $query->day);
}
/**
* 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) {
calendar_load_calendar_api();
if (!isset($query->year)) {
calendar_filter_year($query, calendar_user_date('year'));
}
$arg = str_replace('W', '', $arg);
$query->calendar_type = 'week';
$query->week = calendar_part_is_valid($arg, 'week') ? $arg : calendar_user_date('week');
$query->month = calendar_week('start_month', $query, $query->week);
$query->day = calendar_week('start_day', $query, $query->week);
$query->min = calendar_week('start_year', $query, $query->week) . '-' . sprintf('%02d', calendar_week('start_month', $query, $query->week)) . '-' . calendar_week('start_day', $query, $query->week) . ' 00:00:00';
$query->max = calendar_week('end_year', $query, $query->week) . '-' . sprintf('%02d', calendar_week('end_month', $query, $query->week)) . '-' . calendar_week('end_day', $query, $query->week) . ' 23:59:59';
}
/**
* Custom views handler for all calendar arguments.
*/
function calendar_handler_arg_type($op, &$query, $argtype, $arg, $field_type) {
calendar_load_date_api();
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;
}
/**
* Compile the filter query for this view.
*
* @param object $query
* @param object $view
*/
function calendar_build_filter(&$query, &$view) {
if (!isset($query->week)) {
$query->week = calendar_week('week', $query);
}
if (!$query->min) {
return;
}
// Add elements to the query min and max values to create a complete date value
// for the minimum and maximum once all the View's args have been used.
$minmax = array(
'year' => array(
'-01-01 00:00:00',
"-12-31 23:59:59",
),
'month' => array(
'-01 00:00:00',
'-' . sprintf("%02d", date_last_day_of_month($query->month, $query->year)) . ' 23:59:59',
),
'day' => array(
' 00:00:00',
' 23:59:59',
),
'hour' => array(
':00:00',
':59:59',
),
'minute' => array(
':00',
':59',
),
);
$query->min .= $minmax[$query->calendar_type][0];
$query->max .= $minmax[$query->calendar_type][1];
// find all datetime fields in this view and add filters for them to the query
$queries = array();
foreach ($view->field as $delta => $field) {
$query_strings = calendar_build_field_query($query, $field);
if (!empty($query_strings)) {
$queries = array_merge($queries, $query_strings);
}
}
// bring the node type into the query so we can use it in the theme
$query
->add_field('type', 'node');
if ($queries) {
$query
->add_where(implode(" OR ", $queries));
}
return;
}
/**
* Build a filtering query for an individual date field
*
* @param object $query - the query object
* @param array $field - the view field array
*/
function calendar_build_field_query(&$query, $field) {
$queries = array();
$fields = calendar_fields();
$field_name = $field['field'];
$this_field = $fields[$field_name];
$view_fields[] = $field_name;
if (array_key_exists($field_name, $fields)) {
$query
->ensure_table($this_field['table'], $this_field['table']);
$tz_handling = $this_field['tz_handling'];
$offset_field = $this_field['offset_field'];
$field_type = strstr($this_field['type'], 'string') ? 'iso' : 'int';
// get appropriate timezone offset
switch ($tz_handling) {
case 'user':
global $user;
$start_offset = $end_offset = $user->timezone;
break;
case 'none':
case 'GMT':
$start_offset = $end_offset = 0;
break;
case 'date':
$start_offset = $end_offset = $offset_field;
break;
case 'event':
// event-specific timezones won't work right here because no offset is stored in the database
// the best we can do is treat it the same as if it was a site timezone
default:
$start_offset = $end_offset = variable_get('date_default_timezone', 0);
break;
}
// handling for from and to date ranges
if ($this_field['timestamp_fromto']) {
$queries[] = "(" . date_sql('DATE', $this_field['timestamp_fromto'][1], $field_type, $end_offset) . " >='" . $query->min . "' AND " . date_sql('DATE', $this_field['timestamp_fromto'][0], $field_type, $start_offset) . " <='" . $query->max . "')";
$event_field_processed = TRUE;
}
elseif ($this_field['string_fromto']) {
$queries[] = "(" . date_sql('DATE', $this_field['string_fromto'][1], $field_type, $end_offset) . " >='" . $query->min . "' AND " . date_sql('DATE', $this_field['string_fromto'][0], $field_type, $start_offset) . " <='" . $query->max . "')";
$event_field_processed = TRUE;
}
elseif ($this_field['type'] == 'cck_string') {
$queries[] = "(" . date_sql('DATE', $this_field['fullname'], $field_type, $start_offset) . ">='" . $query->min . "' AND " . date_sql('DATE', $field['fullname'], $field_type, $end_offset) . "<='" . $query->max . "')";
}
elseif (strstr($this_field['type'], 'timestamp')) {
$queries[] = "(" . date_sql('DATE', $this_field['fullname'], $field_type, $start_offset) . ">='" . $query->min . "' AND " . date_sql('DATE', $this_field['fullname'], $field_type, $end_offset) . "<='" . $query->max . "')";
}
}
return $queries;
}
/**
* 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) {
$view->real_args = $view->args;
$view->real_url = calendar_real_url($view, $view->args);
if (!calendar_has_calendar_args($view) || empty($view->args) && !calendar_is_calendar_arg($view) && $view->argument[0]['argdefault'] != 2) {
return;
}
calendar_load_calendar_api();
calendar_load_date_api();
// make sure block views default to the current month
// and make sure day view is not selected
if ($view->build_type == 'block') {
$query->calendar_type = 'month';
$view->args = explode('/', str_replace($view->url . '/', '', $_GET['mini']));
foreach ($view->argument as $delta => $argument) {
// Special handling for OG gid argument.
// Find a default value for the gid when used in a block.
if ($argument['type'] == 'gid') {
$groupnodes = calendar_og_groups($view);
$view->args[$delta] = $groupnodes[0];
$query
->ensure_table('og_ancestry');
$query
->add_where("og_ancestry.group_nid IN (%d)", implode(',', $groupnodes));
}
if ($argument['type'] == 'calendar_year') {
if (!$view->args[$delta]) {
$view->args[$delta] = calendar_user_date('year');
}
$query->year = $view->args[$delta];
calendar_filter_year($query, $query->year);
}
elseif ($argument['type'] == 'calendar_month' || $argument['type'] == 'calendar_week') {
if (!$view->args[$delta]) {
$view->args[$delta] = calendar_user_date('month');
}
$query->month = $view->args[$delta];
calendar_filter_month($query, $query->month);
}
elseif ($argument['type'] == 'calendar_day') {
$query->day = CALENDAR_EMPTY_ARG;
$view->args[$delta] = CALENDAR_EMPTY_ARG;
}
}
}
// Either a month or a week argument could occupy the second position of the group
// this is done so that a single view has the capability to switch between all calendar layouts
// to make this work we must make some adjustments to the view
if ($view->build_type == 'page') {
$GLOBALS['calendar_is_calendar'] = TRUE;
if (empty($view->args) || !calendar_is_calendar_arg($view)) {
// If no arguments are provided, default to current month view.
$query->calendar_type = 'month';
foreach ($view->argument as $delta => $argument) {
if ($argument['type'] == 'calendar_year' && !$view->args[$delta]) {
$view->args[$delta] = calendar_user_date('year');
calendar_filter_year($query, calendar_user_date('year'));
}
elseif ($argument['type'] == 'calendar_month' && !$view->args[$delta]) {
$view->args[$delta] = calendar_user_date('month');
calendar_filter_month($query, calendar_user_date('month'));
}
elseif ($argument['type'] == 'calendar_day' && !$view->args[$delta]) {
$view->args[$delta] = CALENDAR_EMPTY_ARG;
}
else {
$view->args[$delta] = $view->real_args[$delta];
}
}
}
foreach ($view->argument as $delta => $argument) {
if (in_array($argument['type'], calendar_args())) {
// make sure 'display all values' is selected for the calendar arguments
// summary views are meaningless and create errors in this context
$view->argument[$delta]['argdefault'] = 2;
// Pad any unused values in the view arguments with CALENDAR_EMPTY_ARG to indicate all values.
if (empty($view->args[$delta])) {
$view->args[$delta] = CALENDAR_EMPTY_ARG;
}
}
// Calendar_week and Calendar_month can swap positions as the second arg in the url.
// Do some work here to make sure we know which is which and swap view data to match it.
// the difference between a calendar_month arg and a calendar_week arg is the preceeding 'W'
if ($argument['type'] == 'calendar_week' || $argument['type'] == 'calendar_month') {
if (strstr($view->args[$delta], 'W')) {
calendar_filter_week($query, $view->args[$delta]);
$view->argument[$delta]['type'] = 'calendar_week';
$view->argument[$delta]['id'] = 'calendar_week';
$view->argument[$delta + 1]['type'] = 'calendar_day';
$view->argument[$delta + 1]['id'] = 'calendar_day';
// Make sure that there is no day set for the week view.
$view->args[$delta + 1] = CALENDAR_EMPTY_ARG;
}
elseif (!strstr($view->args[$delta], 'W') && $view->build_type == 'page' && $view->argument[$delta]['type'] == 'calendar_week') {
calendar_filter_month($query, $view->args[$delta]);
$view->argument[$delta]['type'] = 'calendar_month';
$view->argument[$delta]['id'] = 'calendar_month';
$view->argument[$delta + 1]['type'] = 'calendar_day';
$view->argument[$delta + 1]['id'] = 'calendar_day';
}
}
}
}
// Make sure the calendar query gets inserted. May not have finished yet on views like year or year/month.
if (!$query->calendar_finished) {
calendar_build_filter($query, $view);
}
$view->calendar_type = $query->calendar_type;
$view->year = $query->year;
$view->month = $query->month;
$view->day = $query->day;
$view->week = $query->week;
}
/**
* Implementation of hook_views_pre_view()
*/
function calendar_views_pre_view(&$view, &$items) {
// If no part of this view has calendar elements, exit.
if (!calendar_is_calendar($view) || !calendar_has_calendar_args($view)) {
return;
}
// Construct a formatted title for the view from the last calendar argument encountered.
switch ($view->calendar_type) {
case 'year':
$view->subtitle = theme('calendar_nav_title', 'YEAR', $view);
break;
case 'month':
$view->subtitle = theme('calendar_nav_title', 'MONTH', $view);
break;
case 'day':
$view->subtitle = theme('calendar_nav_title', 'DAY', $view);
break;
case 'week':
$view->subtitle = theme('calendar_nav_title', 'WEEK', $view);
break;
}
// 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;
}
$title = theme('calendar_page_title', $view, $items, $output);
drupal_set_title($title);
}
/**
* Get the start and end datestamp for a calendar week.
*/
function calendar_week_range($year, $week) {
calendar_load_date_api();
// Get timestamp for January 1 of the requested year.
$min_date = date_gmmktime(array(
'mon' => 1,
'mday' => 1,
'year' => $year,
));
// Adjust back or forward to the first day of the calendar week for the specified first day of week.
$dow = date_format_date('w', $min_date);
$first_day = variable_get('date_first_day', 0);
$diff = -((7 - $first_day + $dow) % 7);
$min_date += $diff * 86400;
// Add the requested number of weeks to that date.
$min_date += intval(($week - 1) * 604800);
// Find the end date, which is one week later, less one second.
$max_date = $min_date + 604800 - 1;
return array(
$min_date,
$max_date,
);
}
/**
* Find the calendar week number and year for a date.
*
* This is complicated by the fact that the calendar week does not match the ISO week,
* since the ISO week starts on Monday for the first week that has 4 or more days in the new year
* while the calendar week starts on the site's preferred first day of the week regardless
* of the number of days that are in the first week or the year.
*
* @param unknown_type $timestamp
* @return array of calendar week number and year
*/
function calendar_week_year($timestamp) {
$first_day = variable_get('date_first_day', 0);
$iso_week = intval(date_format_date('W', $timestamp));
$year = date_format_date('Y', $timestamp);
// Where does this timestamp fall within the range for the iso week number.
$range = calendar_week_range($year, $iso_week);
// If the timestamp is in the range, the ISO week number is correct.
if ($timestamp >= $range[0] && $timestamp <= $range[1]) {
return array(
$iso_week,
$year,
);
}
elseif ($timestamp < $range[1]) {
if ($iso_week >= 2) {
return array(
intval($iso_week - 1),
$year,
);
}
else {
return array(
1,
$year,
);
}
}
elseif ($timestamp > $range[0]) {
if ($iso_week < 52) {
return array(
intval($iso_week + 1),
$year,
);
}
else {
return array(
1,
intval($year + 1),
);
}
}
}
/**
* Handle a lot of messy week calculations all in one place to make maintenance easier
*/
function calendar_week($op, $view, $week = 0) {
calendar_load_date_api();
if ($week == 0) {
$day = !empty($view->day) && $view->day != CALENDAR_EMPTY_ARG ? $view->day : calendar_user_date('day');
$month = !empty($view->month) && $view->month != CALENDAR_EMPTY_ARG ? $view->month : calendar_user_date('month');
$isodate = $view->year . '-' . sprintf('%02d', $month) . '-' . sprintf('%02d', $day) . 'T00:00:00';
$week_year = calendar_week_year(date_iso2unix($isodate));
if ($op == 'week') {
return $week_year[0];
}
}
$range = calendar_week_range($view->year, $week);
$week_start = $range[0];
$week_end = $range[1];
switch ($op) {
case 'start_year':
return date_format_date('Y', $week_start);
case 'end_year':
return date_format_date('Y', $week_end);
case 'start_month':
return date_format_date('n', $week_start);
case 'end_month':
return date_format_date('n', $week_end);
case 'start_day':
return date_format_date('d', $week_start);
case 'end_day':
return date_format_date('d', $week_end);
default:
return $week_start;
}
}
/**
* 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;
}
calendar_load_date_api();
$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'] ? '<div class="calendar legend">' . theme('calendar_stripe_legend', $GLOBALS['calendar_stripe_labels']) . '</div>' : '';
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;
}
/**
* Implementation of hook_calendar_node() from the calendar_get_calendar() api
* calendar api is expecting a function for each calendar type but
* all of them need the same processing, so run them through a single function
* instead of duplicating the processing for each one
*/
function calendar_calendar_node_month($node) {
return calendar_calendar_node($node, 'calendar_node_month');
}
function calendar_calendar_node_day($node) {
return calendar_calendar_node($node, 'calendar_node_day');
}
function calendar_calendar_node_week($node) {
return calendar_calendar_node($node, 'calendar_node_week');
}
function calendar_calendar_node($node, $type) {
calendar_load_calendar_api();
if ($node->nid && $node->nid !== 0 && $node->calendar_start) {
// this is a real calendar, go ahead and display it
if (!$node->remote) {
// switch our psuedo nids back to the right values
$tmp = explode(':', $node->nid);
$node->nid = $tmp[0];
$node->instance = $tmp[1];
}
if (isset($node->calendar_node_theme)) {
return theme($node->calendar_node_theme, $node, $type);
}
else {
return theme('calendar_calendar_node', $node, $type);
}
}
else {
// surpress display of psuedo calendars added to force display of a blank calendar
// have to return some value for blank day so not overridden by normal calendar node theme
// a blank space seems to be sufficient to do that
return ' ';
}
}
/**
* Valid calendar arguments.
*/
function calendar_args() {
return array(
'calendar_year',
'calendar_week',
'calendar_month',
'calendar_day',
);
}
/**
* Figure out what the URL of the calendar view we're currently looking at is.
*/
function calendar_real_url($view, $args) {
// 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 (in_array($part, array(
'$arg',
'$node',
'$user',
'$group',
))) {
$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);
}
/**
* Pick up filter and sort info from url.
*/
function calendar_url_append($view) {
if ($view->build_type == 'page') {
foreach ($_GET as $key => $val) {
if ($key != 'q' && $key != 'view') {
if (!is_array($val)) {
$url .= '&' . $key . '=' . $val;
}
else {
foreach ($val as $v) {
$url .= '&' . $key . '[]=' . $v;
}
}
}
}
}
return $url;
}
/**
* Function to test whether this is a view that uses the calendar plugin theme.
*/
function calendar_is_calendar($view) {
$calendar_info = calendar_info();
return $calendar_info[$view->name][$view->build_type];
}
/**
* 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 (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 id from a combination of the field and content types
* and store value for legend
* formula tries to create a unique id for each possible combination
*
* @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 $label - the label to give this stripe.
*/
function calendar_node_stripe($view, $node, $query_name, $delta, $stripe = NULL, $label = '') {
$type_names = node_get_types('names');
if (!$label) {
$label = $view->field[$delta]['label'] . ' (' . $type_names[$node->type] . ')';
}
if (!$stripe) {
$i = 1;
foreach ($type_names as $k => $v) {
if ($k == $node->type) {
break;
}
$i++;
}
$stripe = intval(20 * $delta + $i);
}
$GLOBALS['calendar_stripe_labels'][$stripe] = $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() {
include_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() {
include_once './' . drupal_get_path('module', 'calendar') . '/calendar_admin.inc';
return _calendar_views_default_views();
}
/**
* Implementation of hook_views_arguments()
*/
function calendar_views_arguments() {
include_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) {
include_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 {
include_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 {
include_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) {
include_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) {
include_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) {
include_once './' . drupal_get_path('module', 'calendar') . '/calendar_admin.inc';
return _calendar_setup_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;
}
Functions
Name | Description |
---|---|
calendar_add_items | Call hooks in other modules to add other items to a calendar view. |
calendar_args | Valid calendar arguments. |
calendar_arg_positions | The positions in the view that hold calendar arguments. |
calendar_block | implementation of hook_block() |
calendar_build_field_query | Build a filtering query for an individual date field |
calendar_build_filter | Compile the filter query for this view. |
calendar_calendar_node | |
calendar_calendar_node_day | |
calendar_calendar_node_month | Implementation of hook_calendar_node() from the calendar_get_calendar() api calendar api is expecting a function for each calendar type but all of them need the same processing, so run them through a single function instead of duplicating the… |
calendar_calendar_node_week | |
calendar_clear_all | Empty or reset cached values. |
calendar_fields | Identify all potential date/timestamp fields |
calendar_filter_day | Callback for day filter. Build year, month, day, min, and max into query object. |
calendar_filter_month | Callback for month filter. Build year, month, day, min, and max into query object. |
calendar_filter_week | Callback for week filter. Build year, month, day, min, and max into query object. |
calendar_filter_year | Callback for year filter. Build year, month, day, min, and max into query object. |
calendar_form_alter | Implementation of hook_form_alter(). Make sure calendar_info() and calendar_fields() get updated. |
calendar_get_formats | Helper function to find the display formats for each part of this view. |
calendar_get_nodes | The workhorse function that takes the beginning array of items and alters it to an array of calendar nodes that the theme can handle. |
calendar_get_paths | |
calendar_handler_arg_day | Custom views handler for the day argument. |
calendar_handler_arg_month | Custom views handler for the month argument. |
calendar_handler_arg_type | Custom views handler for all calendar arguments. |
calendar_handler_arg_week | Custom views handlers for the week argument. |
calendar_handler_arg_year | Custom views handler for the year argument. |
calendar_has_calendar_args | Function to test whether any calendar args are used in this view. |
calendar_help | Implementation of hook_help(). |
calendar_info | Function to get information about all views that have calendar components. |
calendar_is_calendar | Function to test whether this is a view that uses the calendar plugin theme. |
calendar_is_calendar_arg | Is the current argument a calendar argument. Used to sort out whether or not to display the calendar at each point. |
calendar_is_last_arg | 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. |
calendar_load_calendar_api | Helper function for loading calendar_api. |
calendar_load_date_api | Helper function for loading date_api. |
calendar_menu | Implementation of hook_menu(). |
calendar_nav | Function to construct back and next navigation from views arguments |
calendar_node_stripe | create a stripe id from a combination of the field and content types and store value for legend formula tries to create a unique id for each possible combination |
calendar_offset | TODO need to identify type of timezone handling needed for each date field |
calendar_og_groups | Helper function to figure out a group gid to use in blocks. |
calendar_part_is_valid | A function to test the validity of various date parts |
calendar_real_url | Figure out what the URL of the calendar view we're currently looking at is. |
calendar_setup_form | Setup Calendar parameters in the Setup Tab. |
calendar_setup_form_submit | Save Setup values. |
calendar_switch_view | A block with a drop-down list that allows the user to switch between views of the current period |
calendar_url_append | Pick up filter and sort info from url. |
calendar_views_arguments | Implementation of hook_views_arguments() |
calendar_views_default_views | Implementation of hook_views_default_views() |
calendar_views_post_view | Implementation of hook_views_post_view(). |
calendar_views_pre_view | Implementation of hook_views_pre_view() |
calendar_views_query_alter | 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… |
calendar_views_style_plugins | Implementation of hook_views_style_plugins() |
calendar_views_tabs | Implementation of hook_views_tabs(). |
calendar_views_validate | Validate a view during Views administration. |
calendar_view_types | Function to return all possible calendar views page display types. |
calendar_week | Handle a lot of messy week calculations all in one place to make maintenance easier |
calendar_week_range | Get the start and end datestamp for a calendar week. |
calendar_week_year | Find the calendar week number and year for a date. |
_calendar_limit_nodes | A function to adjust node values to slice off times before and after the selected view used for calendars that span days, months, or years since the calendar api automatically creates additional calendars for calendars that extend into another time… |
_calendar_make_node | A function to create a blank date to force a calendar display when there is no data |