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

Contents of /contributions/modules/timemap/timemap.module

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


Revision 1.4 - (show annotations) (download) (as text)
Tue Jul 7 03:27:15 2009 UTC (4 months, 2 weeks ago) by sethfreach
Branch: MAIN
CVS Tags: HEAD
Branch point for: DRUPAL-6--1
Changes since 1.3: +213 -178 lines
File MIME type: text/x-php
fix newlines causing wrapping from previous commit
1 <?php
2 // $Id: timemap.module,v 1.3 2008/06/11 22:24:40 sethfreach Exp $
3
4 /* TODO Implement the hook_theme registry. Combine all theme registry entries
5 into one hook_theme function in each corresponding module file.
6 function timemap_theme() {
7 return array(
8 'timemap_admin_settings' => array(
9 'file' => 'timemap.module',
10 'arguments' => array(
11 'form' => NULL,
12 ),
13 ),
14 'timemap_viewable_reports_list_people' => array(
15 'file' => 'timemap.module',
16 'arguments' => array(
17 'list' => array(),
18 ),
19 ),
20 );
21 } */
22 /**
23 * @file
24 * Timemap module - Track how you spend your day with a simple as possible input interface.
25 */
26
27
28 /**
29 * Implementation of hook_perm
30 */
31 function timemap_perm() {
32 $perms = array(
33 'enter tasks',
34 'edit own categories',
35 'edit global categories',
36 'edit timemap settings',
37 'view own report',
38 'view all reports',
39 );
40
41 // If CiviCRM is installed, offer more perms that allow people to view subsets of reports
42 // as defined by CiviCRM relationships.
43 //
44 // TODO: Add a civi version check to the if() statement to make sure we use the correct Civi API calls when
45 // fetching the relationship data.
46 if (module_exists('civicrm')) {
47 $perms[] = 'view subordinate reports';
48 }
49
50 return $perms;
51 }
52
53
54
55 /**
56 * Implementation of hook_menu
57 */
58 function timemap_menu() {
59 $items['timemap'] = array(
60 'title' => 'Time Maps',
61 'page callback' => 'timemap_dashboard',
62 'access arguments' => array('enter tasks'),
63 );
64 $items['timemap/doing'] = array(
65 'title' => 'Enter a task',
66 'page callback' => 'timemap_enter_task',
67 'access arguments' => array('enter tasks'),
68 );
69 $items['timemap/map'] = array(
70 'title' => 'Personal Time Map',
71 'page callback' => 'timemap_map',
72 'access arguments' => array('view own report'),
73 );
74 $items['timemap/report'] = array(
75 'title' => 'Time Map Reports',
76 'page callback' => 'timemap_report',
77 'access arguments' => array('view own report'),
78 'type' => MENU_CALLBACK, // technically enable it, but effecively hide it while incomplete.
79 );
80 $items['admin/settings/timemap'] = array(
81 'title' => 'Time Map Settings',
82 'description' => 'Change some settings and defaults for the Timemap module',
83 'page callback' => 'drupal_get_form',
84 'page arguments' => array('timemap_admin_settings'),
85 'access arguments' => (user_access('edit global categories') || user_access('edit timemap settings')),
86 );
87 $items['timemap/map/serv'] = array(
88 'title' => 'Time Spent Reports Server',
89 'page callback' => 'timemap_map_serv',
90 'access arguments' => array('view own report'),
91 'type' => MENU_CALLBACK,
92 );
93 $items['timemap/doing/autoc'] = array(
94 'title' => 'Task Entry Autocomplete Ajax Callback',
95 'page callback' => 'timemap_doing_autoc',
96 'access arguments' => array('enter tasks'),
97 'type' => MENU_CALLBACK,
98 );
99
100 return $items;
101 }
102
103
104
105 /**
106 * Implementation of hook_block
107 */
108 function timemap_block($op = 'list', $delta = 0, $edit = array()) {
109 switch ($op) {
110 case 'list':
111 $blocks[0] = array(
112 'info' => t('Time Map Task Entry'),
113 'status' => true,
114 'custom' => false,
115 'title' => t('Time Mapping'),
116 );
117 return $blocks;
118
119 case 'view':
120 switch ($delta) {
121 case 0:
122 $block = array(
123 'subject' => t('Time Tracking'),
124 'content' => drupal_get_form('timemap_enter_task_form', true),
125 );
126 }
127 return $block;
128 }
129 }
130
131 /*******************************************************/
132
133 /**
134 * form to admin and set the defaults. the "config" settings
135 */
136 function timemap_admin_settings() {
137 global $user;
138
139 $form['#validate'][] = 'timemap_admin_settings_validate';
140 $form['#submit'][] = 'timemap_admin_settings_submit';
141
142 $form['gcats'] = array(
143 '#type' => 'fieldset',
144 '#access' => user_access('edit global categories'),
145 '#title' => t('Global Categories'),
146 '#collapsible' => true,
147 '#collapsed' => false,
148 '#weight' => -2,
149 );
150
151 // add a new one.
152 $form['gcats']['newgcat'] = array(
153 '#type' => 'textfield',
154 '#description' => t('A new category available to all users.'),
155 '#title' => t('New Category'),
156 );
157 if (module_exists('colorpicker')) {
158 $form['gcats']['color_new'] = array(
159 '#type' => 'colorpicker',
160 '#title' => t('Category Color'),
161 );
162 $form['gcats']['color_new_v'] = array(
163 '#type' => 'colorpicker_textfield',
164 '#description' => t('Choose a color to display for this category.'),
165 '#default_value' => '#ffffff',
166 '#colorpicker' => 'color_new',
167 );
168 }
169 else {
170 $form['gcats']['color_new_v'] = array(
171 '#type' => 'textfield',
172 '#size' => '7',
173 '#description' => t('Choose a color to display for this category. Enter it in 6 char hex *with* a preceding #.'),
174 '#default_value' => '#ffffff',
175 );
176 }
177
178 // edit existing ones.
179 $result = db_query("select c.cid as cid, c.category as category, c.active as active, cc.hex as hex
180 from {timemap_categories} c left join {timemap_catcolor} cc on c.cid = cc.cid
181 where c.uid = 0");
182 while ($row = db_fetch_object($result)) {
183 $categories[$row->cid] = array(
184 $row->category,
185 $row->active,
186 $row->hex,
187 );
188 }
189
190 if (empty($categories)) {
191 $categories = array();
192 }
193
194 foreach ($categories as $cid => $c) {
195 $form['gcats']['cid_enable_'. $cid] = array(
196 '#type' => 'radios',
197 '#title' => t($c[0]),
198 '#options' => array(0 => 'disabled', 1 => 'enabled'),
199 '#default_value' => $c[1],
200 );
201 if (module_exists('colorpicker')) {
202 $form['gcats']['color_'. $cid] = array(
203 '#type' => 'colorpicker',
204 '#title' => t('Color picker'),
205 );
206 $form['gcats']['color_'. $cid .'_v'] = array(
207 '#type' => 'colorpicker_textfield',
208 '#description' => t('Choose a color to display for this category.'),
209 '#default_value' => $c[2],
210 '#colorpicker' => 'color_'. $cid,
211 );
212 }
213 else {
214 $form['gcats']['color_'. $cid .'_v'] = array(
215 '#type' => 'textfield',
216 '#size' => '7',
217 '#description' => t('Choose a color to display for this category. Enter it in 6 char hex *with* a preceding #.'),
218 '#default_value' => $c[2],
219 );
220 }
221 }
222
223 $form['gsets'] = array(
224 '#type' => 'fieldset',
225 '#access' => user_access('edit timemap settings'),
226 '#title' => t('Global Settings'),
227 '#collapsible' => true,
228 '#collapsed' => false,
229 '#weight' => -1,
230 );
231 $form['gsets']['timemap_report_default_days_to_show'] = array(
232 '#type' => 'textfield',
233 '#title' => t('Default number of days to show on reports'),
234 '#description' => t('Enter the number of days of history to show when viewing reports that utilize this feature. (NOTE: This may be N/A for some reports.)'),
235 '#default_value' => variable_get('timemap_report_default_days_to_show', 7),
236 '#size' => 3,
237 );
238 if (module_exists('civicrm')) {
239 $supervisor_role_opts = array();
240 // TODO: This is a CiviCRM 1.8 API call. Add logic to determine correct CiviCRM version used and API call!!
241 foreach(crm_get_relationship_types() as $rel) {
242 if (
243 $rel->contact_type_a == 'Individual' &&
244 $rel->contact_type_b == 'Individual' &&
245 $rel->name_a_b != $rel->name_b_a
246 ) {
247 $supervisor_role_opts[] = $rel->name_a_b;
248 $supervisor_role_opts[] = $rel->name_b_a;
249 }
250 }
251 $form['gsets']['timemap_civicrm_subord_rel'] = array(
252 '#type' => 'select',
253 '#title' => t('Supervisory Relationship'),
254 '#description' => t('Select the relationship that defines one CiviCRM user as a Supervisor over others. This relationship will be used to determain the reports seen when a user has permission to view subordinates\' reports.'),
255 '#options' => $supervisor_role_opts,
256 '#default_value' => variable_get('timemap_civicrm_subord_rel', null),
257 );
258 }
259
260 return system_settings_form($form);
261 }
262
263 function timemap_admin_settings_validate($form, &$form_state) {
264 if (user_access('edit global categories')) {
265 if ($values['color_new_v'] && (! preg_match('/^#[0-9A-F]{6}$/i', $values['color_new_v'])) ) {
266 form_set_error('color_new_v', t('Please enter a hex value with a preceding \'#\' sign'));
267 }
268 }
269
270 if (user_access('edit timemap settings')) {
271 if (! is_numeric($values['timemap_report_default_days_to_show'])) {
272 form_set_error('timemap_report_default_days_to_show', t('Please enter a number'));
273 }
274 }
275 }
276
277 function timemap_admin_settings_submit($form, &$form_state) {
278 // enter any new global categories
279 $newgcat = trim($values['newgcat']);
280 if (! empty($newgcat)) {
281 db_query("insert into {timemap_categories} (uid, category, active) values (0, '%s', 1)", $newgcat);
282 //this makes is mysql only...
283 $cid = mysql_insert_id();
284 db_query("insert into {timemap_catcolor} (cid, hex) values (%d, '%s')", $cid, $values['color_new_v']);
285 }
286
287 //update the status of any categories
288 foreach (array_keys($values) as $k) {
289 if (strstr($k, 'cid_enable_')) {
290 $cid = substr($k, 11);
291 db_query("update {timemap_categories} set active = %d where cid = %d", $values[$k], $cid);
292 if (db_result(db_query("select cid from {timemap_catcolor} where cid=%d", $cid))) {
293 db_query("update {timemap_catcolor} set hex = '%s' where cid = %d", $values['color_'. $cid .'_v'], $cid);
294 }
295 else {
296 db_query("insert into {timemap_catcolor} (cid, hex) values (%d, '%s')", $cid, $values['color_'. $cid .'_v']);
297 }
298 }
299 }
300
301 //update the variables
302 if (isset($values['timemap_report_default_days_to_show'])) {
303 variable_set('timemap_report_default_days_to_show', (int) $values['timemap_report_default_days_to_show']);
304 }
305 if (isset($values['timemap_civicrm_subord_rel'])) {
306 variable_set('timemap_civicrm_subord_rel', $values['timemap_civicrm_subord_rel']);
307 }
308 }
309
310 function theme_timemap_admin_settings($form) {
311 //$out .= drupal_render($form['gcats']);
312 $out .= '<table border="1"><tr><td>';
313 $out .= drupal_render($form['gcats']['newgcat']);
314 $out .= '</td><td>';
315 $out .= drupal_render($form['gcats']['color_new_v']);
316 $out .= '</td><td>';
317 $out .= drupal_render($form['gcats']['color_new']);
318 $out .= '</td></tr>';
319
320 foreach ($form['gcats'] as $k => $cat) {
321 if (strpos($k, 'cid_enable_') !== false) {
322 $cid = substr($k, 11);
323 $out .= '<tr><td>';
324 $out .= drupal_render($form['gcats'][$k]);
325 $out .= '</td><td>';
326 $out .= drupal_render($form['gcats']['color_'. $cid .'_v']);
327 $out .= '</td><td>';
328 $out .= drupal_render($form['gcats']['color_'. $cid]);
329 $out .= '</td></tr>';
330 }
331 }
332 $out .= '</table>';
333
334 $out .= drupal_render($form);
335 return $out;
336 }
337
338
339 /**
340 * a "dashboard" control panel for all of the timemap management facilities.
341 */
342 function timemap_dashboard() {
343 drupal_goto('timemap/doing');
344 }
345
346
347
348 /**
349 * a callback that loads the form for the task entering interface
350 */
351 function timemap_enter_task() {
352 $return = "<h3>What are you doing right now?</h3>";
353 $return .= drupal_get_form('timemap_enter_task_form');
354 return $return;
355 }
356
357
358
359 /**
360 * The core facility! this form is the twitter like interface.
361 */
362 function timemap_enter_task_form(&$form_state, $as_block = false) {
363 global $user;
364 $result = db_query("select cid, category from {timemap_categories} where uid in (0, %d) and active <> 0", $user->uid);
365 while ($row = db_fetch_object($result)) {
366 $categories[$row->cid] = $row->category;
367 }
368
369 $form['newcatfs'] = array(
370 '#type' => 'fieldset',
371 '#access' => user_access('enter tasks'),
372 '#title' => t('New Category'),
373 '#collapsible' => true,
374 '#collapsed' => true,
375 '#weight' => -5,
376 );
377 $form['newcatfs']['newcat'] = array(
378 '#type' => 'textfield',
379 '#title' => t('New Category'),
380 '#description' => t('Enter a new personal category.'),
381 '#required' => false,
382 '#size' => 15,
383 );
384 if (module_exists('colorpicker')) {
385 $form['newcatfs']['newcatcolor'] = array(
386 '#type' => 'colorpicker',
387 '#title' => t('Category Color'),
388 );
389 $form['newcatfs']['newcatcolor_v'] = array(
390 '#type' => 'colorpicker_textfield',
391 '#description' => t('Choose a color to display for this category.'),
392 '#default_value' => '#ffffff',
393 '#colorpicker' => 'newcatcolor',
394 );
395 }
396 else {
397 $form['newcatfs']['newcatcolor_v'] = array(
398 '#type' => 'textfield',
399 '#size' => '7',
400 '#description' => t('Choose a color to display for this category. Enter it in 6 char hex *with* a preceding #.'),
401 '#default_value' => '#ffffff',
402 );
403 }
404 $form['newcatfs']['newcatsubmit'] = array(
405 '#type' => 'submit',
406 '#value' => 'Create Category',
407 );
408
409 $c_disp = 'radios';
410 if ($as_block) {
411 $c_disp = 'select';
412 }
413
414 if (! empty($categories)) {
415 $form['category'] = array(
416 '#type' => $c_disp,
417 '#title' => t('Category'),
418 '#options' => $categories,
419 '#description' => 'The task or category that your current doings are a part of.',
420 );
421 }
422 $form['entry'] = array(
423 '#type' => 'textfield',
424 '#title' => t('Doing Now'),
425 '#description' => t('What you are doing right now?'),
426 '#required' => false,
427 '#size' => 25,
428 '#autocomplete_path' => 'timemap/doing/autoc',
429 );
430 $form['submit'] = array(
431 '#type' => 'submit',
432 '#value' => 'Update',
433 );
434
435 // is being "done" the last thing we did? if so, don't show the button again.
436 $lastcat = db_result(db_query_range("select cid from {timemap_doings} WHERE uid = %d order by time desc", $user->uid, 0, 1));
437 if ($lastcat >= 0) {
438 $form['done'] = array(
439 '#type' => 'submit',
440 '#value' => 'Quitin\' Time!',
441 );
442 }
443
444 return $form;
445 }
446 function timemap_enter_task_form_validate($form, &$form_state) {
447 /* TODO The 'op' element in the form values is deprecated.
448 Each button can have #validate and #submit functions associated with it.
449 Thus, there should be one button that submits the form and which invokes
450 the normal form_id_validate and form_id_submit handlers. Any additional
451 buttons which need to invoke different validate or submit functionality
452 should have button-specific functions. */
453 if ( (trim($form_state['values']['entry']) == '') && ($form_state['values']['op'] == $form_state['values']['submit']) ) {
454 form_set_error('entry');
455 }
456 /* TODO The 'op' element in the form values is deprecated.
457 Each button can have #validate and #submit functions associated with it.
458 Thus, there should be one button that submits the form and which invokes
459 the normal form_id_validate and form_id_submit handlers. Any additional
460 buttons which need to invoke different validate or submit functionality
461 should have button-specific functions. */
462 if ( (trim($form_state['values']['newcat']) == '') && ($form_state['values']['op'] == $form_state['values']['newcatsubmit']) ) {
463 form_set_error('newcat');
464 }
465 }
466 function timemap_enter_task_form_submit($form, &$form_state) {
467 global $user;
468
469 // have we entered a new category?
470 /* TODO The 'op' element in the form values is deprecated.
471 Each button can have #validate and #submit functions associated with it.
472 Thus, there should be one button that submits the form and which invokes
473 the normal form_id_validate and form_id_submit handlers. Any additional
474 buttons which need to invoke different validate or submit functionality
475 should have button-specific functions. */
476 if ($form_state['values']['op'] == $form_state['values']['newcatsubmit']) {
477 db_query("insert into {timemap_categories} (uid, category, active) values (%d, '%s', %d)",
478 $user->uid, $form_state['values']['newcat'], 1);
479 //this makes it mysql only...
480 $cid = mysql_insert_id();
481 db_query("insert into {timemap_catcolor} (cid, hex) values (%d, '%s')", $cid, $form_state['values']['newcatcolor_v']);
482 }
483
484 // have we "clocked out"?
485 // if so, enter a negative value for the category. the text is informational only.
486 /* TODO The 'op' element in the form values is deprecated.
487 Each button can have #validate and #submit functions associated with it.
488 Thus, there should be one button that submits the form and which invokes
489 the normal form_id_validate and form_id_submit handlers. Any additional
490 buttons which need to invoke different validate or submit functionality
491 should have button-specific functions. */
492 if ($form_state['values']['op'] == $form_state['values']['done']) {
493 // end the last 'task' entered
494 db_query("update {timemap_doings} set stop=%d where uid=%d order by time desc limit 1", time(), $user->uid);
495
496 // record the 'punch clock' stamp
497 db_query("insert into {timemap_doings} (uid, cid, task, time) values (%d, %d, '%s', %d)",
498 $user->uid, -1, '***PUNCH CLOCK: OUT***', time());
499 drupal_set_message('Until next time... Thanks champ, you\'re a star!');
500 }
501
502 // have we entered a task?
503 /* TODO The 'op' element in the form values is deprecated.
504 Each button can have #validate and #submit functions associated with it.
505 Thus, there should be one button that submits the form and which invokes
506 the normal form_id_validate and form_id_submit handlers. Any additional
507 buttons which need to invoke different validate or submit functionality
508 should have button-specific functions. */
509 if ($form_state['values']['op'] == $form_state['values']['submit']) {
510 // end the last 'task' entered
511 db_query("update {timemap_doings} set stop=%d where uid=%d order by time desc limit 1", time(), $user->uid);
512
513 // add the new one
514 db_query("insert into {timemap_doings} (uid, cid, task, time) values (%d, %d, '%s', %d)",
515 $user->uid, $form_state['values']['category'], $form_state['values']['entry'], time());
516 drupal_set_message("roger, Roger: " . $form_state['values']['entry']);
517 }
518 }
519
520 function timemap_doing_autoc($string) {
521 global $user;
522 $result = db_query("select distinct task
523 from {timemap_doings}
524 where uid = %d and task like '%s%%'
525 order by time desc", $user->uid, $string);
526 $return = array();
527 while ($row = db_fetch_object($result)) {
528 $return[$row->task] = $row->task;
529 }
530
531 print drupal_to_js($return);
532 exit();
533 }
534
535 function timemap_map($uid = null) {
536 global $user;
537 if (! $uid) {
538 $uid = $user->uid;
539 }
540 else {
541 $user = user_load($uid);
542 }
543 $allowed = timemap_viewable_reports_list();
544 if ( ! in_array($uid, array_keys($allowed)) ) {
545 drupal_access_denied();
546 exit();
547 }
548
549 $people_chooser = theme('timemap_viewable_reports_list_people', $allowed);
550
551 /*
552 * The Simile Timeline lib from MIT can, per MIT's request, be loaded from the Internet. If, for some
553 * reason, this is not an option, then the library code distro can be placed in the module dir in a dir
554 * called 'timeline'. In this case, it will be autodetected and loaded from the local copy.
555 *
556 * To Download: http://simile.mit.edu/wiki/Timeline/Download_The_Source
557 */
558 if (file_exists($_SERVER['DOCUMENT_ROOT'] . base_path() . drupal_get_path('module', 'timemap') ."/timeline/timeline-api.js")) {
559 drupal_add_js(drupal_get_path('module', 'timemap') ."/timeline/timeline-api.js");
560 }
561 else {
562 drupal_add_js(drupal_get_path('module', 'timemap') ."/load_timeline.js");
563 }
564
565 drupal_add_js(drupal_get_path('module', 'timemap') ."/timemap_simile-timeline.js");
566 drupal_add_css(drupal_get_path('module', 'timemap') ."/timemap.css");
567
568 return $people_chooser .'<div id="timemap" basepath="'. base_path() .'" uid="'. $uid .'" offset="'. $user->timezone .'"></div><div class="timemap_controls" id="timemap_controls"></div>';
569
570 }
571
572 function theme_timemap_viewable_reports_list_people($list = array()) {
573 return '';
574 $ret = '<div id="timemap_report_people">View Reports for: ';
575 foreach ($list as $uid => $name) {
576 $ret .= '<input type="checkbox" id="timemap_person_'. $uid .'" class="timemap_report_person_selector" />';
577 $ret .= '<label for="timemap_person_'. $uid .'">'. $name .'</label>';
578 }
579 return $ret .'</div>';
580 }
581
582 function timemap_map_serv($uid = null) {
583 global $user;
584 if (! $uid) {
585 $uid = $user->uid;
586 }
587 $allowed = timemap_viewable_reports_list();
588 if ( ! in_array($uid, array_keys($allowed)) ) {
589 drupal_access_denied();
590 exit();
591 }
592
593 $result = db_query("select d.cid as cid, d.task as task, d.time as time, d.stop as stop, c.category as category, cc.hex as color
594 from {timemap_doings} d
595 left join {timemap_categories} c on c.cid=d.cid
596 left join {timemap_catcolor} cc on c.cid=cc.cid
597 where d.uid = %d and d.cid >= 0
598 order by d.time", $uid);
599
600 $return = array(
601 'dateTimeFormat' => 'iso8601',
602 'events' => array(),
603 );
604 while ($row = db_fetch_object($result)) {
605 $end_k = $row->stop != '0' ? 'end' : 'earliestEnd';
606 $end_v = $row->stop != '0' ? timemap_datify($row->stop) : timemap_datify(time());
607 $return['events'][] = array(
608 'start' => timemap_datify($row->time),
609 $end_k => $end_v,
610 'title' => $row->task,
611 'color' => $row->color,
612 'description' => 'Category: <i>'. $row->category .'</i>',
613 );
614 }
615
616 print drupal_to_js($return);
617 exit();
618 }
619
620 function timemap_datify($secs) {
621 global $user;
622 //$secs += $user->timezone;
623 //return date(DATE_RFC3339, $secs);
624 return gmdate('c', $secs);
625 }
626
627 function timemap_report($uid = null, $report = 'default', $from = null, $numDays = null) {
628 global $user;
629 if(! $uid) {
630 $uid = $user->uid;
631 }
632
633 $allowed = timemap_viewable_reports_list();
634
635 if ( ! in_array($uid, array_keys($allowed)) ) {
636 drupal_access_denied();
637 exit();
638 }
639
640 $return = '';
641
642 //are we the only only person who has reports we can view, or are there more to choose from?
643 if ( ! ((count($allowed) == 1) && isset($allowed[$user->uid])) ) {
644 $return .= drupal_get_form('timemap_report_choose_person');
645 }
646
647 $return .= timemap_draw_report(timemap_get_report_stats($uid, $from, $numDays), $report);
648 return $return;
649 }
650
651 function timemap_report_choose_person(&$form_state) {
652 global $user;
653
654 $form['uid'] = array(
655 '#type' => 'select',
656 '#options' => timemap_viewable_reports_list(),
657 '#required' => true,
658 '#title' => t('Person to view'),
659 );
660 $form['submit'] = array(
661 '#type' => 'submit',
662 '#value' => t('Go'),
663 );
664
665 return $form;
666 }
667 function timemap_report_choose_person_validate($form, &$form_state) {
668 return true;
669 }
670 function timemap_report_choose_person_submit($form, &$form_state) {
671 return 'timemap/report/'. $values['uid'];
672 }
673
674 function timemap_viewable_reports_list() {
675 global $user;
676
677 if ($user->uid == 1) {
678 $names = array(1, $user->name);
679 }
680 // view all?
681 if ( user_access('view all reports') || ($user->uid == 1) ) {
682 $result = db_query("select distinct uid from {timemap_doings}");
683 while ($row = db_fetch_object($result)) {
684 $userrec = user_load(array('uid' => $row->uid));
685 $names[$userrec->uid] = $userrec->name;
686 }
687 // just return everyone. there's no need to do any further sorting at this point.
688 return $names;
689 }
690
691 $return = array();
692
693 // view reports defined by CiviCRM groups?
694 if (user_access('view subordinate reports')) {
695 $rel = variable_get('timemap_civicrm_subord_rel');
696 $names = crm_get_relationships($user, null, $rel, null, null, 0, 1000);
697
698 $return = array_merge($return, $names);
699 }
700
701 // view your own?
702 if (user_access('view own report')) {
703 $names = array($user->uid => $user->name);
704 $return = array_merge($return, $names);
705 }
706
707 return $return;
708 }
709 /////////////////////////////////////////
710 /**
711 * Implementation of hook_timemap_report
712 */
713 function timemap_timemap_report($op = 'list', $delta = 0, $stats = null) {
714 switch ($op) {
715 case 'list':
716 $return[] = array(
717 'module' => 'timemap', // The module's name that is providing this report!!!
718 'title' => 'default',
719 'delta' => 0,
720 );
721 return $return;
722
723 case 'view':
724 switch($delta) {
725 case 0:
726 return timemap_get_report_0($stats);
727 }
728 break;
729 }
730
731 return array();
732 }
733
734 function timemap_get_report_0($stats = null) {
735 return '<pre><code>' . print_r($stats,1) . '</code></pre>';
736 }
737
738 function timemap_draw_report($stats, $report = 'default') {
739 $avail_reports = module_invoke_all('timemap_report', 'list');
740 foreach($avail_reports as $rpt) {
741 if ($rpt['title'] == $report) {
742 $report_detail = module_invoke($rpt['module'], 'timemap_report', 'view', $rpt['delta'], $stats);
743 }
744 }
745
746 // if for some reason we've requested a report that isn't available, kick in our 'default' and notify
747 if (! isset($report_detail)) {
748 drupal_set_message("We cannot find a report called <i>$report</i>. Hopefully the following information will be helpful.", 'error');
749 $report_detail = module_invoke('timemap', 'timemap_report', 'view', 0, $stats);
750 }
751
752 return $report_detail;
753 }
754
755 /**
756 * Called from timemap_report(). Collect the stats for a given uid and date and return them.
757 * These stats are then passed to whatever report is being used to draw some pretty pictures.
758 */
759 function timemap_get_report_stats($uid = null, $from = null, $days_to_show = null) {
760 global $user;
761 if (! $uid) {
762 $uid = $user->uid;
763 }
764
765 // expect and set variables as days
766 // we'll default to showing the "default" num of days starting from that many days ago... ie, up to today.
767 if (! isset($from)) {
768 $from = variable_get('timemap_report_default_days_to_show', 7);
769 }
770 if (! isset($days_to_show)) {
771 $days_to_show = variable_get('timemap_report_default_days_to_show', 7);
772 }
773
774 // turn days into unix times relative to now.
775 // 86400 = 24 * 60 * 60 --> no. secs to "see"
776 // days-1 because partial today will count as a whole 1 for our purposes
777 $secs = ($from - 1) * 86400;
778
779 $lastmidnight = strtotime("12 am UTC");
780 $from = $lastmidnight - $secs;
781 $secs_to_show = $from + ($days_to_show * 86400);
782
783 $result = db_query("select d.cid as cid, d.task as task, d.time as time, d.stop as stop, c.category as category
784 from {timemap_doings} d left join {timemap_categories} c on c.cid=d.cid
785 where d.uid = %d and d.time between %d and %d
786 order by d.time",
787 $uid, $from, $secs_to_show);
788 $stats_obj['info'] = array(
789 'days' => $days_to_show,
790 );
791 while ($row = db_fetch_object($result)) {
792 $stats_obj['items'][] = array(
793 'cid' => $row->cid,
794 'category' => $row->category,
795 'task' => $row->task,
796 'time' => $row->time,
797 'stop' => $row->stop,
798 );
799 }
800
801 return $stats_obj;
802 }

  ViewVC Help
Powered by ViewVC 1.1.2