getItemTables() * - Add type in the index builder : SearchEngine->buildIndex() * - Add type in item info : SearchEngine->setItemInfo() * - Add type in Databap->getItemList() and create a Databap->getinfo() * - Add type text in Databap->getProfile() * - Consider the message types : add + edit in Databap->getMessages() and in chat.html */ class SearchEngine extends PhpObject { //Objects private $oMySql; //variables private $asWords; private $iLevelMax; private $asItemRanks; private $asItemInfos; private $asUserInfos; //Constants const RESULT_A_PAGE = 20; const KEYWORDS_SEPARATOR = ' '; function __construct($oMySql) { parent::__construct(__CLASS__, Settings::DEBUG); $this->oMySql = $oMySql; $this->asWords = $this->setWords(''); $this->asItemRanks = array(); $this->asItemInfos = array(); $this->asUserInfos = array(); } public function buildIndex($iItemId, $sType) { //Build keywords switch($sType) { case Databap::CODE_TYPE: $asItemData = $this->oMySql->selectRow(Databap::CODE_TABLE, $iItemId); $asWords = array($asItemData[MySqlManager::getText(Databap::CODE_TABLE)], $asItemData['description']); break; case Databap::PROC_TYPE: $sItemIdCol = MySqlManager::getId(Databap::PROC_TABLE); $asItemData = $this->oMySql->selectRow(Databap::PROC_TABLE, $iItemId); $asItemStepsData = $this->oMySql->selectRows(array('select'=>'description', 'from'=>Databap::STEP_TABLE, 'constraint'=>array($sItemIdCol=>$iItemId))); $asWords = array('desc'=>$asItemData['description'], 'title'=>$asItemData['title']) + $asItemStepsData; break; case Databap::ART_TYPE: $asItemData = $this->oMySql->selectRow(Databap::ART_TABLE, $iItemId); $asWords = array($asItemData['first_name'], $asItemData['last_name'], $asItemData['title']); break; case Databap::DOC_TYPE: $sItemIdCol = MySqlManager::getId(Databap::DOC_TABLE); $asItemData = $this->oMySql->selectRow(Databap::DOC_TABLE, $iItemId); $asItemFilesData = $this->oMySql->selectRows(array('select'=>'description', 'from'=>Databap::FILE_TABLE, 'constraint'=>array($sItemIdCol=>$iItemId))); $asWords = array('desc'=>$asItemData['description'], 'title'=>$asItemData['title']) + $asItemFilesData; break; case Databap::TABLE_TYPE: $asItemData = $this->oMySql->selectRow(Databap::TABL_TABLE, $iItemId); $asWords = array('desc'=>$asItemData['description'], 'title'=>$asItemData['title'], 'keywords'=>$asItemData['keywords'], 'system'=>$asItemData['system']); break; default: $this->addError('function '.__FUNCTION__.'(): Incorrect type "'.$sType.'"'); break; } $sWords = implode(self::KEYWORDS_SEPARATOR, $asWords); $sWords = mb_strtolower(str_replace("\n", self::KEYWORDS_SEPARATOR, $sWords)); $sWords = preg_replace('/(\W+)/u', self::KEYWORDS_SEPARATOR, $sWords); //remove all non-word characters //Add / Modify search database $asData = array('id_item'=>$iItemId, 'type'=>$sType, 'refer_id'=>(array_key_exists('refer_id', $asItemData)?$asItemData['refer_id']:$iItemId), 'keywords'=>$sWords); $this->oMySql->insertUpdateRow(Databap::SEARCH_TABLE, $asData, array('id_item', 'type')); } public function setWords($sSearchWords) { $this->asWords = $this->getParsedWords($sSearchWords); $this->iLevelMax = count($this->asWords); $this->setResults(); } /** * TODO Customized item preview $sCodeLines = implode("\n...\n", $this->getCodeInfo($iItemId, 'code')); $oCode = new Reader($sCodeLines); $sCodeLines = $oCode->getColoredCode(); */ private function setItemInfo($iSearchId, $iItemType, $iItemId) { if(!array_key_exists($iSearchId, $this->asItemInfos)) { /*switch($iItemType) { case Databap::CODE_TYPE: $sItemTable = Databap::CODE_TABLE; $asItemFields = array(MySqlManager::getId(Databap::USER_TABLE), 'description', 'led'); break; case Databap::PROC_TYPE: $sItemTable = Databap::PROC_TABLE; $asItemFields = array(MySqlManager::getId(Databap::USER_TABLE), 'title AS description', 'led'); break; case Databap::ART_TYPE: $sItemTable = Databap::ART_TABLE; $asItemFields = array('first_name', 'last_name', 'title AS description', 'led'); break; case Databap::DOC_TYPE: $sItemTable = Databap::DOC_TABLE; $asItemFields = array(MySqlManager::getId(Databap::USER_TABLE), 'title AS description', 'led'); break; case Databap::TABLE_TYPE: $sItemTable = Databap::TABL_TABLE; $asItemFields = array(MySqlManager::getId(Databap::USER_TABLE), 'title AS description', 'led'); break; } $this->asItemInfos[$iSearchId] = $this->oMySql->selectRow($sItemTable, $iItemId, $asItemFields);*/ $this->asItemInfos[$iSearchId]['type'] = $iItemType; $this->asItemInfos[$iSearchId]['id_item'] = $iItemId; } } private function getItemInfo($iSearchId, $sInfoName) { if(array_key_exists($iSearchId, $this->asItemInfos) && array_key_exists($sInfoName, $this->asItemInfos[$iSearchId])) return $this->asItemInfos[$iSearchId][$sInfoName]; else return false; } /* private function setUserInfo($iUserId) { if($iUserId > 0 && !array_key_exists($iUserId, $this->asUserInfos)) { $sCompanyIdCol = MySqlManager::getId(Databap::COMP_TABLE); $this->asUserInfos[$iUserId] = $this->oMySql->selectRow ( Databap::USER_TABLE, $iUserId, array('first_name', 'last_name', $sCompanyIdCol) ); $this->asUserInfos[$iUserId]['company'] = $this->oMySql->selectValue(Databap::COMP_TABLE, MySqlManager::getText(Databap::COMP_TABLE), $this->asUserInfos[$iUserId][$sCompanyIdCol]); unset($this->asUserInfos[$iUserId][$sCompanyIdCol]); } } private function getUserInfo($iUserId, $sInfoName) { if(array_key_exists($iUserId, $this->asUserInfos) && array_key_exists($sInfoName, $this->asUserInfos[$iUserId])) return $this->asUserInfos[$iUserId][$sInfoName]; else return false; } */ private function setResults() { if($this->iLevelMax > 0) { //set Results and Ranking $aiLevels = range(1, $this->iLevelMax); arsort($aiLevels); foreach($aiLevels as $iLevel) { //all possibilies at level $iLevel $iIndex = 0; while(($iIndex + $iLevel) <= $this->iLevelMax) { //building query $asSequence = array_slice($this->asWords, $iIndex, $iLevel); $this->oMySql->cleanSql($asSequence); //$sRegExp = implode('(.{0,2})', $asSequence); $sRegExp = implode(self::KEYWORDS_SEPARATOR.'?', $asSequence); $sSequence = implode(self::KEYWORDS_SEPARATOR, $asSequence); //TODO replace with selectRow() $sQuery = "SELECT id_search, MAX(id_item) AS id_item, type, keywords FROM searchs WHERE keywords REGEXP '{$sRegExp}' GROUP BY type, refer_id"; //search sequence $asItems = $this->oMySql->getArrayQuery($sQuery, true); foreach($asItems as $asItem) { $iSearchId = $asItem['id_search']; $iItemId = $asItem['id_item'];; $iItemType = $asItem['type']; $sWords = $asItem['keywords']; //Calculate bonus points $sWords = str_replace(self::KEYWORDS_SEPARATOR.$sSequence.self::KEYWORDS_SEPARATOR, self::KEYWORDS_SEPARATOR, self::KEYWORDS_SEPARATOR.$sWords.self::KEYWORDS_SEPARATOR, $iSeqCount); $sWords = str_replace(self::KEYWORDS_SEPARATOR.$sSequence, self::KEYWORDS_SEPARATOR, self::KEYWORDS_SEPARATOR.$sWords.self::KEYWORDS_SEPARATOR, $iStaCount); $sWords = str_replace($sSequence.self::KEYWORDS_SEPARATOR, self::KEYWORDS_SEPARATOR, self::KEYWORDS_SEPARATOR.$sWords.self::KEYWORDS_SEPARATOR, $iEndCount); $iBonus = $iSeqCount*5 + $iStaCount*2 + $iEndCount; $this->incItemRank($iSearchId, $iLevel*10+$iBonus); $this->setItemInfo($iSearchId, $iItemType, $iItemId); //$this->setUserInfo($this->getItemInfo($iSearchId, MySqlManager::getId(Databap::USER_TABLE))); } $iIndex++; } } } } public function getResults() { $asResult = array(); //Mixing info arsort($this->asItemRanks); foreach($this->asItemRanks as $iSearchId=>$iRank) { /*$iUserId = $this->getItemInfo($iSearchId, MySqlManager::getId(Databap::USER_TABLE)); $sFirstName = $this->getUserInfo($iUserId, 'first_name')?$this->getUserInfo($iUserId, 'first_name'):$this->getItemInfo($iSearchId, 'first_name'); $sLastName = $this->getUserInfo($iUserId, 'last_name')?$this->getUserInfo($iUserId, 'last_name'):$this->getItemInfo($iSearchId, 'last_name'); $sCompany = $this->getUserInfo($iUserId, 'company')?$this->getUserInfo($iUserId, 'company'):'SAP'; $asResult[] = array('id_item'=>$this->getItemInfo($iSearchId, 'id_item'), 'type'=>$this->getItemInfo($iSearchId, 'type'), 'description'=>$this->getItemInfo($iSearchId, 'description'), 'rank'=>$iRank, 'name'=>Databap::getNameFormat($sFirstName, $sLastName), 'company'=>Databap::getCompanyFormat($sCompany), 'led'=>Databap::getDateFormat($this->getItemInfo($iSearchId, 'led'))); */ $asResult[] = array('id_item'=>$this->getItemInfo($iSearchId, 'id_item'), 'type'=>$this->getItemInfo($iSearchId, 'type'), 'rank'=>$iRank); } return $asResult; } private function incItemRank($iSearchId, $iRank) { if(array_key_exists($iSearchId, $this->asItemRanks)) { $this->asItemRanks[$iSearchId] += $iRank; } else { $this->asItemRanks[$iSearchId] = $iRank; } } private function getParsedWords($sSearchWords) { return array_unique(array_filter(explode(' ', $sSearchWords), array($this, 'checkSearchedWords'))); } private function checkSearchedWords($sWord) { return (mb_strlen($sWord) >= 2); } } ?>