support_reference.module in Support Ticketing System 7
Same filename and directory in other branches
Support ticket references.
File
support_reference/support_reference.moduleView source
<?php
/**
* @file
* Support ticket references.
*/
/**
* Implements hook_menu().
*/
function support_reference_menu() {
$items = array();
$items['support_reference/autocomplete/%support_client/%'] = array(
'title' => 'Autocomplete ticket reference',
'page callback' => 'support_reference_autocomplete',
'page arguments' => array(
2,
3,
),
'access callback' => 'user_access',
'access arguments' => array(
'edit support ticket references',
),
'type' => MENU_CALLBACK,
);
return $items;
}
/**
* Implements hook_permission().
*/
function support_reference_permission() {
return array(
'edit support ticket references' => array(
'title' => t('Edit support ticket references'),
),
'view support ticket references' => array(
'title' => t('View support ticket references'),
),
);
}
/**
* Implements hook_block_info().
*/
function support_reference_block_info() {
return array(
'support_reference_references' => array(
'info' => t('Support ticket references'),
// Turn off caching because the user MIGHT have access to the form.
// We don't have sufficient control over things to do any better.
// If we want to be more agressive, we could turn off
// XSRF protection by setting $form['#token'] = FALSE in the
// builder, but it's probably a bad idea for this form, which doesn't
// have confirm page protection.
'cache' => DRUPAL_NO_CACHE,
),
);
}
/**
* Implements hook_block_view().
*/
function support_reference_block_view($delta = '') {
global $user;
$block = array();
if ($delta == 'support_reference_references' && arg(0) == 'node' && is_numeric(arg(1))) {
if ($node = node_load(arg(1))) {
if ($node->type == 'support_ticket') {
$view = $edit = '';
if (user_access('view support ticket references')) {
$result = db_query('SELECT rnid FROM {support_reference} WHERE nid = :nid ORDER BY rnid DESC', array(
':nid' => $node->nid,
))
->fetchCol();
$nodes = node_load_multiple($result);
$references = array();
foreach ($nodes as $reference) {
// Only list reference if user viewing page has access.
$client = support_client_load($reference->client);
if (support_access_clients($client, $user)) {
$state = _support_state($reference->state);
$priority = _support_priorities($reference->priority);
$class = "support-reference state-{$state} priority-{$priority}";
if ($node->client != $reference->client) {
$class .= ' crossclient';
}
$references[$reference->nid] = '<span class="' . check_plain($class) . '">' . l(t('#!nid: !title', array(
'!nid' => $reference->nid,
'!title' => $reference->title,
)), "node/{$reference->nid}", array(
'attributes' => array(
'title' => t('!state !priority priority ticket.', array(
'!state' => ucfirst($state),
'!priority' => $priority,
)),
),
)) . '</span>';
}
}
$view = theme('item_list', array(
'items' => $references,
));
}
if (user_access('edit support ticket references')) {
$edit = drupal_get_form('support_reference_block_form', $node->client, $node);
}
$block['content'][] = array(
'#markup' => $view,
);
$block['content'][] = $edit;
$block['subject'] = t('Support ticket references');
}
}
}
return $block;
}
function support_reference_block_form($form, &$form_state, $client, $node) {
$path = drupal_get_path('module', 'support_reference');
$form['#attached']['library'][] = array(
'system',
'ui.autocomplete',
);
$form['#attached']['css'][] = "{$path}/support_reference.css";
$form['#attached']['js'][] = "{$path}/support_reference.js";
$form['#attached']['js'][] = array(
'data' => array(
'supportReferenceAutoCompletePath' => base_path() . "support_reference/autocomplete/{$client}/{$node->nid}",
),
'type' => 'setting',
);
$form['#nid'] = $node->nid;
$form['reference'] = array(
'#type' => 'textfield',
'#title' => t('Add / Remove Reference'),
'#default_value' => '',
'#required' => TRUE,
);
// This gets hidden by the css.
$form['submit'] = array(
'#type' => 'submit',
'#value' => t('Change'),
);
return $form;
}
function support_reference_block_form_submit($form, &$form_state) {
$nid = $form['#nid'];
$node = node_load($nid);
$client = support_client_load($node->client);
// Make sure the user is allowed to do this.
if (user_access('edit support ticket references') && support_access_clients($client)) {
$match = array();
if (preg_match_all('/\\[#(\\d+)\\]/', $form_state['values']['reference'], $match)) {
foreach ($match[1] as $rnid) {
$rnode = node_load($rnid);
$rclient = support_client_load($rnode->client);
// Additional access control check to ignore messing with any references
// to tickets belonging to clients that the user doesn't have access to.
if (support_access_clients($rclient)) {
// If it already exists, delete instead.
if (db_query('SELECT 1 FROM {support_reference} WHERE nid = :nid AND rnid = :rnid', array(
':nid' => $nid,
':rnid' => $rnid,
))
->fetchField()) {
db_delete('support_reference')
->condition('nid', $nid)
->condition('rnid', $rnid)
->execute();
db_delete('support_reference')
->condition('nid', $rnid)
->condition('rnid', $nid)
->execute();
}
else {
db_insert('support_reference')
->fields(array(
'nid' => $nid,
'rnid' => $rnid,
))
->execute();
db_insert('support_reference')
->fields(array(
'nid' => $rnid,
'rnid' => $nid,
))
->execute();
}
}
}
}
}
}
/**
* @todo: should we allow cross-client references?
*/
function support_reference_autocomplete($client = NULL, $skipnid = 0) {
$matches = array();
if (is_object($client) && isset($client->clid) && support_access_clients($client)) {
$result = db_query('SELECT n.nid, n.title, r.rnid FROM {support_ticket} s INNER JOIN {node} n ON s.nid = n.nid LEFT JOIN {support_reference} r ON (r.nid = :skipnid AND r.rnid = s.nid) WHERE s.client = :client AND s.nid <> :skipnid ORDER BY n.nid DESC', array(
':skipnid' => $skipnid,
':client' => $client->clid,
));
foreach ($result as $ticket) {
// We are using the titles directly from the database instead of using node_load() for speed / memory reasons.
if (!empty($ticket->rnid)) {
// If rnid is non null, there's a reference already, so indicate that choosing it will cause removal.
// NOTE: check_plain() here causes double escaping on Drupal 7. (But not Drupal 6!)
$matches[] = t('[#!nid]: !title (remove)', array(
'!nid' => $ticket->nid,
'!title' => $ticket->title,
));
}
else {
// NOTE: check_plain() here causes double escaping on Drupal 7. (But not Drupal 6!)
$matches[] = t('[#!nid]: !title', array(
'!nid' => $ticket->nid,
'!title' => $ticket->title,
));
}
}
}
drupal_json_output($matches);
}
Functions
Name | Description |
---|---|
support_reference_autocomplete | @todo: should we allow cross-client references? |
support_reference_block_form | |
support_reference_block_form_submit | |
support_reference_block_info | Implements hook_block_info(). |
support_reference_block_view | Implements hook_block_view(). |
support_reference_menu | Implements hook_menu(). |
support_reference_permission | Implements hook_permission(). |