/[drupal]/contributions/modules/availability_calendars/availability_calendars.module
ViewVC logotype

Contents of /contributions/modules/availability_calendars/availability_calendars.module

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


Revision 1.2 - (show annotations) (download) (as text)
Sat Aug 30 10:56:26 2008 UTC (14 months, 4 weeks ago) by geodan
Branch: MAIN
CVS Tags: HEAD
Changes since 1.1: +6 -6 lines
File MIME type: text/x-php
#301442: localisation for dates
1 <?php
2 // $Id$
3
4 /**
5 * Availability Calendars Module
6 *
7 * @file
8 * Allows for availability information to be displayed using calendars on specified content types. Originally based on the Availability Module.
9 * @author Dan Karran (geodaniel) <dan at karran dot net>
10 */
11
12 /**
13 * Implementation of hook_menu()
14 */
15 function availability_calendars_menu($may_cache) {
16 $items = array();
17
18 if($may_cache) {
19 $items[] = array(
20 'path' => 'admin/settings/availability-calendars',
21 'title' => t('Availability Calendars'),
22 'description' => t('Configure global settings for availability calendars module.'),
23 'callback' => 'drupal_get_form',
24 'callback arguments' => array('availability_calendars_admin_settings')
25 );
26 }
27 else {
28 $items[] = array(
29 'path' => 'availability-calendars',
30 'title' => t('Availability calendar'),
31 'callback' => 'availability_calendars_page',
32 'access' => user_access('edit availability calendars') || user_access('edit own availability calendars'),
33 'type' => MENU_CALLBACK
34 );
35 }
36
37 return $items;
38 }
39
40 /**
41 * Implementation of hook_perm()
42 */
43 function availability_calendars_perm() {
44 return array('edit own availability calendars', 'edit availability calendars');
45 }
46
47 /**
48 * Settings page callback.
49 */
50 function availability_calendars_admin_settings() {
51 $form = array();
52
53 $form['display'] = array(
54 '#type' => 'fieldset',
55 '#title' => t('View settings'),
56 '#description' => t('Check where you want availability calendars to be displayed. If you choose none of the suggested places below you will need to output it manually using %func function.', array('%func' => 'theme_availability_calendars_node()'))
57 );
58 $form['display']['availability_calendars_display_nodeview'] = array(
59 '#type' => 'checkbox',
60 '#title' => t('Node view page'),
61 '#default_value' => variable_get('availability_calendars_display_nodeview', TRUE)
62 );
63 $form['display']['availability_calendars_display_monthcount'] = array(
64 '#type' => 'textfield',
65 '#title' => t('Number of months to display'),
66 '#default_value' => variable_get('availability_calendars_display_monthcount', 12)
67 );
68
69 //TODO: add status codes and css classes in here
70
71 return system_settings_form($form);
72 }
73
74 /**
75 * Create tab to show node availability
76 */
77 function availability_calendars_menu_callback() {
78 $node = node_load(arg(1));
79
80 if (availability_calendars_enabled($node->type)) {
81 return theme('availability_calendars_node', $node);
82 }
83 else {
84 return FALSE;
85 }
86 }
87
88 /**
89 * Availability calendars page
90 */
91 function availability_calendars_page($nid = NULL, $year = NULL, $month = NULL, $edit = FALSE) {
92 if (is_numeric($nid)) {
93 $node = node_load($nid);
94 drupal_set_title(t('Availability for %name', array('%name' => $node->title)));
95
96 if (is_numeric($year) && is_numeric($month)) {
97 drupal_set_title(t('Availability for %name in %date', array('%name' => $node->title, '%date' => format_date(strtotime("$year-$month-01 12:00"), 'custom', 'M Y'))));
98 if ($edit == 'edit') {
99 // Display the edit form for the availability calendar on the node
100 return availability_calendars_node_edit($node, $year, $month);
101 }
102 else {
103 // Display availability calendar for single month
104 $monthstodisplay = 1;
105 return theme('availability_calendars_node', $node, $year, $month, $monthstodisplay);
106 }
107 }
108 elseif (is_numeric($year)) {
109 // Display availability calendar for a whole year
110 $month = 1;
111 $monthstodisplay = 12;
112 return theme('availability_calendars_node', $node, $year, $month, $monthstodisplay);
113 }
114 else {
115 // Display rolling availability calendar from this point onwards
116 $year = date('Y');
117 $month = date('m');
118 $monthstodisplay = variable_get('availability_display_monthcount', 12);
119 return theme('availability_calendars_node', $node, $year, $month, $monthstodisplay);
120 }
121 }
122 else {
123 print drupal_not_found();
124 }
125 }
126
127 function availability_calendars_node_edit() {
128 return drupal_get_form('availability_calendars_node_edit_form');
129 }
130
131 function availability_calendars_node_edit_form() {
132 $nid = check_plain(arg(1));
133 $year = check_plain(arg(2));
134 $month = check_plain(arg(3));
135 $form['nid'] = array(
136 '#type' => 'hidden',
137 '#default_value' => $nid,
138 );
139 $form['year'] = array(
140 '#type' => 'hidden',
141 '#default_value' => $year,
142 );
143 $form['month'] = array(
144 '#type' => 'hidden',
145 '#default_value' => $month,
146 );
147
148 $startofweek = variable_get('availability_calendars_'. $nid .'_startofweek', 1);
149 $month_meta = availability_calendars_month_meta($year, $month, $startofweek);
150
151 // find all entries in database for this month ($availability, $notes) and pre-populate
152 $notes_result = db_query('SELECT week, note FROM {availability_calendars_week} WHERE nid = %d AND year = %d and month = %d', $nid, $year, $month);
153 while ($note = db_fetch_array($notes_result)) {
154 $notes[$note['week']] = $note['note'];
155 }
156
157 $status_result = db_query('SELECT day, status FROM {availability_calendars_day} WHERE nid = %d AND year = %d AND month = %d', $nid, $year, $month);
158 while ($status = db_fetch_array($status_result)) {
159 $day_status[$status['day']] = $status['status'];
160 }
161
162 $day = 1;
163 for ($week = 1; $week <= $month_meta['weeksinmonth']; $week++) {
164 $form['week-'. $week] = array(
165 '#type' => 'fieldset',
166 '#title' => t('Week @week', array('@week' => $week)),
167 );
168 $form['week-'. $week]['note-'. $week] = array(
169 '#type' => 'textfield',
170 '#title' => t('Note'),
171 '#default_value' => $notes[$week],
172 '#description' => t('This will be displayed beside the week in the calendar. It could include, for example, a weekly price.'),
173 );
174 if ($week == 1) {
175 $daysinweekremaining = 7 - $month_meta['firstday'];
176 }
177 else {
178 $daysinweekremaining = 7;
179 }
180 while ($daysinweekremaining > 0 && $day <= $month_meta['daysinmonth']) {
181 $form['week-'. $week]['day-'. $day] = array(
182 '#type' => 'select',
183 '#title' => t("@date", array('@date' => format_date(strtotime("$year-$month-$day 12:00"), 'custom', 'l d F'))),
184 '#options' => availability_calendars_options(),
185 '#default_value' => $day_status[$day]
186 );
187 $day++;
188 $daysinweekremaining--;
189 }
190 }
191
192 $form['submit'] = array(
193 '#type' => 'submit',
194 '#value' => t('Submit'),
195 );
196
197 return $form;
198 }
199
200 function availability_calendars_node_edit_form_submit($form_id, $form_values) {
201 $nid = check_plain($form_values['nid']);
202 $year = check_plain($form_values['year']);
203 $month = check_plain($form_values['month']);
204
205 // save weekly notes
206 $week = 1;
207 $nomoreweeks = FALSE;
208 while (!$nomoreweeks) {
209 if (isset($form_values['note-'. $week])) {
210 $notes[$week] = check_plain($form_values['note-'. $week]);
211 $week++;
212 }
213 else {
214 $nomoreweeks = TRUE;
215 }
216 }
217
218 // save $days
219 $day = 1;
220 $nomoredays = FALSE;
221 while (!$nomoredays) {
222 if (isset($form_values['day-'. $day])) {
223 $days[$day] = $form_values['day-'. $day];
224 $day++;
225 }
226 else {
227 $nomoredays = TRUE;
228 }
229 }
230
231 db_query('DELETE FROM {availability_calendars_week} WHERE nid = %d AND year = %d AND month = %d', $nid, $year, $month);
232 foreach ($notes as $week => $note) {
233 db_query('INSERT INTO {availability_calendars_week} (nid, year, month, week, note) VALUES (%d, %d, %d, %d, "%s")', $nid, $year, $month, $week, $note);
234 }
235
236 db_query('DELETE FROM {availability_calendars_day} WHERE nid = %d AND year = %d AND month = %d', $nid, $year, $month);
237 foreach ($days as $day => $status) {
238 db_query('INSERT INTO {availability_calendars_day} (nid, year, month, day, status) VALUES (%d, %d, %d, %d, %d)', $nid, $year, $month, $day, $status);
239 }
240
241 drupal_set_message('Availability information saved.');
242 }
243
244 /**
245 * Themed output to display a lits of node dates.
246 *
247 * @param $node
248 * @return HTML output.
249 */
250 function theme_availability_calendars_node($node, $year = 2008, $month = 01, $monthstodisplay = 12) {
251 drupal_add_css(drupal_get_path('module', 'availability_calendars') . '/availability_calendars.css');
252 $rows = array();
253
254 // Fill availability array
255 /* foreach ($node->availability_dates as $k => $v) {
256 foreach ($v as $i) {
257 $booked[date("Y", $i['date'])][date("m", $i['date'])][date("d", $i['date'])] = 1;
258 }
259 } */
260
261
262
263 // Calendar code based on example at http://evolt.org/node/60673 :
264 $day = 1;
265
266 $startofweek = variable_get('availability_calendars_'. $node->nid .'_startofweek', 1);
267
268 $monthsremaining = $monthstodisplay;
269 while ($monthsremaining > 0) {
270 $output .= theme('availability_calendars_month', $node, $year, $month, $startofweek, $booked);
271 $monthsremaining--;
272 $month++;
273 if ($month > 12) {
274 $month = 1;
275 $year++;
276 }
277 }
278
279 // add an extra three months for editors only
280 if (user_access('edit availability calendars')) {
281 $monthsremaining = 3;
282 while ($monthsremaining > 0) {
283 $output .= theme('availability_calendars_month', $node, $year, $month, $startofweek, $booked);
284 $monthsremaining--;
285 $month++;
286 if ($month > 12) {
287 $month = 1;
288 $year++;
289 }
290 }
291 }
292
293 return $output;
294
295 }
296
297 function availability_calendars_month_meta($year, $month, $startofweek) {
298 $month_meta['daysinmonth'] = date("t",mktime(0,0,0,$month,1,$year));
299 $month_meta['firstday'] = date("w", mktime(0,0,0,$month,1,$year)) + $startofweek;
300 $tempDays = $month_meta['firstday'] + $month_meta['daysinmonth']; // padding
301 $month_meta['weeksinmonth'] = ceil($tempDays/7);
302
303 // Stop empty weeks occuring at start of month
304 if ($month_meta['firstday'] > 6) {
305 $month_meta['firstday'] = $month_meta['firstday'] - 7;
306 $month_meta['weeksinmonth'] --;
307 }
308 return $month_meta;
309 }
310
311 function theme_availability_calendars_month($node, $year, $month, $startofweek, $booked) {
312 $month_meta = availability_calendars_month_meta($year, $month, $startofweek);
313
314 for ($j=0;$j<$month_meta['weeksinmonth'];$j++) {
315 for ($i=0;$i<7;$i++) {
316 $counter++;
317 $week[$j][$i] = $counter;
318 // offset the days
319 $week[$j][$i] -= $month_meta['firstday'];
320 if (($week[$j][$i] < 1) || ($week[$j][$i] > $month_meta['daysinmonth'])) {
321 $week[$j][$i] = "";
322 }
323 }
324 }
325
326 $output = "<table class='cal'>\n";
327 $output .= "<tr class='calmonth'>\n";
328 $output .= "<th colspan='8'>". t("@date", array('@date' => format_date(mktime(12,0,0,$month,1,$year), 'custom', 'F Y')));
329 if (user_access('edit availability calendars')) {
330 $output .= ' '. l('edit', 'availability-calendars/'. $node->nid .'/'. date('Y/m', mktime(0,0,0,$month,1,$year)) .'/edit', NULL, 'destination=node/'. $node->nid);
331 }
332 $output .= "</th>\n";
333 $output .= "</tr>\n";
334
335 /* $days = array(
336 6 => array("M", "Mon", "Monday"),
337 5 => array("T", "Tue", "Tuesday"),
338 4 => array("W", "Wed", "Wednesday"),
339 3 => array("T", "Thu", "Thursday"),
340 2 => array("F", "Fri", "Friday"),
341 1 => array("S", "Sat", "Saturday"),
342 0 => array("S", "Sun", "Sunday"),
343 );
344
345 // Figure out how to generate the header - see archive.module in 4.7
346 $output .= "<tr class='caldays'>\n";
347 $output .= "<th></th>\n";
348 $output .= "<th>S</th>\n";
349 $output .= "<th>S</th>\n";
350 $output .= "<th>M</th>\n";
351 $output .= "<th>T</th>\n";
352 $output .= "<th>W</th>\n";
353 $output .= "<th>T</th>\n";
354 $output .= "<th>F</th>\n";
355 $output .= "</tr>\n";
356 */
357
358 // find all entries in database for this month ($availability, $notes) and pre-populate
359 $notes_result = db_query('SELECT week, note FROM {availability_calendars_week} WHERE nid = %d AND year = %d AND month = %d', $node->nid, $year, $month);
360 while ($note = db_fetch_array($notes_result)) {
361 $notes[$note['week']] = $note['note'];
362 }
363
364 $status_result = db_query('SELECT day, status FROM {availability_calendars_day} WHERE nid = %d AND year = %d AND month = %d', $node->nid, $year, $month);
365 while ($status = db_fetch_array($status_result)) {
366 $day_status[$status['day']] = $status['status'];
367 }
368
369 $availability_calendars_options = availability_calendars_options();
370
371 foreach ($week as $key => $val) {
372 $weeknumber = $key+1;
373
374 $output .= "<tr class='calweek'>\n";
375 $output .= "<td class='calnote'>". $notes[$weeknumber] ."</td>\n";
376 for ($i=0;$i<7;$i++) {
377
378 // if there's a date, it's part of this month
379 if ($week[$key][$i]) {
380 if ($day_status[$week[$key][$i]] == 1) {
381 // booked
382 $output .= " <td class='calnotavailable'>". $week[$key][$i] ."</td>\n";
383 }
384 elseif ($day_status[$week[$key][$i]] == 2) {
385 // provisionally booked
386 $output .= " <td class='calnotavailableprov'>". $week[$key][$i] ."</td>\n";
387 } else {
388 // available
389 $output .= " <td class='calavailable'>". $week[$key][$i] ."</td>\n";
390 }
391 }
392 else {
393 $output .= " <td class='calothermonth'>". $number ."</td>\n";
394 }
395 }
396 $output .= "</tr>\n";
397 }
398
399 if ($weeknumber == 5) {
400 $output .= "<tr>\n";
401 $output .= "<td colspan='8'>&nbsp;</td>\n";
402 $output .= "</tr>\n";
403 }
404
405 $output .= "</table>";
406
407 return $output;
408 }
409
410 function availability_calendars_options() {
411 // TODO: make these configurable
412 return array(
413 0 => t('Available'),
414 1 => t('Fully booked'),
415 2 => t('Provisionally booked')
416 );
417 }
418
419 /**
420 * Implementation of hook_form_alter();
421 */
422 function availability_calendars_form_alter($form_id, &$form) {
423 global $user;
424
425 // Alter node type form to allow availability support to be enabled/disabled
426 if ($form_id == 'node_type_form') {
427 $form['workflow']['availability_calendars'] = array(
428 '#type' => 'radios',
429 '#title' => t('Availability calendar support'),
430 '#default_value' => variable_get('availability_calendars_'. $form['#node_type']->type, 0),
431 '#options' => array(
432 0 => t('Disabled'),
433 1 => t('Enabled')
434 ),
435 '#description' => t('Enable or disable availability support for this content type. If enabled, node owner will be able to specify node availability.'),
436 );
437 }
438
439 // Alter node edit form if availability support is enabled for that content type
440 elseif (isset($form['type']) && $form['type']['#value'] .'_node_form' == $form_id &&
441 availability_calendars_enabled($form['type']['#value'])) {
442
443 $form['availability'] = array(
444 '#type' => 'fieldset',
445 '#title' => t('Availability calendar settings'),
446 );
447 $form['availability']['startofweek'] = array(
448 '#type' => 'select',
449 '#title' => t('First day of week'),
450 '#default_value' => variable_get('availability_'. $form['nid']['#value'] .'_startofweek', 1),
451 '#options' => array(
452 6 => t('Monday'),
453 5 => t('Tuesday'),
454 4 => t('Wednesday'),
455 3 => t('Thursday'),
456 2 => t('Friday'),
457 1 => t('Saturday'),
458 0 => t('Sunday'),
459 ),
460 );
461
462 }
463 }
464
465 /**
466 * Implementation hook node_nodeapi();
467 */
468 function availability_calendars_nodeapi(&$node, $op, $a3 = null, $a4 = null) {
469 global $user;
470
471 if (!availability_calendars_enabled($node-> type)) return;
472
473 switch($op) {
474 case 'view':
475 if (variable_get('availability_calendars_display_nodeview', TRUE)) {
476 $year = date('Y');
477 $month = date('m');
478 $monthstodisplay = variable_get('availability_calendars_display_monthcount', 12);
479 $node->content['availability_calendars'] = array(
480 '#value' => theme('availability_calendars_node', $node, $year, $month, $monthstodisplay),
481 '#weight' => 10,
482 );
483 }
484 break;
485 case 'insert':
486 case 'update':
487 availability_calendars_save($node);
488 break;
489 case 'delete':
490 break;
491 }
492 }
493
494 /**
495 * Saves a set of dates associated with the node after editing it.
496 *
497 * @param object $node Node information to save into the database.
498 */
499 function availability_calendars_save(&$node) {
500 variable_set('availability_calendars_'. $node->nid .'_startofweek', $node->startofweek);
501 }
502
503 /**
504 * Checks if availability is enabled for specified content type.
505 *
506 * @param string $node_type
507 */
508 function availability_calendars_enabled($node_type) {
509 return variable_get('availability_calendars_'.$node_type, 0);
510 }

  ViewVC Help
Powered by ViewVC 1.1.2