Files
databap/inc/searchengine.php
2019-12-08 10:50:09 +01:00

111 lines
3.3 KiB
PHP

<?php
/**
* Search Engine : Search through all types of databap documents
*
* Procedure to add a new type in the search
* - Add type in Databap->getItemTables()
* - Add type in searched fields : SearchEngine->setResults()
* - Add type in Databap->getItemList() and create a Databap->get<type>info()
* - Add type text in Databap->getProfile()
* - Consider the message types : add + edit in Databap->getMessages() and in chat.html
*/
class SearchEngine extends PhpObject
{
/**
* DB Handle
* @var MySqlManager
*/
private $oMySql;
//variables
private $sWords;
private $asItems;
function __construct($oMySql)
{
parent::__construct(__CLASS__, Settings::DEBUG);
$this->oMySql = $oMySql;
$this->sWords = '';
$this->asItems = array();
}
public function setWords($sSearchWords)
{
$this->oMySql->cleanSql($sSearchWords);
$this->sWords = $sSearchWords;
$this->setResults();
}
private function setResults()
{
$this->asItems = array();
if($this->sWords != '')
{
$asSearches = array(
Databap::CODE_TYPE => array(
Databap::CODE_TABLE => array(MySqlManager::getText(Databap::CODE_TABLE), 'description')
),
Databap::PROC_TYPE => array(
Databap::PROC_TABLE => array('title', 'description'),
Databap::STEP_TABLE => array('description')
),
Databap::ART_TYPE => array(
Databap::ART_TABLE => array('title')
),
Databap::DOC_TYPE => array(
Databap::DOC_TABLE => array('title', 'description'),
Databap::FILE_TABLE => array('description')
),
Databap::TABLE_TYPE=> array(
Databap::TABL_TABLE => array('title', 'description', 'keywords')
)
);
foreach($asSearches as $sType=>$asTables) {
$sMainTableName = $sJoin = '';
$asMatchAgainst = array();
foreach($asTables as $sTableName=>$asFields) {
if($sMainTableName=='') { //First table contains main object
$sMainTableName = $sTableName;
$sMainTableIdCol = MySqlManager::getId($sMainTableName);
$sMainTableIdColFull = MySqlManager::getId($sMainTableName, true);
}
else { //Other tables must be joined
$sJoin .= "LEFT JOIN {$sTableName} ";
if($this->oMySql->isColumnInTable($sTableName, $sMainTableIdCol)) $sJoin .= "USING({$sMainTableIdCol}) ";
else $sJoin .= "ON {$sTableName}.id_item = {$sMainTableIdColFull} ";
}
$asMatchFields = array();
foreach($asFields as $sField) $asMatchFields[] = MySqlManager::getFullColumnName($sTableName, $sField);
$asMatchAgainst[] = "MATCH (".implode(',', $asMatchFields).") AGAINST ('".$this->sWords."' IN BOOLEAN MODE)";
}
$sGroupByCol = $this->oMySql->isColumnInTable($sMainTableName, 'refer_id')?'refer_id':$sMainTableIdColFull;
$sQuery = "SELECT MAX({$sMainTableIdColFull}) AS id_item, '{$sType}' AS type, (".(implode(" + ", $asMatchAgainst)).") AS rank ".
"FROM {$sMainTableName} ".
$sJoin.
"WHERE ".implode(" OR ", $asMatchAgainst)." ".
"GROUP BY {$sGroupByCol}";
$asItems = $this->oMySql->getArrayQuery($sQuery, true);
foreach($asItems as $asItem) {
$asItem['rank'] = round($asItem['rank'] * 100);
$this->asItems[] = $asItem;
}
}
}
}
public function getResults()
{
usort($this->asItems, function($a, $b) {return ($a['rank'] < $b['rank']);});
return $this->asItems;
}
}
?>