<?php
/**
* СодеÑÐ¶Ð¸Ñ ÐºÐ»Ð°ÑÑ Sitemap
*
* @package energine
* @subpackage core
* @author dr.Pavka
* @copyright ColoCall 2006
* @version $Id: Sitemap.class.php,v 1.14 2007/12/17 14:16:03 pavka Exp $
*/
//require_once('core/framework/DBWorker.class.php');
//require_once('core/framework/TreeConverter.class.php');
/**
* ÐлаÑÑ - ÑинглÑон
* СодеÑÐ¶Ð¸Ñ Ð¼ÐµÑÐ¾Ð´Ñ Ð¿Ð¾ ÑабоÑе Ñо ÑÑÑÑкÑÑÑой ÑайÑа
*
* @package energine
* @subpackage core
* @final
*/
final class Sitemap extends DBWorker {
/**
* @var TreeNodeList ÐкземплÑÑ ÐºÐ»Ð°ÑÑа ÑеализÑÑÑего ÑабоÑÑ Ñ Ð´ÑевовиднÑми ÑÑÑÑкÑÑÑами
* @access private
*/
private $tree;
/**
* @var Sitemap Instance обÑекÑа Sitemap
* @access private
* @static
*/
private static $instance;
/**
* ÐнÑоÑмаÑÐ¸Ñ Ð¾ ÑеÑ
ÑазделаÑ
, на коÑоÑÑе Ñ ÑзеÑа еÑÑÑ Ð¿Ñава
* @var array
* @access private
*/
private $info = array();
/**
* ÐнÑоÑмаÑÐ¸Ñ Ð¾Ð±Ð¾ вÑеÑ
ÑазделаÑ
(вклÑÑÐ°Ñ Ñе на коÑоÑÑе Ñ ÑекÑÑего ÑзеÑа Ð½ÐµÑ Ð¿Ñав)
*
* @var array
* @access private
*/
private $allInfo = array();
/**
* ÐденÑиÑикаÑÐ¾Ñ Ð´ÐµÑолÑной ÑÑÑаниÑÑ
* ÐÑнеÑено в пеÑеменнÑÑ ÑÑоб не деÑгаÑÑ Ð·Ð°Ð¿ÑÐ¾Ñ Ð¿Ð¾ÑÑоÑнно
*
* @var int
* @access private
*/
private $defaultID = false;
/**
* ÐеÑолÑнÑе meta keywords
* ÐÑполÑзÑеÑÑÑ Ð´Ð»Ñ Ð²ÑеÑ
ÑÑÑÐ°Ð½Ð¸Ñ Ñ ÐºÐ¾ÑоÑÑÑ
не Ñказано
* ÐÑнеÑено в оÑделÑнÑÑ Ð¿ÐµÑеменнÑÑ, ÑÑÐ¾Ð±Ñ Ð½Ðµ деÑгаÑÑ ÐºÐ°Ð¶Ð´Ñй Ñаз запÑоÑ
*
* @var string
* @access private
*/
private $defaultMetaKeywords;
/**
* ÐеÑолÑное meta description
*
* @var string
* @access private
* @see Sitemap::defaultMetaKeywords
*/
private $defaultMetaDescription;
/**
* ÐденÑиÑикаÑÐ¾Ñ ÑекÑÑего ÑзÑка
*
* @var int
* @access private
*/
private $langID;
/**
* ÐонÑÑÑÑкÑÐ¾Ñ ÐºÐ»Ð°ÑÑа
*
* @return void
*/
public function __construct() {
parent::__construct();
$this->langID = Language::getInstance()->getCurrent();
//ÐагÑÑжаем иденÑиÑикаÑоÑÑ Ð´Ð»Ñ Ð¿Ð¾ÑледÑÑÑего ÑоÑмиÑÐ¾Ð²Ð°Ð½Ð¸Ñ Ð´Ñевовидной ÑÑÑкÑÑÑÑÑ
//ÐолÑÑаем ÑолÑко иденÑиÑикаÑоÑÑ Ñазделов
$res = $this->dbh->selectRequest('
SELECT s.smap_id, s.smap_pid FROM share_sitemap s
LEFT JOIN share_sitemap_translation st ON st.smap_id = s.smap_id
WHERE st.smap_is_disabled = 0 AND st.lang_id = %s AND smap_is_final = 0
ORDER BY smap_order_num
', $this->langID);
if ($res === true) {
throw new SystemException('ERR_NO_TRANSLATION', SystemException::ERR_CRITICAL);
}
//ФилÑÑÑÑем пеÑеÑÐµÐ½Ñ Ð¸Ð´ÐµÐ½ÑиÑикаÑоÑов оÑÑÐµÐºÐ°Ñ Ñе ÑÐ°Ð·Ð´ÐµÐ»Ñ Ð½Ð° коÑоÑÑе Ð½ÐµÑ Ð¿Ñав
$res = array_filter($res, array($this, 'checkPageRights'));
//ÐагÑÑжаем пеÑеÑÐµÐ½Ñ Ð¸Ð´ÐµÐ½ÑиÑикаÑоÑов в обÑÐµÐºÑ Ð´ÐµÑева
$this->tree = TreeConverter::convert($res, 'smap_id', 'smap_pid');
//ÐолÑÑаем деÑолÑнÑе meta заголовки
$res = $this->dbh->select('share_sitemap_translation', array('smap_meta_keywords', 'smap_meta_description'), array('smap_id' => $this->getDefault(), 'lang_id' => $this->langID));
list($res) = $res;
$this->defaultMetaKeywords = $res['smap_meta_keywords'];
$this->defaultMetaDescription = $res['smap_meta_description'];
$this->info = $this->getSitemapData(array_keys($this->tree->asList()));
}
/**
* ÐозвÑаÑÐ°ÐµÑ ÑкземплÑÑ Ð¾Ð±ÑекÑа Sitemap
*
* @access public
* @return Sitemap
* @static
*/
public static function getInstance() {
if (!isset(self::$instance)) {
self::$instance = new Sitemap();
}
return self::$instance;
}
/**
* ÐеÑод возвÑаÑаÑÑий инÑоÑмаÑÐ¸Ñ Ð¾ ÑазделаÑ
*
* @param mixed иденÑиÑикаÑÐ¾Ñ Ñаздела или маÑÑив иденÑиÑикаÑоÑов
* @return array
* @access private
*/
private function getSitemapData($id) {
if (!is_array($id)) {
$id = array($id);
}
$ids = implode(',', $id);
$result = convertDBResult(
$this->dbh->selectRequest(
'SELECT s.smap_id, s.smap_pid, s.tmpl_id as templateID, s.smap_segment as Segment, s.smap_is_final as isFinal, st.smap_name, smap_description_rtf, smap_html_title, smap_meta_keywords, smap_meta_description '.
'FROM share_sitemap s '.
'LEFT JOIN share_sitemap_translation st ON s.smap_id = st.smap_id '.
'WHERE st.lang_id = '.$this->langID.' AND s.smap_id IN ('.$ids.')'),
'smap_id', true);
$result = array_map(array($this, 'preparePageInfo'), $result);
return $result;
}
/**
* ÐнÑÑÑенний меÑод по пÑеобÑÐ°Ð·Ð¾Ð²Ð°Ð½Ð¸Ñ Ð¸Ð½ÑоÑмаÑии о докÑменÑе. Ð¡Ð²Ð¾Ð´Ð¸Ñ Ð²Ñе клÑÑи к camel notation и Ð´Ð»Ñ Ð»Ð¸Ð½ÐºÐ° изменÑÐµÑ Ð·Ð½Ð°Ñение иденÑиÑикаÑоÑа Ñаблона
*
* @param array
* @return array
* @access private
*/
private function preparePageInfo($current) {
$result = convertFieldNames($current,'smap');
if(is_null($result['MetaKeywords'])) $result['MetaKeywords'] = $this->defaultMetaKeywords;
if(is_null($result['MetaDescription'])) $result['MetaDescription'] = $this->defaultMetaDescription;
return $result;
}
/**
* ÐозвÑаÑÐ°ÐµÑ Ð¸Ð´ÐµÐ½ÑиÑикаÑÐ¾Ñ ÑÑÑаниÑÑ Ð¿Ð¾ ÑмолÑаниÑ
*
* @return int
* @access public
*/
public function getDefault() {
if (!$this->defaultID) {
$result = simplifyDBResult($this->dbh->select('share_sitemap', 'smap_id', array('smap_default' => true)), 'smap_id', true);
if ($result === false) {
throw new SystemException('ERR_DEV_NO_DEFAULT_PAGE', SystemException::ERR_CRITICAL);
}
$this->defaultID = $result;
}
return $this->defaultID;
}
/**
* ÐозвÑаÑÐ°ÐµÑ ÑаÑÑÑ ÑÑÑоки УРРпо иденÑиÑикаÑоÑÑ
*
* @param int
* @return string
* @access public
*/
public function getURLByID($smapID) {
$result = array();
$node = $this->tree->getNodeById($smapID);
if (!is_null($node)) {
$parents = array_reverse(array_keys($node->getParents()->asList(false)));
foreach ($parents as $id) {
if (isset($this->info[$id])) {
$result[] = $this->info[$id]['Segment'];
}
else {
$res = $this->getDocumentInfo($id, false);
$result[] = $res['Segment'];
}
}
}
$currentSegment = $this->getDocumentInfo($smapID);
$currentSegment = $currentSegment['Segment'];
$result[] = $currentSegment;
$result = implode('/', $result).'/';
return $result;
}
/**
* ÐозвÑаÑÐ°ÐµÑ Ð¸Ð´ÐµÐ½ÑиÑикаÑÐ¾Ñ ÑÑÑаниÑÑ Ð¿Ð¾ его URL
*
* @param array
* @return int
* @access public
*/
public function getIDByURI(array $segments, $useDefaultIfEmpty = false) {
$id = null;
$i = 1;
$request = Request::getInstance();
if (empty($segments) && $useDefaultIfEmpty) {
return $this->getDefault();
}
foreach ($segments as $segment) {
$res = $this->dbh->select('share_sitemap', array('smap_id'), array('smap_segment' => $segment, 'smap_pid' => $id));
if (!is_array($res)) {
break;
}
$request->setPathOffset($i);
list($res) = $res;
$id = $res['smap_id'];
$i++;
}
return $id;
}
/**
* ÐпÑеделение пÑав набоÑа гÑÑпп на ÑÑÑаниÑÑ
*
* @param int иденÑиÑикаÑÐ¾Ñ Ð´Ð¾ÐºÑменÑа
* @param mixed гÑÑппа/Ð½Ð°Ð±Ð¾Ñ Ð³ÑÑпп, еÑли не Ñказан, беÑеÑÑÑ Ð³ÑÑппа/гÑÑÐ¿Ð¿Ñ ÑекÑÑего полÑзоваÑелÑ
* @return int
* @access public
*/
public function getDocumentRights($docID, $groups = false) {
if (!$groups) {
$user = AuthUser::getInstance();
$groups = $user->getGroups();
}
elseif (!is_array($groups)) {
$groups = array($groups);
}
$result = array(ACCESS_NONE);
foreach ($groups as $groupID) {
//Ð´Ð»Ñ ÐºÐ°Ð¶Ð´Ð¾Ð¹ гÑÑÐ¿Ð¿Ñ Ð¾Ð¿ÑеделÑем ÑÑÐ¾Ð²ÐµÐ½Ñ Ð¿Ñав
$res = $this->dbh->select('share_access_level', 'right_id', array('smap_id' => $docID, 'group_id' => $groupID));
if (is_array($res)) {
$result[] = simplifyDBResult($res, 'right_id', true);
}
}
return max($result);
}
/**
* ÐозвÑаÑÐ°ÐµÑ Ð¼ÐµÐ½Ñ Ð¿ÐµÑвого ÑÑовнÑ
*
* @return array
* @access public
*/
public function getMainLevel() {
return $this->buildPagesMap(array_keys($this->tree->asList(false)));
}
/**
* ÐозвÑаÑÐ°ÐµÑ Ð²Ñе доÑеÑние ÑазделÑ
*
* @param int иденÑиÑикаÑÐ¾Ñ Ñаздела
* @return array
* @access public
*/
public function getChilds($smapID) {
$result = array();
if ($node = $this->tree->getNodeById($smapID)) {
$result = $this->buildPagesMap(array_keys($node->getChildren()->asList(false)));
}
return $result;
}
/**
* ÐозвÑаÑÐ°ÐµÑ Ð¼Ð°ÑÑив ÑодиÑелей
*
* @param int ÐденÑÑикаÑÐ¾Ñ Ñаздела
* @return array
* @access public
*/
public function getParents($smapID) {
$node = $this->tree->getNodeById($smapID);
$result = array();
if (!is_null($node)) {
$result = $this->buildPagesMap(array_reverse(array_keys($node->getParents()->asList(false))));
}
return $result;
}
/**
* Ðо пеÑÐµÐ´Ð°Ð½Ð½Ð¾Ð¼Ñ Ð¼Ð°ÑÑÐ¸Ð²Ñ Ð¸Ð´ÐµÐ½ÑиÑикаÑоÑов Ñазделов и маÑÑÐ¸Ð²Ñ Ð¿ÐµÑеÑÐ½Ñ Ð¿Ð¾Ð»ÐµÐ¹ ÑоÑмиÑÑÐµÑ cÑÑÑкÑÑÑÑ array('$иденÑиÑикаÑоÑ_Ñаздела'=>array())
*
* @param array иденÑиÑикаÑоÑÑ Ñазделов
* @return array
* @access private
*/
private function buildPagesMap($ids) {
$result = array();
if (is_array($ids)) {
foreach ($ids as $id) {
$info = $this->getDocumentInfo($id);
$info['Segment'] = $this->getURLByID($id);
$result[$id] = $info;
}
}
return $result;
}
/**
* ÐозвÑаÑÐ°ÐµÑ Ð¸Ð½ÑоÑмаÑÐ¸Ñ Ð¾ докÑменÑе
* СнаÑала иÑем еÑÑÑ Ð»Ð¸ докÑÐ¼ÐµÐ½Ñ Ñ Ð½ÑжнÑм иденÑиÑикаÑоÑом в $this->info
* ÐÑли его Ñам неÑ, полÑÑаем инÑÑ Ð¾ нем и добавлÑем в $this->info
*
* @param int ÐденÑиÑикаÑÐ¾Ñ Ñаздела
* @param кеÑиÑоваÑÑ Ð»Ð¸ инÑоÑмаÑÐ¸Ñ Ð¾ ÑÑÑаниÑе в $this->info
* @return array
* @access public
*/
public function getDocumentInfo($id, $cache = true) {
if (!isset($this->info[$id])) {
$result = $this->getSitemapData($id);
if ($cache) {
$this->info = $this->info + $result;
}
$result = $result[$id];
}
else {
$result = $this->info[$id];
}
return $result;
}
/**
* ÐозвÑаÑÐ°ÐµÑ Ð¾Ð±ÑÐµÐºÑ Tree
*
* @return TreeNodeList
* @access public
*/
public function getTree() {
return $this->tree;
}
/**
* ÐозвÑаÑÐ°ÐµÑ Ð²ÑÑ Ð¸Ð½ÑоÑмаÑÐ¸Ñ Ð¾ ÑаздеаÑ
в не ÑÑÑÑкÑÑÑиÑованном виде
*
* @return array
* @access public
*/
public function getInfo() {
return $this->info;
}
/**
* ÐнÑÑÑенний меÑод Ð´Ð»Ñ ÑилÑÑÑаÑии Ñазделов, на коÑоÑÑе Ð½ÐµÑ Ð¿Ñав
* ÐÑзÑвеÑÑÑ ÐºÐ°Ðº callback Ð´Ð»Ñ array_filter
*
* @param array
* @return boolean
* @access private
*/
private function checkPageRights($smapInfo) {
return ($this->getDocumentRights($smapInfo['smap_id']) != ACCESS_NONE);
}
}