/lib/biblio_list_sphinx.inc.php
PHP | 328 lines | 224 code | 24 blank | 80 comment | 45 complexity | 95024abd54446122251f77663b11d2e8 MD5 | raw file
- <?php
- /**
- * biblio_list class
- * Class for generating list of bibliographic records from SPHINX index
- *
- * Copyright (C) 2010 Arie Nugraha (dicarve@yahoo.com)
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- */
- // be sure that this file not accessed directly
- if (!defined('INDEX_AUTH')) {
- die("can not access this file directly");
- } elseif (INDEX_AUTH != 1) {
- die("can not access this file directly");
- }
- class biblio_list extends biblio_list_model
- {
- protected $options = array('host' => '127.0.0.1', 'port' => 9312, 'index' => 'slims',
- 'mode' => null, 'timeout' => 0, 'filter' => '@last_update desc',
- 'filtervals' => array(), 'groupby' => null, 'groupsort' => null,
- 'sortby' => null, 'sortexpr' => null, 'distinct' => 'biblio_id',
- 'select' => null, 'limit' => 20, 'max_limit' => 500000,
- 'ranker' => null);
- protected $offset = 0;
- private $sphinx = null;
- private $sphinx_error = false;
- private $no_query = false;
- private $sphinx_no_result = false;
- /**
- * Class Constructor
- *
- * @param object $obj_db
- * @param integer $int_num_show
- */
- public function __construct($obj_db, $int_num_show)
- {
- parent::__construct($obj_db, $int_num_show);
- if (!class_exists('SphinxClient')) {
- throw new Exception('SPHINX API Library is not installed yet!');
- } else {
- $this->sphinx = new SphinxClient();
- // check searchd status
- $_sphinx_status = $this->sphinx->Status();
- if (!$_sphinx_status) {
- throw new Exception('SPHINX Server is not running! Please
- check if it already configured correctly.');
- }
- // defaults
- $this->options['mode'] = SPH_MATCH_EXTENDED2;
- $this->options['ranker'] = SPH_RANK_PROXIMITY_BM25;
- // get page number from http get var
- if (!isset($_GET['page']) OR $_GET['page'] < 1){ $_page = 1; } else {
- $_page = (integer)$_GET['page'];
- }
- $this->current_page = $_page;
- // count the row offset
- if ($this->current_page <= 1) { $_offset = 0; } else {
- $this->offset = ($this->current_page*$this->num2show) - $this->num2show;
- }
- }
- }
- /**
- * Compile SQL
- *
- * @return string
- */
- public function compileSQL()
- {
- $_sql_str = 'SELECT SQL_CALC_FOUND_ROWS index.biblio_id, index.title,
- index.author, index.image, index.isbn_issn, index.labels
- FROM search_biblio AS `index`';
- if (isset($this->criteria['sql_criteria'])) {
- $_sql_str .= ' WHERE '.$this->criteria['sql_criteria'];
- } else if ($this->sphinx_no_result) {
- $_sql_str .= " WHERE index.biblio_id<0";
- } else {
- $this->no_query = true;
- $_sql_str .= " WHERE index.biblio_id IS NOT NULL";
- }
- // ordering
- $_sql_str .= ' ORDER BY index.last_update DESC ';
- // set limit when query is empty
- if (!isset($this->criteria['sql_criteria']) || $this->no_query) {
- $_sql_str .= ' LIMIT '.$this->offset.','.$this->num2show;
- }
- return $_sql_str;
- }
- /**
- * Method to print out document records
- *
- * @param object $obj_db
- * @param integer $int_num2show
- * @param boolean $bool_return_output
- * @return string
- */
- public function getDocumentList($bool_return_output = true)
- {
- global $sysconf;
- if ($this->sphinx_error) {
- $this->resultset = false;
- } else {
- $_sql_str = $this->compileSQL();
- if ($this->no_query) {
- // start time
- $_start = function_exists('microtime')?microtime(true):time();
- // execute query
- $this->resultset = $this->obj_db->query($_sql_str);
- if ($this->obj_db->error) {
- $this->query_error = $this->obj_db->error;
- }
- // get total number of rows from query
- $_total_q = $this->obj_db->query('SELECT FOUND_ROWS()');
- $_total_d = $_total_q->fetch_row();
- $this->num_rows = $_total_d[0];
- // end time
- $_end = function_exists('microtime')?microtime(true):time();
- $this->query_time = round($_end-$_start, 5);
- } else {
- $this->resultset = $this->obj_db->query($_sql_str);
- }
- if ($this->obj_db->error) {
- $this->query_error = $this->obj_db->error;
- }
- }
- if ($bool_return_output) {
- // return the html result
- return $this->makeOutput();
- }
- }
- /**
- * Set sphinx search option
- *
- * @param array $arr_options
- * @return void
- */
- public function setOptions($arr_options)
- {
- $this->options = $arr_options;
- }
- /**
- * Method to set search criteria
- *
- * @param string $str_criteria
- * @return void
- */
- public function setSQLcriteria($str_criteria)
- {
- if (!$str_criteria)
- return null;
- // defaults
- $_query_str = '';
- $_searched_fields = array();
- $_previous_field = '';
- $_boolean = '';
- // parse query
- $this->orig_query = $str_criteria;
- $_queries = simbio_tokenizeCQL($str_criteria, $this->searchable_fields, $this->stop_words, $this->queries_word_num_allowed);
- // var_dump($_queries);
- if (count($_queries) < 1) {
- return null;
- }
- // loop each query
- // echo '<pre>'; var_dump($_queries); echo '</pre>';
- foreach ($_queries as $_num => $_query) {
- // field
- $_field = $_query['f'];
- // break the loop if we meet `cql_end` field
- if ($_field == 'cql_end') { break; }
- // if field is boolean
- if ($_field == 'boolean') {
- if ($_query['b'] == '*') { $_query_str .= ' | '; } else { $_query_str .= ' & '; }
- continue;
- } else {
- if ($_query['b'] == '*') { $_b = ''; } else { $_b = $_query['b']; }
- $_q = @$this->obj_db->escape_string($_query['q']);
- $_q = isset($_query['is_phrase'])?'"'.$_q.'"':$_q;
- $_boolean = '';
- }
- // for debugging purpose only
- // echo "<p>$_num. $_field -> $_boolean -> $_query_str</p><p> </p>";
- // check fields
- switch ($_field) {
- case 'author' :
- $_q = $_b.$_q;
- $_query_str .= " @author $_q";
- break;
- case 'subject' :
- $_q = $_b.$_q;
- $_query_str .= " @topic $_q";
- break;
- case 'location' :
- $_q = $_b.$_q;
- $_query_str .= " @location $_q";
- break;
- case 'colltype' :
- $_q = $_b.$_q;
- $_query_str .= " @collection_types $_q";
- break;
- case 'itemcode' :
- $_q = $_b.$_q;
- $_query_str .= " @items $_q";
- break;
- case 'callnumber' :
- $_q = $_b.$_q;
- $_query_str .= " @call_number $_q";
- break;
- case 'itemcallnumber' :
- $_q = $_b.$_q;
- $_query_str .= " @item_call_number $_q";
- break;
- case 'class' :
- $_q = $_b.$_q;
- $_query_str .= " @classification $_q";
- break;
- case 'isbn' :
- $_q = $_b.$_q;
- $_query_str .= " @isbn_issn $_q";
- break;
- case 'publisher' :
- $_q = $_b.$_q;
- $_query_str .= " @publisher $_q";
- break;
- case 'publishyear' :
- $_q = $_b.$_q;
- $_query_str .= " @publish_year $_q";
- break;
- case 'gmd' :
- $_q = $_b.$_q;
- $_query_str .= " @gmd $_q";
- break;
- case 'notes' :
- $_q = $_b.$_q;
- $_query_str .= " @notes $_q";
- break;
- default :
- $_q = $_b.$_q;
- $_query_str .= " @(title,series) $_q";
- break;
- }
- }
- // check if query is empty
- if (!$_query_str) {
- $this->no_query = true;
- $_sql_criteria = 'index.biblio_id IS NOT NULL';
- $this->criteria = array('sql_criteria' => $_sql_criteria, 'searched_fields' => $_searched_fields);
- return $this->criteria;
- }
- // set options
- $this->sphinx->SetServer ( $this->options['host'], $this->options['port'] );
- $this->sphinx->SetConnectTimeout ( $this->options['timeout'] );
- $this->sphinx->SetArrayResult ( true );
- $this->sphinx->SetWeights ( array ( 100, 1 ) );
- $this->sphinx->SetMatchMode ( $this->options['mode'] );
- if (count($this->options['filtervals'])) { $this->sphinx->SetFilter ( $this->options['filter'], $this->options['filtervals'] ); }
- if ($this->options['groupby']) { $this->sphinx->SetGroupBy ( $this->options['groupby'], SPH_GROUPBY_ATTR, $this->options['groupsort'] ); }
- if ($this->options['sortby']) {
- $this->sphinx->SetSortMode ( SPH_SORT_EXTENDED, $this->options['sortby'] );
- $this->sphinx->SetSortMode ( SPH_SORT_EXPR, $this->options['sortexpr'] );
- }
- $this->sphinx->SetGroupDistinct ( $this->options['distinct'] );
- if ($this->options['select']) { $this->sphinx->SetSelect ( $this->options['select'] ); }
- $this->sphinx->SetLimits ( $this->offset, $this->num2show?$this->num2show:$this->options['limit'], $this->options['max_limit'] );
- $this->sphinx->SetRankingMode ( $this->options['ranker'] );
- // invoke sphinx query
- $_search_result = $this->sphinx->Query($_query_str, $this->options['index']);
- // echo '<pre>'; var_dump($_search_result); echo '</pre>'; die();
- if ($_search_result === false) {
- $this->sphinx_error = true;
- $this->query_error = $this->sphinx->GetLastError();
- return false;
- }
- if (isset($_search_result['matches']) && is_array($_search_result['matches'])) {
- $_matched_ids = '(';
- foreach ($_search_result['matches'] as $_match) {
- $_matched_ids .= $_match['id'].',';
- }
- // remove last comma
- $_matched_ids = substr_replace($_matched_ids, '', -1);
- $_matched_ids .= ')';
- $_sql_criteria = "index.biblio_id IN $_matched_ids";
- $this->num_rows = $_search_result['total_found'];
- $this->query_time = $_search_result['time'];
- $this->criteria = array('sql_criteria' => $_sql_criteria, 'searched_fields' => $_searched_fields);
- return $this->criteria;
- } else {
- $this->sphinx_no_result = true;
- return false;
- }
- }
- }
- ?>