energine
[ class tree: energine ] [ index: energine ] [ all elements ]

Source for file Document.class.php

Documentation is available at Document.class.php

  1. <?php
  2.  
  3. /**
  4.  * Класс Document.
  5.  *
  6.  * @package energine
  7.  * @subpackage core
  8.  * @author dr.Pavka
  9.  * @copyright Energine 2006
  10.  * @version $Id$
  11.  */
  12.  
  13. /**
  14.  * Документ страницы.
  15.  *
  16.  * @package energine
  17.  * @subpackage core
  18.  * @author dr.Pavka
  19.  * @final
  20.  */
  21. final class Document extends DBWorker {
  22.     /**
  23.      * Зарезервированный сегмент URL для single-режима
  24.      */
  25.     const SINGLE_SEGMENT = 'single';
  26.  
  27.     /**
  28.      * Путь к директории с конфигурационными шаблонами
  29.      */
  30.     const TEMPLATES_DIR = 'templates/';
  31.  
  32.     /**
  33.      * @access private
  34.      * @var int идентификатор документа
  35.      */
  36.     private $id = false;
  37.  
  38.     /**
  39.      * @access private
  40.      * @var int идентификатор языка документа
  41.      */
  42.     private $lang;
  43.  
  44.     /**
  45.      * @access protected
  46.      * @var Language информация о языках системы
  47.      */
  48.     protected $language;
  49.  
  50.     /**
  51.      * @access protected
  52.      * @var Sitemap карта сайта
  53.      */
  54.     protected $sitemap;
  55.  
  56.     /**
  57.      * @access private
  58.      * @var Request 
  59.      */
  60.     private $request;
  61.  
  62.     /**
  63.      * @access public
  64.      * @var ComponentManager менеджер компонентов
  65.      */
  66.     public $componentManager;
  67.  
  68.     /**
  69.      * @access private
  70.      * @var DOMDocument результирующий DOM-документ
  71.      */
  72.     private $doc;
  73.  
  74.     /**
  75.      * @access private
  76.      * @var int права пользователя на документ
  77.      */
  78.     private $rights = false;
  79.  
  80.     /**
  81.      * @access private
  82.      * @var array свойства документа
  83.      */
  84.     private $properties = array();
  85.  
  86.     /**
  87.      * @access public
  88.      * @var AuthUser экземпляр класса AuthUser
  89.      * @see AuthUser
  90.      */
  91.     public $user;
  92.  
  93.     /**
  94.      * @access private
  95.      * @var array информация о документе
  96.      * @see Sitemap::getDocumentInfo()
  97.      */
  98.     private $documentInfo = array();
  99.  
  100.     /**
  101.      * Перечень компонентов layout'а
  102.      *
  103.      * @var array 
  104.      * @access private
  105.      */
  106.     private $layoutComponents = array();
  107.  
  108.     /**
  109.      * Перечень компонентов content'а
  110.      *
  111.      * @var array 
  112.      * @access private
  113.      */
  114.     private $contentComponents = array();
  115.  
  116.     /**
  117.      * Массив констант для перевода
  118.      *
  119.      * @var array 
  120.      * @access private
  121.      */
  122.     private $translations = array();
  123.  
  124.     /**
  125.      * Конструктор класса.
  126.      *
  127.      * @access public
  128.      * @return void 
  129.      */
  130.     public function __construct($segments{
  131.         parent::__construct();
  132.         $this->user = AuthUser::getInstance();
  133.         $this->language = Language::getInstance();
  134.         $this->lang = $this->language->getCurrent();
  135.         $this->sitemap = Sitemap::getInstance();
  136.         $this->request = Request::getInstance();
  137.         $this->componentManager = new ComponentManager($this);
  138.         // получаем идентификатор документа
  139.         if (isset($segments[0]&& $segments[0== self::SINGLE_SEGMENT$segments array();
  140.         $this->id = $this->sitemap->getIDByURI($segmentstrue);
  141.         if (empty($this->id)) {
  142.             throw new SystemException('ERR_404'SystemException::ERR_404);
  143.         }
  144.  
  145.         // получаем права пользователя на документ
  146.         $this->rights = $this->sitemap->getDocumentRights($this->getID()$this->user->getGroups());
  147.         if ($this->getRights(== ACCESS_NONE{
  148.             throw new SystemException('ERR_403'SystemException::ERR_403);
  149.         }
  150.  
  151.         // получаем информацию о документе
  152.         $this->documentInfo = $this->sitemap->getDocumentInfo($this->getID());
  153.         //Если его нет в перечне страниц значит он IsDisabled
  154.         if (!$this->documentInfo{
  155.             throw new SystemException('ERR_404'SystemException::ERR_404);
  156.         }
  157.         //Если URL редиректа не пустой  - осуществляем редирект по нему
  158.         if(!empty($this->documentInfo['RedirectUrl'])){
  159.             Response::getInstance()->setStatus('301');
  160.             Response::getInstance()->setRedirect($this->documentInfo['RedirectUrl']);
  161.         }
  162.         // загружаем компоненты страницы
  163.         //$this->loadComponents($this->documentInfo['templateID']);
  164.  
  165.         // устанавливаем свойства документа
  166.         $this->setProperty('base'$this->request->getBasePath());
  167.         $this->setProperty('keywords'$this->documentInfo['MetaKeywords']);
  168.         $this->setProperty('description'$this->documentInfo['MetaDescription']);
  169.         $this->setProperty('ID'$this->getID());
  170.         $this->setProperty('final'$this->documentInfo['isFinal']);
  171.         $this->setProperty('default'$this->sitemap->getDefault()==$this->getID());
  172.         if(($verifyCode $this->getConfigValue('google.verify')) && !empty($verifyCode)){
  173.             $this->setProperty('google_verify'$verifyCode);
  174.         }
  175.         unset($verifyCode);
  176.     }
  177.  
  178.     /**
  179.      * Возвращает идентификатор документа.
  180.      *
  181.      * @access public
  182.      * @return int 
  183.      */
  184.     public function getID({
  185.         return $this->id;
  186.     }
  187.  
  188.     /**
  189.      * Возвращает идентификатор языка документа.
  190.      *
  191.      * @access public
  192.      * @return int 
  193.      */
  194.     public function getLang({
  195.         return $this->lang;
  196.     }
  197.  
  198.     /**
  199.      * Запускает построение компонентов страницы и возвращает результат в виде
  200.      * собранного DOM-документа страницы.
  201.      *
  202.      * @access public
  203.      * @return DOMDocument 
  204.      */
  205.     public function build({
  206.         $this->doc = new DOMDocument('1.0''UTF-8');
  207.         $dom_root $this->doc->createElement('document');
  208.         $dom_root->setAttribute('debug'$this->getConfigValue('site.debug'));
  209.         $this->setProperty('url'(string)$this->request->getURI());
  210.  
  211.         $this->doc->appendChild($dom_root);
  212.         if (!isset($this->properties['title'])) {
  213.             $this->setProperty('title'$this->documentInfo['Name']);
  214.         }
  215.         $dom_documentProperties $this->doc->createElement('properties');
  216.         foreach ($this->properties as $propName => $propValue{
  217.             $dom_property $this->doc->createElement('property'str_replace('&''&amp;'$propValue));
  218.             $dom_property->setAttribute('name'$propName);
  219.             if ($propName == 'title'{
  220.                 $dom_property->setAttribute('alt'$this->documentInfo['HtmlTitle']);
  221.             }
  222.             $dom_documentProperties->appendChild($dom_property);
  223.         }
  224.         $dom_root->appendChild($dom_documentProperties);
  225.  
  226.         $langProperty $this->doc->createElement('property'$this->getLang());
  227.         $langProperty ->setAttribute('name''lang');
  228.         $langProperty ->setAttribute('abbr'$this->request->getLangSegment());
  229.         $langProperty ->setAttribute('real_abbr'Language::getInstance()->getAbbrByID($this->getLang()));
  230.         $dom_documentProperties->appendChild($langProperty);
  231.         
  232.         $dom_layout $this->doc->createElement('layout');
  233.         $dom_layout->setAttribute('file'$this->documentInfo['layoutFileName']);
  234.         $dom_content $this->doc->createElement('content');
  235.         $dom_content->setAttribute('file'$this->documentInfo['contentFileName']);
  236.  
  237.         $dom_root->appendChild($dom_layout);
  238.         $dom_root->appendChild($dom_content);
  239.  
  240.  
  241.  
  242.         foreach ($this->componentManager->getComponents(as $componentInfo{
  243.             $component $componentInfo['component'];
  244.  
  245.             $componentResult false;
  246.             $dom_errors false;
  247.  
  248.             if ($this->getRights(>= $component->getMethodRights(&& $component->enabled()) {
  249.                 try {
  250.                         $componentResult $component->build();
  251.                 }
  252.                 catch (DummyException $dummyException){}
  253.             }
  254.  
  255.             if ($componentResult{
  256.                 $componentResult $this->doc->importNode(
  257.                 $componentResult->documentElement,
  258.                 true
  259.                 );
  260.  
  261.                 if ($dom_errors{
  262.                     $componentResult->insertBefore($dom_errors$componentResult->firstChild);
  263.                 }
  264.  
  265.                 if ($componentInfo['file'== $this->documentInfo['layoutFileName']{
  266.                     $dom_layout->appendChild($componentResult);
  267.                 }
  268.                 elseif ($componentInfo['file'== $this->documentInfo['contentFileName']{
  269.                     $dom_content->appendChild($componentResult);
  270.                 }
  271.                 else {
  272.                     $dom_root->appendChild($componentResult);
  273.                 }
  274.  
  275.             }
  276.             elseif ($dom_errors{
  277.                 $dom_root->appendChild($dom_errors);
  278.             }
  279.         }
  280.         
  281.             if (!empty($this->translations)) {
  282.             $dom_translations $this->doc->createElement('translations');
  283.             $dom_root->appendChild($dom_translations);
  284.         
  285.             foreach ($this->translations as $const => $componentName{
  286.                 $dom_translation $this->doc->createElement('translation'$this->translate($const));
  287.                 $dom_translation->setAttribute('const'$const);
  288.                 if(!is_null($componentName)){
  289.                    $dom_translation->setAttribute('component'$componentName);
  290.                 }
  291.                 $dom_translations->appendChild($dom_translation);
  292.             }
  293.         }
  294.     }
  295.  
  296.     /**
  297.      * Определяет компоненты страницы и загружает их в менеджер компонентов.
  298.      *
  299.      * @access public
  300.      * @param int $templateID идентификатор шаблона страницы
  301.      * @return void 
  302.      * @todo Полный рефакторинг!
  303.      */
  304.     public function loadComponents($templateID{
  305.         // получаем информацию о шаблоне страницы
  306.         $res $this->dbh->select('share_templates'truearray('tmpl_id' => $templateID));
  307.         if (!is_array($res)) {
  308.             throw new SystemException('ERR_DEV_NO_TEMPLATE_INFO'SystemException::ERR_CRITICAL);
  309.         }
  310.         list($templateInfo$res;
  311.  
  312.         // определяем и загружаем описания content- и layout- частей страницы
  313.         $this->documentInfo['layoutFileName'self::TEMPLATES_DIR.'layout/'.$templateInfo['tmpl_layout'];
  314.         $this->documentInfo['contentFileName'self::TEMPLATES_DIR.'content/'.$templateInfo['tmpl_content'];
  315.  
  316.         // вызывается ли какой-либо компонент в single режиме?
  317.         $actionParams $this->request->getPath(Request::PATH_ACTION);
  318.         if (sizeof($actionParams&& $actionParams[0== self::SINGLE_SEGMENT{
  319.                 /*
  320.                 * Устанавливаем смещение пути на количество существующих
  321.                 * сегментов + 1 зарезирвированный сегмент + 1 сегмент
  322.                 * имени компонента.
  323.                 */
  324.                 $this->request->setPathOffset($this->request->getPathOffset(2);
  325.                 $this->setProperty('single''single');
  326.                 if ($actionParams[1== 'pageToolBar'{
  327.                     $this->componentManager->addComponent($this->componentManager->createComponent('pageToolBar''share''DivisionEditor'array('action' => 'showPageToolbar')));
  328.                 }
  329.                 // существует ли запрошенный компонент среди компонентов страницы?
  330.                 elseif (
  331.                     !$this->componentManager->loadComponentsFromFile($this->documentInfo['layoutFileName']$actionParams[1])
  332.                     && !$this->componentManager->loadComponentsFromFile($this->documentInfo['contentFileName']$actionParams[1])
  333.                 {
  334.                     throw new SystemException('ERR_NO_SINGLE_COMPONENT'SystemException::ERR_CRITICAL);
  335.                 }
  336.         }
  337.         else {
  338.             $this->componentManager->loadComponentsFromFile($this->documentInfo['layoutFileName']);
  339.             $this->componentManager->loadComponentsFromFile($this->documentInfo['contentFileName']);
  340.             /*
  341.             * Добавляем к набору компонентов страницы
  342.             * обязательные стандартные компоненты:
  343.             *     - ActionSet
  344.             *     - BreadCrumbs
  345.             */
  346.             $this->componentManager->addComponent($this->componentManager->createComponent('pageToolBar''share''DivisionEditor'array('action' => 'showPageToolbar')));
  347.             $this->componentManager->addComponent($this->componentManager->createComponent('breadCrumbs''share''BreadCrumbs'));
  348.         }
  349.     }
  350.  
  351.     /**
  352.      * Запускает работу всех компонентов страницы.
  353.      *
  354.      * @access public
  355.      * @return void 
  356.      */
  357.     public function runComponents({
  358.         foreach ($this->componentManager->getComponents(as $componentInfo{
  359.             $component $componentInfo['component'];
  360.             /*
  361.             * Запускаем определение текущего действия компонента
  362.             * и загрузку конфигурационной информации.
  363.             */
  364.             //$component->getAction();
  365.  
  366.             // если у пользователя достаточно прав - запускаем работу компонента
  367.             if ($this->getRights(>= $component->getMethodRights()) {
  368.                 $component->run();
  369.             }
  370.         }
  371.     }
  372.  
  373.     /**
  374.      * Возвращает результирующий DOM-документ.
  375.      *
  376.      * @access public
  377.      * @return DOMDocument 
  378.      */
  379.     public function getResult({
  380.         return $this->doc;
  381.     }
  382.  
  383.     /**
  384.      * Возвращает объект текущего пользователя.
  385.      *
  386.      * @access public
  387.      * @return AuthUser 
  388.      */
  389.     public function getUser({
  390.         return $this->user;
  391.     }
  392.  
  393.     /**
  394.      * Возвращает права пользователя на документ.
  395.      *
  396.      * @access public
  397.      * @return int 
  398.      */
  399.     public function getRights({
  400.         return $this->rights;
  401.     }
  402.  
  403.     /**
  404.      * Устанавливает значение свойства документа.
  405.      *
  406.      * @access public
  407.      * @param string $propName 
  408.      * @param string $propValue 
  409.      * @return void 
  410.      */
  411.     public function setProperty($propName$propValue{
  412.         $this->properties[$propName$propValue;
  413.     }
  414.  
  415.     /**
  416.      * Возвращает значение свойства документа.
  417.      *
  418.      * @access public
  419.      * @param string $propName 
  420.      * @return string 
  421.      */
  422.     public function getProperty($propName{
  423.         if (isset($this->properties[$propName])) {
  424.             return $this->properties[$propName];
  425.         }
  426.         return false;
  427.     }
  428.  
  429.     /**
  430.      * Удаляет свойство документа.
  431.      *
  432.      * @access protected
  433.      * @param string $propName 
  434.      * @return void 
  435.      */
  436.     protected function removeProperty($propName{
  437.         if (isset($this->properties[$propName])) {
  438.             unset($this->properties[$propName]);
  439.         }
  440.     }
  441.  
  442.     /**
  443.      * Возвращает абсолютный путь
  444.      *
  445.      * @return string 
  446.      * @access public
  447.      */
  448. /*
  449.     public function getSiteRoot() {
  450.         return dirname($_SERVER['SCRIPT_FILENAME']);
  451.     }*/
  452.  
  453.     /**
  454.      * Добавляет константу перевода к документу
  455.      *
  456.      * @param string 
  457.      * @param Component 
  458.      * 
  459.      * @return void 
  460.      * @access public
  461.      */
  462.  
  463.     public function addTranslation($constComponent $component null{
  464.         $this->translations[$const(!is_null($component))?$component->getName():null;
  465.     }
  466.     
  467.     public function isEditable(){
  468.         return ($this->getConfigValue('site.debug'))?isset($_REQUEST['editMode']):isset($_POST['editMode']);    
  469.     }
  470. }
В создании документации нам помог: phpDocumentor