You are here

function biblio_build_query in Bibliography Module 7

Same name and namespace in other branches
  1. 6.2 includes/biblio.pages.inc \biblio_build_query()
  2. 6 biblio.pages.inc \biblio_build_query()
  3. 7.2 includes/biblio.pages.inc \biblio_build_query()

Biblio_db_search builds the SQL query which will be used to select and order "biblio" type nodes. The query results are then passed to biblio_show_results for output.

3 calls to biblio_build_query()
biblio_export in includes/biblio.import.export.inc
Export nodes in a given file format.
biblio_page in includes/biblio.pages.inc
biblio_profile_page in includes/biblio.pages.inc

File

includes/biblio.pages.inc, line 325
Copyright (C) 2006-2011 Ron Jerome.

Code

function biblio_build_query($arg_list) {
  global $user;

  // biblio_contributor (bc) count , increase for every invocation.
  static $bcc = 0;
  static $bkd = 0;

  // Term counter, increase for every invocation.
  static $tcc = 0;
  $rss_info['feed'] = FALSE;
  $rss_info['title'] = variable_get('biblio_base_title', 'Biblio');
  $rss_info['link'] = '';
  $rss_info['description'] = '';
  if ($arg_list['page_limit'] > 0) {
    $query = db_select('node', 'n')
      ->extend('PagerDefault');
    $query
      ->limit($arg_list['page_limit']);
  }
  else {
    $query = db_select('node', 'n');
  }

  // Add a tag of "node_access" to ensure that only nodes to which the user has access are retrieved.
  $query
    ->addTag('node_access');
  $query
    ->addField('n', 'nid');
  $type_name = $query
    ->addField('bt', 'name', 'biblio_type_name');
  $query
    ->leftJoin('biblio', 'b', 'n.vid=b.vid');
  $query
    ->innerJoin('biblio_types', 'bt', 'b.biblio_type=bt.tid');

  // $query->distinct();
  // POSIX regular expression matching, case insensitive.
  $match_op = db_driver() == 'pgsql' ? '~*' : 'RLIKE';
  $limit = '';
  if (variable_get('biblio_view_only_own', 0)) {
    $limit .= " AND n.uid = {$user->uid} ";
  }
  if (isset($arg_list['s']) || isset($arg_list['sort'])) {
    $sort = isset($arg_list['s']) ? $arg_list['s'] : $arg_list['sort'];
    unset($arg_list['s']);
    unset($arg_list['sort']);
  }
  else {
    $sort = variable_get('biblio_sort', 'year');
  }
  if (isset($arg_list['o']) || isset($arg_list['order'])) {
    if (isset($arg_list['o'])) {
      $order = strcasecmp($arg_list['o'], 'ASC') ? 'DESC' : 'ASC';
      unset($arg_list['o']);
    }
    if (isset($arg_list['order'])) {
      $order = strcasecmp($arg_list['order'], 'ASC') ? 'DESC' : 'ASC';
      unset($arg_list['order']);
    }
  }
  else {
    $order = strtolower(variable_get('biblio_order', 'DESC'));
  }

  /*  if (!isset($_SESSION['biblio_filter']) || !is_array($_SESSION['biblio_filter'])) {
    $_SESSION['biblio_filter'] = array();
    }

    $session = &$_SESSION['biblio_filter'];

    if (!in_array('no_filters', $arg_list)) {
    foreach ($session as $filter) {
    $arg_list = array_merge($arg_list, $filter);
    }
    }
     */
  switch ($sort) {
    case 'type':

      // $sortby = "ORDER BY bt.name %s, b.biblio_year DESC ";.
      $query
        ->addField('n', 'title');
      $query
        ->orderBy($type_name, $order);
      $query
        ->orderBy('biblio_sort_title', $order);
      break;
    case 'title':
      $query
        ->addField('n', 'title');
      $query
        ->orderBy('biblio_sort_title', $order);
      break;
    case 'author':

      // $last_name = $query->addField('bcd', 'lastname');.
      $query
        ->innerJoin('biblio_contributor', 'bc', 'b.vid = bc.vid');
      $query
        ->join('biblio_contributor_data', 'bcd', 'bc.cid = bcd.cid');
      $query
        ->condition('bc.rank', 0);
      $query
        ->addField('bcd', 'lastname');
      $query
        ->orderBy('bcd.lastname', $order);

      // $query->condition('bc.auth_category', 1);.
      break;

    // Added msh 070808.
    case 'keyword':
      $word = $query
        ->addField('bkd', 'word', 'biblio_keyword');
      $query
        ->orderBy($word, $order);
      $query
        ->innerJoin('biblio_keyword', 'bk', 'b.vid = bk.vid');
      $query
        ->innerJoin('biblio_keyword_data', 'bkd', 'bk.kid = bkd.kid');
      break;
    case 'year':
    default:
      $query
        ->addField('b', 'biblio_year');
      $query
        ->addField('b', 'biblio_date');
      $query
        ->orderBy('biblio_year', $order);
      $query
        ->orderBy('biblio_sort_title');
  }

  //end switch
  if (isset($arg_list['f']) && count($arg_list['f'])) {
    $fields = biblio_get_db_fields();
    foreach ($arg_list['f'] as $type => $value) {
      $tables = array_keys($query
        ->getTables());
      switch ($type) {
        case 'no_filters':
          break;
        case 'rss.xml':
          $rss_info['feed'] = TRUE;
          $query
            ->limit(variable_get('biblio_rss_number_of_entries', 10));
          break;
        case 'term':
        case 'term_id':
          $query
            ->innerJoin('taxonomy_index', "ti{$tcc}", "n.nid = ti{$tcc}.nid");
          if ($type == 'term') {
            $query
              ->innerJoin('taxonomy_term_data', 'td', "ti{$tcc}.tid = td.tid");
            $query
              ->condition('td.name', $value);
          }
          elseif ($type == 'term_id') {
            $query
              ->condition("ti{$tcc}.tid", $value);
          }
          $tcc++;
          break;
        case 'tg':
          $query
            ->where("UPPER(substring(biblio_sort_title,1 ,1)) = :letter", array(
            ':letter' => $value,
          ));
          break;

        // Selects entries whoose authors firstname starts with the letter provided.
        case 'ag':
          $query
            ->where(" UPPER(substring(bcd.lastname,1,1)) = :letter ", array(
            ':letter' => $value,
          ));

          // $where['bc-rank'] = "bc.rank=0";.
          if ($sort != 'author') {
            if (array_search('bc', $tables) === FALSE) {
              $query
                ->innerJoin('biblio_contributor', 'bc', 'n.vid = bc.vid');
            }
            $query
              ->innerJoin('biblio_contributor_data', 'bcd', 'bc.cid = bcd.cid');
          }
          break;
        case 'cid':
        case 'aid':
          $bcc++;
          $query
            ->innerJoin('biblio_contributor', "bc{$bcc}", "n.vid = bc{$bcc}.vid");
          $query
            ->condition("bc{$bcc}.cid", $value);
          break;
        case 'author':
          module_load_include('inc', 'biblio', 'includes/biblio.contributors');
          $bcc++;
          if (array_search('bc', $tables) === FALSE) {
            $query
              ->innerJoin('biblio_contributor', 'bc', 'n.vid = bc.vid');
          }
          if (is_numeric($value)) {
            $cids = biblio_get_linked_contributors($value);
            $cids[] = $value;
            $cid_count = 0;
            $or = db_or();
            foreach ($cids as $cid) {
              $or
                ->condition("bc.cid", $cid);
              $cid_count++;
            }
            if ($cid_count == 0) {
              $query
                ->condition("bc.cid", -1);
            }
            else {
              $query
                ->condition($or);
            }
          }
          else {
            if (array_search('bcd', $tables) === FALSE) {
              $query
                ->innerJoin('biblio_contributor_data', 'bcd', 'bcd.cid = bc.cid');
            }

            // [[:<:]], [[:>:]] These markers stand for word boundaries. They
            // match the beginning and end of words, respectively. A word is a
            // sequence of word characters that is not preceded by or followed
            // by word characters. A word character is an alphanumeric character
            // in the alnum class or an underscore (_).
            // https://dev.mysql.com/doc/refman/5.7/en/regexp.html
            $query
              ->condition('bcd.name', "[[:<:]]" . preg_quote($value) . "[[:>:]]", $match_op);
            $rss_info['title'] = t("Publications by @value", array(
              '@value' => $value,
            ));
            $rss_info['description'] = t("These publications by %author are part of the works listed at %sitename", array(
              '%author' => $value,
              '%sitename' => variable_get('site_name', 'Drupal'),
            ));
            $rss_info['link'] = '/author/' . $value;
          }
          break;
        case 'publisher':
          $query
            ->condition('b.biblio_publisher', "[[:<:]]" . preg_quote($value) . "[[:>:]]", $match_op);
          break;
        case 'year':
          $query
            ->condition('b.biblio_year', $value);
          break;
        case 'uid':
          $query
            ->addField('n', 'uid');
          $query
            ->condition('n.uid', $value);
          break;
        case 'keyword':
          $bkd++;
          if (array_search('bk', $tables) === FALSE) {
            $query
              ->innerJoin('biblio_keyword', 'bk', 'n.vid = bk.vid');
          }
          if (is_numeric($value)) {
            $query
              ->condition('bk.kid', $value);
          }
          else {
            if (array_search('bkd', $tables) === FALSE) {
              $query
                ->innerJoin('biblio_keyword_data', 'bkd', 'bkd.kid = bk.kid');
            }
            if (strlen($value) == 1) {

              // $query->condition('',  $value, 'SUBSTR(bkd.word, 1, 1) =');.
              $query
                ->where(" UPPER(substring(bkd.word,1,1)) = :letter ", array(
                ':letter' => $value,
              ));
            }
            else {
              $query
                ->condition('bkd.word', "[[:<:]]" . preg_quote($value) . "[[:>:]]", 'LIKE');
            }
            $rss_info['title'] = t("Keyword @value", array(
              '@value' => $value,
            ));
            $rss_info['description'] = t("These publications, containing the keyword: %keyword, are part of the works listed at %sitename", array(
              '%keyword' => $value,
              '%sitename' => variable_get('site_name', 'Drupal'),
            ));
            $rss_info['link'] = '/keyword/' . $value;
          }
          break;
        case 'citekey':
          $query
            ->condition('b.biblio_citekey', $value);
          break;
        case 'type':
          $query
            ->condition('b.biblio_type', $value);
          break;
        case 'search':
          $search_nids = array();
          $search_nids = biblio_search_query($value);
          if (empty($search_nids)) {

            // If we didn't find anything, then add one value of -1 since there will never be a node id == -1.
            $search_nids[] = -1;
          }
          $query
            ->condition('n.nid', $search_nids, 'IN');
          break;
        default:
          if (in_array("biblio_{$type}", $fields)) {
            $query
              ->condition("b.biblio_{$type} ", $value, 'LIKE');
          }
          break;
      }
    }
  }

  // Show unpublished nodes to users with uid = 1 or  with 'Administer Biblio' permissions.
  if ($user->uid != 1 && !biblio_access('admin')) {
    $query
      ->condition('n.status', 1);
  }
  $result = $query
    ->execute();
  $nids = array();
  $extras = array();
  foreach ($result as $node) {
    $nids[] = $node->nid;
    if (isset($node->biblio_year)) {
      unset($node->biblio_year);
    }
    $extras[] = $node;
  }
  return array(
    $nids,
    $extras,
    $rss_info,
  );
}