|
@@ -1,4 +1,5 @@
|
|
|
<?php
|
|
|
+
|
|
|
/* For licensing terms, see /license.txt */
|
|
|
/**
|
|
|
* @package chamilo.include.search
|
|
@@ -15,6 +16,7 @@ require_once dirname(__FILE__) . '/../IndexableChunk.class.php';
|
|
|
*/
|
|
|
abstract class XapianIndexer {
|
|
|
/* XapianWritableDatabase */
|
|
|
+
|
|
|
protected $db;
|
|
|
/* IndexableChunk[] */
|
|
|
protected $chunks;
|
|
@@ -23,48 +25,48 @@ abstract class XapianIndexer {
|
|
|
/* XapianStem */
|
|
|
public $stemmer;
|
|
|
|
|
|
- /**
|
|
|
- * Generates a list of languages Xapian manages
|
|
|
- *
|
|
|
- * This method enables the definition of more matches between
|
|
|
- * Chamilo languages and Xapian languages (through hardcoding)
|
|
|
- * @return array Array of languages codes -> Xapian languages
|
|
|
- */
|
|
|
+ /**
|
|
|
+ * Generates a list of languages Xapian manages
|
|
|
+ *
|
|
|
+ * This method enables the definition of more matches between
|
|
|
+ * Chamilo languages and Xapian languages (through hardcoding)
|
|
|
+ * @return array Array of languages codes -> 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
|
|
|
- 'da' => 'danish',
|
|
|
- 'nl' => 'dutch',
|
|
|
- /* Martin Porter's 2002 revision of his stemmer */
|
|
|
- 'en' => 'english',
|
|
|
- /* Lovin's stemmer */
|
|
|
- 'lovins' => 'english_lovins',
|
|
|
- /* Porter's stemmer as described in his 1980 paper */
|
|
|
- 'porter' => 'english_porter',
|
|
|
- 'fi' => 'finnish',
|
|
|
- 'fr' => 'french',
|
|
|
- 'de' => 'german',
|
|
|
- 'it' => 'italian',
|
|
|
- 'no' => 'norwegian',
|
|
|
- 'pt' => 'portuguese',
|
|
|
- 'ru' => 'russian',
|
|
|
- 'es' => 'spanish',
|
|
|
- 'sv' => 'swedish',
|
|
|
- );
|
|
|
+ /* http://xapian.org/docs/apidoc/html/classXapian_1_1Stem.html */
|
|
|
+ return array(
|
|
|
+ 'none' => 'none', //don't stem terms
|
|
|
+ 'da' => 'danish',
|
|
|
+ 'nl' => 'dutch',
|
|
|
+ /* Martin Porter's 2002 revision of his stemmer */
|
|
|
+ 'en' => 'english',
|
|
|
+ /* Lovin's stemmer */
|
|
|
+ 'lovins' => 'english_lovins',
|
|
|
+ /* Porter's stemmer as described in his 1980 paper */
|
|
|
+ 'porter' => 'english_porter',
|
|
|
+ 'fi' => 'finnish',
|
|
|
+ 'fr' => 'french',
|
|
|
+ 'de' => 'german',
|
|
|
+ 'it' => 'italian',
|
|
|
+ 'no' => 'norwegian',
|
|
|
+ 'pt' => 'portuguese',
|
|
|
+ 'ru' => 'russian',
|
|
|
+ 'es' => 'spanish',
|
|
|
+ 'sv' => 'swedish',
|
|
|
+ );
|
|
|
}
|
|
|
|
|
|
- /**
|
|
|
- * Connect to the database, and create it if it doesn't exist
|
|
|
- */
|
|
|
- function connectDb($path=NULL, $dbMode=NULL, $lang='english') {
|
|
|
- if ($this->db != NULL)
|
|
|
- return $this->db;
|
|
|
+ /**
|
|
|
+ * Connect to the database, and create it if it doesn't exist
|
|
|
+ */
|
|
|
+ function connectDb($path = NULL, $dbMode = NULL, $lang = 'english') {
|
|
|
+ if ($this->db != NULL)
|
|
|
+ return $this->db;
|
|
|
if ($dbMode == NULL)
|
|
|
$dbMode = Xapian::DB_CREATE_OR_OPEN;
|
|
|
|
|
|
if ($path == NULL)
|
|
|
- $path = api_get_path(SYS_PATH).'searchdb/';
|
|
|
+ $path = api_get_path(SYS_PATH) . 'searchdb/';
|
|
|
|
|
|
try {
|
|
|
$this->db = new XapianWritableDatabase($path, $dbMode);
|
|
@@ -75,7 +77,7 @@ abstract class XapianIndexer {
|
|
|
}
|
|
|
$this->stemmer = new XapianStem($lang);
|
|
|
$this->indexer->set_stemmer($this->stemmer);
|
|
|
-
|
|
|
+
|
|
|
return $this->db;
|
|
|
} catch (Exception $e) {
|
|
|
Display::display_error_message($e->getMessage());
|
|
@@ -91,11 +93,11 @@ abstract class XapianIndexer {
|
|
|
return $this->db;
|
|
|
}
|
|
|
|
|
|
- /**
|
|
|
- * Add this chunk to the chunk array attribute
|
|
|
- * @param string Chunk of text
|
|
|
- * @return void
|
|
|
- */
|
|
|
+ /**
|
|
|
+ * Add this chunk to the chunk array attribute
|
|
|
+ * @param string Chunk of text
|
|
|
+ * @return void
|
|
|
+ */
|
|
|
function addChunk($chunk) {
|
|
|
$this->chunks[] = $chunk;
|
|
|
}
|
|
@@ -107,7 +109,7 @@ abstract class XapianIndexer {
|
|
|
*/
|
|
|
function index() {
|
|
|
try {
|
|
|
- if (!empty($this->chunks)) {
|
|
|
+ if (!empty($this->chunks)) {
|
|
|
foreach ($this->chunks as $chunk) {
|
|
|
$doc = new XapianDocument();
|
|
|
$this->indexer->set_document($doc);
|
|
@@ -117,19 +119,19 @@ abstract class XapianIndexer {
|
|
|
$doc->add_term($term['flag'] . $term['name'], 1);
|
|
|
}
|
|
|
}
|
|
|
-
|
|
|
+
|
|
|
// free-form index all data array (title, content, etc)
|
|
|
if (!empty($chunk->data)) {
|
|
|
foreach ($chunk->data as $key => $value) {
|
|
|
$this->indexer->index_text($value, 1);
|
|
|
}
|
|
|
- }
|
|
|
- $doc->set_data($chunk->xapian_data, 1);
|
|
|
+ }
|
|
|
+ $doc->set_data($chunk->xapian_data, 1);
|
|
|
$did = $this->db->add_document($doc);
|
|
|
-
|
|
|
+
|
|
|
//write to disk
|
|
|
$this->db->flush();
|
|
|
-
|
|
|
+
|
|
|
return $did;
|
|
|
}
|
|
|
}
|
|
@@ -146,17 +148,16 @@ abstract class XapianIndexer {
|
|
|
* @return mixed XapianDocument, or false on error
|
|
|
*/
|
|
|
function get_document($did) {
|
|
|
- if ($this->db == NULL) {
|
|
|
- $this->connectDb();
|
|
|
- }
|
|
|
- try {
|
|
|
- $docid = $this->db->get_document($did);
|
|
|
- }
|
|
|
- catch (Exception $e) {
|
|
|
- //Display::display_error_message($e->getMessage());
|
|
|
- return false;
|
|
|
- }
|
|
|
- return $docid;
|
|
|
+ if ($this->db == NULL) {
|
|
|
+ $this->connectDb();
|
|
|
+ }
|
|
|
+ try {
|
|
|
+ $docid = $this->db->get_document($did);
|
|
|
+ } catch (Exception $e) {
|
|
|
+ //Display::display_error_message($e->getMessage());
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ return $docid;
|
|
|
}
|
|
|
|
|
|
/**
|
|
@@ -166,20 +167,19 @@ abstract class XapianIndexer {
|
|
|
* @return mixed xapian document data or FALSE if error
|
|
|
*/
|
|
|
function get_document_data($doc) {
|
|
|
- if ($this->db == NULL) {
|
|
|
- $this->connectDb();
|
|
|
- }
|
|
|
- try {
|
|
|
- if (!is_a($doc, 'XapianDocument')) {
|
|
|
- return FALSE;
|
|
|
+ if ($this->db == NULL) {
|
|
|
+ $this->connectDb();
|
|
|
+ }
|
|
|
+ try {
|
|
|
+ if (!is_a($doc, 'XapianDocument')) {
|
|
|
+ return FALSE;
|
|
|
+ }
|
|
|
+ $doc_data = $doc->get_data();
|
|
|
+ return $doc_data;
|
|
|
+ } catch (Exception $e) {
|
|
|
+ //Display::display_error_message($e->getMessage());
|
|
|
+ return false;
|
|
|
}
|
|
|
- $doc_data = $doc->get_data();
|
|
|
- return $doc_data;
|
|
|
- }
|
|
|
- catch (Exception $e) {
|
|
|
- //Display::display_error_message($e->getMessage());
|
|
|
- return false;
|
|
|
- }
|
|
|
}
|
|
|
|
|
|
/**
|
|
@@ -190,16 +190,18 @@ abstract class XapianIndexer {
|
|
|
* @return boolean false on error
|
|
|
*/
|
|
|
function update_terms($did, $terms, $prefix) {
|
|
|
- $doc = $this->get_document($did);
|
|
|
- if($doc===false){return false;}
|
|
|
- $doc->clear_terms();
|
|
|
- foreach ($terms as $term) {
|
|
|
- //add directly
|
|
|
- $doc->add_term($prefix.$term, 1);
|
|
|
- }
|
|
|
- $this->db->replace_document($did, $doc);
|
|
|
- $this->db->flush();
|
|
|
- return true;
|
|
|
+ $doc = $this->get_document($did);
|
|
|
+ if ($doc === false) {
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ $doc->clear_terms();
|
|
|
+ foreach ($terms as $term) {
|
|
|
+ //add directly
|
|
|
+ $doc->add_term($prefix . $term, 1);
|
|
|
+ }
|
|
|
+ $this->db->replace_document($did, $doc);
|
|
|
+ $this->db->flush();
|
|
|
+ return true;
|
|
|
}
|
|
|
|
|
|
/**
|
|
@@ -211,7 +213,7 @@ abstract class XapianIndexer {
|
|
|
if ($this->db == NULL) {
|
|
|
$this->connectDb();
|
|
|
}
|
|
|
- if (is_numeric($did) && $did>0) {
|
|
|
+ if (is_numeric($did) && $did > 0) {
|
|
|
$doc = $this->get_document($did);
|
|
|
if ($doc !== FALSE) {
|
|
|
$this->db->delete_document($did);
|
|
@@ -228,15 +230,14 @@ abstract class XapianIndexer {
|
|
|
* @return mixed XapianDocument, or false on error
|
|
|
*/
|
|
|
function add_term_to_doc($term, $doc) {
|
|
|
- if (!is_a($doc,'XapianDocument')) {
|
|
|
+ if (!is_a($doc, 'XapianDocument')) {
|
|
|
return FALSE;
|
|
|
}
|
|
|
try {
|
|
|
$doc->add_term($term);
|
|
|
- }
|
|
|
- catch (Exception $e) {
|
|
|
- Display::display_error_message($e->getMessage());
|
|
|
- return 1;
|
|
|
+ } catch (Exception $e) {
|
|
|
+ Display::display_error_message($e->getMessage());
|
|
|
+ return 1;
|
|
|
}
|
|
|
}
|
|
|
|
|
@@ -248,15 +249,14 @@ abstract class XapianIndexer {
|
|
|
* @return mixed XapianDocument, or false on error
|
|
|
*/
|
|
|
function remove_term_from_doc($term, $doc) {
|
|
|
- if (!is_a($doc,'XapianDocument')) {
|
|
|
+ if (!is_a($doc, 'XapianDocument')) {
|
|
|
return FALSE;
|
|
|
}
|
|
|
try {
|
|
|
$doc->remove_term($term);
|
|
|
- }
|
|
|
- catch (Exception $e) {
|
|
|
- Display::display_error_message($e->getMessage());
|
|
|
- return 1;
|
|
|
+ } catch (Exception $e) {
|
|
|
+ Display::display_error_message($e->getMessage());
|
|
|
+ return 1;
|
|
|
}
|
|
|
}
|
|
|
|
|
@@ -267,30 +267,29 @@ abstract class XapianIndexer {
|
|
|
* @param Xapian::docid $did xapian document id of the document to replace
|
|
|
*/
|
|
|
function replace_document($doc, $did) {
|
|
|
- if (!is_a($doc,'XapianDocument')) {
|
|
|
+ if (!is_a($doc, 'XapianDocument')) {
|
|
|
return FALSE;
|
|
|
}
|
|
|
if ($this->db == NULL) {
|
|
|
$this->connectDb();
|
|
|
}
|
|
|
try {
|
|
|
- $this->getDb()->replace_document((int)$did, $doc);
|
|
|
- $this->getDb()->flush();
|
|
|
- }
|
|
|
- catch (Exception $e) {
|
|
|
- Display::display_error_message($e->getMessage());
|
|
|
- return 1;
|
|
|
+ $this->getDb()->replace_document((int) $did, $doc);
|
|
|
+ $this->getDb()->flush();
|
|
|
+ } catch (Exception $e) {
|
|
|
+ Display::display_error_message($e->getMessage());
|
|
|
+ return 1;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-
|
|
|
- /**
|
|
|
- * Class contructor
|
|
|
- */
|
|
|
+ /**
|
|
|
+ * Class contructor
|
|
|
+ */
|
|
|
function __construct() {
|
|
|
$this->db = NULL;
|
|
|
$this->stemmer = NULL;
|
|
|
}
|
|
|
+
|
|
|
/**
|
|
|
* Class destructor
|
|
|
*/
|
|
@@ -298,4 +297,4 @@ abstract class XapianIndexer {
|
|
|
unset($this->db);
|
|
|
unset($this->stemmer);
|
|
|
}
|
|
|
-}
|
|
|
+}
|