| 1 |
<?php |
<?php |
| 2 |
// $Id: casetracker_services.module,v 1.2.2.1 2008/03/29 08:40:03 sime Exp $ |
// $Id: casetracker_services.module,v 1.2.2.5 2008/03/29 19:51:54 sime Exp $ |
| 3 |
|
|
| 4 |
/** |
/** |
| 5 |
* Implementation of hook_menu(). |
* Implementation of hook_menu(). |
| 6 |
*/ |
*/ |
| 7 |
function casetracker_services_menu($may_cache) { |
function casetracker_services_menu($may_cache) { |
|
|
|
| 8 |
if ($may_cache) { |
if ($may_cache) { |
| 9 |
$items[] = array( |
$items[] = array( |
| 10 |
'path' => 'admin/settings/casetracker_services', |
'path' => 'admin/settings/casetracker_services', |
| 31 |
function casetracker_services_settings() { |
function casetracker_services_settings() { |
| 32 |
$form = array(); |
$form = array(); |
| 33 |
|
|
| 34 |
$form['casetracker_services']['overview'] = array( |
$form['casetracker_services']['general'] = array( |
| 35 |
'#value' => '', |
'#type' => 'fieldset', |
| 36 |
|
'#title' => t('General settings'), |
| 37 |
|
'#collapsible' => true, |
| 38 |
|
'#collapsed' => true, |
| 39 |
|
); |
| 40 |
|
$form['casetracker_services']['config_summary'] = array( |
| 41 |
|
'#type' => 'fieldset', |
| 42 |
|
'#title' => t('Project access summary'), |
| 43 |
|
'#collapsible' => true, |
| 44 |
|
'#collapsed' => true, |
| 45 |
); |
); |
| 46 |
$form['casetracker_services']['config'] = array( |
$form['casetracker_services']['config'] = array( |
| 47 |
'#type' => 'fieldset', |
'#type' => 'fieldset', |
| 48 |
'#title' => t('Project access'), |
'#title' => t('Project access settings'), |
| 49 |
'#collapsible' => true, |
'#collapsible' => true, |
| 50 |
'#collapsed' => false, |
'#collapsed' => false, |
| 51 |
); |
); |
| 75 |
|
|
| 76 |
$project_choices = array(0 => 'BLOCKED') + $project_choices; |
$project_choices = array(0 => 'BLOCKED') + $project_choices; |
| 77 |
|
|
| 78 |
$overview = '<p>For each remote client configured in the '. l('Services admin', 'admin/build/services/keys') .', assign valid projects that these sites may accesd.</p>'; |
$form['casetracker_services']['general']['client_css'] = array( |
| 79 |
|
'#type' => 'textarea', |
| 80 |
|
'#rows' => 15, |
| 81 |
|
'#default_value' => variable_get('casetracker_services_client_css', '/* This style is set from the main support site. */'), |
| 82 |
|
'#title' => t('Client CSS'), |
| 83 |
|
'#description' => t('This style will be used on the client support site, eg. you may specify specific colors for case status and type.'), |
| 84 |
|
); |
| 85 |
|
$form['casetracker_services']['general']['only_authored'] = array( |
| 86 |
|
'#type' => 'checkbox', |
| 87 |
|
'#default_value' => variable_get('casetracker_services_only_authored', false), |
| 88 |
|
'#title' => t('Client sees \'authored\' cases only.'), |
| 89 |
|
'#description' => t('Case Tracker Services only returns cases belonging to the assigned projects. If you check this box, you can further restrict the client: they will see only those cases opened by same user who owns the project. This allows administrators/support staff to create issues against a project that the client/customer does not see. If you\'ve checked this box, to toggle visibility of a case, change the \'Authored by\' field of the case.'), |
| 90 |
|
); |
| 91 |
|
|
| 92 |
|
$overview = '<p>For each remote client configured in the '. l('Services admin', 'admin/build/services/keys') .', assign valid projects that these sites may accessed.</p>'; |
| 93 |
foreach ($mappings as $key => $data) { |
foreach ($mappings as $key => $data) { |
| 94 |
$overview .= '<h3>'. $data['title'] .'</h3><p>'. $data['domain'] .'</p><ul>'; |
$overview .= '<h3>'. $data['title'] .'</h3><p>'. $data['domain'] .'</p><ul>'; |
| 95 |
foreach ($data['projects'] as $pid) { |
foreach ($data['projects'] as $pid) { |
| 96 |
$overview .= '<li>'. (($pid) ? l($project_choices[$pid] .' ('. $pid .')', "node/$pid") : 'BLOCKED') .'</li>'; |
$overview .= '<li>'. (($pid) ? l($project_choices[$pid] .' ('. $pid .')', "node/$pid") : 'BLOCKED') .'</li>'; |
| 97 |
} |
} |
| 98 |
$overview .= '</ul>'; |
$overview .= '</ul>'; |
| 99 |
|
|
| 100 |
|
$form['casetracker_services']['config_summary']['summary'] = array('#value' => $overview); |
| 101 |
$form['casetracker_services']['config'][$key] = array( |
$form['casetracker_services']['config'][$key] = array( |
| 102 |
'#type' => 'fieldset', |
'#type' => 'fieldset', |
| 103 |
'#tree' => true, |
'#tree' => true, |
| 116 |
'#type' => 'submit', |
'#type' => 'submit', |
| 117 |
'#value' => t('Submit'), |
'#value' => t('Submit'), |
| 118 |
); |
); |
|
$form['casetracker_services']['overview']['#value'] = $overview; |
|
| 119 |
return $form; |
return $form; |
| 120 |
} |
} |
| 121 |
|
|
| 148 |
} |
} |
| 149 |
|
|
| 150 |
function casetracker_services_settings_submit($form_id, $form_values) { |
function casetracker_services_settings_submit($form_id, $form_values) { |
| 151 |
|
variable_set('casetracker_services_only_authored', $form_values['only_authored']); |
| 152 |
|
variable_set('casetracker_services_client_css', $form_values['client_css']); |
| 153 |
casetracker_services_project_mapping_save($form_values); |
casetracker_services_project_mapping_save($form_values); |
| 154 |
} |
} |
| 155 |
|
|
| 276 |
'#help' => t('Returns a list of casetracker cases.'), |
'#help' => t('Returns a list of casetracker cases.'), |
| 277 |
), |
), |
| 278 |
array( |
array( |
| 279 |
|
'#method' => 'casetracker.reports', |
| 280 |
|
'#callback' => 'casetracker_services_reports', |
| 281 |
|
'#return' => 'struct', |
| 282 |
|
'#help' => t('Returns a list of viewable reports in hook_menu $item format.'), |
| 283 |
|
), |
| 284 |
|
array( |
| 285 |
|
'#method' => 'casetracker.report', |
| 286 |
|
'#callback' => 'casetracker_services_show_report', |
| 287 |
|
'#args' => array( |
| 288 |
|
array( |
| 289 |
|
'#name' => 'report', |
| 290 |
|
'#type' => 'string', |
| 291 |
|
'#description' => t('One of the reports identified by defined by casetracker.reports.'), |
| 292 |
|
), |
| 293 |
|
array( |
| 294 |
|
'#name' => 'args', |
| 295 |
|
'#type' => 'array', |
| 296 |
|
'#description' => t("Array of arguments for the report."), |
| 297 |
|
), |
| 298 |
|
), |
| 299 |
|
'#return' => 'struct', |
| 300 |
|
'#help' => t('Returns a report.'), |
| 301 |
|
), |
| 302 |
|
array( |
| 303 |
'#method' => 'casetracker.log', |
'#method' => 'casetracker.log', |
| 304 |
'#callback' => 'casetracker_services_log', |
'#callback' => 'casetracker_services_log', |
| 305 |
'#args' => array( |
'#args' => array( |
| 335 |
'#return' => 'struct', |
'#return' => 'struct', |
| 336 |
'#help' => t('Returns version of the Casetracker Services module, so that clients can determine compatibility issues.'), |
'#help' => t('Returns version of the Casetracker Services module, so that clients can determine compatibility issues.'), |
| 337 |
), |
), |
| 338 |
|
array( |
| 339 |
|
'#method' => 'casetracker.css', |
| 340 |
|
'#callback' => 'casetracker_services_css', |
| 341 |
|
'#return' => 'struct', |
| 342 |
|
'#help' => t('Returns centrally maintained style to client site.'), |
| 343 |
|
), |
| 344 |
); |
); |
| 345 |
} |
} |
| 346 |
|
|
| 351 |
$info = parse_ini_file(drupal_get_path('module', 'casetracker_services') .'/casetracker_services.info'); |
$info = parse_ini_file(drupal_get_path('module', 'casetracker_services') .'/casetracker_services.info'); |
| 352 |
return $info; |
return $info; |
| 353 |
} |
} |
| 354 |
|
/** |
| 355 |
|
* Returns css (casetracker.css). |
| 356 |
|
*/ |
| 357 |
|
function casetracker_services_css() { |
| 358 |
|
$css = variable_get('casetracker_services_client_css', '/* This style is set from the main support site. */') . "\n". casetracker_services_fixed_css(); |
| 359 |
|
return $css; |
| 360 |
|
} |
| 361 |
|
|
| 362 |
|
// We don't expect to use much custom css on the client site since we can predict the theme. |
| 363 |
|
// Any css that is used we want to control from the central support site to minimise the |
| 364 |
|
// need to constantly update remote client sites for simple css usability improvements. |
| 365 |
|
// We also can't predict colors of status messages, etc, since these are wholly configurable. |
| 366 |
|
// Hence, lets just define the default css here and make it a configurable variable. |
| 367 |
|
function casetracker_services_fixed_css() { |
| 368 |
|
return ' |
| 369 |
|
/* Hackish hide comment links, because they are not appropriate on client site. */ |
| 370 |
|
.casetracker-client-case ul.links { |
| 371 |
|
display: none; |
| 372 |
|
} |
| 373 |
|
'; |
| 374 |
|
} |
| 375 |
|
|
| 376 |
/** |
/** |
| 377 |
* Returns a list of projects. |
* Returns a list of projects. |
| 410 |
function casetracker_services_cases($pid, $filter) { |
function casetracker_services_cases($pid, $filter) { |
| 411 |
|
|
| 412 |
if ($pid == 'all') { |
if ($pid == 'all') { |
| 413 |
$projects = array_keys(casetracker_services_get_projects()); |
$projects_in = casetracker_services_where_projects_in(); |
|
$pid = implode(', ', $projects); |
|
| 414 |
} |
} |
| 415 |
else { |
else { |
| 416 |
if (!casetracker_services_check_project($pid)) { |
if (!casetracker_services_check_project($pid)) { |
| 417 |
return t("Access denied"); |
return services_error(t("Access denied")); |
| 418 |
|
} |
| 419 |
|
else { |
| 420 |
|
$projects_in = $pid; |
| 421 |
} |
} |
| 422 |
} |
} |
| 423 |
$return = array(); |
$return = array(); |
| 425 |
|
|
| 426 |
$types_in = "'". implode("', '", casetracker_services_case_types()) ."'"; |
$types_in = "'". implode("', '", casetracker_services_case_types()) ."'"; |
| 427 |
|
|
| 428 |
|
// Restrict returned cases to those opened by the project author? |
| 429 |
|
if (variable_get('casetracker_services_only_authored', false)) { |
| 430 |
|
$authors_in = casetracker_services_where_projects_authors_in(); |
| 431 |
|
} |
| 432 |
|
else { |
| 433 |
|
$authors_in = false; |
| 434 |
|
} |
| 435 |
|
|
| 436 |
// Would be nice to be able to get the result set from casetracker_cases_overview(), |
// Would be nice to be able to get the result set from casetracker_cases_overview(), |
| 437 |
// instead we completely ignore that monster and just use some similar SQL. |
// instead we completely ignore that monster and just use some similar SQL. |
| 438 |
$query = "SELECT DISTINCT(n.nid), cc.pid, n.title, ncs.last_comment_timestamp, cc.case_number, cc.case_priority_id, cc.case_status_id, cc.case_type_id, cc.assign_to, cp.project_number FROM node n LEFT JOIN casetracker_case cc ON (n.vid = cc.vid) LEFT JOIN casetracker_project cp ON (cp.nid = cc.pid) LEFT JOIN node_comment_statistics ncs ON (n.nid = ncs.nid) WHERE n.status = 1 AND n.type IN ($types_in) AND cc.pid IN ($pid) ORDER BY ncs.last_comment_timestamp DESC"; |
$query = " |
| 439 |
|
SELECT |
| 440 |
|
DISTINCT(n.nid), n.title, ncs.last_comment_timestamp, |
| 441 |
|
cc.pid, cc.case_number, cc.case_priority_id, cc.case_status_id, cc.case_type_id, cc.assign_to, |
| 442 |
|
cp.project_number, n2.title AS project_title, n2.uid as project_author |
| 443 |
|
FROM node n LEFT JOIN casetracker_case cc ON (n.vid = cc.vid) |
| 444 |
|
LEFT JOIN casetracker_project cp |
| 445 |
|
ON (cp.nid = cc.pid) |
| 446 |
|
LEFT JOIN node n2 |
| 447 |
|
ON (cp.nid = n2.nid) |
| 448 |
|
LEFT JOIN node_comment_statistics ncs |
| 449 |
|
ON (n.nid = ncs.nid) |
| 450 |
|
WHERE |
| 451 |
|
n.status = 1 |
| 452 |
|
AND n.type IN ($types_in) |
| 453 |
|
AND cc.pid IN ($projects_in) |
| 454 |
|
". (($authors_in) ? " AND n.uid IN ($authors_in) " : '') ." |
| 455 |
|
ORDER BY ncs.last_comment_timestamp DESC |
| 456 |
|
"; |
| 457 |
|
|
| 458 |
$result = pager_query($query, 100, 0); |
$result = pager_query($query, 100, 0); |
| 459 |
while ($row = db_fetch_array($result)) { |
while ($row = db_fetch_array($result)) { |
| 460 |
$rows[] = $row; |
$rows[] = $row; |
| 461 |
} |
} |
| 462 |
$output['data'] = $rows; |
$output['data'] = $rows; |
| 463 |
|
$output['header'] = array('PID', 'Case', 'Title', 'Updated', 'Type', 'Status', 'Prioirity'); |
| 464 |
|
|
| 465 |
$lookup = array(); |
$lookup = array(); |
| 466 |
$query = "SELECT csid, case_state_name FROM {casetracker_case_states}"; |
$query = "SELECT csid, case_state_name FROM {casetracker_case_states}"; |
| 475 |
return $output; |
return $output; |
| 476 |
} |
} |
| 477 |
|
|
| 478 |
|
// Get sql-ready list of project ids for current caller |
| 479 |
|
function casetracker_services_where_projects_in() { |
| 480 |
|
$projects = array_keys(casetracker_services_get_projects()); |
| 481 |
|
return implode(', ', $projects); |
| 482 |
|
} |
| 483 |
|
|
| 484 |
|
// Get sql-ready list of project owners allowed for current caller |
| 485 |
|
function casetracker_services_where_projects_authors_in() { |
| 486 |
|
$projects_in = casetracker_services_where_projects_in(); |
| 487 |
|
$results = db_query('SELECT DISTINCT uid FROM {node} WHERE nid IN ('. $projects_in .')'); |
| 488 |
|
while ($row = db_fetch_array($results)) { |
| 489 |
|
$authors[] = $row['uid']; |
| 490 |
|
} |
| 491 |
|
return implode(', ', $authors); |
| 492 |
|
} |
| 493 |
|
|
| 494 |
/** |
/** |
| 495 |
* Returns a list of CT codes |
* Returns a list of CT codes |
| 496 |
*/ |
*/ |
| 510 |
* Create a case, or add a comment, depending on the presense of a nid. |
* Create a case, or add a comment, depending on the presense of a nid. |
| 511 |
*/ |
*/ |
| 512 |
function casetracker_services_log($id, $data) { |
function casetracker_services_log($id, $data) { |
|
watchdog('ct', 'here '. $id); |
|
| 513 |
$case_types = casetracker_services_case_types(); |
$case_types = casetracker_services_case_types(); |
| 514 |
$proj_types = casetracker_services_project_types(); |
$proj_types = casetracker_services_project_types(); |
| 515 |
if (is_numeric($id)) { |
if (is_numeric($id)) { |
| 528 |
} |
} |
| 529 |
} |
} |
| 530 |
|
|
| 531 |
$uid = $project->uid; |
$project_owner_uid = $project->uid; |
| 532 |
if ($new) { |
if ($new) { |
| 533 |
$case_type = array_pop($case_types); |
$case_type = array_pop($case_types); |
| 534 |
$data = (object)$data; |
$data = (object)$data; |
| 535 |
$data->type = $case_type; |
$data->type = $case_type; |
| 536 |
$data->uid = $project->uid; |
$data->uid = $project_owner_uid; |
| 537 |
|
$data->status = true; |
| 538 |
|
$data->comment = true; // who would have thought node_prepare doesn't set defaults... |
| 539 |
$node = node_prepare($data); |
$node = node_prepare($data); |
| 540 |
|
// Casetracker specific |
| 541 |
$node->pid = $project->nid; |
$node->pid = $project->nid; |
| 542 |
|
if ($project->field_project_lead[0]['uid'] > 0) { |
| 543 |
|
// Do this if we have a node userreference field called "project_lead" |
| 544 |
|
$node->assign_to = casetracker_get_name($project->field_project_lead[0]['uid']); |
| 545 |
|
} |
| 546 |
node_save($node); |
node_save($node); |
| 547 |
return $node->nid; |
return $node->nid; |
| 548 |
} |
} |
| 549 |
else { |
else { |
| 550 |
$account = user_load(array('uid' => $uid)); |
$account = user_load(array('uid' => $project_owner_uid)); |
| 551 |
global $user; |
global $user; |
| 552 |
$user = $account; |
$user = $account; |
| 553 |
|
|
| 571 |
return $node->nid; |
return $node->nid; |
| 572 |
} |
} |
| 573 |
} |
} |
|
|
|
| 574 |
return false; |
return false; |
| 575 |
} |
} |
| 576 |
|
|
| 577 |
|
/* |
| 578 |
|
* Considering a views service for table data, except casetracker views support isn't enough |
| 579 |
|
* developed (arguments anyone?) |
| 580 |
|
* and I have issues with the technique for limiting viewed cases and combing this with views. |
| 581 |
|
function casetracker_services_view($view_name, $args = array()) { |
| 582 |
|
$view = views_get_view($view_name); |
| 583 |
|
if ($view == null) |
| 584 |
|
{ |
| 585 |
|
return services_error('View does not exist.'); |
| 586 |
|
} |
| 587 |
|
$result = views_build_view('result', $view, $args); |
| 588 |
|
return $result; |
| 589 |
|
} |
| 590 |
|
*/ |
| 591 |
|
|
| 592 |
function db_queryct($query) { |
function db_queryct($query) { |
| 593 |
$args = func_get_args(); |
$args = func_get_args(); |
| 594 |
array_shift($args); |
array_shift($args); |
| 599 |
_db_query_callback($args, TRUE); |
_db_query_callback($args, TRUE); |
| 600 |
$query = preg_replace_callback(DB_QUERY_REGEXP, '_db_query_callback', $query); |
$query = preg_replace_callback(DB_QUERY_REGEXP, '_db_query_callback', $query); |
| 601 |
watchdog('ct', $query); |
watchdog('ct', $query); |
|
} |
|
| 602 |
|
} |