You are here

biblio.pages.inc in Bibliography Module 7.2

Same filename and directory in other branches
  1. 6.2 includes/biblio.pages.inc
  2. 7 includes/biblio.pages.inc

File

includes/biblio.pages.inc
View source
<?php

/**
 *
 *   Copyright (C) 2006-2011  Ron Jerome
 *
 */
function biblio_view_node($nid) {
  $options = array();
  drupal_goto('node/' . (int) $nid, $options, 301);

  // set a 301 response code
}
function biblio_arg_handler($arg_info) {
  $arg_list = array();
  if (count($arg_info['func_args']) == 1 && is_array($arg_info['func_args'][0])) {
    return $arg_info['func_args'][0];
  }
  while ($arg_info['func_args']) {
    $arg = array_shift($arg_info['func_args']);
    $value = array_shift($arg_info['func_args']);
    if ($arg == 'sort') {
      $arg_list['s'] = $value;
    }
    elseif ($arg == 'order') {
      $arg_list['o'] = strtolower($value) == 'desc' ? 'desc' : 'asc';
    }
    else {
      $arg_list['f'][$arg] = $value;
    }
  }
  $arg_list = array_merge_recursive($arg_list, $arg_info['uri']['query']);
  return $arg_list;
}
function biblio_profile_page($user) {
  $arg_list = array();
  if (isset($user->data['biblio_contributor_id']) && $user->data['biblio_contributor_id'] > 0) {
    $arg_list = array(
      'f' => array(
        'author' => $user->data['biblio_contributor_id'],
      ),
    );
  }
  elseif (isset($user->data['biblio_lastname']) && !empty($user->data['biblio_lastname'])) {
    $arg_list = array(
      'f' => array(
        'author' => $user->data['biblio_lastname'],
      ),
    );
  }
  else {
    $arg_list = array(
      'f' => array(
        'uid' => $user->uid,
      ),
    );
  }
  $arg_list['page_limit'] = variable_get('biblio_rowsperpage', 25);
  list($nids, $extras, $rss_info) = biblio_build_query($arg_list);
  $render['biblio_page']['profile'] = biblio_page_content($nids, $extras);
  return $render;
}
function biblio_page() {
  $biblios = $bids = $extras = $rss_info = $info = $arg_list = $render = array();
  $base = variable_get('biblio_base', 'biblio');
  $info['func_args'] = func_get_args();
  $info['uri'] = drupal_parse_url(request_uri());
  $arg_list = biblio_arg_handler($info);
  $arg_list['page_limit'] = variable_get('biblio_rowsperpage', 25);
  list($bids, $extras, $rss_info) = biblio_build_query($arg_list);
  if ($rss_info['feed']) {
    biblio_filter_feed($rss_info, $bids);
    return;
  }
  if (variable_get('biblio_rss', 0)) {
    drupal_add_html_head_link(array(
      'rel' => 'alternate',
      'type' => 'application/rss+xml',
      'title' => variable_get('site_name', 'Drupal') . ' RSS',
      'href' => url("{$base}/rss.xml"),
    ));
  }
  drupal_set_title(check_plain(variable_get('biblio_base_title', 'Biblio')));
  $filter = isset($arg_list['f']) ? array(
    'f' => $arg_list['f'],
  ) : array();
  $render['biblio_page']['header'] = biblio_page_header($filter);
  $render['biblio_page']['content'] = biblio_page_content($bids, $extras);
  return $render;
}
function biblio_page_header($filter = array()) {
  $header = array();
  $header = array(
    '#prefix' => '<div id="biblio-header" class="clear-block">',
    '#suffix' => '</div>',
    '#weight' => -100,
  );

  // Search box. Has same permissions as the filter tab.
  if (variable_get('biblio_search', 0) && user_access('show filter tab')) {
    $header += array(
      'search_form' => drupal_get_form('biblio_search_form'),
    );
  }
  $header += array(
    'export_links' => array(
      '#prefix' => '<div class="biblio-export">',
      '#biblio' => NULL,
      '#filter' => $filter,
      '#theme' => 'biblio_export_links',
      '#suffix' => '</div>',
    ),
  );
  if (!biblio_access('export')) {
    global $pager_total_items;
    $header['export_links']['#markup'] = t('Found @count results', array(
      '@count' => $pager_total_items[0],
    ));
    unset($header['export_links']['#theme']);
  }

  // Add some links to the top of the page to change the sorting/ordering...
  if (user_access('show sort links')) {
    $header += array(
      'sort_links' => array(
        '#markup' => _biblio_sort_tabs(),
      ),
    );
  }
  $header += array(
    'filter_status' => array(
      '#prefix' => '<div class="biblio-filter-status">',
      '#suffix' => '</div>',
      '#markup' => _biblio_filter_info_line($filter),
    ),
  );
  if (isset($_GET['s'])) {
    if ($_GET['s'] == 'title' || $_GET['s'] == 'author' || $_GET['s'] == 'keyword') {
      if (strpos($_GET['q'], 'ag') || strpos($_GET['q'], 'tg') || strpos($_GET['q'], 'keyword')) {
        $value = substr($_GET['q'], strrpos($_GET['q'], '/') + 1);
      }
      else {
        $value = '';
      }
      $header += array(
        'alpha_line' => array(
          '#prefix' => '<div class="biblio-alpha-line">',
          '#suffix' => '</div>',
          '#markup' => theme('biblio_alpha_line', array(
            'type' => $_GET['s'],
            'current' => $value,
            'path' => variable_get('biblio_base', 'biblio'),
          )),
        ),
      );
    }
  }
  return $header;
}
function biblio_page_content($bids = array(), $extras = array()) {
  $base = variable_get('biblio_base', 'biblio');
  $content = $raw_biblios = $biblios = array();
  $count = $section_id = 0;
  if (module_exists('popups')) {
    popups_add_popups();
  }
  if (count($bids)) {

    //  $nids = array_unique($nids);
    $raw_biblios = biblio_load_multiple($bids);
    $langcode = $GLOBALS['language_content']->language;

    // @todo determine the language programatically
    $field_language = 'und';
    field_attach_prepare_view('biblio', $raw_biblios, 'biblio_list', $langcode);
    entity_prepare_view('biblio', $raw_biblios, $langcode);
    foreach ($bids as $key => $bid) {
      if (!empty($extras)) {
        $biblios[] = (object) array_merge((array) $raw_biblios[$bid], (array) $extras[$key]);
      }
      else {
        $biblios[] = $raw_biblios[$bid];
      }
    }
  }
  foreach ($biblios as $biblio) {
    $count++;
    if (is_array($biblio)) {
      $biblio = (object) $biblio;
    }
    $biblio->language = $field_language;
    if (variable_get('biblio_hide_bibtex_braces', 0)) {
      $biblio->title = biblio_remove_brace($biblio->title);
    }
    $biblio->content = field_attach_view('biblio', $biblio, 'biblio_list');

    // output new section if needed
    if ($section = biblio_category_section($biblio)) {
      $section_id++;
      $content['section_' . $section_id] = $section;
    }
    $content['section_' . $section_id][] = biblio_entry($biblio);
  }
  $content['pager']['#markup'] = theme('pager');
  if ($count == 0) {
    $content .= "<h3>" . t("No items found") . "</h3>";
    if (strstr($content, "Filters:")) {
      $content['message']['#markup'] = t('!modify_link or !remove_link your filters and try again.', array(
        '!modify_link' => l(t('Modify'), "{$base}/filter"),
        '!remove_link' => l(t('remove'), "{$base}/filter/clear"),
      ));
    }
  }
  return $content;
}
function biblio_entry($biblio) {
  $entry = array();
  $style = biblio_get_style();

  /*
    $select_box = array(
      '#type' => 'checkbox',
      '#return_value'  => $node->nid,
      '#default_value' => 0,
      '#attributes' => array('class' => array('biblio-export-selector'),)

    );
  */
  $prefix = '<div class="biblio-entry">';
  $suffix = '</div>';

  // @todo: get rid of below line and add published/unpublished support. See http://drupal.org/node/1537396
  $biblio->status = 1;
  if (!$biblio->status) {
    $prefix .= '<div id="node-' . $biblio->bid . '" class="node node-unpublished">';
    $suffix .= '</div>';
  }

  //  $prefix .= theme('checkbox', array('element' => $select_box));
  $entry = array(
    '#prefix' => $prefix,
    '#suffix' => $suffix,
  );
  $entry['entry']['#markup'] = theme('biblio_style', array(
    'biblio' => $biblio,
    'style_name' => $style,
  ));
  $annotation_field = variable_get('biblio_annotations', 'none');
  if ($annotation_field != 'none' && $biblio->{$annotation_field}) {
    $entry['annotation'] = array(
      '#prefix' => '<div class="biblio-annotation">',
      '#markup' => filter_xss($biblio->{$annotation_field}, biblio_get_allowed_tags()),
      '#suffix' => '</div>',
    );
  }
  $openurl_base = variable_get('biblio_baseopenurl', '');
  if ($openurl_base) {
    $entry['openurl'] = array(
      '#markup' => theme('biblio_openurl', array(
        'openURL' => biblio_openurl($biblio),
      )),
    );
  }
  if (biblio_access('export')) {
    $base = variable_get('biblio_base', 'biblio');
    $entry['export_links'] = array(
      '#markup' => theme('biblio_export_links', array(
        'biblio' => $biblio,
      )),
    );
  }
  if (biblio_access('download', $biblio)) {

    // add links to attached files (if any)
    $entry['download_links'] = array(
      '#markup' => theme('biblio_download_links', array(
        'biblio' => $biblio,
      )),
    );
  }
  return $entry;
}

