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

Contents of /contributions/modules/office_hours/office_hours.module

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


Revision 1.1 - (show annotations) (download) (as text)
Sat Jan 19 09:44:50 2008 UTC (22 months, 1 week ago) by ozeuss
Branch: MAIN
CVS Tags: DRUPAL-5--1-1, DRUPAL-5--1-0, HEAD
Branch point for: DRUPAL-5
File MIME type: text/x-php
Initial commit of office_hours module. this is a CCK module that can add an Opening or Office hours field.
1 <?php
2 // $Id: office_hours.module $
3
4 /**
5 * @file
6 * Creates a field and widget for inserting working or office hours per day
7 *
8 *
9 *TODO: allow for more than one 'block' of hours per day, or merge them if the day is identical.
10
11
12 /**
13 * implementation of hook_menu.
14 */
15 function office_hours_menu ($may_cache) {
16 if (!$may_cache) {
17 drupal_add_css(drupal_get_path('module', 'office_hours') .'/office_hours.css');
18 }
19 }
20
21 /**
22 * Implementation of hook_field_info
23 *
24 * @return
25 * An array keyed by field type name. Each element of the array is an associative
26 * array with these keys and values:
27 * - "label": The human-readable label for the field type.
28 */
29 function office_hours_field_info() {
30 return array(
31 'office_hours' => array('label' => 'Office Hours'),
32 );
33 }
34
35 /**
36 * implementation of hook_field
37 * Handle the parameters for a field.
38 *
39 * @param $op
40 * @param $field
41 * The field on which the operation is to be performed.
42 * @return
43 * This varies depending on the operation.
44 * - "form": an array of form elements to add to
45 * the settings page.
46 * - "validate": no return value. Use form_set_error().
47 * - "save": an array of names of form elements to
48 * be saved in the database.
49 * - "database columns": an array keyed by column name, with arrays of column
50 * information as values.
51 * - "callbacks": an array describing the field's behaviour regarding hook_field
52 * operations. The array is keyed by hook_field operations ('view', 'validate'...)
53 * and has the following possible values :
54 * CONTENT_CALLBACK_NONE : do nothing for this operation
55 * CONTENT_CALLBACK_CUSTOM : use the behaviour in hook_field(operation)
56 * CONTENT_CALLBACK_DEFAULT : use content.module's default bahaviour
57 * Note : currently only the 'view' operation implements this feature.
58 * - "tables": an array of 'tables' definitions as expected by views.module
59 * (see Views Documentation).
60 * - "arguments": an array of 'arguments' definitions as expected by views.module
61 * (see Views Documentation).
62 * - "filters": an array of 'filters' definitions as expected by views.module
63 * (see Views Documentation).
64 * When providing several filters, it is recommended to use the 'name'
65 * attribute in order to let the user distinguish between them. If no 'name'
66 * is specified for a filter, the key of the filter will be used instead.
67 */
68 function office_hours_field_settings($op, $field) {
69 switch ($op) {
70 case 'form':
71 $options= _create_hours_arr($field, FALSE);
72 $form = array();
73 $form['hoursformat'] = array(
74 '#type' => 'select',
75 '#title' => t('Hours format'),
76 '#options' => array (t('24 hrs.'), t('12 hrs')),
77 '#default_value' => $field['hoursformat'] ? $field['hoursformat'] : 0,
78 '#required' => FALSE,
79 '#description' => t('format of the clock'),
80 );
81 $form['granularity'] = array(
82 '#type' => 'select',
83 '#title' => t('granularity of time'),
84 '#options' => array ( 0 =>t('Hours'), 30=> t('Half hours'), 15=> t('Quarter hours')),
85 '#default_value' => $field['granularity'] ? $field['granularity'] : 0,
86 '#required' => FALSE,
87 '#description' => t('Allow inserting quarter hours, half hours, or only hours of the day'),
88 );
89 $form['limitstart'] = array(
90 '#type' => 'select',
91 '#title' => t('Limit hours start'),
92 '#options' => $options,
93 '#default_value' => $field['limitstart']? $field['limitstart'] : FALSE, // $options['None'],
94 '#required' => FALSE,
95 '#description' => t('Set the allowed start hours. Note: if you just changed the clock format, please submit before changing this.'),
96 );
97 $form['limitend'] = array(
98 '#type' => 'select',
99 '#title' => t('Limit hours end'),
100 '#options' => $options,
101 '#default_value' => $field['limitend'] ? $field['limitend'] : FALSE, // $options['None'],
102 '#required' => FALSE,
103 '#description' => t('Set the allowed end hours. Note: if you just changed the clock format, please submit before changing this'),
104 );
105
106 return $form;
107
108 case 'save':
109 return array('hoursformat', 'granularity', 'limitstart', 'limitend');
110
111 case 'database columns':
112 $columns = array(
113 'starthours' => array('type' => 'varchar', 'length' => 10 , 'not null' => TRUE, 'default' => "''", 'sortable' => TRUE),
114 'endhours' => array('type' => 'varchar', 'length' => 10 , 'not null' => TRUE, 'default' => "''", 'sortable' => TRUE),
115 'day' => array('type' => 'int', 'unsigned' =>TRUE, 'not null' => FALSE),
116 );
117 return $columns;
118
119 case 'callbacks':
120 return array(
121 'view' => CONTENT_CALLBACK_CUSTOM,
122 );
123
124 case 'tables':
125 $tables = content_views_field_tables($field);
126 // whatever additions / modifications needed on the default definitions
127 return $tables;
128
129 case 'arguments':
130 $arguments = content_views_field_arguments($field);
131 // whatever additions / modifications needed on the default definitions
132 return $arguments;
133
134 case 'filters':
135 return array(
136 'substring' => array(
137 'operator' => 'views_handler_operator_like',
138 'handler' => 'views_handler_filter_like',
139 ),
140 'alpha_order' => array(
141 'name' => 'alphabetical order',
142 'operator' => 'views_handler_operator_gtlt',
143 ),
144 );
145
146 }
147 }
148
149 /**
150 * implementation of hook_field
151 * Define the behavior of a field type.
152 *
153 * @param $op
154 * What kind of action is being performed. Possible values.
155 * @param &$node
156 * The node the action is being performed on. This argument is passed by
157 * reference for performance only; do not modify it.
158 * @param $field
159 * The field the action is being performed on.
160 * @param &$node_field
161 * The contents of the field in this node. Changes to this variable will
162 * be saved back to the node object.
163 * @return
164 * This varies depending on the operation.
165 * - The "load" operation should return an object containing extra values
166 * to be merged into the node object.
167 * - The "view" operation should return a string containing an HTML
168 * representation of the field data.
169 * - The "insert", "update", "delete", "validate", and "submit" operations
170 * have no return value.
171 *
172 * In most cases, only "validate" operations is relevant ; the rest
173 * have default implementations in content_field() that usually suffice.
174 */
175 function office_hours_field($op, &$node, $field, &$node_field, $teaser, $page) {
176 switch ($op) {
177 case 'view':
178 $context = $teaser ? 'teaser' : 'full';
179 $formatter = isset($field['display_settings'][$context]['format']) ? $field['display_settings'][$context]['format'] : 'default';
180 $items = array();
181 foreach ($node_field as $delta => $item) {
182 $items[$delta]['view'] = content_format($field, $item, $formatter, $node);
183 }
184 return theme('field', $node, $field, $items, $teaser, $page);
185
186 case 'validate':
187 //holder for validation. possibly add restriction so that the start hour couldn't be later than end hour.
188 break;
189 }
190 }
191
192 /**
193 * Declare information about a formatter.
194 *
195 * @return
196 * An array keyed by formatter name. Each element of the array is an associative
197 * array with these keys and values:
198 * - "label": The human-readable label for the formatter.
199 * - "field types": An array of field type names that can be displayed using
200 * this formatter.
201 */
202 function office_hours_field_formatter_info() {
203 return array(
204 'default' => array(
205 'label' => 'default',
206 'field types' => array('office_hours'),
207 ),
208 );
209 }
210
211 /**
212 * implementation of hook_field_formatter
213 * Prepare an individual item for viewing in a browser.
214 *
215 * @param $field
216 * The field the action is being performed on.
217 * @param $item
218 * An array, keyed by column, of the data stored for this item in this field.
219 * @param $formatter
220 * The name of the formatter being used to display the field.
221 * @param $node
222 * The node object, for context. Will be NULL in some cases.
223 * Warning : when displaying field retrieved by Views, $node will not
224 * be a "full-fledged" node object, but an object containg the data returned
225 * by the Views query (at least nid, vid, changed)
226 * @return
227 * An HTML string containing the formatted item.
228 *
229 * It is important that this function at the minimum perform security
230 * transformations such as running check_plain() or check_markup().
231 */
232 function office_hours_field_formatter($field, $item, $formatter, $node) {
233 if (isset($item['day'])) {
234 $daykey= check_plain($item['day']);
235 $days=array(0 => t('Sunday'), 1 => t('Monday'), 2 => t('Tuesday'),3 => t('Wednesday'), 4 => t('Thursday'), 5 => t('Friday'), 6 => t('Saturday'));
236 $day= $days[$daykey];
237 }
238 else {$day= '';}
239 $endhrs=check_plain($item['endhours']);
240 $strhrs=check_plain($item['starthours']);
241
242 if ($field['hoursformat']== 1) {
243 $endhrs=convert_to_ampm($endhrs);
244 $strhrs=convert_to_ampm($strhrs);
245 }
246
247 switch ($formatter) {
248 default:
249 return theme('oh_formatter_display', $day, $strhrs, $endhrs);
250 }
251 }
252
253
254 /**
255 * Declare information about a widget.
256 *
257 * @return
258 * An array keyed by widget name. Each element of the array is an associative
259 * array with these keys and values:
260 * - "label": The human-readable label for the widget.
261 * - "field types": An array of field type names that can be edited using
262 * this widget.
263 */
264 function office_hours_widget_info() {
265 return array(
266 'default' => array(
267 'label' => t('Office Hours'),
268 'field types' => array('office_hours'),
269 ),
270 );
271 }
272
273 /**
274 * Implementation of hook_widget_settings().
275 *
276 * @param $op
277 * The operation to be performed. Possible values:
278 * @param $widget
279 * The widget on which the operation is to be performed.
280 * @return
281 * This varies depending on the operation.
282 * - "form": an array of form elements to add to the settings page.
283 * - "validate": no return value. Use form_set_error().
284 * - "save": an array of names of form elements to be saved in the database.
285 * - "callbacks": an array describing the widget's behaviour regarding hook_widget
286 * operations. The array is keyed by hook_widget operations ('form', 'validate'...)
287 * and has the following possible values :
288 * CONTENT_CALLBACK_NONE : do nothing for this operation
289 * CONTENT_CALLBACK_CUSTOM : use the behaviour in hook_widget(operation)
290 * CONTENT_CALLBACK_DEFAULT : use content.module's default bahaviour
291 * Note : currently only the 'default value' operation implements this feature.
292 * All other widget operation implemented by the module _will_ be executed
293 * no matter what.
294 */
295 function office_hours_widget_settings($op, $widget) {
296 switch ($op) {
297 case 'form':
298 $form = array();
299 /* $form['numitems'] = array(
300 '#type' => 'textfield',
301 '#title' => t('number of hour blocks/days'),
302 '#default_value' => $widget['numitems'] ? $widget['numitems'] : 1,
303 '#required' => TRUE,
304 );*/
305 return $form;
306
307 case 'validate':
308 break;
309
310 //case 'save':
311 // return array('numitems');
312
313 case 'callbacks':
314 return array(
315 'default value' => CONTENT_CALLBACK_DEFAULT,
316 );
317 }
318 }
319
320 /**
321 * * Implementation of hook_widget().
322 *
323 * @param $op
324 * What kind of action is being performed. Possible values:
325 * @param &$node
326 * The node the action is being performed on. This argument is passed by
327 * reference for performance only; do not modify it.
328 * @param $field
329 * The field the action is being performed on.
330 * @param &$node_field
331 * The contents of the field in this node. Changes to this variable will
332 * be saved back to the node object.
333 * @return
334 * This varies depending on the operation.
335 * - The "form" operation should return an array of form elements to display.
336 * - Other operations have no return value.
337 */
338 function office_hours_widget($op, &$node, $field, &$node_field) {
339
340 switch ($op) {
341 case 'prepare form values':
342 break;
343
344 case 'form':
345 $ophours= _create_hours_arr($field, TRUE);
346 $form[$field['field_name']] = array('#tree' => TRUE);
347
348 if ($field['multiple']) {
349
350 $form[$field['field_name']]['#type'] = 'fieldset';
351 $form[$field['field_name']]['#description'] = t($field['widget']['description']);
352 $form[$field['field_name']]['#attributes'] = array('class' => 'office-container-inline');
353
354 $delta = 0;
355 foreach ($node_field as $data) {
356 if (isset($data['day']) && isset($data['starthours']) && isset($data['endhours']) ) {
357 $form[$field['field_name']][$delta]['day'] = array(
358 '#type' => 'select',
359 '#title' => t('Day'), //($delta == 0) ? t($field['widget']['label']) : '',
360 '#options' => array(0 => t('Sunday'), 1 => t('Monday'), 2 => t('Tuesday'),
361 3 => t('Wednesday'), 4 => t('Thursday'), 5 => t('Friday'), 6 => t('Saturday'), 7=> t('None')),
362 '#description' => $field['widget']['description'],
363 '#default_value' => $data['day'], //$node_field[$key]['day'],
364 '#required' => ($delta == 0) ? $field['required'] : FALSE,
365 '#prefix' => '<div class="office_hours_block">',
366 );
367 $form[$field['field_name']][$delta]['starthours'] = array(
368 '#type' => 'select',
369 '#title' => t('Starting from'),//($delta == 0) ? t($field['widget']['label']) : '',
370 '#options' => $ophours,
371 '#required' => ($delta == 0) ? $field['required'] : FALSE,
372 '#description' => $field['widget']['description'],
373 '#default_value' => $data['starthours'],
374 );
375 $form[$field['field_name']][$delta]['endhours'] = array(
376 '#type' => 'select',
377 '#title' => t('Ending at'),//($delta == 0) ? t($field['widget']['label']) : '',
378 '#options' => $ophours,
379 '#required' => ($delta == 0) ? $field['required'] : FALSE,
380 '#description' => $field['widget']['description'],
381 '#default_value' => $data['endhours'], //$node_field[$key]['endhours'],
382 '#suffix' => '</div>',
383 );
384 $delta++;
385 }
386 }
387 foreach (range($delta,$delta+1) as $delta) {
388 $form[$field['field_name']][$delta]['day'] = array(
389 '#type' => 'select',
390 '#title' => t('Day'), //($delta == 0) ? t($field['widget']['label']) : '',
391 '#options' => array(0 => t('Sunday'), 1 => t('Monday'), 2 => t('Tuesday'),
392 3 => t('Wednesday'), 4 => t('Thursday'), 5 => t('Friday'), 6 => t('Saturday'), 7=> t('None')),
393 '#description' => $field['widget']['description'],
394 '#default_value' => 7,
395 '#prefix' => '<div class="office-hours-block">'
396 );
397 $form[$field['field_name']][$delta]['starthours'] = array(
398 '#type' => 'select',
399 '#title' => t('Starting from'),//($delta == 0) ? t($field['widget']['label']) : '',
400 '#options' => $ophours,
401 '#required' => $field['required'],
402 '#description' => $field['widget']['description'],
403 '#default_value' => 0,
404 );
405 $form[$field['field_name']][$delta]['endhours'] = array(
406 '#type' => 'select',
407 '#title' => t('Ending at'),
408 '#options' => $ophours,
409 '#required' => $field['required'],
410 '#description' => $field['widget']['description'],
411 '#default_value' => 'erase',
412 '#suffix' => '</div>',
413 );
414 }
415 }
416 else {
417 $form[$field['field_name']][0]['day'] = array(
418 '#type' => 'select',
419 '#title' => t('day'),
420 '#options' => array(0 => t('Sunday'), 1 => t('Monday'), 2 => t('Tuesday'),
421 3 => t('Wednesday'), 4 => t('Thursday'), 5 => t('Friday'), 6 => t('Saturday'), 7=> ''),
422 '#description' => $field['widget']['description'],
423 '#default_value' => $node_field[0]['day'],
424 );
425
426 $form[$field['field_name']][0]['starthours'] = array(
427 '#type' => 'select',
428 '#title' => t('start hours block'),
429 '#options' => $ophours,
430 '#required' => $field['required'],
431 '#description' => $field['widget']['description'],
432 '#default_value' => $node_field[0]['starthours'],
433 );
434 $form[$field['field_name']][0]['endhours'] = array(
435 '#type' => 'select',
436 '#title' => t('end of hour block'),
437 '#multiple' => $field['multiple'],
438 '#options' => $ophours,
439 '#required' => $field['required'],
440 '#description' => $field['widget']['description'],
441 '#default_value' => $node_field[0]['endhours'],
442 );
443 }
444 return $form;
445
446 case 'process form values':
447 foreach ($node_field as $delta => $item) {
448 if ( $item['starthours'] == 'erase' ) {
449 unset($node_field[$delta]);
450 }
451 }
452 break;
453 }
454 }
455
456 /**
457 * helper function to create hours array.
458 * items are saved in 24 hours string format (i.e '18:00'). the logic of this function could be better.
459 */
460 function _create_hours_arr($field, $limit = TRUE) {
461 $fl1= $field['limitstart'];
462 $fl2= $field['limitend'];
463 $limst=0; $limend=24; $stam=1; $endam=12; $stpm= 1; $endpm= 12; $mins='00';
464 if ($limit === TRUE) {
465 if (isset($field['limitstart'])) {
466 list($limst, $mins)= explode(":",$fl1);
467 if ($limst>12) { $stpm=$limst-12; }
468 else {$stam=$limst;}
469 }
470 else {$limst=0;}
471 if (isset($field['limitend'])) {
472 list($limend, $mine)= explode(":",$fl2);
473 if ($limend>12) { $endpm=$limend-12; }
474 else {$endam=$limend;}
475 }
476 else {$limend=24;}
477 }
478
479 $ophours['erase'] = t('None');
480
481 if ($field['hoursformat'] == 1) { //AMPM
482 if ($stpm == 1) {
483 foreach (range($stam,$endam) as $i) {
484 if ($mins=='00') {
485 $hr= $i.':00';
486 $ophours[$hr]= $i.':00 AM';
487 }
488 else {$mins='00';} // next iteration, go through round hours
489 if ( $field['granularity'] > 0) {
490 $j=$field['granularity']; $add=$j; // either 15 or 30
491 for(; $j<=45; $j=$j+$add) {
492 $hr1=$i.':'.$j;
493 if ($i<12) $ophours[$hr1]=$i.':'.$j.' AM';
494 }
495 }
496 }
497 }
498 foreach (range($stpm,$endpm) as $i) {
499 $milh= $i+12;
500 if ($mins=='00') {
501 $hr= $milh.':00';
502 $ophours[$hr]= $i.':00 PM';
503 }
504 else {$mins='00';} // next iteration, go through round hours
505 if ($field['granularity'] > 0) {
506 $add=$j=$field['granularity']; // either 15 or 30
507 for(; $j<=45; $j=$j+$add) {
508 $hr1= $milh.':'.$j;
509 if ($i<12) $ophours[$hr1]=$i.':'.$j.' PM';
510 }
511 }
512 }
513 }
514 else {
515 foreach (range($limst,$limend) as $i) {
516 if ($mins=='00') {
517 $hr= $i.':00';
518 $ophours[$hr]= $hr;
519 }
520 else {$mins='00';} // next iteration, go through round hours
521 if ($field['granularity'] > 0) {
522 $add=$j=$field['granularity']; // either 15 or 30
523 for(; $j<=45; $j=$j+$add) {
524 $hr1=$i.':'.$j;
525 $ophours[$hr1]=$hr1;
526 }
527 }
528 }
529 }
530 return $ophours;
531 }
532 /**
533 * Helper function for conversion of clock format.
534 */
535 function convert_to_ampm($hour) {
536 list($hr, $min)= explode(":",$hour);
537 if ($hr>12 && $hr<24) {
538 $hr= $hr-12;
539 $ampm= ' PM';
540 }
541 else {
542 $ampm=' AM';
543 }
544 return $hr.':'.$min.$ampm ;
545 }
546
547 /**
548 * Theme function for date node display
549 */
550 function theme_oh_formatter_display($day, $strhrs, $endhrs) {
551 return '<div class="oh-display"><span class="oh-display-day">'.$day.'</span>
552 <span class="oh-display-start">'. $strhrs .'</span>
553 <span class="oh-display-separator"> - </span>
554 <span class="oh-display-end">'. $endhrs .'</span></div>';
555
556 }

  ViewVC Help
Powered by ViewVC 1.1.2