function calendar_get_nodes in Calendar 5
The workhorse function that takes the beginning array of items and alters it to an array of calendar nodes that the theme can handle.
2 calls to calendar_get_nodes()
- theme_calendar_ical_feed in ./
calendar_ical.module - plugin that actually displays an ical feed
- theme_calendar_view_calendar in ./
calendar.theme - Calendar Views plugin theme, overrides default views theme to create a calendar view.
File
- ./
calendar.module, line 125 - Adds calendar filtering and displays to Views.
Code
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,
);
}