function support_search in Support Ticketing System 6
Implementation of hook _search.
File
- ./
support.module, line 1988 - support.module
Code
function support_search($op = 'search', $keys = NULL, $skip_access_check = FALSE) {
global $user;
switch ($op) {
case 'name':
if ($skip_access_check || support_access_clients()) {
return t('Tickets');
}
break;
case 'search':
// Build matching conditions
$join = 'INNER JOIN {node} n ON n.nid = i.sid';
$conditions = "n.status = 1 AND n.type = 'support_ticket'";
$arguments = array();
// clients
if ($client = search_query_extract($keys, 'client')) {
$clients = array();
foreach (explode(',', $client) as $c) {
$clients[] = "jt.client = %d";
$arguments[] = $c;
}
$conditions .= ' AND (' . implode(' OR ', $clients) . ')';
$keys = search_query_insert($keys, 'client');
}
// states
if ($state = search_query_extract($keys, 'state')) {
$states = array();
foreach (explode(',', $state) as $s) {
$states[] = "jt.state = %d";
$arguments[] = $s;
}
$conditions .= ' AND (' . implode(' OR ', $states) . ')';
$keys = search_query_insert($keys, 'state');
}
// priorities
if ($priority = search_query_extract($keys, 'priority')) {
$priorities = array();
foreach (explode(',', $priority) as $p) {
$priorities[] = "jt.priority = %d";
$arguments[] = $p;
}
$conditions .= ' AND (' . implode(' OR ', $priorities) . ')';
$keys = search_query_insert($keys, 'priority');
}
$keys = search_query_insert($keys, 'type');
$clients = support_search_available_clients();
if (!empty($clients)) {
$join .= " LEFT JOIN {support_ticket} jt ON n.nid = jt.nid";
$conditions .= ' AND jt.client IN (' . implode(',', support_search_available_clients()) . ')';
}
else {
// User can not access any tickets
$conditions .= " AND n.type != 'support_ticket'";
}
if (!user_access('view other users tickets') && !user_access('administer support') && !user_access('edit any ticket') && !user_access('delete any ticket')) {
$conditions .= " AND n.uid = {$user->uid}";
}
// Build ranking expression (we try to map each parameter to a uniform
// distribution in the range 0..1).
// Tickets are nodes, so use the same ranking.
$ranking = array();
$arguments2 = array();
$join2 = '';
// Used to avoid joining on node_comment_statistics twice
$stats_join = FALSE;
$total = 0;
if ($weight = (int) variable_get('node_rank_relevance', 5)) {
// Average relevance values hover around 0.15
$ranking[] = '%d * i.relevance';
$arguments2[] = $weight;
$total += $weight;
}
if ($weight = (int) variable_get('node_rank_recent', 5)) {
// Exponential decay with half-life of 6 months, starting at last indexed node
$ranking[] = '%d * POW(2, (GREATEST(MAX(n.created), MAX(n.changed), MAX(c.last_comment_timestamp)) - %d) * 6.43e-8)';
$arguments2[] = $weight;
$arguments2[] = (int) variable_get('node_cron_last', 0);
$join2 .= ' LEFT JOIN {node_comment_statistics} c ON c.nid = i.sid';
$stats_join = TRUE;
$total += $weight;
}
if (module_exists('comment') && ($weight = (int) variable_get('node_rank_comments', 5))) {
// Inverse law that maps the highest reply count on the site to 1 and 0 to 0.
$scale = variable_get('node_cron_comments_scale', 0.0);
$ranking[] = '%d * (2.0 - 2.0 / (1.0 + MAX(c.comment_count) * %f))';
$arguments2[] = $weight;
$arguments2[] = $scale;
if (!$stats_join) {
$join2 .= ' LEFT JOIN {node_comment_statistics} c ON c.nid = i.sid';
}
$total += $weight;
}
if (module_exists('statistics') && variable_get('statistics_count_content_views', 0) && ($weight = (int) variable_get('node_rank_views', 5))) {
// Inverse law that maps the highest view count on the site to 1 and 0 to 0.
$scale = variable_get('node_cron_views_scale', 0.0);
$ranking[] = '%d * (2.0 - 2.0 / (1.0 + MAX(nc.totalcount) * %f))';
$arguments2[] = $weight;
$arguments2[] = $scale;
$join2 .= ' LEFT JOIN {node_counter} nc ON nc.nid = i.sid';
$total += $weight;
}
// When all search factors are disabled (ie they have a weight of zero),
// the default score is based only on keyword relevance and there is no need to
// adjust the score of each item.
if ($total == 0) {
$select2 = 'i.relevance AS score';
$total = 1;
}
else {
$select2 = implode(' + ', $ranking) . ' AS score';
}
// Do search.
$find = do_search($keys, 'node', $join, $conditions, $arguments, $select2, $join2, $arguments2);
// Load results.
$results = array();
foreach ($find as $item) {
// Build the node body.
$node = node_load($item->sid);
$node->build_mode = NODE_BUILD_SEARCH_RESULT;
$node = node_build_content($node, FALSE, FALSE);
$node->body = drupal_render($node->content);
// Fetch comments for snippet.
$node->body .= module_invoke('comment', 'nodeapi', $node, 'update index');
// Fetch terms for snippet.
$node->body .= module_invoke('taxonomy', 'nodeapi', $node, 'update index');
$extra = node_invoke_nodeapi($node, 'search result');
if (!is_array($extra)) {
$extra = array();
}
if (sizeof($clients) > 1) {
$title = check_plain(_support_client($node->client)) . ': ' . $node->title;
}
else {
$title = $node->title;
}
// change 'comments' to 'follow ups' for support tickets
foreach ($extra as $key => $value) {
$trans = array(
' comments' => ' follow ups',
);
$extra[$key] = strtr($value, $trans);
}
$extra[] = check_plain(_support_state($node->state));
$extra[] = check_plain(_support_priorities($node->priority));
$clients = support_search_available_clients();
$results[] = array(
'link' => url('node/' . $item->sid, array(
'absolute' => TRUE,
)),
'type' => check_plain(node_get_types('name', $node)),
'title' => $title,
'user' => theme('username', $node),
'date' => $node->changed,
'node' => $node,
'extra' => $extra,
'score' => $item->score / $total,
'snippet' => search_excerpt($keys, $node->body),
);
}
return $results;
}
}