/[drupal]/contributions/sandbox/frjo/event46/event.module
ViewVC logotype

Contents of /contributions/sandbox/frjo/event46/event.module

Parent Directory Parent Directory | Revision Log Revision Log | View Revision Graph Revision Graph


Revision 1.2 - (show annotations) (download) (as text)
Fri Apr 28 19:36:33 2006 UTC (3 years, 7 months ago) by frjo
Branch: MAIN
CVS Tags: HEAD
Changes since 1.1: +4 -4 lines
File MIME type: text/x-php
#49429, fixing mysql5 issue, patch by starbow
1 <?php
2 // $Id: event.module,v 1.1 2006/03/30 08:54:25 frjo Exp $
3
4 include(drupal_get_path('module', 'event') .'/event.theme');
5 include(drupal_get_path('module', 'event') .'/event_timezones.inc');
6 include(drupal_get_path('module', 'event') .'/ical.inc');
7
8 /**
9 * @defgroup event_core Core drupal hooks
10 */
11
12 /**
13 * Provides a link to the CSS stylesheet associated with this module.
14 *
15 * @ingroup event_core
16 * @return a &lt;style&gt; tag that indicates what file browsers should import
17 */
18 function event_html_head() {
19 $output = '<script type="text/javascript" src="'. drupal_get_path('module', 'event') .'/event.js"></script>';
20 $output .= theme('stylesheet_import', drupal_get_path('module', 'event') .'/event.css','screen');
21 return $output;
22 }
23
24 /**
25 * Provides the links that should be displayed when viewing events.
26 *
27 * @ingroup event_core
28 * @param $type the type of link (for example, 'node', 'page', or 'system') being requested
29 * @param $node the node that is requesting the link. This is used in conjunction with $type to further determine
30 * what sort of link to display.
31 * @param $main unused in this method.
32 * @return an array of links, or an empty array if no links apply for the criteria passed to this method.
33 */
34 function event_link($type, $node = NULL, $teaser = FALSE) {
35 switch ($type) {
36 case 'node':
37 if (event_enabled_state($node->type) == 'all') {
38 $links[] = l(t('calendar'), 'event/'. format_date($node->event_start, 'custom', 'Y/m/d'));
39 }
40 elseif (event_enabled_state($node->type) == 'solo') {
41 $links[] = l(t('calendar'), 'event/'. format_date($node->event_start, 'custom', 'Y/m/d') .'/month/'. $node->type);
42 }
43 break;
44 case 'event_month':
45 if (user_access('access content')) {
46 $links[] = l(t('week'), "event/$node->year/$node->month/$node->day/week/". $node->filter, array('title' => t('Week view')));
47 $links[] = l(t('day'), "event/$node->year/$node->month/$node->day/day/". $node->filter, array('title' => t('Day view')));
48 $links[] = l(t('table'), "event/$node->year/$node->month/$node->day/table/". $node->filter, array('title' => t('Table view')));
49 $links[] = l(t('list'), "event/$node->year/$node->month/$node->day/list/". $node->filter, array('title' => t('List view')));
50 }
51 break;
52 case 'event_week':
53 if (user_access('access content')) {
54 $links[] = l(t('month'), "event/$node->year/$node->month/$node->day/month/". $node->filter, array('title' => t('Month view')));
55 $links[] = l(t('day'), "event/$node->year/$node->month/$node->day/day/". $node->filter, array('title' => t('Day view')));
56 $links[] = l(t('table'), "event/$node->year/$node->month/$node->day/table/". $node->filter, array('title' => t('Table view')));
57 $links[] = l(t('list'), "event/$node->year/$node->month/$node->day/list/". $node->filter, array('title' => t('List view')));
58 }
59 break;
60 case 'event_day':
61 if (user_access('access content')) {
62 $links[] = l(t('month'), "event/$node->year/$node->month/$node->day/month/". $node->filter, array('title' => t('Month view')));
63 $links[] = l(t('week'), "event/$node->year/$node->month/$node->day/week/". $node->filter, array('title' => t('Week view')));
64 $links[] = l(t('table'), "event/$node->year/$node->month/$node->day/table/". $node->filter, array('title' => t('Table view')));
65 $links[] = l(t('list'), "event/$node->year/$node->month/$node->day/list/". $node->filter, array('title' => t('List view')));
66 }
67 break;
68 case 'event_table':
69 if (user_access('access content')) {
70 $links[] = l(t('month'), "event/$node->year/$node->month/$node->day/month/". $node->filter, array('title' => t('Month view')));
71 $links[] = l(t('week'), "event/$node->year/$node->month/$node->day/week/". $node->filter, array('title' => t('Week view')));
72 $links[] = l(t('day'), "event/$node->year/$node->month/$node->day/day/". $node->filter, array('title' => t('Day view')));
73 $links[] = l(t('list'), "event/$node->year/$node->month/$node->day/list/". $node->filter, array('title' => t('List view')));
74 }
75 break;
76 case 'event_list':
77 if (user_access('access content')) {
78 $links[] = l(t('month'), "event/$node->year/$node->month/$node->day/month/". $node->filter, array('title' => t('Month view')));
79 $links[] = l(t('week'), "event/$node->year/$node->month/$node->day/week/". $node->filter, array('title' => t('Week view')));
80 $links[] = l(t('day'), "event/$node->year/$node->month/$node->day/day/". $node->filter, array('title' => t('Day view')));
81 $links[] = l(t('table'), "event/$node->year/$node->month/$node->day/table/". $node->filter, array('title' => t('Table view')));
82 }
83 break;
84 }
85 return $links ? $links : array();
86 }
87
88 /**
89 * Implementation of hook_menu()
90 *
91 * @ingroup event_core
92 */
93 function event_menu($may_cache) {
94 global $user;
95
96 $items = array();
97 if ($may_cache) {
98 $items[] = array('path' => 'event',
99 'title' => t('events'),
100 'callback' => 'event_page',
101 'access' => user_access('access content'),
102 'type' => MENU_CALLBACK);
103 $items[] = array('path' => 'event/additem',
104 'title' => t('add item to calendar'),
105 'callback' => 'event_add_item',
106 'access' => user_access('access content'),
107 'type' => MENU_CALLBACK);
108 $items[] = array('path' => 'event/type',
109 'title' => t('filter by content type'),
110 'callback' => 'event_type',
111 'access' => user_access('access content'),
112 'type' => MENU_CALLBACK);
113 $items[] = array('path' => 'event/term',
114 'title' => t('filter by taxonomy'),
115 'callback' => 'event_term',
116 'access' => user_access('access content'),
117 'type' => MENU_CALLBACK);
118 $items[] = array('path' => 'event/feed',
119 'title' => t('event rss feed'),
120 'callback' => 'event_feed',
121 'access' => user_access('access content'),
122 'type' => MENU_CALLBACK);
123 $items[] = array('path' => 'event/dst',
124 'title' => t('event dst view'),
125 'callback' => 'event_dst',
126 'access' => user_access('access content'),
127 'type' => MENU_CALLBACK);
128 $items[] = array('path' => 'event/ical',
129 'title' => t('event ical feed'),
130 'callback' => 'event_ical',
131 'access' => user_access('access content'),
132 'type' => MENU_CALLBACK);
133 }
134 else {
135 drupal_set_html_head(event_html_head());
136 }
137 return $items;
138 }
139
140 /**
141 * Displays and allows an administrator to change the settings for this module.
142 *
143 * @ingroup event_core
144 * @return the content for a settings page.
145 */
146 function event_settings() {
147
148 if (variable_get('configurable_timezones', 0)) {
149 $group .= form_radios(t('Event time zone input'), 'event_timezone_input', variable_get('event_timezone_input', 'site'), array('site' => t('Use the sitewide time zone'), 'user' => t('Use the time zone of the user editing or creating the event'), 'input' => t('Allow users to set event time zones')), t('Events are saved with a time zone value. This setting allows you to determine how the time zone is determined when creating or editing an event.'));
150
151 $group .= form_radios(t('Event time zone display'), 'event_timezone_display', variable_get('event_timezone_display', 'event'), array('event' => t("Use the event's time zone"), 'user' => t("Use the user's time zone"), 'site' => t('Use the sitewide time zone')), t("Events are saved with a time zone value. This setting allows you to determine if the event's time zone, the sitewide time zone, or the user's personal time zone setting is used to display the time for an event."));
152 }
153 else {
154 if (variable_get('event_timezone_input', 'site') == 'user') {
155 variable_set('event_timezone_input', 'site');
156 }
157 variable_set('event_timezone_display', 'event');
158
159 $group .= form_radios(t('Event time zone input'), 'event_timezone_input', variable_get('event_timezone_input', 'site'), array('site' => t('Use the sitewide time zone'), 'user" disabled' => t('Use the time zone of the user editing or creating the event'), 'input' => t('Allow users to set event time zones')), t("Events are saved with a time zone value. This setting allows you to determine how the time zone is determined when creating or editing an event. You must have 'Configurable time zones' enabled in %url before you can enable user's time zones for this feature.", array('%url' => l(t('site configuration'), 'admin/settings'))));
160
161 $group .= form_radios(t('Event time zone display'), 'event_timezone_display', 'event', array('event' => t("Use the event's time zone"), 'site' => t('Use the sitewide time zone')), t("Events are saved with a time zone value. This setting allows you to determine if the event's time zone, the sitewide time zone, or the user's personal time zone setting is used to display the time for an event. You must have 'Configurable time zones' enabled in %url before you can enable user's time zones for this feature.", array('%url' => l(t('site configuration'), 'admin/settings'))));
162 }
163 $group .= form_radios(t('Time notation preference'), 'event_ampm', variable_get('event_ampm', '0'), array('0' => t('24h'),'1' => t('12h')), t('The time notation system used for entering event times.'));
164 $group .= form_textfield(t('Upcoming event block limit'), 'event_upcoming_limit', variable_get('event_upcoming_limit', '6'), 5, 2, t('Limit the amount of events displayed in the upcoming events block by this amount.'));
165 $output = form_group(t('General Event options'), $group);
166
167 $group = form_radios(t('Default overview'), 'event_overview', variable_get('event_overview', 'month'), array('day' => t('Day'), 'week' => t('Week'), 'month' => t('Month'), 'table' => t('Table'), 'list' => t('List')), t('The default event view to display when no format is specifically requested. This is also the view that will be displayed from the block calendar links.'));
168 $group .= form_textfield(t('Table view default period'), 'event_table_duration', variable_get('event_table_duration', '30'), 5, 3, t('The default number of days to display in the table view. You can specify a different number of days in the url. More info on the event url format %link', array('%link' => l(t('here'), 'admin/help/event#url-format'))));
169
170 if (module_exist('taxonomy')) {
171 $group .= form_radios('Taxonomy filter controls', 'event_taxonomy_control',
172 variable_get('event_taxonomy_control', 'all'),
173 array('all' => t('Show taxonomy filter control on calendar views'),
174 'request' => t('Only show taxonomy filter control when taxonomy filter view is requested'),
175 'never' => t('Never show taxonomy filter control')));
176 }
177 $group .= form_radios('Content type filter controls', 'event_type_control',
178 variable_get('event_type_control', 'all'),
179 array('all' => t('Show content type filter control on calendar views'),
180 'request' => t('Only show content type filter control when content type filter view is requested'),
181 'never' => t('Never show content type filter control')));
182
183 $output .= form_group(t('Event overview options'), $group);
184
185 return $output;
186 }
187
188 /**
189 * @defgroup event_callback Functions which are the menu callbacks for this module
190 */
191
192 /**
193 * Displays a page containing event information. The page layout defaults to a graphical calendar.
194 *
195 * @ingroup event_callback
196 * @return the content for the event page.
197 */
198 function event_page($year = NULL, $month = NULL, $day = NULL, $view = NULL, $types = NULL, $tids = NULL, $duration = NULL) {
199
200 // get local timestamp value
201 $now = _event_user_time();
202
203 // create request timestamp and date values
204 $stamp = gmmktime(0, 0, 0, ($month ? $month : gmdate('m', $now)), ($day ? $day : gmdate('d', $now)), ($year ? $year : gmdate('Y', $now)));
205 $year = gmdate('Y', $stamp);
206 $month = gmdate('m', $stamp);
207 $day = gmdate('d', $stamp);
208
209 $view = $view ? $view : variable_get('event_overview', 'month');
210
211 if ($_POST['edit']['event_type_select']) {
212 drupal_goto('event/'. $year .'/'. $month .'/'. $day .'/'. $view .'/'. $_POST['edit']['event_type_select'] .'/'. $tids);
213 }
214
215 if ($_POST['edit']['event_term_select']) {
216 drupal_goto('event/'. $year .'/'. $month .'/'. $day .'/'. $view .'/'. ($types ? $types : 'all') .'/'. $_POST['edit']['event_term_select']);
217 }
218
219 $breadcrumbs[] = l(t('Home'), NULL);
220 $breadcrumbs[] = l(t('Events'), 'event');
221 $links = array();
222
223 if ($types) {
224 // The '+' character in a query string may be parsed as ' '.
225 $types = preg_split('/[+ ]/', $types);
226 foreach ($types as $type) {
227 if (is_numeric($type)) {
228 $ctype = module_invoke('flexinode', 'load_content_type', $type);
229 if ($ctype->name) {
230 $temp[$ctype->name] = 'flexinode-'. $type;
231 $filter[] = $ctype->name;
232 }
233 }
234 elseif (substr($type, 0, 10) == 'flexinode-') {
235 $ctype = module_invoke('flexinode', 'load_content_type', substr($type, 10));
236 if ($ctype->name) {
237 $temp[$ctype->name] = $type;
238 $filter[] = $ctype->name;
239 }
240 }
241 elseif ($name = module_hook($type, 'node_name')) {
242 $x = module_invoke($type, 'node_name', $node);
243 $temp[$x] = $type;
244 $filter[] = module_invoke($type, 'node_name', $node);
245 }
246 }
247
248 if (is_array($filter)) {
249 $links[] = l(t('view all'), 'event/'. $year .'/'. $month .'/'. $day .'/'. $view .'/');
250 $title = t('Filter') .': ' .implode(', ', $filter);
251 $types = $temp;
252 }
253 else {
254 $types = null;
255 }
256 }
257
258 $terms = null;
259 if ($tids && $tids != 'all') {
260 $links[] = l(t('view all'), 'event/'.$year.'/'.$month.'/'.$day.'/day');
261 if (preg_match('/^([0-9]+[+ ])+[0-9]+$/', $tids)) {
262 // The '+' character in a query string may be parsed as ' '.
263 $terms = preg_split('/[+ ]/', $tids);
264 }
265 else if (preg_match('/^([0-9]+,)*[0-9]+$/', $tids)) {
266 $terms = explode(',', $tids);
267 }
268 }
269
270 // add taxonomy filter controls to top of calendar
271 if (variable_get('event_taxonomy_control', 'all') == 'all' || (variable_get('event_taxonomy_control', 'all') == 'request' && isset($terms))) {
272 $output .= _event_get_taxonomy_control($terms);
273 }
274 // add content type filter controls to top of calendar
275 if (variable_get('event_type_control', 'all') == 'all' || (variable_get('event_type_control', 'all') == 'request' && isset($types))) {
276 $output .= _event_get_type_control($types);
277 }
278
279 switch ($view) {
280 case 'day':
281 // day view
282 $headertitle = t('%weekday %month %day, %year', array('%weekday' => t(gmdate('l', $stamp)), '%month' => t(gmdate('F', $stamp)), '%day' => $day, '%year' => $year));
283 $rows = event_calendar_day('page', $stamp, $types, $terms);
284 break;
285 case 'week':
286 // week view
287 // setup calendar table header
288 $temp = $stamp - (_event_day_of_week($stamp) * (86400));
289 $headertitle = t('Week of %month %day, %year', array('%month' => t(gmdate('F', $temp)), '%day' => gmdate('d', $temp), '%year' => $year));
290 $colspan = 5;
291 $rows = event_calendar_week('page', $stamp, $types, $terms);
292 break;
293 case 'month':
294 // month view
295 $headertitle = t('%month %year', array('%month' => t(gmdate('F', $stamp)), '%year' => $year));
296 $colspan = 5;
297 $rows = event_calendar_month('page', $stamp, $types, $terms);
298 break;
299 case 'table':
300 // table view
301 // next 30 day view, $duration can be set for different ranges
302 // but set a maximum $duration of 1 year.
303 $duration = $duration && $duration <= 366 ? $duration : variable_get('event_table_duration', '30');
304 $endstamp = $stamp + ($duration * 86400);
305 $headertitle = t('%startmonth %startdate, %startyear - %endmonth %enddate, %endyear', array('%startmonth' => t(gmdate('F', $stamp)), '%startdate' => gmdate('d', $stamp), '%startyear' => gmdate('Y', $stamp), '%endmonth' => t(gmdate('F', $endstamp)), '%enddate' => gmdate('d', $endstamp), '%endyear' => gmdate('Y', $endstamp)));
306 $rows = event_calendar_table('page', $stamp, $endstamp, $types, $terms);
307 break;
308 case 'list':
309 // list view
310 // next 30 day view, $duration can be set for different ranges
311 // but set a maximum $duration of 1 year.
312 $duration = $duration && $duration <= 366 ? $duration : variable_get('event_table_duration', '30');
313 $endstamp = $stamp + ($duration * 86400);
314 $headertitle = t('%startmonth %startdate, %startyear - %endmonth %enddate, %endyear', array('%startmonth' => t(gmdate('F', $stamp)), '%startdate' => gmdate('d', $stamp), '%startyear' => gmdate('Y', $stamp), '%endmonth' => t(gmdate('F', $endstamp)), '%enddate' => gmdate('d', $endstamp), '%endyear' => gmdate('Y', $endstamp)));
315 $rows = event_calendar_list('page', $stamp, $endstamp, $types, $terms);
316 break;
317 case 'feed':
318 // rss feed
319 drupal_set_header('Content-Type: text/xml; charset=utf-8');
320 $duration = $duration ? $duration : variable_get('event_table_duration', '30');
321 print event_calendar_rss($stamp, $duration, $types, $terms, $title);
322 break;
323 case 'ical':
324 // ical feed
325 drupal_set_header('Content-Type: text/calendar; charset=utf-8');
326 drupal_set_header('Content-Disposition: attachment; filename="calendar.ics"; ');
327 $duration = $duration ? $duration : variable_get('event_table_duration', '30');
328 print event_calendar_ical($stamp, $duration, $types, $terms, $title);
329 break;
330 }
331
332 if($view != 'feed' && $view != 'ical') {
333 // build header navigation
334 $prev = _event_nav($stamp, 'prev', $view, $types, $terms, $duration);
335 $next = _event_nav($stamp, 'next', $view, $types, $terms, $duration);
336
337 // setup calendar table header
338 $header = array(
339 array('class' => 'prev', 'data' => $prev),
340 array('class' => 'heading', 'data' => $headertitle, 'colspan' => $colspan),
341 array('class' => 'next', 'data' => $next));
342
343 $node->day = $day;
344 $node->month = $month;
345 $node->year = $year;
346 $node->filter = ($types ? implode('+', $types) : 'all') .'/'. ($terms ? implode('+', $terms) : 'all');
347
348 $output .= theme('event_links', array_merge(module_invoke_all('link', 'event_'. $view, $node, FALSE), $links), $view);
349
350 $output .= theme('event_calendar_'. $view, 'page', $header, $rows);
351 $output .= theme('event_ical_link', 'event/ical/'. $node->filter);
352
353 drupal_set_title(t('Events') . ($title ? ' - '. $title : ''));
354 drupal_set_breadcrumb($breadcrumbs);
355 print theme('page', $output);
356 }
357 }
358
359 /**
360 * Url wrapper function for static link to calendar by content type.
361 *
362 * @ingroup event_callback
363 * @return redirect to the event page for calendar node type.
364 */
365 function event_type($types = NULL, $view = NULL, $terms = NULL) {
366 drupal_goto('event/'. format_date(_event_user_time(), 'custom', 'Y/m/d') .'/'. ($view ? $view : variable_get('event_overview', 'month')) .'/'. $types);
367 }
368
369 /**
370 * Url wrapper function for static link to calendar by taxonomy terms.
371 *
372 * @ingroup event_callback
373 * @return redirect to the event page for calendar taxonomy term.
374 */
375 function event_term($filter = NULL, $view = NULL) {
376 drupal_goto('event/'. format_date(_event_user_time(), 'custom', 'Y/m/d') .'/'. ($view ? $view : variable_get('event_overview', 'month')) .'/all/'. $filter);
377 }
378
379 /**
380 * Url wrapper function for rss feeds
381 *
382 * @ingroup event_callback
383 * @return redirect to the event rss feed page at current day
384 */
385 function event_feed($types = 'all', $terms = 'all', $duration = NULL) {
386 drupal_goto('event/'. format_date(_event_user_time(), 'custom', 'Y/m/d') .'/feed/'. $types .'/'. $terms .'/'. $duration);
387 }
388
389 /**
390 * Url wrapper function for ical feeds
391 *
392 * @ingroup event_callback
393 * @return redirect to the event ical feed page at current day
394 */
395 function event_ical($types = 'all', $terms = 'all', $duration = NULL) {
396
397 drupal_goto('event/'. format_date(_event_user_time(), 'custom', 'Y/m/d') .'/ical/'. $types .'/'. $terms .'/'. $duration);
398
399 drupal_set_title(t('iCal support not enabled'));
400 print theme('page', $output);
401 }
402
403 /**
404 * @defgroup event_view Functions which handle the display of event nodes
405 */
406
407 /**
408 * Displays a monthly event calendar.
409 *
410 * @ingroup event_view
411 * @return a themed monthly event calendar.
412 */
413 function event_calendar_month($op, $stamp, $types = NULL, $terms = NULL) {
414
415 $year = gmdate('Y', $stamp);
416 $month = gmdate('m', $stamp);
417 $day = gmdate('d', $stamp);
418
419 switch ($op) {
420 case 'page':
421 // setup callback for data population
422 $callback = 'event_render_day';
423 $view = 'month';
424 break;
425
426 case 'block':
427 // create navigation links
428 $prev = _event_nav($stamp, 'prev', 'month', $types, $terms);
429 $next = _event_nav($stamp, 'next', 'month', $types, $terms);
430
431 $headertitle = l(t(gmdate('F', $stamp)) .' '. $year, 'event/'. $year .'/'. $month .'/'. $day .'/month');
432 $header = array(
433 array('class' => 'prev', 'data' => $prev),
434 array('class' => 'heading', 'data' => $headertitle, 'colspan' => 5),
435 array('class' => 'next', 'data' => $next));
436
437 $callback = 'event_render_day_single';
438 $view = 'block';
439 break;
440 }
441
442 // get weekdays array and header information
443 $weekdays = event_week_days();
444 $rows[] = event_week_header();
445
446 // get GMT current date value
447 $today = _event_user_date();
448
449 // name of the month
450 $month_name = gmdate('M', $stamp);
451
452 // timestamp of first day of month
453 $curstamp = gmmktime(0, 0, 0, $month, 01, $year);
454
455 // timestamp of last day in month
456 $lastday = gmmktime(0, 0, 0, $month, gmdate('t', $stamp), $year);
457
458 // pad the first week row array to fill up days in the previous month we don't build
459 $row = array_fill(0, 6, '');
460 // get the day of week offset value for the first day of the month
461 $start = $offset = _event_day_of_week($curstamp);
462 // render the month calendar
463 while ($curstamp <= $lastday) {
464 for ($x = $start; $x < 7; $x++) {
465 $cur_day = (($week * 7) + ($x + 1) - $offset);
466 $row[$x] = array(
467 'class' => strtolower("$month_name ". $weekdays[$x]['day'] . ($curstamp == $today ? ' today' : '') . ($cur_day == $day ? ' selected' : '')),
468 'id' => strtolower($month_name . $cur_day),
469 'data' => $callback($year, $month, $cur_day, $view, $types, $terms));
470 $curstamp += 86400;
471 if ($curstamp > $lastday) {
472 $x = 8;
473 }
474 }
475 $week++;
476 $start = 0;
477 $rows[] = array_pad($row, 7, '&nbsp;');
478 $row = array();
479 }
480
481 switch ($op) {
482 case 'page':
483 return $rows;
484 break;
485 case 'block':
486 return theme("event_calendar_month", $op, $header, $rows);
487 break;
488 }
489 }
490
491 /**
492 * Displays a weekly event calendar.
493 *
494 * @ingroup event_view
495 * @return a themed weekly event calendar.
496 */
497 function event_calendar_week($op, $stamp, $types = NULL, $terms = NULL) {
498 // get weekdays array and header information
499 $weekdays = event_week_days();
500 $rows[] = event_week_header();
501
502 // get GMT current date value
503 $today = _event_user_date();
504
505 // apply offset to goto first day of week
506 $stamp -= (_event_day_of_week($stamp) * (86400));
507
508 for ($x = 0; $x < 7; $x++) {
509 $year = gmdate('Y', $stamp);
510 $month = gmdate('m', $stamp);
511 $cur_day = gmdate('j', $stamp);
512 $month_name = gmdate('M', $stamp);
513
514 $row[$x] = array(
515 'class' => strtolower("$month_name ". $weekdays[$x]['day'] . ($stamp == $today ? ' today' : '') . ($cur_day == $day ? ' selected' : '')),
516 'id' => strtolower($month_name . $cur_day),
517 'data' => event_render_day($year, $month, $cur_day, 'week', $types, $terms));
518 $stamp += 86400;
519 }
520 $rows[] = $row;
521 return $rows;
522 }
523
524 /**
525 * Displays a daily event calendar.
526 *
527 * @ingroup event_view
528 * @return a themed daily event calendar.
529 */
530 function event_calendar_day($op, $stamp, $types = NULL, $terms = NULL) {
531
532 $today = _event_user_date();
533
534 $year = gmdate('Y', $stamp);
535 $month = gmdate('m', $stamp);
536 $day = gmdate('j', $stamp);
537 $dow = _event_day_of_week($stamp);
538 $month_name = gmdate('M', $stamp);
539 $weekdays = event_week_days();
540
541 $rows[][] = array(
542 'class' => strtolower("$month_name ". $weekdays[$dow]['day'] . ($stamp == $today ? ' today' : '')),
543 'id' => strtolower($month_name . $day),
544 'data' => event_render_day($year, $month, $day, 'day', $types, $terms),
545 'colspan' => 3);
546
547 return $rows;
548 }
549
550 /**
551 * Creates a themed table of events.
552 *
553 * @ingroup event_view
554 * @param $start The GMT starting date for the table.
555 * @param $end The GMT ending date for the table.
556 * @return A fully themed table.
557 */
558 function event_calendar_table($op, $stamp, $endstamp, $types = NULL, $terms = NULL) {
559
560 $today = _event_user_date();
561
562 while ($stamp <= $endstamp) {
563 $year = gmdate('Y', $stamp);
564 $month = gmdate('m', $stamp);
565 $cur_day = gmdate('j', $stamp);
566 $month_name = gmdate('M', $stamp);
567 $dow = _event_day_of_week($stamp);
568 $weekdays = event_week_days();
569
570 $rows[][] = array('colspan' => 3,
571 'class' => strtolower("$month_name ". $weekdays[$dow]['day'] . ($stamp == $today ? ' today' : '') . ($cur_day == $day ? ' selected' : '')),
572 'id' => strtolower($month_name . $cur_day),
573 'data' => event_render_day($year, $month, $cur_day, 'table', $types, $terms));
574 $stamp += 86400;
575 }
576
577 return $rows;
578 }
579
580 /**
581 * Creates a themed list of events.
582 *
583 * @ingroup event_view
584 * @param $start The GMT starting date for the table.
585 * @param $end The GMT ending date for the table.
586 * @return A themed list of events.
587 */
588 function event_calendar_list($op, $stamp, $endstamp, $types = NULL, $terms = NULL) {
589
590 $today = _event_user_date();
591 $rows = '';
592
593 while ($stamp <= $endstamp) {
594 $year = gmdate('Y', $stamp);
595 $month = gmdate('m', $stamp);
596 $cur_day = gmdate('j', $stamp);
597 $month_name = gmdate('M', $stamp);
598 $dow = _event_day_of_week($stamp);
599 $weekdays = event_week_days();
600
601 $rows .= event_render_day($year, $month, $cur_day, 'list', $types, $terms);
602 $stamp += 86400;
603 }
604
605 return $rows;
606 }
607
608 /**
609 * Creates an rss feed of events.
610 *
611 * @ingroup event_view
612 * @param $stamp The GMT starting date for the feed.
613 * @param $duration The number of days the feeds duration is.
614 * @param $types The content types to filter the feed by.
615 * @param $terms The taxonomy term tids to filter the feed by.
616 * @param $title The filter title to append to the channel description.
617 * @return A formatted rss feed.
618 */
619 function event_calendar_rss($stamp, $duration, $types = NULL, $terms = NULL, $title = NULL) {
620 global $base_url, $locale;
621
622 $endstamp = $stamp + ($duration * 86400);
623 $headertitle = t('%startmonth %startdate, %startyear - %endmonth %enddate, %endyear', array('%startmonth' => t(gmdate('F', $stamp)), '%startdate' => gmdate('d', $stamp), '%startyear' => gmdate('Y', $stamp), '%endmonth' => t(gmdate('F', $endstamp)), '%enddate' => gmdate('d', $endstamp), '%endyear' => gmdate('Y', $endstamp)));
624
625 $result = db_query(db_rewrite_sql('SELECT n.nid, e.event_start FROM {node} n INNER JOIN {event} e ON n.nid = e.nid WHERE n.status = 1 AND ((e.event_start > %d AND e.event_start < %d) OR (e.event_end > %d AND e.event_end < %d) OR (e.event_start < %d AND e.event_end > %d)) ORDER BY event_start '), $stamp, $endstamp, $stamp, $endstamp, $stamp, $endstamp);
626
627 $nodes = array();
628 while ($nid = db_fetch_object($result)) {
629 $node = node_load(array('nid' => $nid->nid));
630 $nodes[] = $node;
631 }
632
633 $filtered = event_filter_nodes($nodes, $types, $terms);
634
635 foreach($filtered as $node) {
636 $body = '<div class="start">'. t('Start') .': '. $node->start_format .'</div>'."\n";
637 $body .= '<div class="end">'. t('End') .': '. $node->end_format .'</div>'."\n";
638 $body .= '<div class="end">'. t('Location') .': '. $node->event_location .'</div>'."\n";
639 $body .= $node->teaser;
640 $link = url("node/$node->nid", NULL, NULL, 1);
641 // Allow modules to add additional item fields
642 $extra = node_invoke_nodeapi($node, 'rss item');
643 $extra = array_merge($extra, array(array('key' => 'pubDate', 'value' => date('r', $node->changed))));
644 $items .= format_rss_item($node->title, $link, $body, $extra);
645 }
646
647 $description = $headertitle . ($title ? ' | '. $title : '');
648
649 $output = "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n";
650 $output .= "<!DOCTYPE rss [<!ENTITY % HTMLlat1 PUBLIC \"-//W3C//ENTITIES Latin 1 for XHTML//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml-lat1.ent\">]>\n";
651 $output .= "<rss version=\"2.0\" xml:base=\"". $base_url ."\">\n";
652 $output .= format_rss_channel(variable_get('site_name', 'drupal') . t(' - Events Feed'), $base_url . '/event/feed', $description, $items, $locale);
653 $output .= "</rss>\n";
654
655 return $output;
656 }
657
658 /**
659 * Creates an ical feed of events.
660 *
661 * @ingroup event_view
662 * @param $stamp The GMT starting date for the feed.
663 * @param $duration The number of days the feeds duration is.
664 * @param $types The content types to filter the feed by.
665 * @param $terms The taxonomy term tids to filter the feed by.
666 * @param $title The filter title to append to the channel description.
667 * @return A formatted ical feed.
668 */
669 function event_calendar_ical($stamp, $duration, $types = NULL, $terms = NULL, $title = NULL) {
670 global $base_url, $locale;
671
672 $endstamp = $stamp + ($duration * 86400);
673 //$headertitle = t('%startmonth %startdate, %startyear - %endmonth %enddate, %endyear', array('%startmonth' => t(gmdate('F', $stamp)), '%startdate' => gmdate('d', $stamp), '%startyear' => gmdate('Y', $stamp), '%endmonth' => t(gmdate('F', $endstamp)), '%enddate' => gmdate('d', $endstamp), '%endyear' => gmdate('Y', $endstamp)));
674 $headertitle = t('Upcoming events');
675
676 $result = db_query(db_rewrite_sql('SELECT n.nid, e.event_start FROM {node} n INNER JOIN {event} e ON n.nid = e.nid WHERE n.status = 1 AND ((e.event_start > %d AND e.event_start < %d) OR (e.event_end > %d AND e.event_end < %d) OR (e.event_start < %d AND e.event_end > %d)) ORDER BY event_start '), $stamp, $endstamp, $stamp, $endstamp, $stamp, $endstamp);
677
678 $events = array();
679 while ($nid = db_fetch_object($result)) {
680 $event = array();
681 $node = node_load(array('nid' => $nid->nid));
682 if (event_filter_node($node, $types, $terms)) {
683 // Allow modules to affect item fields
684 node_invoke_nodeapi($node, 'view', 'ical item');
685 node_invoke_nodeapi($node, 'ical item');
686 $event['start'] = $node->event_start;
687 $event['end'] = $node->event_end;
688 $event['event_location'] = $node->event_location;
689 $event['summary'] = $node->title;
690 $event['description'] = ($node->teaser ? $node->teaser : $node->body);
691 $event['uid'] = url("node/$node->nid", NULL, NULL, 1);
692 $event['url'] = url("node/$node->nid", NULL, NULL, 1);
693 $events[] = $event;
694 }
695 }
696
697 $description = $headertitle . ($title ? ' | '. $title : '');
698
699 return ical_export($events, $description);
700 }
701
702 /**
703 * Returns a calendar in the requested format, populated with the provided nodes.
704 * This is not used internally, rather it is an API funciton for external modules
705 * to use for rendering calendars when constructing thier own event objects.
706 *
707 * @ingroup event_view
708 *
709 * @param $view - The format of calendar to return. Possible values:
710 * "table": A tabular calendar.
711 * "month": A month calendar.
712 * "week": A week calendar.
713 * "day": A day calendar.
714 * @param $nodes – An associative array of nodes with nids for key values.
715 * Node objects must have GMT timestamp values for start ($node->event_start).
716 * Optionally, an end value ($node->event_end) and a time zone offset value
717 * in the same format as drupal core ($node->tz). If a node has no end
718 * value, it is rendered on only one day. If no time zone value is displayed
719 * the time is rendered with no time zone offset (GMT).
720 * @param $module - String containing the name of the module calling the function
721 * @param $title - A string value that will be printed into the header of the calendar
722 * @return Themed calendar view of nodes
723 */
724 function event_get_calendar($view, $nodes, $module, $title = NULL) {
725 $today = _event_user_date();
726
727 foreach ($nodes as $node) {
728 $node->event_links = module_invoke_all('link', 'event_node_'. $view, $node, FALSE);
729 $nodes[$node->nid] = $node;
730 $nid->nid = $node->nid;
731
732 // $node_start and $node_end are local timestamp values
733 $node_start = gmmktime(0, 0, 0, _event_date('m', $node->event_start, $node->start_offset), _event_date('d', $node->event_start, $node->start_offset), _event_date('Y', $node->event_start, $node->start_offset));
734 if ($node->event_end) {
735 $node_end = gmmktime(0, 0, 0, _event_date('m', $node->event_end, $node->end_offset), _event_date('d', $node->event_end, $node->end_offset), _event_date('Y', $node->event_end, $node->end_offset));
736 }
737 else {
738 $node_end = $node_start;
739 }
740
741 if ($node_start == $node_end) {
742 $nid->event_state = 'singleday';
743 $nid->stamp = $node_start;
744 $data[gmdate('Y', $node_start)][gmdate('m', $node_start)][gmdate('j', $node_start)][] = $nid;
745 }
746 else {
747 // roll through each day the event occurs and set an entry for each
748 for ($x = $node_start; $x <= $node_end; $x += 86400) {
749 if ($x == $node_end) {
750 $nid->event_state = 'end';
751 $nid->stamp = $x;
752 $data[gmdate('Y', $x)][gmdate('m', $x)][gmdate('j', $x)][] = $nid;
753 }
754 elseif ($x == $node_start) {
755 $nid->event_state = 'start';
756 $nid->stamp = $x;
757 $data[gmdate('Y', $x)][gmdate('m', $x)][gmdate('j', $x)][] = $nid;
758 }
759 else {
760 $nid->event_state = 'ongoing';
761 $nid->stamp = $x;
762 $data[gmdate('Y', $x)][gmdate('m', $x)][gmdate('j', $x)][] = $nid;
763 }
764 }
765 }
766 }
767
768 // order the years, months and days
769 ksort($data, SORT_NUMERIC);
770 foreach($data as $year => $months) {
771 ksort($data[$year], SORT_NUMERIC);
772 foreach($data[$year] as $month => $days) {
773 ksort($data[$year][$month], SORT_NUMERIC);
774 }
775 }
776
777 $weekdays = event_week_days();
778 switch ($view) {
779 case 'day':
780 case 'table':
781 foreach ($data as $year => $months) {
782 if(count($data) > 1) {
783 // add year heading
784 $rows[][] = array(
785 'class' => 'heading year',
786 'id' => 'year'.$year,
787 'data' => $year);
788 }
789 foreach($months as $month => $days) {
790 foreach($days as $day => $nids) {
791 $content = theme('event_calendar_date_box', $year, $month, $day, 'table');
792 foreach($nids as $nid) {
793 if(!$month_name) {
794 $month_name = gmdate('M', $nid->stamp);
795 $dow = _event_day_of_week($nid->stamp);
796 }
797 $node = $nodes[$nid->nid];
798
799 $node->event_state = $nid->event_state;
800
801 $content .= theme('event_node_'. $view, $node, $module);
802 }
803 $rows[][] = array(
804 'class' => strtolower("$month_name ". $weekdays[$dow]['day'] . ($nid->stamp == $today ? ' today' : '')),
805 'id' => strtolower($month_name . $day),
806 'data' => $content);
807 $month_name = NULL;
808 }
809 }
810 }
811 break;
812
813 case 'week':
814 case 'month':
815 $colspan = '7';
816 foreach ($data as $year => $months) {
817 if(count($data) > 1) {
818 // add year heading
819 $rows[][] = array(
820 'class' => 'heading year',
821 'id' => 'year'. $year,
822 'data' => $year,
823 'colspan' => $colspan);
824 }
825 foreach ($months as $month => $days) {
826 // timestamp of first day in month
827 $curstamp = gmmktime(0, 0, 0, $month, 1, $year);
828 // timestamp of last day in month
829 $lastday = gmmktime(0, 0, 0, $month, gmdate('t', $curstamp), $year);
830 // pad the first week row array to fill up days in the previous month we don't build
831 $row = array_fill(0, 6, '');
832 // get the day of week offset value for the first day of the month
833 $start = $offset = _event_day_of_week($curstamp);
834 // get name of month
835 $month_name = gmdate('M', $curstamp);
836 // set week counter
837 $week = 0;
838 // add month header
839 $rows[][] = array(
840 'class' => 'heading month',
841 'id' => 'month'. $month,
842 'data' => $month_name,
843 'colspan' => $colspan);
844 $rows[] = event_week_header();
845
846 while ($curstamp <= $lastday) {
847 for ($x = $start; $x < 7; $x++) {
848 $cur_day = (($week * 7) + ($x + 1) - $offset);
849
850 $content = theme('event_calendar_date_box', $year, $month, $cur_day, $view);
851
852 // render nodes for the day
853 if(is_array($days[$cur_day])) {
854 foreach($days[$cur_day] as $nid) {
855 $node = $nodes[$nid->nid];
856 $node->event_state = $nid->event_state;
857 $content .= theme('event_node_'. $view, $node, $module);
858 }
859 }
860
861 $row[$x] = array(
862 'class' => strtolower("$month_name ". $weekdays[$x]['day'] . ($curstamp == $today ? ' today' : '')),
863 'id' => strtolower($month_name . $day),
864 'data' => $content);
865
866 $curstamp += 86400;
867 if ($curstamp > $lastday) {
868 $x = 8;
869 }
870 }
871 $week++;
872 $start = 0;
873 $rows[] = array_pad($row, 7, '&nbsp;');
874 $row = array();
875 }
876 }
877 }
878 break;
879 }
880
881 $header[] = ($title ? array('class' => 'heading', 'data' => $title, 'colspan' => $colspan) : array());
882 return theme('event_calendar_'. $view, 'page', $header, $rows);
883 }
884
885 /**
886 * @defgroup event_support Functions that support the event system
887 */
888
889
890 /**
891 * Returns an array of nodes that occur on a given date.
892 * Handles content type and taxonomy filters.
893 *
894 * @ingroup event_support
895 * @param $year The year the event is taking place.
896 * @param $month The month the event is taking place.
897 * @param $day The day the event is taking place. No leading zeroes.
898 * @return An array containing all of the events taking place on the specified date, or an empty array if none exist.
899 */
900 function event_calendar_data($year, $month, $day, $view = NULL, $types = NULL, $terms = NULL) {
901 static $data;
902 global $user;
903
904 $day_start = _event_mktime(0, 0, 0, $month, $day, $year);
905
906 if (!is_array($data[$year][$month])) {
907 $data[$year][$month] = array();
908
909 //call the event_load function in all modules
910 module_invoke_all('event_load', $year, $month, $day, $view, $types, $terms);
911
912 // get GMT values from local date values for db query
913 $first = _event_mktime(0, 0, 0, $month, 1, $year);
914 $last = _event_mktime(23, 59, 59, $month + 1, 0, $year);
915
916 $result = db_query(db_rewrite_sql('SELECT n.nid, e.event_start FROM {node} n INNER JOIN {event} e ON n.nid = e.nid WHERE n.status = 1 AND ((e.event_start > %d AND e.event_start < %d) OR (e.event_end > %d AND e.event_end < %d) OR (e.event_start < %d AND e.event_end > %d)) ORDER BY event_start '), $first, $last, $first, $last, $first, $last);
917
918 while ($nid = db_fetch_object($result)) {
919 $node = node_load(array('nid' => $nid->nid));
920
921 // we have to load these here since there is no way to pass the $view parameter to nodeapi through node_load :/
922 $node->event_links = module_invoke_all('link', 'event_node_'. $view, $node, FALSE);
923
924 // this array contains the loaded nodes for the month, so we dont have them stored for every day they occur
925 $data