/*
 * 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
 *
 *
 */
function biblio_build_query($arg_list) {
  global $user;
  static $bcc = 0;

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

  //term counter, increase for every invocation
  $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('biblio', 'b')
      ->extend('PagerDefault');
    $query
      ->limit($arg_list['page_limit']);
  }
  else {
    $query = db_select('biblio', 'b');
  }

  //add a tag of "node_access" to ensure that only nodes to which the user has access are retrieved
  $query
    ->addTag('biblio_access');
  $query
    ->addField('b', 'bid');
  $type_name = $query
    ->addField('b', 'publication_type', 'pt');

  //  $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 = '';

  //@todo add this functionality

  //  if (variable_get('biblio_view_only_own', 0) ) {
  //    $limit .= " AND n.uid = $user->uid ";
  //  }
  if (!isset($arg_list['s'])) {
    $arg_list['s'] = variable_get('biblio_sort', 'year');
  }
  if (!isset($arg_list['o'])) {
    $arg_list['o'] = 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 ($arg_list['s']) {
    case 'type':

      //$sortby = "ORDER BY bt.name %s, b.biblio_year DESC ";
      $query
        ->addField('b', 'publication_type');
      $query
        ->orderBy($type_name, $arg_list['o']);
      $query
        ->orderBy('biblio_sort_title', $arg_list['o']);
      break;
    case 'title':
      $query
        ->addField('fdbt', 'biblio_title_value');
      $query
        ->join('field_data_biblio_title', 'fdbt', 'fdbt.entity_id = b.bid');
      $query
        ->orderBy('biblio_sort_title', $arg_list['o']);
      break;

    // @todo: get functionality for contributor data
    //    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', $arg_list['o']);
    //      // $query->condition('bc.auth_category', 1);
    //      break;
    // @todo: get functionality for keywords working
    //    case 'keyword': // added msh 070808
    //      $word = $query->addField('bkd', 'word', 'biblio_keyword');
    //      $query->orderBy($word, $arg_list['o']);
    //      $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('fdby', 'biblio_year_value');
      $query
        ->leftJoin('field_data_biblio_year', 'fdby', 'fdby.entity_id = b.bid');
      $query
        ->addField('fdbd', 'biblio_date_value');
      $query
        ->leftJoin('field_data_biblio_date', 'fdbd', 'fdbd.entity_id = b.bid');
      $query
        ->orderBy('biblio_year_value', $arg_list['o']);
      $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 'and':
          $operator = " AND ";
          break;
        case 'or':
          $operator = " OR ";
          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;
        case 'ag':

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

          //$where['bc-rank'] = "bc.rank=0";
          if ($arg_list['s'] != 'author') {
            $query
              ->innerJoin('biblio_contributor', 'bc', 'b.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':
          $bcc++;
          if (array_search('bc', $tables) === FALSE) {
            $query
              ->innerJoin('biblio_contributor', 'bc', 'n.vid = bc.vid');
          }
          if (is_numeric($value)) {
            $cids = db_query('SELECT cid FROM {biblio_contributor_data}
                              WHERE cid = :cid OR
                              (aka = (SELECT aka FROM {biblio_contributor_data} WHERE cid = :cdid AND aka != 0))', array(
              ':cid' => $value,
              ':cdid' => $value,
            ));
            $cid_count = 0;
            $or = db_or();
            foreach ($cids as $cid) {
              $or
                ->condition("bc.cid", $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');
            }
            $query
              ->condition('bcd.name', "[[:<:]]" . $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', "[[:<:]]" . $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', "[[:<:]]" . $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)) {
            $search_nids[] = -1;

            // if we didn't find anything, then add one value of -1 since there will never be a node id == -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();
  $bids = array();
  $extras = array();
  foreach ($result as $biblio) {
    $bids[] = $biblio->bid;
    if (isset($biblio->biblio_year)) {
      unset($biblio->biblio_year);
    }
    $extras[] = $biblio;
  }
  return array(
    $bids,
    $extras,
    $rss_info,
  );
}
function _biblio_sort_tabs() {
  global $base_path;
  $content = '';
  $sort_links = array();
  $tabs = variable_get('biblio_sort_tabs_style', 0);
  $uri = drupal_parse_url(request_uri());
  $uri['path'] = variable_get('biblio_base', 'biblio');
  if (substr($uri['path'], 0, 1) == '/') {
    $uri['path'] = substr($uri['path'], 1);
  }
  if (isset($uri['query']['s'])) {
    $sort = $uri['query']['s'];
  }
  else {
    $sort = variable_get('biblio_sort', 'year');
  }
  if (isset($uri['query']['o'])) {
    $order = $uri['query']['o'] == 'desc' || $uri['query']['o'] == 'DESC' ? 'asc' : 'desc';
  }
  else {
    $order = strtolower(variable_get('biblio_order', 'desc'));
    $order = $order == 'desc' || $order == 'DESC' ? 'asc' : 'desc';
  }
  $path = drupal_get_path('module', 'biblio');
  $order_arrow = $order == 'asc' ? '<img src ="' . $base_path . $path . '/misc/arrow-asc.png" alt =" (Desc)" />' : '<img src ="' . $base_path . $path . '/misc/arrow-desc.png" alt = " (Asc)" />';
  $sort_links = variable_get('biblio_sort_tabs', array(
    'author' => 'author',
    'title' => 'title',
    'type' => 'type',
    'year' => 'year',
    'keyword' => 'keyword',
  ));
  ksort($sort_links);
  $content .= $tabs ? '<ul class="tabs secondary ">' : '';
  foreach ($sort_links as $key => $title) {
    $uri['attributes'] = array(
      "title" => t("Click a second time to reverse the sort order"),
    );
    $uri['html'] = TRUE;
    $uri['text'] = t(ucfirst($title));
    if ($key === $title && $title == $sort) {
      $uri['query']['s'] = $title;
      $uri['query']['o'] = $order;
      $uri['attributes']['class'][] = "active";
      $uri['active'] = TRUE;
      $uri['pfx'] = ' [ ';
      $uri['sfx'] = '] ';
      $uri['arrow'] = $order_arrow;
      $content .= _biblio_sort_tab($uri, $tabs);
    }
    elseif ($key === $title) {
      $uri['query']['s'] = $title;
      $uri['query']['o'] = $order;
      $uri['active'] = FALSE;
      $uri['pfx'] = ' ';
      $uri['sfx'] = ' ';
      $uri['arrow'] = '';
      $content .= _biblio_sort_tab($uri, $tabs);
    }
  }
  if (!$tabs) {
    $content = t('Sort by') . ': ' . $content;
  }
  $content .= $tabs ? '</ul>' : '';
  return $content;
}
function _biblio_sort_tab($tab, $tabs = FALSE) {
  if ($tabs) {
    $text = '<span class="a"><span class="b">' . $tab['text'] . $tab['arrow'] . '</span></span>';
    $class = isset($tab['attributes']['class']) ? 'class="active"' : '';
    $link = l($text, $tab['path'], $tab);
    return "<li {$class} >" . str_replace('class="active"', $class, $link) . '</li>';
  }
  else {
    return $tab['pfx'] . l($tab['text'], $tab['path'], $tab) . $tab['arrow'] . $tab['sfx'];
  }
  return;
}
function _biblio_filter_info_line($args = array()) {
  $content = '';
  $filtercontent = '';
  $search_content = '';
  $base = variable_get('biblio_base', 'biblio');
  $session =& $_SESSION['biblio_filter'];

  // if there are any filters in place, print them at the top of the list
  $uri = drupal_parse_url(request_uri());
  $uri['path'] = variable_get('biblio_base', 'biblio');
  $filters = isset($uri['query']['f']) ? $uri['query']['f'] : (isset($args['f']) ? $args['f'] : array());
  if (count($filters)) {
    $i = 0;
    foreach ($filters as $type => $value) {
      if ($type == 'search') {
        $search_content = $value;
        continue;
      }
      if ($type == 'term_id') {
        $term = taxonomy_term_load($value);
        $value = $term->name;
        $type = t("Taxonomy term");
      }
      if ($type == 'keyword') {
        module_load_include('inc', 'biblio', 'includes/biblio.keywords');
        $type = t("Keyword");
        if (is_numeric($value)) {
          $term = biblio_get_keyword_by_id($value);
          if (isset($term->word)) {
            $value = $term->word;
          }
        }
        elseif (is_string($value) && strlen($value) == 1) {
          $type = t("First letter of keyword");
        }
      }
      if ($type == 'uid') {
        $user = user_load($value);
        $value = $user->name;
        $type = t("Drupal user");
      }
      if ($type == 'aid' || $type == 'author' && is_numeric($value)) {
        module_load_include('inc', 'biblio', 'includes/biblio.contributors');
        $author = biblio_get_contributor($value);
        $value = isset($author->name) ? $author->name : t('Unknown Author');
        $type = t("Author");
      }
      if ($type == 'ag') {

        //return;
        $type = t("First letter of last name");
      }
      if ($type == 'tg') {

        //return;
        $type = t("First letter of title");
      }
      if ($type == 'type' && $value > 0) {
        if ($pub_type = db_query('SELECT t.* FROM {biblio_types} as t WHERE t.tid=:tid', array(
          ':tid' => $value,
        ))
          ->fetchObject()) {
          $value = drupal_ucfirst(_biblio_localize_type($pub_type->tid, $pub_type->name));
          $type = t("Type");
        }
      }
      $params = array(
        '%a' => check_plain(ucwords($type)),
        '%b' => check_plain($value),
      );
      $filtercontent .= $i++ ? t('<em> and</em> <strong>%a</strong> is <strong>%b</strong>', $params) : t('<strong>%a</strong> is <strong>%b</strong>', $params);
    }
    if ($search_content) {
      $content .= '<div class="biblio-current-filters"><b>' . t('Search results for') . '</b>';
      $content .= '<em> ' . check_plain($search_content) . '</em>';
      if ($filtercontent) {
        $content .= '<br><b>' . t('Filters') . ': </b>';
      }
    }
    else {
      $content .= '<div class="biblio-current-filters"><b>' . t('Filters') . ': </b>';
    }
    $content .= $filtercontent;
    $link_options = array();
    if (isset($_GET['s'])) {
      $link_options['query']['s'] = $_GET['s'];
    }
    if (isset($_GET['o'])) {
      $link_options['query']['o'] = $_GET['o'];
    }
    unset($uri['query']['f']);
    if ($search_content) {
      $content .= '&nbsp;&nbsp;' . l('[' . t('Reset Search') . ']', "{$base}/filter/clear", $link_options);
    }
    else {
      $content .= '&nbsp;&nbsp;' . l('[' . t('Clear All Filters') . ']', "{$base}/filter/clear", $uri);
    }
    $content .= '</div>';
  }
  return $content;
}
function _biblio_category_separator_bar($node, $reset = FALSE) {
  $_text =& drupal_static(__FUNCTION__, '');
  if ($reset) {
    $_text =& drupal_static(__FUNCTION__, '', TRUE);
    return;
  }
  $content = '';
  if (isset($_GET['s'])) {
    $sort = $_GET['s'];
  }
  else {
    $sort = variable_get('biblio_sort', 'year');
  }
  switch ($sort) {
    case 'title':
      $title = $node->biblio_sort_title;
      $first = drupal_substr(drupal_ucfirst(ltrim($title)), 0, 1);
      if ($first != $_text) {
        if ($_text != '') {
          $content .= theme_biblio_end_category_section();
        }
        $_text = $first;
        $content .= theme_biblio_separator_bar($_text);
      }
      break;
    case 'author':
      if (isset($node->biblio_contributors[0]['lastname']) && drupal_substr(drupal_ucfirst(ltrim($node->biblio_contributors[0]['lastname'])), 0, 1) != $_text) {
        if ($_text != '') {
          $content .= theme_biblio_end_category_section();
        }
        $_text = drupal_substr(drupal_ucfirst(ltrim($node->biblio_contributors[0]['lastname'])), 0, 1);
        $content .= theme_biblio_separator_bar($_text);
      }
      break;
    case 'type':
      if ($node->biblio_type_name != $_text) {
        if ($_text != '') {
          $content .= theme_biblio_end_category_section();
        }
        $_text = $node->biblio_type_name;

        //      $name = db_result(db_query("SELECT name FROM {biblio_types} as t where t.tid=%d", $node->biblio_type)) ;
        $content .= theme_biblio_separator_bar(_biblio_localize_type($node->biblio_type, $_text));
      }
      break;
    case 'keyword':

      // added msh 08 aug 07
      // $kw = array_shift($node->biblio_keyword);
      $tok = $node->biblio_keyword;
      if (empty($tok)) {
        $tok = t("No Keywords");
      }
      if ($tok != $_text) {
        if ($_text != '') {
          $content .= theme_biblio_end_category_section();
        }
        $_text = $tok;
        if ($_text != '') {
          $content .= theme_biblio_separator_bar($_text);
        }
      }
      break;
    case 'year':
    default:
      if ($node->biblio_year != $_text) {
        if ($_text != '') {
          $content .= theme_biblio_end_category_section();
        }
        $_text = $node->biblio_year;
        $content .= theme_biblio_separator_bar($_text);
      }
  }

  //end switch
  return $content;
}
function biblio_category_section($biblio, $reset = FALSE) {
  $wrapper = biblio_wrapper($biblio);
  $_text =& drupal_static(__FUNCTION__, '');
  if ($reset) {
    $_text =& drupal_static(__FUNCTION__, '', TRUE);
    return;
  }
  $section = array();
  if (isset($_GET['s'])) {
    $sort = $_GET['s'];
  }
  else {
    $sort = variable_get('biblio_sort', 'year');
  }
  switch ($sort) {
    case 'title':
      $title = $wrapper->biblio_sort_title
        ->value();
      $first = drupal_substr(drupal_ucfirst(ltrim($title)), 0, 1);
      if ($first != $_text) {
        $_text = $first;
        $section['bar'] = biblio_section_bar($_text);
      }
      break;
    case 'author':
      if (isset($biblio->biblio_contributors[0]['lastname']) && drupal_substr(drupal_ucfirst(ltrim($biblio->biblio_contributors[0]['lastname'])), 0, 1) != $_text) {
        $_text = drupal_substr(drupal_ucfirst(ltrim($biblio->biblio_contributors[0]['lastname'])), 0, 1);
        $section['bar'] = biblio_section_bar($_text);
      }
      break;
    case 'type':
      if ($biblio->biblio_type_name != $_text) {
        $_text = $biblio->biblio_type_name;

        //      $name = db_result(db_query("SELECT name FROM {biblio_types} as t where t.tid=%d", $node->biblio_type)) ;
        $section['bar'] = biblio_section_bar(_biblio_localize_type($biblio->biblio_type, $_text));
      }
      break;
    case 'keyword':

      // added msh 08 aug 07
      // $kw = array_shift($node->biblio_keyword);
      $tok = $biblio->biblio_keyword;
      if (empty($tok)) {
        $tok = t("No Keywords");
      }
      if ($tok != $_text) {
        $_text = $tok;
        if ($_text != '') {
          $section['bar'] = biblio_section_bar($_text);
        }
      }
      break;
    case 'year':
    default:
      if ($wrapper->biblio_year
        ->value() != $_text) {
        $_text = $wrapper->biblio_year
          ->value();
        $section['bar'] = biblio_section_bar($_text);
      }
  }

  //end switch
  if (!empty($section)) {
    $section += array(
      '#prefix' => '<div class="biblio-category-section">',
      '#suffix' => '</div>',
    );
  }
  return $section;
}
function biblio_section_bar($text) {
  return array(
    '#prefix' => '<div class="biblio-separator-bar">',
    '#suffix' => '</div>',
    '#markup' => check_plain($text),
  );
}

/**
 * Add a search field on the main biblio page.
 */

/**
 * @param $form_state
 * @return unknown_type
 */
function biblio_search_form($form, &$form_state) {
  $base = variable_get('biblio_base', 'biblio');
  $searchform['biblio_search'] = array(
    '#prefix' => '<div class="container-inline biblio-search clear-block">',
    '#suffix' => '</div>',
  );
  $searchform['biblio_search']['keys'] = array(
    '#type' => 'textfield',
    '#title' => '',
    '#default_value' => '',
    '#size' => 25,
    '#maxlength' => 255,
  );
  $button_text = variable_get('biblio_search_button_text', 'Biblio search');
  $searchform['biblio_search']['submit'] = array(
    '#type' => 'submit',
    '#value' => t($button_text),
  );
  $form['search_form'] = array(
    '#type' => 'fieldset',
    '#title' => t('Search'),
    '#collapsible' => TRUE,
    '#collapsed' => TRUE,
    'searchform' => $searchform,
    'filterform' => biblio_form_filter(),
  );
  return $form;
}
function biblio_search_form_submit($form, &$form_state) {
  static $keys = '';
  $base = variable_get('biblio_base', 'biblio');
  $keys = trim($form_state['values']['keys']);
  if (!empty($keys)) {
    $uri = drupal_parse_url(request_uri());
    $uri['path'] = variable_get('biblio_base', 'biblio');
    $uri['query']['f']['search'] = $keys;
    $form_state['redirect'] = array(
      $uri['path'],
      $uri,
    );
  }
}
function biblio_search_query($keys) {
  if (!empty($keys)) {
    $query = db_select('search_index', 'i', array(
      'target' => 'slave',
    ))
      ->extend('SearchQuery');

    // ->extend('PagerDefault');
    $query
      ->join('node', 'n', 'n.nid = i.sid');
    $query
      ->condition('n.status', 1)
      ->addTag('node_access')
      ->searchExpression($keys, 'node');

    // Insert special keywords.
    $query
      ->setOption('type', 'n.type');
    $query
      ->setOption('language', 'n.language');
    if ($query
      ->setOption('term', 'ti.tid')) {
      $query
        ->join('taxonomy_index', 'ti', 'n.nid = ti.nid');
    }

    // Only continue if the first pass query matches.
    if (!$query
      ->executeFirstPass()) {
      return array();
    }

    // Add the ranking expressions.
    _node_rankings($query);

    // Load results.
    $find = $query
      ->execute();
    $nids = array();
    foreach ($find as $item) {
      $nids[] = $item->sid;
    }
    return $nids;
  }
}

/**
 * @param $arg
 * @return unknown_type
 */
function _get_biblio_search_filter($arg = 'keys') {
  if (variable_get('biblio_search', 0) && !empty($_SESSION['biblio_filter']) && is_array($_SESSION['biblio_filter']) && is_array($_SESSION['biblio_filter'][0]) && in_array('search', $_SESSION['biblio_filter'][0])) {
    switch ($arg) {
      case 'keys':
        return $_SESSION['biblio_filter'][0][2];
        break;
      case 'nodelist':
        return $_SESSION['biblio_filter'][0][1];
        break;
    }
  }
}
function _get_biblio_filters() {
  $fields = " b.biblio_year, t.name , t.tid ";
  $order = " b.biblio_year DESC";
  $taxo_fields = "td.name as termname, td.tid as taxid, v.name as vocab_name";
  $taxo_order = "vocab_name ASC, termname ASC";
  $table = "{node} as n  inner join {biblio} as b on n.vid=b.vid ";
  $join = "left join {biblio_types} as t on b.biblio_type = t.tid";
  $taxo_join = array(
    "inner join {taxonomy_index} as ti on n.nid = ti.nid",
    "left join  {taxonomy_term_data} as td on ti.tid = td.tid",
    "left join  {taxonomy_vocabulary} as v on v.vid = td.vid",
  );
  $taxo_joins = implode(' ', $taxo_join);
  $result = db_query("SELECT {$fields} FROM {$table} {$join} ORDER BY {$order}");
  $authors = db_query("SELECT DISTINCT firstname, initials, lastname, bcd.cid\n                       FROM {biblio_contributor_data} as bcd\n                       INNER JOIN {biblio_contributor} as bc on bc.cid = bcd.cid\n                       ORDER BY lastname ASC");
  $keywords = db_query("SELECT word, kid FROM {biblio_keyword_data} ORDER BY word ASC");
  $taxoresult = db_query("SELECT {$taxo_fields} FROM {$table} {$taxo_joins} ORDER BY {$taxo_order}");
  $pub_years['any'] = t('any');
  $pub_type['any'] = t('any');
  $pub_authors['any'] = t('any');
  $pub_keywords['any'] = t('any');
  $pub_taxo['any'] = t('any');
  foreach ($result as $option) {
    if (isset($option->biblio_year)) {
      $option->biblio_year = _biblio_text_year($option->biblio_year);
    }
    $pub_years[$option->biblio_year] = $option->biblio_year;
    $pub_type[$option->tid] = _biblio_localize_type($option->tid, $option->name);
  }
  foreach ($authors as $auth) {
    $pub_authors[$auth->cid] = $auth->lastname . (!empty($auth->firstname) || !empty($auth->initials) ? ', ' . $auth->firstname . ' ' . $auth->initials : '');
  }
  foreach ($keywords as $keyword) {
    $pub_keywords[$keyword->kid] = $keyword->word;
  }
  foreach ($taxoresult as $tax) {
    $pub_taxo["{$tax->taxid}"] = "{$tax->vocab_name} - {$tax->termname}";
  }
  $author_select = isset($pub_authors) ? array(
    'title' => t('Author'),
    'options' => $pub_authors,
  ) : NULL;
  $years_select = isset($pub_years) ? array(
    'title' => t('Year'),
    'options' => array_unique($pub_years),
  ) : NULL;
  $type_select = isset($pub_type) ? array(
    'title' => t('Type'),
    'options' => array_unique($pub_type),
  ) : NULL;
  $tax_select = isset($pub_taxo) ? array(
    'title' => t('Term'),
    'options' => array_unique($pub_taxo),
  ) : NULL;
  $keyword_select = isset($pub_keywords) ? array(
    'title' => t('Keyword'),
    'options' => $pub_keywords,
  ) : NULL;
  $filters = array(
    'author' => $author_select,
    'type' => $type_select,
    'term_id' => $tax_select,
    'year' => $years_select,
    'keyword' => $keyword_select,
  );
  return $filters;
}

/**
 * @return unknown_type
 */
function biblio_form_filter() {
  $session = $_SESSION['biblio_filter'];
  $session = is_array($session) ? $session : array();
  $filters = _get_biblio_filters();
  $i = 0;
  $form['filters'] = array(
    '#type' => 'fieldset',
    '#title' => t('Show only items where'),
    '#theme' => 'exposed_filters__node',
    '#collapsible' => TRUE,
    '#collapsed' => TRUE,
  );
  foreach ($session as $filter) {
    $type = key($filter);
    $value = $filter[$type];

    // list($type, $value) = $filter;
    if ($type == 'search') {
      $session = array();
      break;
    }
    if ($type == 'category') {

      // Load term name from DB rather than search and parse options array.
      $value = module_invoke('taxonomy', 'get_term', $value);
      $value = $value->name;
    }
    else {
      $value = $filters[$type]['options'][$value];
    }
    $t_args = array(
      '%property' => $filters[$type]['title'],
      '%value' => $value,
    );
    if ($i++) {
      $form['filters']['current'][] = array(
        '#markup' => t('and where %property is %value', $t_args),
      );
    }
    else {
      $form['filters']['current'][] = array(
        '#markup' => t('where %property is %value', $t_args),
      );
    }
    if (in_array($type, array(
      'type',
      'language',
    ))) {

      // Remove the option if it is already being filtered on.
      unset($filters[$type]);
    }
  }
  $form['filters']['status'] = array(
    '#type' => 'container',
    '#attributes' => array(
      'class' => array(
        'clearfix',
      ),
    ),
    '#prefix' => $i ? '<div class="additional-filters">' . t('and where') . '</div>' : '',
  );
  $form['filters']['status']['filters'] = array(
    '#type' => 'container',
    '#attributes' => array(
      'class' => array(
        'filters',
      ),
    ),
  );
  foreach ($filters as $key => $filter) {
    $form['filters']['status']['filters'][$key] = array(
      '#type' => 'select',
      '#options' => $filter['options'],
      '#title' => $filter['title'],
      '#default_value' => 'any',
    );
  }
  $form['filters']['status']['actions'] = array(
    '#type' => 'actions',
    '#attributes' => array(
      'class' => array(
        'container-inline',
      ),
    ),
  );
  $form['filters']['status']['actions']['submit'] = array(
    '#type' => 'submit',
    '#value' => count($session) ? t('Refine') : t('Filter'),
    '#submit' => array(
      'biblio_form_filter_submit',
    ),
  );
  if (count($session)) {
    $form['filters']['status']['actions']['undo'] = array(
      '#type' => 'submit',
      '#value' => t('Undo'),
      '#submit' => array(
        'biblio_form_filter_submit',
      ),
    );
    $form['filters']['status']['actions']['reset'] = array(
      '#type' => 'submit',
      '#value' => t('Reset'),
      '#submit' => array(
        'biblio_form_filter_submit',
      ),
    );
  }
  return $form;
}

/**
 * @param $form
 * @param $form_state
 * @return unknown_type
 */
function biblio_form_filter_submit($form, &$form_state) {

  // If the search filter was set, remove it now.
  if (_get_biblio_search_filter()) {
    $_SESSION['biblio_filter'] = array();
  }
  $op = $form_state['values']['op'];
  $filters = _get_biblio_filters();
  switch ($op) {
    case t('Filter'):
    case t('Refine'):
      $uri = drupal_parse_url(request_uri());
      $uri['path'] = variable_get('biblio_base', 'biblio');
      foreach ($filters as $filter => $options) {
        if (isset($form_state['values'][$filter]) && $form_state['values'][$filter] != 'any') {

          // Flatten the options array to accommodate hierarchical/nested options.
          $flat_options = form_options_flatten($filters[$filter]['options']);

          // Only accept valid selections offered on the dropdown, block bad input.
          if (isset($flat_options[$form_state['values'][$filter]])) {
            $_SESSION['biblio_filter'][] = array(
              $filter => $form_state['values'][$filter],
            );
            $uri['query']['f'][$filter] = $form_state['values'][$filter];
          }
        }
      }
      $form_state['redirect'] = array(
        $uri['path'],
        $uri,
      );
      break;
    case t('Undo'):
      array_pop($_SESSION['biblio_filter']);
      break;
    case t('Reset'):
      $_SESSION['biblio_filter'] = array();
      break;
  }
}

/**
 * @return unknown_type
 */
function biblio_citekey_view() {
  $citekey = arg(2);
  $nid = db_query("SELECT nid FROM {biblio} WHERE biblio_citekey = :citekey ORDER BY vid DESC", array(
    ':citekey' => $citekey,
  ))
    ->fetchObject();
  if ($nid->nid > 0) {
    $node = node_load($nid->nid);
    return node_page_view($node);
  }
  else {
    return t("Sorry, citekey @cite not found", array(
      '@cite' => $citekey,
    ));
  }
}
function biblio_author_page() {
  $path = drupal_get_path('module', 'biblio');
  drupal_add_js($path . '/misc/biblio.highlight.js', 'file');
  $uri = drupal_parse_url(request_uri());
  $filter = isset($uri['query']['f']['author']) ? $uri['query']['f']['author'] : '';
  $authors = _biblio_get_authors($filter);
  return _biblio_format_author_page($uri['path'], $filter, $authors);
}
function _biblio_get_authors($filter = NULL) {
  global $user;
  $where = array();
  $authors = array();
  $where_clause = '';
  $output = '';
  if ($filter) {
    $filter = strtoupper($filter);
    $where['filter'] = "UPPER(SUBSTRING(lastname,1,1)) = :filter ";
    $header_ext = t(' (whose last name starts with the letter "@letter") ', array(
      '@letter' => $filter,
    ));
  }
  else {
    $query_ext = NULL;
    $header_ext = NULL;
  }
  if (!biblio_access('edit_author')) {

    // $where['access'] = 'n.status = 1 ';
  }

  //show only published entries to everyone except admin
  if (count($where)) {
    $where_clause = 'WHERE (' . implode(') AND (', $where) . ')';
  }
  $suspects = array();
  $query = db_select('biblio_contributor_data', 'bcd')
    ->fields('bcd', array(
    'lastname',
  ))
    ->groupBy('lastname')
    ->having('COUNT(*) > 1');
  if ($filter) {
    $filter = strtoupper($filter);
    $query
      ->where("UPPER(SUBSTRING(lastname,1,1)) = :filter ", array(
      ':filter' => $filter,
    ));
  }
  $result = $query
    ->execute();
  foreach ($result as $author) {
    $suspects[] = $author->lastname;
  }

  //  $db_result = db_query('SELECT bd.cid, bd.drupal_uid, bd.name, bd.lastname,
  //                                bd.firstname, bd.prefix, bd.suffix,
  //                                bd.initials, bd.affiliation, bd.md5, bd.literal,
  //                                COUNT(*) AS cnt
  //                            FROM {biblio_contributor} b
  //                                 LEFT JOIN {biblio_contributor_data} bd ON b.cid = bd.cid
  //                                 INNER JOIN {node} n on n.vid = b.vid
  //                            ' . $where_clause . '
  //                            GROUP BY bd.cid, bd.drupal_uid, bd.name, bd.lastname,
  //                                     bd.firstname, bd.prefix, bd.suffix,
  //                                     bd.initials, bd.affiliation, bd.md5, bd.literal
  //                            ORDER BY  lastname ASC, SUBSTRING(firstname,1,1) ASC,
  //                            initials ASC', array(':filter' => $filter));
  // Placeholder so page loads without errors
  $db_result = db_query('SELECT * from biblio_contributor');
  foreach ($db_result as $author) {
    if (array_search($author->lastname, $suspects) !== FALSE) {
      $author->suspect = TRUE;
    }
    $authors[] = $author;
  }
  return $authors;
}
function _biblio_format_author_page($path, $filter, $authors) {
  $header_ext = $checkbox = '';
  $header = array();
  if (biblio_access('edit_author')) {
    if (!empty($filter)) {
      $header_ext = ' ' . t('whose last name begins with the letter') . ': ' . $filter;
    }
    $checkbox = array(
      '#title' => t('Hightlight possible duplicates'),
      '#type' => 'checkbox',
      '#id' => 'biblio-highlight',
    );
    $checkbox = '<div class="biblio-alpha-line">' . drupal_render($checkbox) . '</div>';
    $header = array(
      array(
        'data' => t('There are a total of @count authors in the database!header_ext.', array(
          '@count' => count($authors),
          '!header_ext' => $header_ext,
        )),
        'align' => 'center',
        'colspan' => 3,
      ),
    );
  }
  $rows[] = array(
    array(
      'data' => theme('biblio_alpha_line', array(
        'type' => 'authors',
        'current' => $filter,
        'path' => $path,
      )) . $checkbox,
      'colspan' => 3,
    ),
  );
  if (count($authors)) {
    for ($i = 0; $i < count($authors); $i += 3) {
      $rows[] = array(
        array(
          'data' => _biblio_format_author($authors[$i]),
        ),
        array(
          'data' => isset($authors[$i + 1]) ? _biblio_format_author($authors[$i + 1]) : '',
        ),
        array(
          'data' => isset($authors[$i + 2]) ? _biblio_format_author($authors[$i + 2]) : '',
        ),
      );
    }
  }
  return array(
    '#theme' => 'table',
    '#header' => $header,
    '#rows' => $rows,
  );
}

/*
 * Helper function to format the authors and add edit links if required
 */
function _biblio_format_author($author) {
  if ($author->literal) {
    $name = $author->name;
  }
  else {
    $name = $author->lastname;
    $name .= !empty($author->firstname) ? ', ' . drupal_substr($author->firstname, 0, 1) . '.' : (!empty($author->initials) ? ', ' . $author->initials : '');
  }
  $uri['path'] = variable_get('biblio_base', 'biblio');
  $uri['query']['f']['author'] = $author->cid;
  $uri['attributes'] = array();
  if (isset($author->drupal_uid) && $author->drupal_uid > 0) {
    $uri['attributes'] += array(
      'class' => array(
        'biblio-local-author',
      ),
    );
  }
  if (variable_get('biblio_links_target_new_window', null)) {
    $uri['attributes'] += array(
      'target' => '_blank',
    );
    $uri['html'] = TRUE;
  }
  $name = l(trim($name), $uri['path'], $uri);

  // $format = biblio_format_authors(array($author));
  $name .= ' (' . $author->cnt . ') ' . (biblio_access('edit_author') ? _biblio_author_edit_links($author) : '');
  if (biblio_access('edit_author') && isset($author->suspect)) {
    $name = '<div class="suspect">' . $name . '</div>';
  }
  return $name;
}
function _biblio_author_edit_links($author) {
  static $path = '';
  $destination = drupal_get_destination();
  if (empty($path)) {
    $path = ord(substr($_GET['q'], -1)) > 97 ? $_GET['q'] . "/" : substr($_GET['q'], 0, -1);
    $path = strpos($path, 'list/') ? str_replace('list/', '', $path) : $path;
  }
  return l(' [' . t('edit') . ']', $path . $author->cid . "/edit", array(
    'query' => $destination,
  ));
}
function biblio_keyword_page() {
  $uri = drupal_parse_url(request_uri());

  //  $uri['path'] = variable_get('biblio_base', 'biblio');
  $filter = isset($uri['query']['f']['keyword']) ? $uri['query']['f']['keyword'] : '';
  $keywords = _biblio_get_keywords($filter);
  return _biblio_format_keyword_page($uri, $filter, $keywords);
}
function _biblio_get_keywords($filter = NULL) {
  global $user;
  $keywords = array();
  $where = array();
  $where_clause = '';
  if ($filter) {
    $filter = strtoupper($filter);
    $where[] = "UPPER(SUBSTRING(word,1,1)) = :filter ";
    $header_ext = t(' (which start with the letter "@letter") ', array(
      '@letter' => $filter,
    ));
  }
  else {
    $query_ext = NULL;
    $header_ext = NULL;
  }
  if ($user->uid != 1) {
    $where[] = 'n.status = 1 ';
  }

  //show only published entries to everyone except admin
  if (count($where)) {
    $where_clause = count($where) > 1 ? 'WHERE (' . implode(') AND (', $where) . ')' : 'WHERE ' . $where[0];
  }
  $db_result = db_query('SELECT bkd.kid, bkd.word, COUNT(*) AS cnt
                         FROM {biblio_keyword} bk
                         LEFT JOIN {biblio_keyword_data} bkd ON bkd.kid = bk.kid
                         INNER JOIN {node} n ON n.vid = bk.vid
                         ' . $where_clause . '
                         GROUP BY bkd.kid, bkd.word
                         ORDER BY  word ASC', array(
    ':filter' => $filter,
  ));
  foreach ($db_result as $keyword) {
    $keywords[] = $keyword;
  }
  return $keywords;
}
function _biblio_format_keyword_page($uri, $filter, $keywords) {
  $rows[] = array(
    array(
      'data' => theme('biblio_alpha_line', array(
        'type' => 'keywords',
        'current' => $filter,
        'path' => $uri['path'],
      )),
      'colspan' => 3,
    ),
  );
  for ($i = 0; $i < count($keywords); $i += 3) {
    $rows[] = array(
      array(
        'data' => _biblio_format_keyword($uri, $keywords[$i]),
      ),
      array(
        'data' => isset($keywords[$i + 1]) ? _biblio_format_keyword($uri, $keywords[$i + 1]) : '',
      ),
      array(
        'data' => isset($keywords[$i + 2]) ? _biblio_format_keyword($uri, $keywords[$i + 2]) : '',
      ),
    );
  }

  //$header = array(array('data' => t('There are a total of @count keywords !header_ext in the database',array('@count' => count($keywords), '!header_ext' => $header_ext)), 'align' =>'center', 'colspan' => 3));
  $output = theme('table', array(
    'rows' => $rows,
  ));
  return $output;
}
function _biblio_format_keyword($uri, $keyword) {
  $base = variable_get('biblio_base', 'biblio');
  $uri['path'] = $base;
  $uri['query']['f']['keyword'] = $keyword->kid;
  $format = l(trim($keyword->word), $base, $uri);
  $format .= ' (' . $keyword->cnt . ') ';
  $destination = drupal_get_destination();
  $path = ord(substr($_GET['q'], -1)) > 97 ? $_GET['q'] . "/" : substr($_GET['q'], 0, -1);
  $edit_link = ' [' . l(t('edit'), $path . $keyword->kid . "/edit", array(
    'query' => $destination,
  )) . '] ';
  $format .= user_access('administer biblio') ? $edit_link : '';
  return $format;
}