<?php
class sqlite_fulltextsearch {
var $_againsts_cache = array ();
var $use_against_cache = false;
var $word_separators_pattern = "/[\s\.,'\"\/\|]+/";
function sqlite_fulltextsearch () {
$this->_againsts_cache = array ();
$this->use_against_cache = false;
}
function wordspreparation (&$string, &$against) {
// do nothing here, override in subclasses, see sqlite_fulltextsearchex example
}
function _wordspreparation ($string, $against, $usecase, &$string_words, &$against_words, &$string_words_count, &$against_words_count) {
if (!$usecase) {
$string = strtolower ($string);
$against = strtolower ($against);
}
$this->wordspreparation ($string, $against);
$string_words = preg_split ("/ +/", preg_replace ($this->word_separators_pattern, ' ', $string));
$against_words = null;
if ($this->use_against_cache && isset ($this->_againsts_cache[$against])) {
$against_words = $this->_againsts_cache[$against];
} else {
$against_words = preg_split ("/ +/", preg_replace ($this->word_separators_pattern, ' ', $against));
if ($this->use_against_cache) {
$this->_againsts_cache[$against] = $against_words;
}
}
$string_words_count = count ($string_words);
$against_words_count = count ($against_words);
return true;
}
function prominence ($position, $string_words_count, $against_words_count) {
/* lenear prominence */
return $position;
}
function _internal_wordprominence ($string_words, $against_words, $string_words_count, $against_words_count) {
if ($string_words_count == 0) {
return 0;
}
$global_prominance = 0;
foreach ($against_words as $against_word) {
foreach ($string_words as $position => $string_word) {
$position++;
if ($string_word == $against_word) {
$global_prominance += $this->prominence ($position, $string_words_count, $against_words_count);
}
}
}
$divisor = ($string_words_count + 1) * ($string_words_count / 2); // sum of N integer numbers from 1 to N
$result = $global_prominance / $divisor;
return $result;
}
function _wordprominence ($string, $against, $usecase) {
$this->_wordspreparation ($string, $against, $usecase, &$string_words, &$against_words, &$string_words_count, &$against_words_count);
$string_words = array_reverse ($string_words);
$result = $this->_internal_wordprominence ($string_words, $against_words, $string_words_count, $against_words_count);
return $result;
}
function _reversewordprominence ($string, $against, $usecase) {
$this->_wordspreparation ($string, $against, $usecase, &$string_words, &$against_words, &$string_words_count, &$against_words_count);
$result = $this->_internal_wordprominence ($string_words, $against_words, $string_words_count, $against_words_count);
return $result;
}
function _centerwordprominence ($string, $against, $usecase) {
$this->_wordspreparation ($string, $against, $usecase, &$string_words, &$against_words, &$string_words_count, &$against_words_count);
/* begin centering keywords, from 'a, b, c, d, e' to 'c, d, b, e, a' */
$start = ceil ($string_words_count / 2) - 1;
$left = $start;
$right = $start;
$centered_string_words = array ();
$centered_string_words[] = $string_words[$start];
while (($left > 0) && ($right < $string_words_count)) {
$left--;
$right++;
$centered_string_words[] = $string_words[$right];
$centered_string_words[] = $string_words[$left];
}
if ($right < $string_words_count - 1) {
$centered_string_words[] = $string_words[$string_words_count - 1];
}
/* end centering keywords */
$centered_string_words = array_reverse ($centered_string_words);
$result = $this->_internal_wordprominence ($centered_string_words, $against_words, $string_words_count, $against_words_count);
return $result;
}
function _fulltextsearch ($string, $against, $usecase) {
$result = 0;
$this->_wordspreparation ($string, $against, $usecase, &$string_words, &$against_words, &$string_words_count, &$against_words_count);
if ($string_words_count == 0) {
return $result;
}
$string = ' ' . implode (' ', $string_words) . ' ';
$against_ex = ' ';
for ($from = 0; $from < $against_words_count; $from++) {
$against_ex .= $against_words[$from] . ' ';
$result += (substr_count ($string, $against_ex) * ($from + 1)) / $string_words_count;
}
return $result;
}
function register (&$dbhandle) {
sqlite_create_function ($dbhandle, 'fulltextsearch', array (&$this, '_fulltextsearch'), 3);
sqlite_create_function ($dbhandle, 'wordprominence', array (&$this, '_wordprominence'), 3);
sqlite_create_function ($dbhandle, 'reversewordprominence', array (&$this, '_reversewordprominence'), 3);
sqlite_create_function ($dbhandle, 'centerwordprominence', array (&$this, '_centerwordprominence'), 3);
}
}
?>
|