event_start). * Optionally, an end value ($node->event_end) and a time zone offset value * in the same format as drupal core ($node->tz). If a node has no end * value, it is rendered on only one day. If no time zone value is displayed * the time is rendered with no time zone offset (GMT). * @param $module - String containing the name of the module calling the function * @param $title - A string value that will be printed into the header of the calendar * @param $params - an optional array of additional values that may be needed * $params[force_week] - a week number to limit the displayed calendar to only that week * $params[with_weekno] - add a column for the week number to the calendar * $params[hide_header] - true to omit td header row(s) * $params[as_array] - true to return the rows array instead of the themed table * $params[mini] - this is a mini calendar, don't display item details * $params[url] - an url to use as a base url in month and days * $params[append] - a query string to append to urls * $params[stripe] - an node field to use instead of nid for stripes * $params[limit] - an array of a minimum and maximum timestamp to include on the calendar * used in case node array has values that overlap periods * @return Themed calendar view of nodes or array of calendar rows */ function calendar_get_calendar($view, $nodes, $module, $title = NULL, $params = array()) { $today = calendar_user_date(); if ($params['limit'][0]) { $min_date = $params['limit'][0]; $max_date = $params['limit'][1]; } else { $min_date = 0; $max_date = 999999999999; } $data = array(); foreach ($nodes as $nid => $node) { $node->stripe = $params['stripe'] ? $node->$params['stripe'] : $node->nid; $calendar = new stdClass(); $nodes[$node->nid] = $node; $calendar->nid = $node->nid; // $node_start and $node_end are local timestamp values if ($min_date - $node->start_offset > $node->calendar_start) { $node->calendar_start = $min_date - $node->start_offset; } if ($max_date - $node->end_offset < $node->calendar_end) { $node->calendar_end = $max_date - $node->end_offset; } $node_start = gmmktime(0, 0, 0, calendar_event_date('m', $node->calendar_start, $node->start_offset), calendar_event_date('d', $node->calendar_start, $node->start_offset), calendar_event_date('Y', $node->calendar_start, $node->start_offset)); if ($node->calendar_end) { $node_end = gmmktime(0, 0, 0, calendar_event_date('m', $node->calendar_end, $node->end_offset), calendar_event_date('d', $node->calendar_end, $node->end_offset), calendar_event_date('Y', $node->calendar_end, $node->end_offset)); } else { $node_end = $node_start; } if ($node_start == $node_end) { $calendar->calendar_state = 'singleday'; $calendar->stamp = $node_start; $calendar->stripe = $node->stripe; $data[gmdate('Y', $node_start)][gmdate('m', $node_start)][gmdate('j', $node_start)][] = $calendar; } else { // roll through each day the calendar occurs and set an entry for each for ($x = $node_start; $x <= $node_end; $x += 86400) { if ($x == $node_end) { $calendar = new StdClass(); $calendar->nid = $node->nid; $calendar->stripe = $node->stripe; $calendar->calendar_state = 'end'; $calendar->stamp = $x; $data[gmdate('Y', $x)][gmdate('m', $x)][gmdate('j', $x)][] = $calendar; } elseif ($x == $node_start) { $calendar = new StdClass(); $calendar->nid = $node->nid; $calendar->stripe = $node->stripe; $calendar->calendar_state = 'start'; $calendar->stamp = $x; $data[gmdate('Y', $x)][gmdate('m', $x)][gmdate('j', $x)][] = $calendar; } else { $calendar = new StdClass(); $calendar->nid = $node->nid; $calendar->stripe = $node->stripe; $calendar->calendar_state = 'ongoing'; $calendar->stamp = $x; $data[gmdate('Y', $x)][gmdate('m', $x)][gmdate('j', $x)][] = $calendar; } } } } // order the years, months and days ksort($data, SORT_NUMERIC); foreach($data as $year => $months) { ksort($data[$year], SORT_NUMERIC); foreach($data[$year] as $month => $days) { ksort($data[$year][$month], SORT_NUMERIC); } } $weekdays = calendar_week_days(); switch ($view) { case 'day': case 'table': foreach ($data as $year => $months) { if(count($data) > 1 && !$params['hide_header']) { // add year heading $rows[][] = array( 'class' => 'heading year', 'id' => 'year'.$year, 'data' => $year); } foreach($months as $month => $days) { foreach($days as $day => $calendars) { $content = theme('calendar_date_box', $year, $month, $day, 'table', $params['mini'], $calendars, $params['url']); foreach($calendars as $calendar) { if(!$month_name) { $month_name = gmdate('M', $calendar->stamp); $dow = _calendar_day_of_week($calendar->stamp); } $node = $nodes[$calendar->nid]; $node->calendar_state = $calendar->calendar_state; if($output = module_invoke($module, 'calendar_node_'. $view, $node)) { $content .= $output; } else { $content .= theme('calendar_node_'. $view, $node); } } $rows[][] = array( 'class' => strtolower("$month_name ". $weekdays[$dow]['day'] . ($calendar->stamp == $today ? ' today' : '')), 'id' => strtolower($month_name . $day), 'data' => $content); $month_name = NULL; } } } break; case 'week': case 'month': case 'year': $colspan = $params['with_weekno'] ? '8' : '7'; foreach ($data as $year => $months) { $month_rows[] = $title; if(count($data) > 1 && !$params['hide_header']) { // add year heading $rows[][] = array( 'class' => 'heading year', 'id' => 'year'. $year, 'data' => $year, 'colspan' => $colspan); } foreach ($months as $month => $days) { // timestamp of first day in month $curstamp = gmmktime(0, 0, 0, $month, 1, $year); // timestamp of last day in month $lastday = gmmktime(0, 0, 0, $month, gmdate('t', $curstamp), $year); // pad the first week row array to fill up days in the previous month we don't build $row = array_fill(0, 6, ''); // get the day of week offset value for the first day of the month $start = $offset = _calendar_day_of_week($curstamp); // get name of month $month_name = gmdate('M', $curstamp); $month_link = $params['url'] ? l($month_name, $params['url'] .'/'. $year .'/'. intval($month)) : $month_name; // set week counter $week = 0; if (!$params['hide_header']) { $rows[][] = array( 'class' => 'heading month', 'id' => 'month'. $month, 'data' => $month_name, 'colspan' => $colspan); } $rows[] = calendar_week_header($params['mini'], $params['with_weekno']); while ($curstamp <= $lastday) { for ($x = $start; $x < 7; $x++) { $cur_day = (($week * 7) + ($x + 1) - $offset); $selected = FALSE; if(is_array($days[$cur_day])) { // make sure dummy nodes added to create blank calendars don't get marked as having content foreach ($items = $days[$cur_day] as $item) { if ($item->nid) { $selected = TRUE; } } } $content = theme('calendar_date_box', $year, $month, $cur_day, $view, $params['mini'], $selected, $params['url']); // render nodes for the day if(is_array($days[$cur_day]) && !$params['mini']) { foreach($days[$cur_day] as $calendar) { $node = $nodes[$calendar->nid]; $node->calendar_state = $calendar->calendar_state; if($output = module_invoke($module, 'calendar_node_'. $view, $node)) { $content .= $output; } elseif (!$params['mini'] && $node->nid > 0) { $content .= theme('calendar_node_'. $view, $node); } } } $row[$x] = array( 'class' => strtolower("$month_name ". $weekdays[$x]['day'] . ($curstamp == $today ? ' today' : '') . ($params['mini'] ? ' mini' : '')), 'id' => strtolower($month_name . $cur_day), 'data' => $params['mini'] ? $content : '