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

Contents of /contributions/modules/timer/timer.module

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


Revision 1.1 - (show annotations) (download) (as text)
Tue Oct 9 08:27:25 2007 UTC (2 years, 1 month ago) by gestaltware
Branch: MAIN
CVS Tags: DRUPAL-5--1-0, HEAD
Branch point for: DRUPAL-5
File MIME type: text/x-php
Initial Release for Drupal 5.x
1 <?php
2 // $Id$
3
4 /**
5 * @file
6 * Defines a CCK field type for a timer, which can be started, stopped and reset via timer button controls or workflow actions.
7 */
8
9 /**
10 * Implementation of hook_help().
11 */
12 function timer_help($section) {
13 switch ($section) {
14 case 'admin/modules#description':
15 return t('Defines a CCK field type for a timer, which can be started, stopped and reset via timer button controls or workflow actions.');
16 }
17 }
18
19 /**
20 * Implementation of hook_perm()
21 */
22 function timer_perm() {
23 return array('use timer controls');
24 }
25
26 //============= DATA LAYER ==================================
27
28 /**
29 * Declare information about a field type.
30 */
31 function timer_field_info() {
32 return array(
33 'timer' => array('label' => t('Timer')),
34 );
35 }
36
37 /**
38 * Handle the parameters for a field.
39 */
40 function timer_field_settings($op, $field) {
41 switch ($op) {
42 case 'form':
43 $form['timer_enable_controls'] = array(
44 '#type' => 'checkbox',
45 '#title' => t('Enable timer button controls?'),
46 '#default_value' => isset($field['timer_enable_controls']) ? $field['timer_enable_controls'] : 1,
47 '#return_value' => 1,
48 '#description' => t('Disabling this setting will only allow workflow actions to control the timer.'),
49 );
50 $form['timer_enable_dhtml'] = array(
51 '#type' => 'checkbox',
52 '#title' => t('Enable DHTML timer update?'),
53 '#default_value' => isset($field['timer_enable_dhtml']) ? $field['timer_enable_dhtml'] : 1,
54 '#return_value' => 1,
55 '#description' => t('If enabled, the timer will be shown in real-time. If disabled, the timer will be updated on page refresh.'),
56 );
57 $form['timer_granularity'] = array(
58 '#type' => 'checkbox',
59 '#title' => t('Show timer in seconds?'),
60 '#default_value' => isset($field['timer_granularity']) ? $field['timer_granularity'] : 1,
61 '#return_value' => 1,
62 '#description' => t('If disabled, seconds will only be shown if the timer is less than 24 hours (e.g. seconds are not displayed for 1 day 2 hours 3 minutes). Seconds are always shown if DHTML timer update is enabled above.'),
63 );
64 $form['required']['#type'] = 'hidden';
65 $form['multiple']['#type'] = 'hidden';
66 return $form;
67
68 case 'validate':
69 unset ($field['multiple'],$field['required']);
70 break;
71
72 case 'save':
73 return array('timer_enable_controls','timer_enable_dhtml', 'timer_granularity');
74
75 case 'database columns':
76 $columns = array(
77 'timer_start' => array('type' => 'int', 'length' => 10, 'unsigned' => TRUE, 'not null' => TRUE, 'default' => 0),
78 'timer_stop' => array('type' => 'int', 'length' => 10, 'unsigned' => TRUE, 'not null' => TRUE, 'default' => 0),
79 'timer_elapsed' => array('type' => 'int', 'length' => 10, 'unsigned' => TRUE, 'not null' => TRUE, 'default' => 0),
80 );
81 return $columns;
82 }
83 }
84
85 /**
86 * Define the behavior of a field type.
87 */
88 function timer_field($op, &$node, $field, &$items) {
89 switch ($op) {
90 // case 'load':
91 // case 'validate':
92 // case 'submit':
93 // case 'insert':
94 // case 'update':
95 // case 'delete':
96
97 case 'load':
98 foreach ($items as $delta => $item) {
99 $items[$delta]['view'] = content_format($field, $item, 'default', $node);
100 }
101 return theme('field', $node, $field, $items, $teaser, $page);
102 break;
103 }
104 return $output;
105 }
106
107 //============= PRESENTATION LAYER ==================================
108 /**
109 * Declare information about a formatter.
110 * - define one or more ways to display information
111 * - The 'default' formatter is used for the standard node display.
112 * - All the available formatters are displayed as options when the field is used in Views.
113 */
114 function timer_field_formatter_info() {
115 return array(
116 'default' => array(
117 'label' => 'Default',
118 'field types' => array('timer'),
119 ),
120 );
121 }
122
123 /**
124 * Prepare an individual item for viewing in a browser.
125 */
126 function timer_field_formatter($field, $item, $formatter, $node) {
127 $path = drupal_get_path('module', 'timer');
128 drupal_add_css($path . '/timer.css', 'module', 'screen', FALSE);
129
130 $enable_button_controls = $field['timer_enable_controls'] && user_access('use timer controls');
131 $timer_granularity = $field['timer_granularity'] ? 6 : 3;
132
133 if ($item['timer_start'] == 0) {
134 if ($enable_button_controls) {
135 return theme('timer_button', $field['field_name'], $node, 'start');
136 }
137 return '';
138 }
139
140 $timer = $item['timer_elapsed'];
141 if ($item['timer_stop'] != 0) {
142 if ($enable_button_controls) {
143 $timer_button .= theme('timer_button', $field['field_name'], $node, 'reset');
144 }
145 $timer += $item['timer_stop'] - $item['timer_start'];
146 }
147 else {
148 if ($enable_button_controls) {
149 $timer_button = theme('timer_button', $field['field_name'], $node, 'stop');
150 }
151 $timer += time() - $item['timer_start'];
152 if ($field['timer_enable_dhtml']) {
153 drupal_add_js($path . '/timer.js');
154 drupal_add_js("\n" . 'var ' . $field['field_name'] . '=new timer(' . $timer . ', "' . $field['field_name'] . '");', 'inline', 'footer');
155 }
156 }
157
158 switch ($formatter) {
159 default:
160 return theme('timer_field', $field['field_name'], format_interval($timer, $timer_granularity)) . $timer_button; //always display seconds
161 }
162 }
163
164 //============= FORM LAYER ==================================
165
166 /**
167 * Declare information about a widget.
168 */
169 function timer_widget_info() {
170 return array(
171 'timer' => array(
172 'label' => t('Elapsed Timer'),
173 'field types' => array('timer'),
174 ),
175 );
176 }
177
178 /**
179 * Handle the parameters for a widget.
180 */
181 function timer_widget_settings($op, $widget) {
182 switch ($op) {
183 case 'form':
184 $form = array();
185 return $form;
186 }
187 }
188
189 /**
190 * Define the behavior of a widget.
191 */
192 function timer_widget($op, &$node, $field, &$items) {
193 switch ($op) {
194 case 'prepare form values':
195 break;
196
197 case 'form':
198 $form = array();
199 $form[$field['field_name']] = array('#tree' => TRUE);
200 $form[$field['field_name']][0]['timer_start'] = array(
201 '#type' => 'hidden',
202 '#default_value' => isset($items[0]['timer_start']) ? $items[0]['timer_start'] : 0,
203 '#required' => $field['required'] ? $field['required'] : FALSE,
204 );
205 $form[$field['field_name']][0]['timer_stop'] = array(
206 '#type' => 'hidden',
207 '#default_value' => isset($items[0]['timer_stop']) ? $items[0]['timer_stop'] : 0,
208 '#required' => $field['required'] ? $field['required'] : FALSE,
209 );
210 $form[$field['field_name']][0]['timer_elapsed'] = array(
211 '#type' => 'hidden',
212 '#default_value' => isset($items[0]['timer_elapsed']) ? $items[0]['timer_elapsed'] : 0,
213 '#required' => $field['required'] ? $field['required'] : FALSE,
214 );
215
216 return $form;
217
218 case 'validate':
219 break;
220
221 case 'process form values':
222 break;
223
224 case 'submit':
225 break;
226 }
227 }
228
229 //============= TIMER FORM BUTTONS ==================================
230
231 function timer_form($op = 'reset', $node, $timer_field) {
232 $form = array();
233 $form['nid'] = array('#type' => 'hidden', '#value' => $node->nid);
234 $form['timer_field'] = array('#type' => 'hidden', '#value' => $timer_field);
235
236 switch ($op) {
237 case 'start':
238 $form['submit'] = array('#type' => 'submit', '#value' => t('Start'), '#attributes' => array('class' => 'start'));
239 break;
240 case 'stop':
241 $form['submit'] = array('#type' => 'submit', '#value' => t('Stop'), '#attributes' => array('class' => 'stop'));
242 break;
243 default:
244 $form['start'] = array('#type' => 'button', '#value' => t('Start'), '#attributes' => array('class' => 'start'));
245 $form['submit'] = array('#type' => 'submit', '#value' => t('Reset'), '#attributes' => array('class' => 'reset'));
246 break;
247 }
248
249 return $form;
250 }
251
252 function timer_form_validate($form_id, $form_values) {
253 $op = $_POST['op'];
254 unset($_POST['op']); //need to unset or infinite loop?
255
256 switch ($op) {
257 case t('Start'):
258 drupal_set_message(t('Timer started.'));
259 _timer_start(node_load($form_values['nid']), $form_values['timer_field']);
260 break;
261 case t('Stop'):
262 drupal_set_message(t('Timer stopped.'));
263 _timer_stop(node_load($form_values['nid']), $form_values['timer_field']);
264 break;
265 case t('Reset'):
266 drupal_set_message(t('Timer reset.'));
267 _timer_reset(node_load($form_values['nid']), $form_values['timer_field']);
268 break;
269 }
270
271 //redirect to page for refresh
272 //cache_clear_all('content:'. intval($form_values['nid']) .':' , 'cache_content', TRUE);
273 drupal_goto($_GET['q']);
274 }
275
276 //============= THEME FUNCTIONS =====================================
277
278 /**
279 * Renders timer button output
280 * @ingroup themeable
281 */
282 function theme_timer_button($field, &$node, $action = 'start') {
283 return '<div class="timer-button">' . drupal_get_form('timer_form', $action, $node, $field) . '</div>';
284 }
285
286 /**
287 * Renders timer field output
288 * @ingroup themeable
289 */
290 function theme_timer_field($field, $timer) {
291 return '<div class="timer" id="' . $field . '">' . $timer . '</div>';
292 }
293
294 //============= ACTIONS ==================================
295
296 function action_timer_start($op, $edit = array(), &$node) {
297 switch($op) {
298 case 'metadata':
299 return array(
300 'description' => t('Start timer'),
301 'type' => t('CCK'),
302 'batchable' => false,
303 'configurable' => true,
304 );
305
306 case 'do':
307 list($timer_node_type,$timer_field) = split("-",$edit['timer_field']);
308 if ($node->type == $timer_node_type) {
309 $found_field = db_result(db_query("SELECT f.type_name FROM {node_field_instance} f WHERE f.field_name='%s' AND f.widget_type LIKE '%s' LIMIT 0,1", $timer_field, 'timer%'));
310 if ($found_field) {
311 _timer_start($node, $timer_field);
312 }
313 else {
314 watchdog('error', t('Action timer field %timer_field not valid for node type %timer_node_type', array('%timer_field' => $timer_field, '%timer_node_type' => $timer_node_type)));
315 }
316 }
317 else {
318 watchdog('error', t('Action timer node type %timer_node_type not valid for node type %node_type', array('%timer_node_type' => $timer_node_type, '%node_type' => $node->type)));
319 }
320 break;
321
322 // return an HTML config form for the action
323 case 'form':
324 $form = array();
325 $options = array();
326 $result = db_query("SELECT f.field_name, f.type_name, f.label, t.name FROM {node_field_instance} f LEFT JOIN {node_type} t ON (f.type_name = t.type) WHERE f.widget_type LIKE '%s' ORDER BY f.type_name", 'timer%');
327 while ($data = db_fetch_object($result)) {
328 $options[$data->type_name .'-'. $data->field_name] = $data->name . ': ' . $data->label;
329 }
330
331 $form['timer_field'] = array (
332 '#type' => 'select',
333 '#title' => 'Timer field',
334 '#default_value' => $edit['timer_field'],
335 '#options' => $options,
336 '#required' => TRUE,
337 '#description' => t('Select the CCK Timer field you would like to start. Note that the workflow must only be associated with the node type selected above.'),
338 );
339 return $form;
340
341 // validate the HTML form
342 case 'validate':
343 $errors = array();
344 foreach ($errors as $name => $message) {
345 form_set_error($name, $message);
346 }
347 return count($errors) == 0;
348
349 // process the HTML form to store configuration
350 case 'submit':
351 $params = array('timer_field' => $edit['timer_field']);
352 return $params;
353 }
354 }
355
356 function action_timer_stop($op, $edit = array(), &$node) {
357 switch($op) {
358 case 'metadata':
359 return array(
360 'description' => t('Stop timer'),
361 'type' => t('CCK'),
362 'batchable' => false,
363 'configurable' => true,
364 );
365
366 case 'do':
367 list($timer_node_type,$timer_field) = split("-",$edit['timer_field']);
368 if ($node->type == $timer_node_type) {
369 $found_field = db_result(db_query("SELECT f.type_name FROM {node_field_instance} f WHERE f.field_name='%s' AND f.widget_type LIKE '%s' LIMIT 0,1", $timer_field, 'timer%'));
370 if ($found_field) {
371 _timer_stop($node, $timer_field);
372 }
373 else {
374 watchdog('error', t('Action timer field %timer_field not valid for node type %timer_node_type', array('%timer_field' => $timer_field, '%timer_node_type' => $timer_node_type)));
375 }
376 }
377 else {
378 watchdog('error', t('Action timer node type %timer_node_type not valid for node type %node_type', array('%timer_node_type' => $timer_node_type, '%node_type' => $node->type)));
379 }
380 break;
381
382 // return an HTML config form for the action
383 case 'form':
384 $form = array();
385 $options = array();
386 $result = db_query("SELECT f.field_name, f.type_name, f.label, t.name FROM {node_field_instance} f LEFT JOIN {node_type} t ON (f.type_name = t.type) WHERE f.widget_type LIKE '%s' ORDER BY f.type_name", 'timer%');
387 while ($data = db_fetch_object($result)) {
388 $options[$data->type_name .'-'. $data->field_name] = $data->name . ': ' . $data->label;
389 }
390
391 $form['timer_field'] = array (
392 '#type' => 'select',
393 '#title' => 'Timer field',
394 '#default_value' => $edit['timer_field'],
395 '#options' => $options,
396 '#required' => TRUE,
397 '#description' => t('Select the CCK Timer field you would like to stop. Note that the workflow must only be associated with the node type selected above.'),
398 );
399 return $form;
400
401 // validate the HTML form
402 case 'validate':
403 $errors = array();
404 foreach ($errors as $name => $message) {
405 form_set_error($name, $message);
406 }
407 return count($errors) == 0;
408
409 // process the HTML form to store configuration
410 case 'submit':
411 $params = array('timer_field' => $edit['timer_field']);
412 return $params;
413 }
414 }
415
416 function action_timer_reset($op, $edit = array(), &$node) {
417 switch($op) {
418 case 'metadata':
419 return array(
420 'description' => t('Reset timer'),
421 'type' => t('CCK'),
422 'batchable' => false,
423 'configurable' => true,
424 );
425
426 case 'do':
427 list($timer_node_type,$timer_field) = split("-",$edit['timer_field']);
428 if ($node->type == $timer_node_type) {
429 $found_field = db_result(db_query("SELECT f.type_name FROM {node_field_instance} f WHERE f.field_name='%s' AND f.widget_type LIKE '%s' LIMIT 0,1", $timer_field, 'timer%'));
430 if ($found_field) {
431 _timer_reset($node, $timer_field);
432 }
433 else {
434 watchdog('error', t('Action timer field %timer_field not valid for node type %timer_node_type', array('%timer_field' => $timer_field, '%timer_node_type' => $timer_node_type)));
435 }
436 }
437 else {
438 watchdog('error', t('Action timer node type %timer_node_type not valid for node type %node_type', array('%timer_node_type' => $timer_node_type, '%node_type' => $node->type)));
439 }
440 break;
441
442 // return an HTML config form for the action
443 case 'form':
444 $form = array();
445 $options = array();
446 $result = db_query("SELECT f.field_name, f.type_name, f.label, t.name FROM {node_field_instance} f LEFT JOIN {node_type} t ON (f.type_name = t.type) WHERE f.widget_type LIKE '%s' ORDER BY f.type_name", 'timer%');
447 while ($data = db_fetch_object($result)) {
448 $options[$data->type_name .'-'. $data->field_name] = $data->name . ': ' . $data->label;
449 }
450
451 $form['timer_field'] = array (
452 '#type' => 'select',
453 '#title' => 'Timer field',
454 '#default_value' => $edit['timer_field'],
455 '#options' => $options,
456 '#required' => TRUE,
457 '#description' => t('Select the CCK Timer field you would like to reset to 0. Note that the workflow must only be associated with the node type selected above.'),
458 );
459 return $form;
460
461 // validate the HTML form
462 case 'validate':
463 $errors = array();
464 foreach ($errors as $name => $message) {
465 form_set_error($name, $message);
466 }
467 return count($errors) == 0;
468
469 // process the HTML form to store configuration
470 case 'submit':
471 $params = array('timer_field' => $edit['timer_field']);
472 return $params;
473 }
474 }
475
476 //============= INTERNAL FUNCTIONS ==================================
477
478 function _timer_start(&$node, $timer_field) {
479 if (!(int)$node->nid) return false;
480 $time = time();
481 $timer_node = &$node->$timer_field;
482 $timer_start = ($timer_node[0]['timer_start'] > 0) ? $timer_node[0]['timer_start'] : $time;
483 $timer_stop = ($timer_node[0]['timer_stop'] > 0) ? $timer_node[0]['timer_stop'] : $time;
484 $timer_node[0]['timer_start'] = $time;
485 $timer_node[0]['timer_stop'] = 0;
486 $timer_node[0]['timer_elapsed'] += $timer_stop - $timer_start;
487 $node->revision = '0';
488 node_save($node);
489 watchdog('content', t('@type: started timer field %timer_field on %title.', array('@type' => t($node->type), '%timer_field' => $timer_field, '%title' => $node->title)), WATCHDOG_NOTICE, l(t('view'), 'node/'. $node->nid));
490 return true;
491 }
492
493 function _timer_stop(&$node, $timer_field) {
494 if (!(int)$node->nid) return false;
495 $timer_node = &$node->$timer_field;
496 if ($timer_node[0]['timer_stop'] == 0) {
497 $timer_node[0]['timer_stop'] = time();
498 $node->revision = '0';
499 node_save($node);
500 watchdog('content', t('@type: stopped timer field %timer_field on %title.', array('@type' => t($node->type), '%timer_field' => $timer_field, '%title' => $node->title)), WATCHDOG_NOTICE, l(t('view'), 'node/'. $node->nid));
501 return true;
502 }
503 return false;
504 }
505
506 function _timer_reset(&$node, $timer_field) {
507 if (!(int)$node->nid) return false;
508 $timer_node = &$node->$timer_field;
509 $timer_node[0]['timer_start'] = 0;
510 $timer_node[0]['timer_stop'] = 0;
511 $timer_node[0]['timer_elapsed'] = 0;
512 $node->revision = '0';
513 node_save($node);
514 watchdog('content', t('@type: reset timer field %timer_field on %title.', array('@type' => t($node->type), '%timer_field' => $timer_field, '%title' => $node->title)), WATCHDOG_NOTICE, l(t('view'), 'node/'. $node->nid));
515 return true;
516 }

  ViewVC Help
Powered by ViewVC 1.1.2