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

Source for file Component.class.php

Documentation is available at Component.class.php

  1. <?php
  2.  
  3. /**
  4.  * Класс Component.
  5.  *
  6.  * @package energine
  7.  * @subpackage core
  8.  * @author 1m.dm
  9.  * @copyright Energine 2006
  10.  * @version $Id$
  11.  */
  12.  
  13. //require_once('core/framework/ComponentConfig.class.php');
  14. //require_once('core/framework/DBWorker.class.php');
  15. //require_once('core/framework/Request.class.php');
  16. //require_once('core/framework/Builder.class.php');
  17.  
  18. /**
  19.  * Компонент страницы.
  20.  *
  21.  * @package energine
  22.  * @subpackage core
  23.  * @author 1m.dm
  24.  */
  25. class Component extends DBWorker {
  26.  
  27.     /**
  28.      * Имя действия по-умолчанию.
  29.      */
  30.     const DEFAULT_ACTION_NAME = 'main';
  31.     /**
  32.      * @access protected
  33.      * @var DOMDocument DOM-документ компонента
  34.      */
  35.     protected $doc;
  36.  
  37.     /**
  38.      * @access protected
  39.      * @var Request экземпляр объекта Request
  40.      */
  41.     protected $request;
  42.  
  43.     /**
  44.      * @access protected
  45.      * @var array параметры компонента
  46.      */
  47.     protected $params;
  48.  
  49.     /**
  50.      * @access public
  51.      * @var Document документ страницы
  52.      */
  53.     public $document;
  54.  
  55.     /**
  56.      * @access protected
  57.      * @var string имя модуля, которому принадлежит компонент
  58.      */
  59.     protected $module;
  60.  
  61.     /**
  62.      * @access protected
  63.      * @var Response экземпляр объекта Response
  64.      */
  65.     protected $response;
  66.  
  67.     /**
  68.      * @access private
  69.      * @var int уровень прав, необходимый для запуска метода компонента
  70.      */
  71.     private $rights;
  72.  
  73.     /**
  74.      * @access private
  75.      * @var string имя компонента
  76.      */
  77.     private $name;
  78.  
  79.     /**
  80.      * @var boolean Флаг, указывающий на то, является ли компонент активным
  81.      * @access private
  82.      */
  83.  
  84.     private $enabled = true;
  85.     /**
  86.      * @access private
  87.      * @var array параметры действия
  88.      */
  89.     private $actionParams = false;
  90.  
  91.     /**
  92.      * @access private
  93.      * @var array свойства компонента
  94.      */
  95.     private $properties = array();
  96.  
  97.     /**
  98.      * @access private
  99.      * @var array список ошибок, произошедших во время работы компонента
  100.      */
  101.     private $errors = array();
  102.  
  103.     /**
  104.      * Результат является объектом класса DOMNode или boolean:
  105.      * true - компонент отработал успешно, но ничего не вывел;
  106.      * false - произошла ошибка при работе компонента.
  107.      *
  108.      * @access private
  109.      * @var mixed результат работы компонента
  110.      */
  111.     private $result;
  112.  
  113.     /**
  114.      * @access private
  115.      * @var string имя текущего действия компонента
  116.      */
  117.     private $action = self::DEFAULT_ACTION_NAME;
  118.  
  119.     /**
  120.      * @access private
  121.      * @var Builder построитель результата работы компонента
  122.      */
  123.     private $builder = false;
  124.  
  125.     /**
  126.      * @access protected
  127.      * @var ComponentConfig конфигурация компонента
  128.      */
  129.     protected $config;
  130.  
  131.     /**
  132.      * Конструктор класса.
  133.      *
  134.      * @access public
  135.      * @param string $name 
  136.      * @param string $module 
  137.      * @param Document $document 
  138.      * @param array $params 
  139.      * @return void 
  140.      */
  141.     public function __construct($name$moduleDocument $documentarray $params null{
  142.         parent::__construct();
  143.  
  144.         $this->name = $name;
  145.         $this->module = $module;
  146.         $this->document = $document;
  147.         $this->params = $this->defineParams();
  148.         if (is_array($params)) {
  149.             foreach ($params as $name => $value{
  150.                 $this->setParam($name$value);
  151.             }
  152.         }
  153.         $this->rights $this->getParam('rights');
  154.         $this->response Response::getInstance();
  155.         $this->request Request::getInstance();
  156.         /**
  157.          * @todo Проверить, можно ли перенести в build
  158.          */
  159.         $this->doc new DOMDocument('1.0''UTF-8');
  160.  
  161.         $this->setProperty('template'$template $this->request->getPath(Request::PATH_TEMPLATEtrue));
  162.         $this->setProperty(
  163.             'single_template',
  164.             ($this->document->getProperty('single'$template $template.'single/'.$this->getName().'/')
  165.         );
  166.         $this->config new ComponentConfig($this->getParam('configFilename')get_class($this)$this->module);
  167.  
  168.         $this->determineAction();
  169.     }
  170. /*    
  171.     protected function __set($name, $value){
  172.         if($name == 'params'){
  173.             $this->setParam($name, $value);
  174.         }
  175.         else{
  176.             throw new SystemException('ERR_BAD_VARIABLE', SystemException::ERR_DEVELOPER, $name);
  177.         }
  178.     }
  179.     protected function __get($name){
  180.         $result = null;
  181.         if($name == 'params'){
  182.             $result =  $this->_params[$name];          
  183.         }
  184.         else{
  185.             throw new SystemException('ERR_BAD_VARIABLE', SystemException::ERR_DEVELOPER, $name);
  186.         }
  187.  
  188.         
  189.     }
  190. */
  191.      /**
  192.       * Возвращает флаг активности компонента
  193.       *
  194.       * @return bool 
  195.       * @access protected
  196.       * @final
  197.       */
  198.  
  199.       final protected function isActive({
  200.          return $this->params['active'];
  201.       }
  202.  
  203.  
  204.     /**
  205.      * Устанавливает построитель компонента.
  206.      *
  207.      * @access protected
  208.      * @final
  209.      * @param Builder $builder 
  210.      * @return void 
  211.      */
  212.     final protected function setBuilder(Builder $builder{
  213.         $this->builder $builder;
  214.     }
  215.  
  216.     /**
  217.      * Возвращает построитель компонента.
  218.      *
  219.      * @access protected
  220.      * @final
  221.      * @return Builder 
  222.      */
  223.     final protected function getBuilder({
  224.         return $this->builder;
  225.     }
  226.  
  227.     /**
  228.      * Определяет допустимые параметры компонента и их значения по-умолчанию
  229.      * в виде массива array(paramName => defaultValue).
  230.      *
  231.      * @access protected
  232.      * @return array 
  233.      */
  234.     protected function defineParams({
  235.         return array(
  236.             'action' => $this->action,
  237.             'rights' => $this->document->getRights(),
  238.             'configFilename' => false,
  239.             'active' => false,
  240.         );
  241.     }
  242.  
  243.     /**
  244.      * Устанавливает значение параметра компонента, если такой существует.
  245.      * В противном случае возбуждается исключение.
  246.      *
  247.      * @access protected
  248.      * @param string $name 
  249.      * @param mixed $value 
  250.      * @return void 
  251.      */
  252.     protected function setParam($name$value{
  253.         if (!isset($this->params[$name])) {
  254.             throw new SystemException('ERR_DEV_NO_PARAM'SystemException::ERR_DEVELOPER$name);
  255.         }
  256.         if($name == 'active'){
  257.             $value = (bool)$value;
  258.         }
  259.         /*if (in_array($name, array('action','configFilename', 'active'))) {
  260.             throw new SystemException('ERR_DEV_INVARIANT_PARAM', SystemException::ERR_DEVELOPER, $name);
  261.         }*/
  262.  
  263.         // если новое значение пустое - оставляем значение по-умолчанию
  264.         if (!empty($value|| $value === false{
  265.             if(!is_array($value)){
  266.                 //ОБрабатываем случай передачи массива-строки в параметры
  267.                 $value explode('|'$value);
  268.                 $this->params[$name(sizeof($value== 1)?current($value):$value;
  269.             }
  270.             else{
  271.                 $this->params[$namearray_values($value);
  272.             }
  273.         }
  274.     }
  275.  
  276.     /**
  277.      * Возвращает значение параметра компонента, или null, если такого
  278.      * параметра не существует.
  279.      *
  280.      * @access protected
  281.      * @final
  282.      * @param string $name 
  283.      * @return mixed 
  284.      */
  285.     final protected function getParam($name{
  286.         return (isset($this->params[$name]$this->params[$namenull);
  287.     }
  288.  
  289.     /**
  290.      * Определяет текущее действие
  291.      *
  292.      * @return void 
  293.      * @access private
  294.      */
  295.  
  296.     protected  function determineAction({
  297.         //Текущее действие берем из параметров
  298.         //По умолчанию оно равно self::DEFAULT_ACTION_NAME
  299.         $this->action $this->getParam('action');
  300.  
  301.         // если это основной компонент страницы, должен быть конфигурационный файл
  302.         if ($this->isActive()) {
  303.             if ($this->config->isEmpty()) {
  304.                 throw new SystemException('ERR_DEV_NO_COMPONENT_CONFIG'SystemException::ERR_DEVELOPER$this->getName());
  305.             }
  306.  
  307.             // определяем действие по запрошенному URI
  308.             $action $this->config->getActionByURI($this->request->getPath(Request::PATH_ACTIONtrue));
  309.             if ($action !== false{
  310.                 $this->action $action['name'];
  311.                 $this->actionParams $action['params'];
  312.             }
  313.  
  314.         }
  315.         // если имя действия указано в POST-запросе - используем его
  316.         elseif (isset($_POST[$this->getName()]['action'])) {
  317.             $this->action $_POST[$this->getName()]['action'];
  318.         }
  319.         // устанавливаем права на действие из конфигурации, если определены
  320.         if (!$this->config->isEmpty()) {
  321.             $this->config->setCurrentMethod($this->getAction());
  322.  
  323.             if (!is_null($rights $this->config->getCurrentMethodConfig()->getAttribute('rights'))) {
  324.                 $this->rights = (int)$rights;
  325.             }
  326.         }
  327.  
  328.     }
  329.  
  330.     /**
  331.      * Определяет имя текущего действия компонента.
  332.      *
  333.      * @access public
  334.      * @return string 
  335.      * @final
  336.      */
  337.     final public function getAction({
  338.         return $this->action;
  339.     }
  340.  
  341.     /**
  342.      * Возвращает уровень прав пользователя, необходимых для запуска
  343.      * текущего действия компонента.
  344.      *
  345.      * @access public
  346.      * @final
  347.      * @return int 
  348.      */
  349.     final public function getMethodRights({
  350.         return (int)$this->rights;
  351.     }
  352.  
  353.     /**
  354.      * Возвращает имя компонента.
  355.      *
  356.      * @access public
  357.      * @final
  358.      * @return string 
  359.      */
  360.     final public function getName({
  361.         return $this->name;
  362.     }
  363.  
  364.     /**
  365.      * Запускает компонент на исполнение.
  366.      *
  367.      * @access public
  368.      * @final
  369.      * @return void 
  370.      */
  371.     final public function run({
  372.         if (!method_exists($this$this->getAction())) {
  373.             throw new SystemException(
  374.                 'ERR_DEV_NO_ACTION',
  375.                 SystemException::ERR_DEVELOPER,
  376.                 array($this->getAction()$this->getName())
  377.             );
  378.         }
  379.         $this->{$this->getAction()}();
  380.     }
  381.  
  382.     /**
  383.      * Действие по-умолчанию.
  384.      *
  385.      * @access protected
  386.      * @return boolean 
  387.      */
  388.     protected function main({
  389.         $this->prepare()// вызываем метод подготовки данных
  390.         return true;
  391.     }
  392.  
  393.     /**
  394.      * Метод подготовки данных.
  395.      * Вызывается вначале работы метода, реализующего основное действие.
  396.      *
  397.      * @access protected
  398.      * @return void 
  399.      */
  400.      protected function prepare({
  401.      }
  402.      /**
  403.       * Отключает отображение компонента
  404.       *
  405.       * @return void 
  406.       * @access public
  407.       * @final
  408.       */
  409.  
  410.      final public function disable({
  411.          $this->enabled = false;
  412.      }
  413.  
  414.      /**
  415.       * Включает отображение компонента
  416.       *
  417.       * @return void 
  418.       * @access public
  419.       * @final
  420.       */
  421.  
  422.      final public function enable({
  423.          $this->enabled = true;
  424.      }
  425.  
  426.      /**
  427.       * Возвращает активность компонента
  428.       *
  429.       * @return boolean 
  430.       * @access public
  431.       * @final
  432.       */
  433.  
  434.      final public function enabled({
  435.          return $this->enabled;
  436.      }
  437.     /**
  438.      * Устанавливает значение свойства компонента.
  439.      *
  440.      * @access protected
  441.      * @final
  442.      * @param string $propName 
  443.      * @param mixed $propValue 
  444.      * @return void 
  445.      */
  446.     final protected function setProperty($propName$propValue{
  447.         $this->properties[$propName$propValue;
  448.     }
  449.  
  450.     /**
  451.      * Возвращает значение свойства компонента.
  452.      *
  453.      * @access protected
  454.      * @final
  455.      * @param string $propName 
  456.      * @return mixed 
  457.      */
  458.     final protected function getProperty($propName{
  459.         $result false;
  460.         if (isset($this->properties[$propName])) {
  461.             $result $this->properties[$propName];
  462.         }
  463.         return $result;
  464.     }
  465.  
  466.     /**
  467.      * Удаляет свойство компонента.
  468.      *
  469.      * @access protected
  470.      * @final
  471.      * @param string 
  472.      * @return void 
  473.      */
  474.     final protected function removeProperty($propName{
  475.         unset($this->properties[$propName]);
  476.     }
  477.     /**
  478.      * Строит результат работы компонента используя определённый построитель.
  479.      *
  480.      * @access public
  481.      * @return DOMDocument 
  482.      */
  483.     public function build({
  484.         $result $this->doc->createElement('component');
  485.         $result->setAttribute('name'$this->getName());
  486.         $result->setAttribute('module'$this->module);
  487.         $result->setAttribute('componentAction'$this->getAction());
  488.         $result->setAttribute('class'get_class($this));
  489.  
  490.         foreach ($this->properties as $propName => $propValue{
  491.             $result->setAttribute($propName$propValue);
  492.         }
  493.  
  494.         /*
  495.          * Существует ли построитель и правильно ли он отработал?
  496.          * Построитель может не существовать, если мы создаем компонент в котором нет данных.
  497.          */
  498.         if ($this->getBuilder(&& $this->getBuilder()->build()) {
  499.             $result->appendChild(
  500.                 $this->doc->importNode(
  501.                     $this->getBuilder()->getResult(),
  502.                     true
  503.                 )
  504.             );
  505.         }
  506.  
  507.         $this->doc->appendChild($result);
  508.         $result $this->doc;
  509.         return $result;
  510.     }
  511.  
  512.  
  513.  
  514.     /**
  515.      * Генерирует ошибку и добавляет её в список ошибок компонента.
  516.      *
  517.      * @access protected
  518.      * @param int $errorType тип ошибки
  519.      * @param string $errorMessage сообщение об ошибке
  520.      * @param mixed $errorCustomInfo дополнительная информация об ошибке
  521.      * @return void 
  522.      */
  523.     protected function generateError($errorType$errorMessage$errorCustomInfo false{
  524.         $errorInfo array(
  525.             'type' => $errorType,
  526.             'message' => $errorMessage,
  527.             'custom' => $errorCustomInfo
  528.         );
  529.  
  530.         array_push($this->errors$errorInfo);
  531.  
  532.         // если ошибка не позволяет продолжить работу компонента, возбуждаем фиктивное исключение
  533.         if ($errorType == SystemException::ERR_WARNING{
  534.             throw new DummyException;
  535.         }
  536.     }
  537.  
  538.     /**
  539.      * Обрабатывает ошибки, произошедшие во время работы компонента.
  540.      * Возвращает DOMDocument, представляющий ошибки компонента, или
  541.      * false, если никаких ошибок не произошло.
  542.      *
  543.      * @access public
  544.      * @final
  545.      * @return mixed 
  546.      */
  547.     final public function handleErrors({
  548.         $result false;
  549.         if (sizeof($this->errors0{
  550.             $dom_errorDoc new DOMDocument('1.0''UTF-8');
  551.             $dom_errors $dom_errorDoc->createElement('errors');
  552.             $dom_errors->setAttribute('title'$this->translate('TXT_ERRORS'));
  553.             foreach ($this->errors as $errorInfo{
  554.                 $dom_error $dom_errorDoc->createElement('error'$errorInfo['message']);
  555.                 $dom_error->setAttribute('type'$errorInfo['type']);
  556.                 /**
  557.                  * @todo выводить дополнительную информацию только в debug-режиме.
  558.                  */
  559.                 if (isset($errorInfo['custom'])) {
  560.                     if (is_array($errorInfo['custom'])) {
  561.                         $customMessage implode('. '$errorInfo['custom']);
  562.                     }
  563.                     else {
  564.                         $customMessage $errorInfo['custom'];
  565.                     }
  566.  
  567.                     if (!empty($customMessage)) {
  568.                         $dom_error->nodeValue "{$errorInfo['message']} [ $customMessage ]";
  569.                     }
  570.                     else {
  571.                         $dom_error->nodeValue $errorInfo['message'];
  572.                     }
  573.                 }
  574.                 $dom_errors->appendChild($dom_error);
  575.             }
  576.             $dom_errorDoc->appendChild($dom_errors);
  577.             $result $dom_errorDoc;
  578.         }
  579.         return $result;
  580.     }
  581.  
  582.     /**
  583.      * Возвращает параметры действия.
  584.      *
  585.      * @access protected
  586.      * @return array 
  587.      */
  588.     protected function getActionParams({
  589.         return $this->actionParams;
  590.     }
  591. }
В создании документации нам помог: phpDocumentor