/**
* Класс для работы с SAPA-демоном (система размещения ссылок)
*
*/
// Проверяем наличие класса GlobalClassSocket
if (!class_exists("GlobalClassSocket")) {
require_once(META_CLASS_DIR."common/socket.class.php");
}
define("SAPA_MEMCACHE_EXPIRE",1800);
class GlobalClassSapa extends GlobalClassSocket {
var $aConfig;
var $sProject;
// Конструктор класса, принимает проект при индексировании и сразу открывает коннект
// При получении ссылок может ничего не принимать
function GlobalClassSapa($sProject = false, $bHelloDaemon = false){
// Получаем параметры из файла инициализации
$sIniFile = "main";
if ($sProject&&(trim($sProject)!="")&&file_exists(dirname(__FILE__)."/sapa/".$sProject.".ini")) {
$sIniFile = $sProject;
}
if($sProject)
$this->sProject = $sProject;
$this->aConfig = parse_ini_file(dirname(__FILE__)."/sapa/".$sIniFile.".ini", true);
// Если необходимо сразу приконнектится к демону для индексации
if($bHelloDaemon){
if(!$this->connect($this->aConfig["sapahost"],intval($this->aConfig["sapaport"]),10))
return false;
$sAnswear = $this->request("HELO $sProject",true);
if(preg_match("/^error/i",$sAnswear)){
$this->_triggerError($sAnswear);
return false;
}
}
return true;
}
/**
* Функция для передачи объекта на индексацию в сапу
* Принимает уникальный для проекта идентификатор объекта
*/
function addToIndex($vId){
$sAnswear = $this->request("ADD $vId",true);
if(preg_match("/^error/i",$sAnswear)){
$this->_triggerError($sAnswear);
return false;
}
return $sAnswear;
}
function getLinks($vObjectId,$iPage,$bUseCache = true){
if(!$this->sProject)
return false;
// Получаем из сапавского мемкеша ссылки (если они есть) или значение 0(если их нет)
$oMemcache = new Memcache;
$sMemcacheKey = "sapa::".$this->sProject."::".$vObjectId."::".$iPage;
$sLinks = false;
$bMemcachConnected = false;
if($bUseCache && $oMemcache->connect($this->aConfig["memhost"], $this->aConfig["memport"])){
$bMemcachConnected = true;
$sLinks = $oMemcache->get($sMemcacheKey);
if($sLinks === '0')
return false;
}
$aLinks = array();
if(!$sLinks){
// Если ссылок нет - проверяем их в базе
// Перед обращением к базе пишем в мемкеш чтоб больше не было обращений
if($bMemcachConnected){
$oMemcache->set($sMemcacheKey,"0",false,SAPA_MEMCACHE_EXPIRE);
}
if(!class_exists("GlobalClassDb"))
require_once(META_CLASS_DIR."DB/db.php");
$oSapaDB = new GlobalClassDb("sapa");
$sSql = "SELECT linkHref,linkText FROM links,project WHERE project.alias='".addslashes($this->sProject)."' AND project.id=links.projectId AND links.objectId='".addslashes($vObjectId)."' AND links.page='".addslashes($iPage)."'";
$aResultLinks = $oSapaDB->getRowSet($sSql);
if(is_array($aResultLinks))
foreach($aResultLinks as $aResultLink){
$aLinks[$aResultLink["linkHref"]] = $aResultLink["linkText"];
}
// И результат пишем в мемкеш
if($bMemcachConnected&&!empty($aLinks)){
$oMemcache->set($sMemcacheKey,serialize($aLinks),false,SAPA_MEMCACHE_EXPIRE);
}
}else{
$aLinks = unserialize($sLinks);
}
if(!is_array($aLinks) || empty($aLinks))
return false;
// Массив финальных ссылок, которые отдадуться пользователю
$aFinalLinks = array();
// Обрабатываем шаблонные ссылки, формируя текст для выдачи
foreach($aLinks as $sHref=>$sText){
$aChunk = preg_split("/(\[|\])/",$sText,0,PREG_SPLIT_DELIM_CAPTURE);
$aLinkChunks = array();
if(count($aChunk) < 3){
// Если чанков меньше 3 (с учетом скобок) - то это просто текст с полной ссылкой
$aLinkChunks[] = "".$sText."";
}else{
$bOpenBracket = 0;
$iCounter = 0;
foreach($aChunk as $sTextChunk){
// Открытая скобка - ставим флаг
if($sTextChunk == "["){
$bOpenBracket++;
// Если это не первая открывающая скобка - значит она принадлежит тексту
if($bOpenBracket == 1)
continue;
}
if($sTextChunk == "]"){
// Закрытая скобка - понижаем счетчик закрытых скобок
$bOpenBracket--;
// Если это последняя открытая скобка - то обрабатываем текст счетчика
if(!$bOpenBracket){
$aLinkTexts = explode(",", $aLinkChunks[$iCounter]);
shuffle($aLinkTexts);
foreach($aLinkTexts as $iLinkId => $sLinkText){
$aLinkTexts[$iLinkId] = "".$sLinkText."";
}
$aLinkChunks[$iCounter] = implode(", ",$aLinkTexts);
$iCounter++;
continue;
}
// Тут не делаем continue если это не последняя скобка - она принадлежит тексту
}
// Скобка не открыта - пишем просто в текст, увеличиваем счетчик
if(!$bOpenBracket){
$aLinkChunks[$iCounter] = $sTextChunk;
$iCounter++;
continue;
}else{
// Накапливаем содержимое, которое нужно будет воткнуть в ссылку когда она закроется
$aLinkChunks[$iCounter].=$sTextChunk;
}
}
}
$aFinalLinks[] = implode("",$aLinkChunks);
}
return (!empty($aFinalLinks))?$aFinalLinks:false;
}
/**
*
* Функция получения ссылок в статической сапе
*
**/
function getStaticLinks(){
$sIncludePath = get_include_path();
$sDelimiter = (isset($_ENV["OS"])&&preg_match("/^win/i",$_ENV["OS"]))?";":":";
$aIncludePath = explode($sDelimiter,$sIncludePath);
foreach($aIncludePath as $sIncludeDir){
if($sIncludeDir == ".")
continue;
$sIncludeDir .= (substr($sIncludeDir,-1) == "/")?"":"/";
$sFilePath = META_CLASS_DIR."common/sapa/codes/".$_SERVER["HTTP_HOST"]."/".md5("http://".$_SERVER["HTTP_HOST"].$_SERVER["REQUEST_URI"])."/index.xml";
if(file_exists($sFilePath)){
return array_map("trim",explode("\n",trim(strip_tags(file_get_contents($sFilePath),""))));
}
}
return false;
}
/**
*
* Функция получения поисковых фраз по домену
*
**/
function getSearchPhrases($iCount = 7){
$sIncludePath = get_include_path();
$sDelimiter = (isset($_ENV["OS"])&&preg_match("/^win/i",$_ENV["OS"]))?";":":";
$aIncludePath = explode($sDelimiter,$sIncludePath);
$aSearchPhrase = array();
foreach($aIncludePath as $sIncludeDir){
if($sIncludeDir == ".")
continue;
$sIncludeDir .= (substr($sIncludeDir,-1) == "/")?"":"/";
$aFilePath [] = META_CLASS_DIR."common/sapa/codes/".$_SERVER["HTTP_HOST"]."/".md5("http://".$_SERVER["HTTP_HOST"].$_SERVER["REQUEST_URI"])."/query.csv";
$aFilePath [] = META_CLASS_DIR."common/sapa/codes/".$_SERVER["HTTP_HOST"]."/query.csv";
foreach($aFilePath as $sFilePath){
if(file_exists($sFilePath)){
$fp=fopen($sFilePath,"r");
$aAllPhrase = array();
while($fp&&($buffer = fgets($fp, 4096)) !== false){
if(trim($buffer) == "")
continue;
$aParts = explode(",",trim($buffer));
$aAllPhrase[$aParts[0]] = $aParts[1]*rand(1,100);
}
arsort($aAllPhrase);
$aSearchPhrase = array_keys(array_slice($aAllPhrase,0,$iCount));
shuffle($aSearchPhrase);
// Если вдруг нашли фразы для страницы - для домена фразы уже не выбираем
return $aSearchPhrase;
}
}
}
return false;
}
function makeSearchLink($sQuery){
return sprintf("http://meta.ua/ex/search.asp?mode=ex&q=%s",urlencode($sQuery));
}
/**
* Функция закрывает соединение с демоном
*
*/
function close(){
$sAnswear = $this->request("QUIT",true);
parent::close();
}
}
?>