2 // $Id: casetracker.module,v 1.123.2.6 2009/03/15 23:27:39 jmiccolis Exp $
6 * Enables the handling of projects and their cases.
10 * Implementation of hook_views_api().
12 function casetracker_views_api() {
13 return array('api' => 2);
17 * Implementation of hook_help().
19 function casetracker_help($path, $arg) {
21 case 'admin/settings/casetracker/states':
22 return '<p>'. t('Current Case Tracker case states are listed below.') .'</p>';
23 case 'admin/settings/casetracker/states/add':
24 return '<p>'. t('You may add a new case state below.') .'</p>';
25 case 'admin/settings/casetracker/states/edit/'. arg(4):
26 return '<p>'. t('You may edit an existing case state below.') .'</p>';
27 case 'admin/settings/casetracker':
28 return '<p>'. t('Configure the various Case Tracker options with these settings.') .'</p>';
33 * Implementation of hook_perm().
35 function casetracker_perm() {
37 'access case tracker',
38 'administer case tracker',
43 * Implementation of hook_menu().
45 function casetracker_menu() {
46 /* casetracker main settings */
47 $items['admin/settings/casetracker'] = array(
48 'file' => 'casetracker_admin.inc',
49 'access arguments' => array('administer case tracker'),
50 'page callback' => 'drupal_get_form',
51 'page arguments' => array('casetracker_settings'),
52 'description' => 'Configure the various Case Tracker options with these settings.',
53 'title' => 'Case Tracker',
54 'type' => MENU_NORMAL_ITEM,
56 $items['admin/settings/casetracker/settings'] = array(
57 'file' => 'casetracker_admin.inc',
58 'access arguments' => array('administer case tracker'),
59 'page callback' => 'drupal_get_form',
60 'page arguments' => array('casetracker_settings'),
61 'title' => 'Settings',
63 'type' => MENU_DEFAULT_LOCAL_TASK,
65 /* casetracker state handling */
66 $items['admin/settings/casetracker/states'] = array(
67 'file' => 'casetracker_admin.inc',
68 'access arguments' => array('administer case tracker'),
69 'page callback' => 'casetracker_case_state_overview',
70 'type' => MENU_LOCAL_TASK,
71 'title' => 'Case states',
72 'description' => 'Add, edit and delete Case States, Types and Priorities',
74 $items['admin/settings/casetracker/states/list'] = array(
75 'file' => 'casetracker_admin.inc',
76 'access arguments' => array('administer case tracker'),
77 'page callback' => 'casetracker_case_state_overview',
78 'type' => MENU_DEFAULT_LOCAL_TASK,
79 'title' => 'Overview',
81 'description' => 'Add, edit and delete Case States, Types and Priorities',
83 $items['admin/settings/casetracker/states/add'] = array(
84 'file' => 'casetracker_admin.inc',
85 'access arguments' => array('administer case tracker'),
86 'page callback' => 'drupal_get_form',
87 'page arguments' => array('casetracker_case_state_edit'),
88 'title' => 'Add case state',
89 'type' => MENU_LOCAL_TASK,
91 $items['admin/settings/casetracker/states/edit/%casetracker_case_state'] = array(
92 'file' => 'casetracker_admin.inc',
93 'access arguments' => array('administer case tracker'),
94 'page callback' => 'drupal_get_form',
95 'page arguments' => array('casetracker_case_state_edit', 5),
96 'title' => 'Edit case state',
97 'type' => MENU_CALLBACK,
99 $items['admin/settings/casetracker/states/delete/%casetracker_case_state'] = array(
100 'file' => 'casetracker_admin.inc',
101 'access arguments' => array('administer case tracker'),
102 'page callback' => 'drupal_get_form',
103 'page arguments' => array('casetracker_case_state_confirm_delete', 5),
104 'title' => 'Delete case state',
105 'type' => MENU_CALLBACK,
107 /* casetracker autocomplete */
108 $items['casetracker_autocomplete'] = array(
109 'title' => 'Case Tracker autocomplete',
110 'page callback' => 'casetracker_autocomplete',
111 'access callback' => 'user_access',
112 'access arguments' => array('access case tracker'),
113 'type' => MENU_CALLBACK,
119 * Implementation of hook_nodeapi().
121 function casetracker_nodeapi(&$node, $op, $teaser = NULL, $page = NULL) {
123 if (casetracker_is_case($node->type)) {
127 // delete case and its comments.
128 $comment_results = db_query("SELECT cid FROM {comments} WHERE nid = %d", $node->nid);
129 while ($comment_result = db_fetch_object($comment_results)) {
130 db_query("DELETE FROM {casetracker_comment_status} WHERE cid = %d", $comment_result->cid);
132 db_query('DELETE FROM {casetracker_case} WHERE nid = %d', $node->nid);
136 // $node->casetracker is an Array and we wanna it to be an object. I
137 // guess it's a nasty workaround.
138 $node->casetracker = (object) $node->casetracker;
140 // cases: generate a case ID and send it along.
141 $record = $node->casetracker;
142 $record->assign_to = casetracker_get_uid($record->assign_to);
143 $record->nid = $node->nid;
144 $record->vid = $node->vid;
146 drupal_write_record('casetracker_case', $record);
150 $casetracker = db_fetch_object(db_query('SELECT pid, case_priority_id, case_type_id, assign_to, case_status_id FROM {casetracker_case} WHERE nid = %d AND vid = %d', $node->nid, $node->vid));
152 return array('casetracker' => $casetracker);
157 $record = (object) $node->casetracker;
158 $record->assign_to = casetracker_get_uid($record->assign_to);
159 $record->nid = $node->nid;
160 $record->vid = $node->vid;
162 $primary = $node->revision ? array('nid') : array('nid', 'vid');
163 drupal_write_record('casetracker_case', $record, $primary);
167 // used in the breadcrumb and our theme function, mostly for nid and project number display.
168 $project = node_load($node->casetracker->pid);
173 l(t('Case Tracker'), 'casetracker/projects'),
174 l($project->title, "node/{$node->casetracker->pid}"),
175 l(t('All cases'), "casetracker/cases/{$node->casetracker->pid}/all"),
177 drupal_set_breadcrumb($trail);
180 $node->content['casetracker_case_summary'] = array(
181 '#value' => theme('casetracker_case_summary', $node, $project),
189 else if (casetracker_is_project($node->type)) {
193 // projects: delete all the cases under the project and all the comments under each case.
194 $case_results = db_query("SELECT nid from {casetracker_case} WHERE pid = %d", $node->nid);
195 while ($case_result = db_fetch_object($case_results)) {
196 db_query("DELETE FROM {casetracker_case} WHERE nid = %d", $case_result->nid);
197 $comment_results = db_query("SELECT cid FROM {comments} WHERE nid = %d", $case_result->nid);
198 while ($comment_result = db_fetch_object($comment_results)) {
199 db_query("DELETE FROM {casetracker_comment_status} WHERE cid = %d", $comment_result->cid);
201 node_delete($case_result->nid); // this'll handle comment deletion too.
209 l(t('Case Tracker'), 'casetracker/projects'),
211 drupal_set_breadcrumb($trail);
214 $node->content['casetracker_project_summary'] = array('#value' => theme('casetracker_project_summary', $node), '#weight' => -10);
221 * Implementation of hook_comment().
223 function casetracker_comment(&$comment, $op) {
224 // Load the node here anyway -- it is almost certainly static cached already.
225 $node = is_array($comment) ? node_load($comment['nid']) : node_load($comment->nid);
227 // Bail if this is not a casetracker node.
228 if (!casetracker_is_case($node->type)) {
232 if ($op == 'insert' || $op == 'update') {
233 $new = (object) $comment['casetracker'];
234 $new->cid = $comment['cid'];
235 $new->nid = $comment['nid'];
236 $new->vid = $comment['revision_id'];
238 $new->assign_to = casetracker_get_uid($new->assign_to);
240 // Populate old state values from node
241 $old = $node->casetracker;
242 $old->cid = $comment['cid'];
245 drupal_write_record('casetracker_case', $new, array('nid', 'vid'));
250 drupal_write_record('casetracker_comment_status', $old);
251 drupal_write_record('casetracker_comment_status', $new);
254 drupal_write_record('casetracker_comment_status', $old, array('cid', 'state'));
255 drupal_write_record('casetracker_comment_status', $new, array('cid', 'state'));
258 // @todo theoretically, if you delete a comment, we should reset all the values
259 // to what they were before the comment was submitted. this doesn't happen yet.
260 db_query("DELETE FROM {casetracker_comment_status} WHERE cid = %d", $comment->cid);
263 $results = db_query("SELECT * FROM {casetracker_comment_status} WHERE cid = %d", $comment->cid);
264 while ($result = db_fetch_object($results)) {
265 $state = $result->state ? 'new' : 'old';
266 $case_data[$state] = $result;
268 $comment->comment = theme('casetracker_comment_changes', $case_data['old'], $case_data['new']) . $comment->comment;
274 * Implementation of hook_form_alter().
276 function casetracker_form_alter(&$form, &$form_state, $form_id) {
277 if (!empty($form['#node'])) {
278 $node = $form['#node'];
280 // Add case options to our basic case type.
281 if (casetracker_is_case($node->type)) {
282 $count = count(casetracker_project_options());
284 drupal_set_message(t('You must create a project before adding cases.'), 'error');
288 $default_project = null;
289 if (!isset($form['#node']->nid) && is_numeric(arg(3))) {
290 $default_project = arg(3);
292 casetracker_case_form_common($form, $default_project);
299 * Implementation of hook_form_comment_form_alter().
301 function casetracker_form_comment_form_alter(&$form, &$form_state) {
302 $node = isset($form['nid']['#value']) ? node_load($form['nid']['#value']) : NULL;
303 if (casetracker_is_case($node->type)) {
304 $form['#node'] = $node;
306 // add case options to the comment form.
307 casetracker_case_form_common($form);
309 // necessary for our casetracker_comment() callback.
310 $form['revision_id'] = array('#type' => 'hidden', '#value' => $node->vid);
315 * Common form elements for cases, generic enough for use either in
316 * a full node display, or in comment displays and updating. Default
317 * values are calculated based on an existing $form['nid']['#value'].
320 * A Forms API $form, as received from a hook_form_alter().
321 * @param $default_project
322 * The project ID that should be pre-selected.
324 * A modified Forms API $form.
326 function casetracker_case_form_common(&$form, $default_project = NULL) {
329 $node = $form['#node'];
331 // project to set as the default is based on how the user got here.
332 if (empty($default_project) && !empty($node->casetracker->pid)) {
333 $default_project = $node->casetracker->pid;
336 $project_options = casetracker_project_options();
338 $form['casetracker'] = array(
339 '#type' => 'fieldset',
340 '#title' => t('Case information'),
342 '#collapsible' => TRUE,
343 '#collapsed' => FALSE,
345 '#theme' => 'casetracker_case_form_common',
348 // if there's no project ID from the URL, or more than one project,
349 // we'll create a select menu for the user; otherwise, we'll save
350 // the passed (or only) project ID into a hidden field.
351 if (count($project_options) > 1) {
352 $form['casetracker']['pid'] = array(
353 '#title' => t('Project'),
355 '#default_value' => $default_project,
356 '#options' => $project_options,
360 $form['casetracker']['pid'] = array(
361 '#type' => 'value', // default value, or the only the project ID in the project_options array.
362 '#value' => !empty($default_project) ? $default_project : key($project_options),
366 $options = casetracker_user_options();
368 $form['casetracker']['assign_to'] = array(
369 '#type' => 'textfield',
370 '#title' => t('Assign to'),
371 '#autocomplete_path' => 'casetracker_autocomplete',
375 if (count($options) < 20) {
376 $normalized = array();
377 foreach ($options as $name) {
378 $normalized[$name] = $name;
380 $form['casetracker']['assign_to'] = array(
382 '#title' => t('Assign to'),
384 '#options' => $normalized,
388 if (isset($node->casetracker->assign_to)) {
389 $form['casetracker']['assign_to']['#default_value'] = is_numeric($node->casetracker->assign_to) ? casetracker_get_name($node->casetracker->assign_to) : $node->casetracker->assign_to;
392 $form['casetracker']['assign_to']['#default_value'] = variable_get('casetracker_default_assign_to', variable_get('anonymous', t('Anonymous')));
395 $case_status_options = casetracker_realm_load('status');
396 $default_status = !empty($node->casetracker->case_status_id) ? $node->casetracker->case_status_id : variable_get('casetracker_default_case_status', key($case_status_options));
397 $form['casetracker']['case_status_id'] = array(
399 '#title' => t('Status'),
400 '#options' => $case_status_options,
401 '#default_value' => $default_status,
404 $case_priority_options = casetracker_realm_load('priority');
405 $default_priority = !empty($node->casetracker->case_priority_id) ? $node->casetracker->case_priority_id : variable_get('casetracker_default_case_priority', key($case_priority_options));
406 $form['casetracker']['case_priority_id'] = array(
408 '#title' => t('Priority'),
409 '#options' => $case_priority_options,
410 '#default_value' => $default_priority,
413 $case_type_options = casetracker_realm_load('type');
414 $default_type = !empty($node->casetracker->case_type_id) ? $node->casetracker->case_type_id : variable_get('casetracker_default_case_type', key($case_type_options));
415 $form['casetracker']['case_type_id'] = array(
417 '#title' => t('Type'),
418 '#options' => $case_type_options,
419 '#default_value' => $default_type,
426 * CASE STATE CRUD ====================================================
430 * Returns information about the various case states and their options.
431 * The number of parameters passed will determine the return value.
434 * Optional; the state ID to return from the passed $realm.
436 * Optional; the name of the realm ('status', 'priority', or 'type').
438 * Optional; set to TRUE to reset the static cache.
441 * If only $realm is passed, you'll receive an array with the keys
442 * being the state ID and the values being their names. If a $csid
443 * is also passed, you'll receive just a string of the state name.
444 * If ONLY a $csid is passed, we'll return a list of 'name', 'realm'.
446 function casetracker_case_state_load($csid = NULL, $realm = NULL, $reset = FALSE) {
447 static $states_lookup;
449 if (!$states_lookup || $reset) {
450 $results = db_query("SELECT csid, case_state_name AS name, case_state_realm AS realm, weight
451 FROM {casetracker_case_states} ORDER BY weight");
452 $states_lookup = array();
453 while ($row = db_fetch_object($results)) {
454 $states_lookup[$row->realm][$row->csid] = $states_lookup['all'][$row->csid] = $row;
458 if ($csid && $realm) {
459 return $states_lookup['all'][$csid]->name;
461 elseif ($csid && !$realm) {
462 return $states_lookup['all'][$csid];
464 elseif (!$csid && $realm) {
465 $options = array(); // suitable for form api.
466 if (!empty($states_lookup[$realm])) {
467 foreach ($states_lookup[$realm] as $state) {
468 $options[$state->csid] = $state->name;
476 * Load states for a particular realm. Wrapper around casetracker_case_state_load()
479 * Name of the realm ('status', 'priority', or 'type').
481 * array with the keys being the state ID and the values being their names.
483 function casetracker_realm_load($realm) {
484 return casetracker_case_state_load(null, $realm);
488 * Saves a case state.
491 * An array containing 'name' and 'realm' keys. If no 'csid'
492 * is passed, a new state is created, otherwise, we'll update
493 * the record that corresponds to that ID.
495 function casetracker_case_state_save($case_state = NULL) {
496 if (!$case_state['name'] || !$case_state['realm']) {
499 // Need to collect information into another array since the db columns have different names : (
501 'case_state_name' => $case_state['name'],
502 'case_state_realm' => $case_state['realm'],
503 'weight' => $case_state['weight'],
505 if (isset($case_state['csid'])) {
506 $record['csid'] = $case_state['csid'];
507 drupal_write_record('casetracker_case_states', $record, array('csid'));
510 drupal_write_record('casetracker_case_states', $record);
516 * Deletes a case state.
518 * @todo There is currently no attempt to do anything with cases which
519 * have been assigned the $csid that is about to be deleted. We should
520 * reset them to the default per our settings (and warn the user on our
521 * confirmation page), or something else entirely.
524 * The case state ID to delete.
526 function casetracker_case_state_delete($csid = NULL) {
528 db_query('DELETE FROM {casetracker_case_states} WHERE csid = %d', $csid);
533 * COMMENT DISPLAY ====================================================
537 * Retrieve a pipe delimited string of autocomplete suggestions for existing
538 * users. Stolen from user_autocomplete. Eventually this will be expanded to
539 * include OG specific users subscribed to a project.
541 function casetracker_autocomplete($string) {
543 $group = module_exists('og') ? og_get_group_context() : NULL;
546 $result = db_query_range("SELECT u.name FROM {users} u LEFT JOIN {og_uid} ou ON u.uid = ou.uid WHERE LOWER(name) LIKE LOWER('%s%%') AND u.status > 0 AND ou.nid = %d", $string, $gid, 0, 10);
549 $result = db_query_range("SELECT name FROM {users} WHERE LOWER(name) LIKE LOWER('%s%%')", $string, 0, 10);
551 while ($user = db_fetch_object($result)) {
552 $matches[$user->name] = check_plain($user->name);
554 drupal_json($matches);
558 * Returns an query string needed in case of Organic Groups
559 * providing preselected audience checkboxes for projects as groups (og)
561 * @param object CT project
564 function _casetracker_get_og_query_string(&$project) {
565 $querystring = array();
566 // checking if project is group
567 if ($project->type == 'group') {
568 $querystring[] = 'gids[]='. $project->nid;
569 //checking if group-project is part of another group
570 if (isset($project->og_groups)
571 && is_array($project->og_groups)
573 foreach ($project->og_groups as $group) {
574 $querystring[] = 'gids[]='. $group;
578 //checking if project is part of a group
579 elseif (isset($project->og_groups)
580 && is_array($project->og_groups)
581 && $project->type !== 'group'
583 foreach ($project->og_groups as $group) {
584 $querystring[] = 'gids[]='. $group;
588 return (0 < count($querystring))
589 ? implode('&', $querystring)
594 * THEME ==============================================================
598 * Implementation of hook_theme
600 function casetracker_theme() {
602 'casetracker_comment_changes' => array(),
603 'casetracker_case_form_common' => array(),
604 'casetracker_case_summary' => array(),
605 'casetracker_project_summary' => array(),
610 * Displays the changes a comment has made to the case fields.
613 * An array of both 'old' and 'new' objects that contains
614 * the before and after values this comment has changed.
616 function theme_casetracker_comment_changes($old, $new) {
620 'pid' => t('Project'),
621 'title' => t('Title'),
622 'case_status_id' => t('Status'),
623 'assign_to' => t('Assigned'),
624 'case_priority_id' => t('Priority'),
625 'case_type_id' => t('Type'),
627 foreach ($fields as $field => $label) {
628 if ($new->{$field} != $old->{$field}) {
631 $old_title = db_result(db_query("SELECT title FROM {node} WHERE nid = %d", $old->pid));
632 $new_title = db_result(db_query("SELECT title FROM {node} WHERE nid = %d", $new->pid));
633 $old->{$field} = l($old_title, "node/{$old->pid}");
634 $new->{$field} = l($new_title, "node/{$new->pid}");
636 case 'case_status_id':
637 $old->{$field} = casetracker_case_state_load($old->{$field}, 'status');
638 $new->{$field} = casetracker_case_state_load($new->{$field}, 'status');
641 $old->{$field} = casetracker_get_name($old->{$field});
642 $new->{$field} = casetracker_get_name($new->{$field});
644 case 'case_priority_id':
645 $old->{$field} = casetracker_case_state_load($old->{$field}, 'priority');
646 $new->{$field} = casetracker_case_state_load($new->{$field}, 'priority');
649 $old->{$field} = casetracker_case_state_load($old->{$field}, 'type');
650 $new->{$field} = casetracker_case_state_load($new->{$field}, 'type');
653 $rows[] = array(t('!label: !old » !new', array('!label' => $label, '!old' => $old->{$field}, '!new' => $new->{$field})));
657 return theme('table', NULL, $rows, array('class' => 'case_changes'));
661 * Theme function for cleaning up the casetracker common form.
663 function theme_casetracker_case_form_common($form) {
664 drupal_add_css(drupal_get_path('module', 'casetracker') .'/casetracker.css');
666 $output .= drupal_render($form['pid']);
667 $output .= drupal_render($form['case_title']);
669 if ($form['assign_to']['#type'] == 'radios') {
670 $header = array_fill(0, 5, array());
671 $header[0] = $form['assign_to']['#title'];
673 foreach (element_children($form['assign_to']) as $id) {
674 $radios[] = drupal_render($form['assign_to'][$id]);
676 $radios = array_chunk($radios, 5);
677 $output .= theme('table', $header, $radios, array('class' => 'casetracker-assign-to'));
678 drupal_render($form['assign_to']);
681 $output .= drupal_render($form['assign_to']);
685 foreach (element_children($form) as $id) {
686 if (!in_array($id, array('pid', 'case_title', 'assign_to'))) {
687 $row[] = drupal_render($form[$id]);
691 $output .= theme('table', array(), $rows);
692 $output .= drupal_render($form);
697 * Theme the case summary shown at the beginning of a case's node.
700 * The node object of the case being viewed.
702 * The node object of the project this case belongs to.
704 function theme_casetracker_case_summary($case, $project) {
705 $last_comment = db_result(db_query('SELECT last_comment_timestamp FROM {node_comment_statistics} WHERE nid = %d', $case->nid));
710 theme('username', user_load(array('uid' => $case->casetracker->assign_to))),
714 theme_username($case) ." ". t('at') ." ". format_date($case->created, 'medium'),
718 "<strong>". casetracker_case_state_load($case->casetracker->case_status_id, 'status') ."</strong> (" .
719 casetracker_case_state_load($case->casetracker->case_type_id, 'type') .' / '.
721 casetracker_case_state_load($case->casetracker->case_priority_id, 'priority') .
726 l($project->title, 'node/'. $case->casetracker->pid) .': '. $project->nid .'-'. $case->nid,
728 if ($last_comment != $case->created) {
731 format_date($last_comment, 'medium')
735 $output = '<div class="case">';
736 $output .= theme('table', NULL, $rows, array('class' => 'summary'));
742 * Theme the project summary shown at the beginning of a project's node.
745 * The node object of the project being viewed.
747 function theme_casetracker_project_summary($project) {
749 $rows[] = array(t('Project number:'), $project->nid);
750 $rows[] = array(t('Opened by:'), theme_username($project));
751 $rows[] = array(t('Opened on:'), format_date($project->created, 'large'));
752 $rows[] = array(t('Last modified:'), format_date($project->changed, 'large'));
754 $querystring = _casetracker_get_og_query_string($project);
755 $operations = array(); $node_types = node_get_types('names');
756 foreach (array_filter(variable_get('casetracker_case_node_types', array('casetracker_basic_case'))) as $type) {
758 t('add !name', array('!name' => $node_types[$type])),
759 'node/add/'. str_replace('_', '-', $type) .'/'. $project->nid,
760 array('query' => $querystring)
763 $operations = implode(' | ', $operations); // ready for printing in our Operations table cell - delimited by a pipe. nonstandard.
764 $rows[] = array(t('Operations:'), $operations .' | '. l(t('view all project cases'), 'casetracker', array('query' => 'keys=&pid='. $project->nid)));
766 $output = '<div class="project">';
767 $output .= theme('table', NULL, $rows, array('class' => 'summary'));
773 * API FUNCTIONS ======================================================
777 * API function that returns valid project options.
779 function casetracker_project_options() {
781 // Fetch the views list of projects, which is space-aware.
782 if ($view = views_get_view('casetracker_project_options')) {
783 $view->set_display();
784 $view->set_items_per_page(0);
786 foreach ($view->result as $row) {
787 $projects[$row->nid] = $row->node_title;
794 * API function that returns valid user options.
796 function casetracker_user_options() {
797 $group = module_exists('og') ? og_get_group_context() : NULL;
798 $options = array(0 => variable_get('casetracker_default_assign_to', variable_get('anonymous', t('Anonymous'))));
801 $results = db_query('SELECT u.uid, u.name FROM {users} u INNER JOIN {og_uid} ou ON u.uid = ou.uid WHERE u.status > 0 AND u.uid > 0 AND ou.nid = %d ORDER BY u.name ASC', $gid);
804 $results = db_query('SELECT u.uid, u.name FROM {users} u WHERE u.status > 0 AND u.uid > 0 ORDER BY u.name ASC');
806 while ($result = db_fetch_object($results)) {
807 $options[$result->uid] = check_plain($result->name);
813 * API function for checking whether a node type is a casetracker case.
815 function casetracker_is_case($node) {
816 if (is_object($node) && !empty($node->type)) {
819 else if (is_string($node)) {
823 return in_array($type, variable_get('casetracker_case_node_types', array('casetracker_basic_case')), TRUE);
829 * API function for checking whether a node type is a casetracker project.
831 function casetracker_is_project($node) {
832 if (is_object($node) && !empty($node->type)) {
835 else if (is_string($node)) {
839 return in_array($type, variable_get('casetracker_project_node_types', array('casetracker_basic_project')), TRUE);
845 * Given a user name, returns the uid of that account.
846 * If the passed name is not found, returns 0.
847 * See also casetracker_get_name().
849 function casetracker_get_uid($name = NULL, $reset = FALSE) {
850 static $users = array();
851 if (!isset($users[$name]) || $reset) {
852 $result = db_result(db_query("SELECT uid FROM {users} WHERE name = '%s'", $name));
853 $users[$name] = $result ? $result : 0;
855 return $users[$name];
859 * Given a uid, returns the name of that account. If the passed uid is
860 * not found, returns the default "assign to" name as specified in the
861 * settings. @todo This may not always be desired, but is how we use it.
862 * See also casetracker_get_uid().
864 function casetracker_get_name($uid = NULL, $reset = FALSE) {
865 static $users = array();
866 if (!isset($users[$uid]) || $reset) {
867 $result = db_result(db_query("SELECT name FROM {users} WHERE uid = %d", $uid));
868 $users[$uid] = $result ? $result : '';
870 return !empty($users[$uid]) ? $users[$uid] : variable_get('casetracker_default_assign_to', variable_get('anonymous', t('Anonymous')));