|
|
|
@ -1,12 +1,9 @@ |
|
|
|
|
<?php |
|
|
|
|
|
|
|
|
|
/* For licensing terms, see /license.txt */ |
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
* @package chamilo.include.search |
|
|
|
|
*/ |
|
|
|
|
/** |
|
|
|
|
* Code |
|
|
|
|
*/ |
|
|
|
|
|
|
|
|
|
require_once 'xapian.php'; |
|
|
|
|
require_once dirname(__FILE__) . '/../IndexableChunk.class.php'; |
|
|
|
@ -15,7 +12,8 @@ require_once dirname(__FILE__) . '/../IndexableChunk.class.php'; |
|
|
|
|
* Abstract helper class |
|
|
|
|
* @package chamilo.include.search |
|
|
|
|
*/ |
|
|
|
|
abstract class XapianIndexer { |
|
|
|
|
abstract class XapianIndexer |
|
|
|
|
{ |
|
|
|
|
/* XapianWritableDatabase */ |
|
|
|
|
|
|
|
|
|
protected $db; |
|
|
|
@ -26,6 +24,15 @@ abstract class XapianIndexer { |
|
|
|
|
/* XapianStem */ |
|
|
|
|
public $stemmer; |
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
* Class contructor |
|
|
|
|
*/ |
|
|
|
|
function __construct() |
|
|
|
|
{ |
|
|
|
|
$this->db = null; |
|
|
|
|
$this->stemmer = null; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
* Generates a list of languages Xapian manages |
|
|
|
|
* |
|
|
|
@ -33,7 +40,8 @@ abstract class XapianIndexer { |
|
|
|
|
* Chamilo languages and Xapian languages (through hardcoding) |
|
|
|
|
* @return array Array of languages codes -> Xapian languages |
|
|
|
|
*/ |
|
|
|
|
public final function xapian_languages() { |
|
|
|
|
public final function xapian_languages() |
|
|
|
|
{ |
|
|
|
|
/* http://xapian.org/docs/apidoc/html/classXapian_1_1Stem.html */ |
|
|
|
|
return array( |
|
|
|
|
'none' => 'none', //don't stem terms |
|
|
|
@ -60,14 +68,15 @@ abstract class XapianIndexer { |
|
|
|
|
/** |
|
|
|
|
* Connect to the database, and create it if it doesn't exist |
|
|
|
|
*/ |
|
|
|
|
function connectDb($path = NULL, $dbMode = NULL, $lang = 'english') { |
|
|
|
|
if ($this->db != NULL) |
|
|
|
|
function connectDb($path = null, $dbMode = null, $lang = 'english') |
|
|
|
|
{ |
|
|
|
|
if ($this->db != null) |
|
|
|
|
return $this->db; |
|
|
|
|
if ($dbMode == NULL) |
|
|
|
|
if ($dbMode == null) |
|
|
|
|
$dbMode = Xapian::DB_CREATE_OR_OPEN; |
|
|
|
|
|
|
|
|
|
if ($path == NULL) |
|
|
|
|
$path = api_get_path(SYS_PATH) . 'searchdb/'; |
|
|
|
|
if ($path == null) |
|
|
|
|
$path = api_get_path(SYS_UPLOAD_PATH).'plugins/xapian/searchdb/'; |
|
|
|
|
|
|
|
|
|
try { |
|
|
|
|
$this->db = new XapianWritableDatabase($path, $dbMode); |
|
|
|
@ -82,6 +91,7 @@ abstract class XapianIndexer { |
|
|
|
|
return $this->db; |
|
|
|
|
} catch (Exception $e) { |
|
|
|
|
Display::display_error_message($e->getMessage()); |
|
|
|
|
|
|
|
|
|
return 1; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
@ -90,7 +100,8 @@ abstract class XapianIndexer { |
|
|
|
|
* Simple getter for the db attribute |
|
|
|
|
* @return object The db attribute |
|
|
|
|
*/ |
|
|
|
|
function getDb() { |
|
|
|
|
function getDb() |
|
|
|
|
{ |
|
|
|
|
return $this->db; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
@ -99,16 +110,18 @@ abstract class XapianIndexer { |
|
|
|
|
* @param string Chunk of text |
|
|
|
|
* @return void |
|
|
|
|
*/ |
|
|
|
|
function addChunk($chunk) { |
|
|
|
|
function addChunk($chunk) |
|
|
|
|
{ |
|
|
|
|
$this->chunks[] = $chunk; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
* Actually index the current data |
|
|
|
|
* |
|
|
|
|
* @return integer New Xapian document ID or NULL upon failure |
|
|
|
|
* @return integer New Xapian document ID or null upon failure |
|
|
|
|
*/ |
|
|
|
|
function index() { |
|
|
|
|
function index() |
|
|
|
|
{ |
|
|
|
|
try { |
|
|
|
|
if (!empty($this->chunks)) { |
|
|
|
|
foreach ($this->chunks as $chunk) { |
|
|
|
@ -148,8 +161,9 @@ abstract class XapianIndexer { |
|
|
|
|
* @param int did Xapian::docid |
|
|
|
|
* @return mixed XapianDocument, or false on error |
|
|
|
|
*/ |
|
|
|
|
function get_document($did) { |
|
|
|
|
if ($this->db == NULL) { |
|
|
|
|
function get_document($did) |
|
|
|
|
{ |
|
|
|
|
if ($this->db == null) { |
|
|
|
|
$this->connectDb(); |
|
|
|
|
} |
|
|
|
|
try { |
|
|
|
@ -167,8 +181,9 @@ abstract class XapianIndexer { |
|
|
|
|
* @param XapianDocument $doc xapian document to push into the db |
|
|
|
|
* @return mixed xapian document data or FALSE if error |
|
|
|
|
*/ |
|
|
|
|
function get_document_data($doc) { |
|
|
|
|
if ($this->db == NULL) { |
|
|
|
|
function get_document_data($doc) |
|
|
|
|
{ |
|
|
|
|
if ($this->db == null) { |
|
|
|
|
$this->connectDb(); |
|
|
|
|
} |
|
|
|
|
try { |
|
|
|
@ -191,7 +206,8 @@ abstract class XapianIndexer { |
|
|
|
|
* @param string $prefix Prefix used to categorize the doc (usually 'T' for title, 'A' for author) |
|
|
|
|
* @return boolean false on error |
|
|
|
|
*/ |
|
|
|
|
function update_terms($did, $terms, $prefix) { |
|
|
|
|
function update_terms($did, $terms, $prefix) |
|
|
|
|
{ |
|
|
|
|
$doc = $this->get_document($did); |
|
|
|
|
if ($doc === false) { |
|
|
|
|
return false; |
|
|
|
@ -203,6 +219,7 @@ abstract class XapianIndexer { |
|
|
|
|
} |
|
|
|
|
$this->db->replace_document($did, $doc); |
|
|
|
|
$this->db->flush(); |
|
|
|
|
|
|
|
|
|
return true; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
@ -211,8 +228,9 @@ abstract class XapianIndexer { |
|
|
|
|
* |
|
|
|
|
* @param int did Xapian::docid |
|
|
|
|
*/ |
|
|
|
|
function remove_document($did) { |
|
|
|
|
if ($this->db == NULL) { |
|
|
|
|
function remove_document($did) |
|
|
|
|
{ |
|
|
|
|
if ($this->db == null) { |
|
|
|
|
$this->connectDb(); |
|
|
|
|
} |
|
|
|
|
if (is_numeric($did) && $did > 0) { |
|
|
|
@ -231,7 +249,8 @@ abstract class XapianIndexer { |
|
|
|
|
* @param XapianDocument $doc The xapian document where to add the term |
|
|
|
|
* @return mixed XapianDocument, or false on error |
|
|
|
|
*/ |
|
|
|
|
function add_term_to_doc($term, $doc) { |
|
|
|
|
function add_term_to_doc($term, $doc) |
|
|
|
|
{ |
|
|
|
|
if (!is_a($doc, 'XapianDocument')) { |
|
|
|
|
return FALSE; |
|
|
|
|
} |
|
|
|
@ -250,7 +269,8 @@ abstract class XapianIndexer { |
|
|
|
|
* @param XapianDocument $doc The xapian document where to add the term |
|
|
|
|
* @return mixed XapianDocument, or false on error |
|
|
|
|
*/ |
|
|
|
|
function remove_term_from_doc($term, $doc) { |
|
|
|
|
function remove_term_from_doc($term, $doc) |
|
|
|
|
{ |
|
|
|
|
if (!is_a($doc, 'XapianDocument')) { |
|
|
|
|
return FALSE; |
|
|
|
|
} |
|
|
|
@ -268,11 +288,12 @@ abstract class XapianIndexer { |
|
|
|
|
* @param XapianDocument $doc xapian document to push into the db |
|
|
|
|
* @param Xapian::docid $did xapian document id of the document to replace |
|
|
|
|
*/ |
|
|
|
|
function replace_document($doc, $did) { |
|
|
|
|
function replace_document($doc, $did) |
|
|
|
|
{ |
|
|
|
|
if (!is_a($doc, 'XapianDocument')) { |
|
|
|
|
return FALSE; |
|
|
|
|
} |
|
|
|
|
if ($this->db == NULL) { |
|
|
|
|
if ($this->db == null) { |
|
|
|
|
$this->connectDb(); |
|
|
|
|
} |
|
|
|
|
try { |
|
|
|
@ -284,18 +305,12 @@ abstract class XapianIndexer { |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
* Class contructor |
|
|
|
|
*/ |
|
|
|
|
function __construct() { |
|
|
|
|
$this->db = NULL; |
|
|
|
|
$this->stemmer = NULL; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
* Class destructor |
|
|
|
|
*/ |
|
|
|
|
function __destruct() { |
|
|
|
|
function __destruct() |
|
|
|
|
{ |
|
|
|
|
unset($this->db); |
|
|
|
|
unset($this->stemmer); |
|
|
|
|
} |
|
|
|
|