<?php
/**
* ÐлаÑÑ Document.
*
* @package energine
* @subpackage core
* @author dr.Pavka
* @copyright ColoCall 2006
* @version $Id: Document.class.php,v 1.19 2008/04/09 10:49:32 pavka Exp $
*/
//require_once('core/framework/DBWorker.class.php');
//require_once('core/framework/AuthUser.class.php');
//require_once('core/framework/Language.class.php');
//require_once('core/framework/Sitemap.class.php');
//require_once('core/framework/Request.class.php');
//require_once('core/framework/Response.class.php');
//require_once('core/framework/ComponentManager.class.php');
/**
* ÐокÑÐ¼ÐµÐ½Ñ ÑÑÑаниÑÑ.
*
* @package energine
* @subpackage core
* @final
*/
final class Document extends DBWorker {
/**
* ÐаÑезеÑвиÑованнÑй ÑÐµÐ³Ð¼ÐµÐ½Ñ URL Ð´Ð»Ñ single-Ñежима
*/
const SINGLE_SEGMENT = 'single';
/**
* ÐÑÑÑ Ðº диÑекÑоÑии Ñ ÐºÐ¾Ð½ÑигÑÑаÑионнÑми Ñаблонами
*/
const TEMPLATES_DIR = 'templates/';
/**
* @access private
* @var int иденÑиÑикаÑÐ¾Ñ Ð´Ð¾ÐºÑменÑа
*/
private $id = false;
/**
* @access private
* @var int иденÑиÑикаÑÐ¾Ñ ÑзÑка докÑменÑа
*/
private $lang;
/**
* @access protected
* @var Language инÑоÑмаÑÐ¸Ñ Ð¾ ÑзÑкаÑ
ÑиÑÑемÑ
*/
protected $language;
/**
* @access protected
* @var Sitemap каÑÑа ÑайÑа
*/
protected $sitemap;
/**
* @access private
* @var Request
*/
private $request;
/**
* @access public
* @var ComponentManager Ð¼ÐµÐ½ÐµÐ´Ð¶ÐµÑ ÐºÐ¾Ð¼Ð¿Ð¾Ð½ÐµÐ½Ñов
*/
public $componentManager;
/**
* @access private
* @var DOMDocument ÑезÑлÑÑиÑÑÑÑий DOM-докÑменÑ
*/
private $doc;
/**
* @access private
* @var int пÑава полÑзоваÑÐµÐ»Ñ Ð½Ð° докÑменÑ
*/
private $rights = false;
/**
* @access private
* @var array ÑвойÑÑва докÑменÑа
*/
private $properties = array();
/**
* @access public
* @var AuthUser ÑкземплÑÑ ÐºÐ»Ð°ÑÑа AuthUser
* @see AuthUser
*/
public $user;
/**
* @access private
* @var array инÑоÑмаÑÐ¸Ñ Ð¾ докÑменÑе
* @see Sitemap::getDocumentInfo()
*/
private $documentInfo = array();
/**
* ÐеÑеÑÐµÐ½Ñ ÐºÐ¾Ð¼Ð¿Ð¾Ð½ÐµÐ½Ñов layout'а
*
* @var array
* @access private
*/
private $layoutComponents = array();
/**
* ÐеÑеÑÐµÐ½Ñ ÐºÐ¾Ð¼Ð¿Ð¾Ð½ÐµÐ½Ñов content'а
*
* @var array
* @access private
*/
private $contentComponents = array();
/**
* ÐаÑÑив конÑÑÐ°Ð½Ñ Ð´Ð»Ñ Ð¿ÐµÑевода
*
* @var array
* @access private
*/
private $translations = array();
/**
* ÐонÑÑÑÑкÑÐ¾Ñ ÐºÐ»Ð°ÑÑа.
*
* @access public
* @return void
*/
public function __construct() {
parent::__construct();
$this->user = AuthUser::getInstance();
$this->language = Language::getInstance();
$this->lang = $this->language->getCurrent();
$this->sitemap = Sitemap::getInstance();
$this->request = Request::getInstance();
$this->componentManager = new ComponentManager($this);
// полÑÑаем иденÑиÑикаÑÐ¾Ñ Ð´Ð¾ÐºÑменÑа
$segments = $this->request->getPath();
if (isset($segments[0]) && $segments[0] == self::SINGLE_SEGMENT) $segments = array();
$this->id = $this->sitemap->getIDByURI($segments, true);
if (empty($this->id)) {
throw new SystemException('ERR_404', SystemException::ERR_404);
}
// полÑÑаем пÑава полÑзоваÑÐµÐ»Ñ Ð½Ð° докÑменÑ
$this->rights = $this->sitemap->getDocumentRights($this->getID(), $this->user->getGroups());
if ($this->getRights() == ACCESS_NONE) {
throw new SystemException('ERR_403', SystemException::ERR_403);
}
// полÑÑаем инÑоÑмаÑÐ¸Ñ Ð¾ докÑменÑе
$this->documentInfo = $this->sitemap->getDocumentInfo($this->getID());
//ÐÑли его Ð½ÐµÑ Ð² пеÑеÑне ÑÑÑÐ°Ð½Ð¸Ñ Ð·Ð½Ð°ÑÐ¸Ñ Ð¾Ð½ IsDisabled
if (!$this->documentInfo) {
throw new SystemException('ERR_404', SystemException::ERR_404);
}
// загÑÑжаем компоненÑÑ ÑÑÑаниÑÑ
$this->loadComponents($this->documentInfo['templateID']);
// ÑÑÑанавливаем ÑвойÑÑва докÑменÑа
$this->setProperty('base', $this->request->getBasePath());
$this->setProperty('keywords', $this->documentInfo['MetaKeywords']);
$this->setProperty('description', $this->documentInfo['MetaDescription']);
$this->setProperty('ID', $this->getID());
$this->setProperty('final', $this->documentInfo['isFinal']);
$this->setProperty('default', $this->sitemap->getDefault()==$this->getID());
/*
* ÐÑли в каком-либо компоненÑе пÑоиÑÑ
Ð¾Ð´Ð¸Ñ Ð¾Ñибка, не позволÑÑÑÐ°Ñ ÐµÐ¼Ñ
* пÑодолжиÑÑ ÑабоÑÑ, генеÑиÑÑеÑÑÑ ÑикÑивное иÑклÑÑение, Ñ Ð¿Ð¾Ð¼Ð¾ÑÑÑ
* коÑоÑого пÑеÑÑваеÑÑÑ ÑабоÑа компоненÑа. РдалÑнейÑем, пÑи вÑзове
* меÑода Document::build, пÑоиÑÑ
Ð¾Ð´Ð¸Ñ Ð¾Ð±ÑабоÑка вÑеÑ
возникÑиÑ
оÑибок.
*/
try {
$this->runComponents();
}
catch (DummyException $dummyException) {}
}
/**
* ÐозвÑаÑÐ°ÐµÑ Ð¸Ð´ÐµÐ½ÑиÑикаÑÐ¾Ñ Ð´Ð¾ÐºÑменÑа.
*
* @access public
* @return int
*/
public function getID() {
return $this->id;
}
/**
* ÐозвÑаÑÐ°ÐµÑ Ð¸Ð´ÐµÐ½ÑиÑикаÑÐ¾Ñ ÑзÑка докÑменÑа.
*
* @access public
* @return int
*/
public function getLang() {
return $this->lang;
}
/**
* ÐапÑÑÐºÐ°ÐµÑ Ð¿Ð¾ÑÑÑоение компоненÑов ÑÑÑаниÑÑ Ð¸ возвÑаÑÐ°ÐµÑ ÑезÑлÑÑÐ°Ñ Ð² виде
* ÑобÑанного DOM-докÑменÑа ÑÑÑаниÑÑ.
*
* @access public
* @return DOMDocument
*/
public function build() {
$this->doc = new DOMDocument('1.0', 'UTF-8');
$dom_root = $this->doc->createElement('document');
$dom_root->setAttribute('debug', $this->getConfigValue('site.debug'));
$this->doc->appendChild($dom_root);
if (!isset($this->properties['title'])) {
$this->setProperty('title', $this->documentInfo['Name']);
}
$dom_documentProperties = $this->doc->createElement('properties');
foreach ($this->properties as $propName => $propValue) {
$dom_property = $this->doc->createElement('property', str_replace('&', '&', $propValue));
$dom_property->setAttribute('name', $propName);
if ($propName == 'title') {
$dom_property->setAttribute('alt', $this->documentInfo['HtmlTitle']);
}
$dom_documentProperties->appendChild($dom_property);
}
$dom_root->appendChild($dom_documentProperties);
$langProperty = $this->doc->createElement('property', $this->getLang());
$langProperty ->setAttribute('name', 'lang');
$langProperty ->setAttribute('abbr', $this->request->getLangSegment());
$dom_documentProperties->appendChild($langProperty);
if (!empty($this->translations)) {
$dom_translations = $this->doc->createElement('translations');
foreach ($this->translations as $const => $value) {
$dom_translation = $this->doc->createElement('translation', $value);
$dom_translation->setAttribute('const', $const);
$dom_translations->appendChild($dom_translation);
}
$dom_root->appendChild($dom_translations);
}
$dom_layout = $this->doc->createElement('layout');
$dom_layout->setAttribute('file', $this->documentInfo['layoutFileName']);
$dom_content = $this->doc->createElement('content');
$dom_content->setAttribute('file', $this->documentInfo['contentFileName']);
$dom_root->appendChild($dom_layout);
$dom_root->appendChild($dom_content);
foreach ($this->componentManager->getComponents() as $componentInfo) {
$component = $componentInfo['component'];
$componentResult = false;
$dom_errors = false;
if ($this->getRights() >= $component->getMethodRights() && $component->enabled()) {
try {
$componentResult = $component->build();
}
catch (DummyException $dummyException){}
}
if ($componentResult) {
$componentResult = $this->doc->importNode(
$componentResult->documentElement,
true
);
if ($dom_errors) {
$componentResult->insertBefore($dom_errors, $componentResult->firstChild);
}
if ($componentInfo['file'] == $this->documentInfo['layoutFileName']) {
$dom_layout->appendChild($componentResult);
}
elseif ($componentInfo['file'] == $this->documentInfo['contentFileName']) {
$dom_content->appendChild($componentResult);
}
else {
$dom_root->appendChild($componentResult);
}
}
elseif ($dom_errors) {
$dom_root->appendChild($dom_errors);
}
}
}
/**
* ÐпÑеделÑÐµÑ ÐºÐ¾Ð¼Ð¿Ð¾Ð½ÐµÐ½ÑÑ ÑÑÑаниÑÑ Ð¸ загÑÑÐ¶Ð°ÐµÑ Ð¸Ñ
в Ð¼ÐµÐ½ÐµÐ´Ð¶ÐµÑ ÐºÐ¾Ð¼Ð¿Ð¾Ð½ÐµÐ½Ñов.
*
* @access private
* @param int $templateID иденÑиÑикаÑÐ¾Ñ Ñаблона ÑÑÑаниÑÑ
* @return void
* @todo ÐолнÑй ÑеÑакÑоÑинг!
*/
private function loadComponents($templateID) {
// полÑÑаем инÑоÑмаÑÐ¸Ñ Ð¾ Ñаблоне ÑÑÑаниÑÑ
$res = $this->dbh->select('share_templates', true, array('tmpl_id' => $templateID));
if (!is_array($res)) {
throw new SystemException('ERR_DEV_NO_TEMPLATE_INFO', SystemException::ERR_CRITICAL);
}
$templateInfo = $res[0];
// опÑеделÑем и загÑÑжаем опиÑÐ°Ð½Ð¸Ñ content- и layout- ÑаÑÑей ÑÑÑаниÑÑ
$this->documentInfo['layoutFileName'] = self::TEMPLATES_DIR.'layout/'.$templateInfo['tmpl_layout'];
$this->documentInfo['contentFileName'] = self::TEMPLATES_DIR.'content/'.$templateInfo['tmpl_content'];
// вÑзÑваеÑÑÑ Ð»Ð¸ какой-либо ÐºÐ¾Ð¼Ð¿Ð¾Ð½ÐµÐ½Ñ Ð² single Ñежиме?
$actionParams = $this->request->getPath(Request::PATH_ACTION);
if (sizeof($actionParams) > 1 && $actionParams[0] == self::SINGLE_SEGMENT) {
/*
* УÑÑанавливаем ÑмеÑение пÑÑи на колиÑеÑÑво ÑÑÑеÑÑвÑÑÑиÑ
* ÑегменÑов + 1 заÑезиÑвиÑованнÑй ÑÐµÐ³Ð¼ÐµÐ½Ñ + 1 ÑегменÑ
* имени компоненÑа.
*/
$this->request->setPathOffset($this->request->getPathOffset() + 2);
$this->setProperty('single', 'single');
if ($actionParams[1] == 'pageToolBar') {
$this->componentManager->addComponent($this->componentManager->createComponent('pageToolBar', 'share', 'DivisionEditor', array('action' => 'showPageToolbar')));
}
// ÑÑÑеÑÑвÑÐµÑ Ð»Ð¸ запÑоÑеннÑй ÐºÐ¾Ð¼Ð¿Ð¾Ð½ÐµÐ½Ñ ÑÑеди компоненÑов ÑÑÑаниÑÑ?
elseif (
!$this->componentManager->loadComponentsFromFile($this->documentInfo['layoutFileName'], $actionParams[1])
&& !$this->componentManager->loadComponentsFromFile($this->documentInfo['contentFileName'], $actionParams[1])
) {
throw new SystemException('ERR_NO_SINGLE_COMPONENT', SystemException::ERR_CRITICAL);
}
}
else {
$this->componentManager->loadComponentsFromFile($this->documentInfo['layoutFileName']);
$this->componentManager->loadComponentsFromFile($this->documentInfo['contentFileName']);
/*
* ÐобавлÑем к набоÑÑ ÐºÐ¾Ð¼Ð¿Ð¾Ð½ÐµÐ½Ñов ÑÑÑаниÑÑ
* обÑзаÑелÑнÑе ÑÑандаÑÑнÑе компоненÑÑ:
* - ActionSet
* - BreadCrumbs
*/
$this->componentManager->addComponent($this->componentManager->createComponent('pageToolBar', 'share', 'DivisionEditor', array('action' => 'showPageToolbar')));
$this->componentManager->addComponent($this->componentManager->createComponent('breadCrumbs', 'share', 'BreadCrumbs'));
}
}
/**
* ÐапÑÑÐºÐ°ÐµÑ ÑабоÑÑ Ð²ÑеÑ
компоненÑов ÑÑÑаниÑÑ.
*
* @access private
* @return void
*/
private function runComponents() {
foreach ($this->componentManager->getComponents() as $componentInfo) {
$component = $componentInfo['component'];
/*
* ÐапÑÑкаем опÑеделение ÑекÑÑего дейÑÑÐ²Ð¸Ñ ÐºÐ¾Ð¼Ð¿Ð¾Ð½ÐµÐ½Ñа
* и загÑÑÐ·ÐºÑ ÐºÐ¾Ð½ÑигÑÑаÑионной инÑоÑмаÑии.
*/
//$component->getAction();
// еÑли Ñ Ð¿Ð¾Ð»ÑзоваÑÐµÐ»Ñ Ð´Ð¾ÑÑаÑоÑно пÑав - запÑÑкаем ÑабоÑÑ ÐºÐ¾Ð¼Ð¿Ð¾Ð½ÐµÐ½Ñа
if ($this->getRights() >= $component->getMethodRights()) {
$component->run();
}
}
}
/**
* ÐозвÑаÑÐ°ÐµÑ ÑезÑлÑÑиÑÑÑÑий DOM-докÑменÑ.
*
* @access public
* @return DOMDocument
*/
public function getResult() {
return $this->doc;
}
/**
* ÐозвÑаÑÐ°ÐµÑ Ð¾Ð±ÑÐµÐºÑ ÑекÑÑего полÑзоваÑелÑ.
*
* @access public
* @return AuthUser
*/
public function getUser() {
return $this->user;
}
/**
* ÐозвÑаÑÐ°ÐµÑ Ð¿Ñава полÑзоваÑÐµÐ»Ñ Ð½Ð° докÑменÑ.
*
* @access public
* @return int
*/
public function getRights() {
return $this->rights;
}
/**
* УÑÑÐ°Ð½Ð°Ð²Ð»Ð¸Ð²Ð°ÐµÑ Ð·Ð½Ð°Ñение ÑвойÑÑва докÑменÑа.
*
* @access public
* @param string $propName
* @param string $propValue
* @return void
*/
public function setProperty($propName, $propValue) {
$this->properties[$propName] = $propValue;
}
/**
* ÐозвÑаÑÐ°ÐµÑ Ð·Ð½Ð°Ñение ÑвойÑÑва докÑменÑа.
*
* @access public
* @param string $propName
* @return string
*/
public function getProperty($propName) {
if (isset($this->properties[$propName])) {
return $this->properties[$propName];
}
return false;
}
/**
* УдалÑÐµÑ ÑвойÑÑво докÑменÑа.
*
* @access protected
* @param string $propName
* @return void
*/
protected function removeProperty($propName) {
if (isset($this->properties[$propName])) {
unset($this->properties[$propName]);
}
}
/**
* ÐозвÑаÑÐ°ÐµÑ Ð°Ð±ÑолÑÑнÑй пÑÑÑ
*
* @return string
* @access public
*/
public function getSiteRoot() {
return dirname($_SERVER['SCRIPT_FILENAME']);
}
/**
* ÐобавлÑÐµÑ ÐºÐ¾Ð½ÑÑанÑÑ Ð¿ÐµÑевода к докÑменÑÑ
*
* @param string
* @return void
* @access public
*/
public function addTranslation($const) {
$this->translations[$const] = $this->translate($const);
}
}