You are here

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;
  }
}