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

Source for file ComponentConfig.class.php

Documentation is available at ComponentConfig.class.php

  1. <?php
  2.  
  3. /**
  4.  * Содержит класс ComponentConfig
  5.  *
  6.  * @package energine
  7.  * @subpackage core
  8.  * @author dr.Pavka
  9.  * @copyright Energine 2007
  10.  * @version $Id$
  11.  */
  12.  
  13. //require_once('core/framework/Object.class.php');
  14. //require_once('core/framework/ConfigElement.class.php');
  15. /**
  16.  * Класс реализующий работу с конфигурационным файлом компонента
  17.  *
  18.  * @package energine
  19.  * @subpackage core
  20.  * @author dr.Pavka
  21.  * @final
  22.  */
  23. final class ComponentConfig extends Object {
  24.     /**
  25.      * Путь к директории, содержащей пользовательские файлы конфигурации для компонентов
  26.      */
  27.     const SITE_CONFIG_DIR = 'site/config/';
  28.  
  29.     /**
  30.      * Путь к директории, содержащей файлы конфигурации для стандартных компонентов
  31.      * (вместо %s будет подставлено имя модуля, содержащего компонент)
  32.      */
  33.     const CORE_CONFIG_DIR = 'core/modules/%s/config/';
  34.  
  35.     /**
  36.      * Конфигурационный файл
  37.      *
  38.      * @var SimpleXMLElement 
  39.      * @access private
  40.      */
  41.     private $config = false;
  42.  
  43.     /**
  44.      * Имя текущего метода
  45.      *
  46.      * @var ConfigElement 
  47.      * @access private
  48.      */
  49.     private $currentMethod = false;
  50.  
  51.     /**
  52.      * Конструктор класса
  53.      *
  54.      * @param string имя конфигурационного файла
  55.      * @return void 
  56.      */
  57.  
  58.     public function __construct($configFileName$className$moduleName{
  59.         parent::__construct();
  60.         $configFileName ($param $this->getConfigPath($configFileName$moduleName))?$param:$this->getConfigPath($className.'.component.xml'$moduleName);
  61.  
  62.         if ($configFileName{
  63.             try {
  64.                 $this->config = simplexml_load_file($configFileName'ConfigElement');
  65.             }
  66.             catch (Exception  $e{
  67.                 throw new SystemException('ERR_DEV_BAD_CONFIG_FILE'SystemException::ERR_DEVELOPER$configFileName);
  68.             }
  69.         }
  70.     }
  71.  
  72.     /**
  73.      * Возвращает полный путь к конфигурационному файлу, или false если файл не существует.
  74.      *
  75.      * @access private
  76.      * @param string $configFilename имя конфигурационного файла
  77.      * @return mixed 
  78.      */
  79.     private function getConfigPath($configFilename$moduleName{
  80.         $file false;
  81.         if ($configFilename && !file_exists($file $configFilename))
  82.         //Смотрим в директории с пользовательскими конфигами
  83.         if (!file_exists($file self::SITE_CONFIG_DIR.$configFilename)) {
  84.             if(!file_exists($file sprintf(self::CORE_CONFIG_DIR$moduleName).$configFilename)){
  85.             //если файла с указанным именем нет ни в папке с пользовательскими конфигами, ни в папке модуля с конфигами
  86.             //throw new SystemException('ERR_DEV_NO_CONFIG', SystemException::ERR_DEVELOPER, $configFilename);
  87.             $file false;
  88.             }
  89.         }
  90.         return $file;
  91.     }
  92.     /**
  93.      * Устанавливает имя текущего метода
  94.      *
  95.      * @param string имя метода
  96.      * @return void 
  97.      * @access public
  98.      */
  99.  
  100.     public function setCurrentMethod($methodName{
  101.         if(!($this->currentMethod = $this->getMethodConfig($methodName))){
  102.             throw new SystemException('ERR_NO_METHOD'SystemException::ERR_DEVELOPER);
  103.         }
  104.     }
  105.  
  106.     /**
  107.      * Возвращает конфигурацию текущего метода
  108.      *
  109.      * @return ConfigElement 
  110.      * @access public
  111.      */
  112.  
  113.     public function getCurrentMethodConfig({
  114.         return $this->currentMethod;
  115.     }
  116.  
  117.     /**
  118.      * Возвращает флаг того, что конфиг пустой
  119.      *
  120.      * @return boolean 
  121.      * @access public
  122.      */
  123.  
  124.     public function isEmpty({
  125.         return ($this->config)?false:true;
  126.     }
  127.  
  128.     /**
  129.      * Возвращает имя действия из конфигурации, основываясь на URI запроса.
  130.      *
  131.      * @access public
  132.      * @return array 
  133.      */
  134.     public function getActionByURI($path{
  135.         $actionName false;
  136.         $actionParams array();
  137.         $path '/'.$path;
  138.  
  139.         $patterns array();
  140.         foreach ($this->config->methods->method as $method{
  141.             if (isset($method->uri_patterns->pattern)) {
  142.                 foreach ($method->uri_patterns->pattern as $pattern{
  143.                     $patterns[$pattern->getValue()$method->getAttribute('name');
  144.                 }
  145.             }
  146.         }
  147.  
  148.         // сортируем шаблоны URI от более специфичных к менее специфичным
  149.         //uksort($patterns,array('ComponentConfig', 'uriPatternsCmp'));
  150.         /**
  151.          * @todo Нужно заменить на uksort когда будет ликвидирован глюк с segfault
  152.          */
  153.         $patterns $this->sortByKeys($patternsarray('ComponentConfig','uriPatternsCmp'));
  154.  
  155.         foreach ($patterns as $pattern => $methodName{
  156.             $regexpr str_replace(
  157.                 array('/',  '[int]''[string]''[any]\/''[any]'),
  158.                 array('\/''(\d+)''([^\/]+)''(.*)',    '(.*)'),
  159.                 $pattern
  160.             );
  161.             if (preg_match("/^$regexpr$/"$path$matches)) {
  162.                 array_shift($matches);
  163.                 if (strpos($pattern'[any]'!== false{
  164.                     array_pop($matches);
  165.                 }
  166.                 $actionName $methodName;
  167.                 $actionParams $matches;
  168.                 //inspect($this->getName());
  169.                 //$this->request->setPathOffset($this->request->getPathOffset()+sizeof($actionParams));
  170.                 break;
  171.             }
  172.         }
  173.  
  174.         if ($actionName == false{
  175.             return false;
  176.         }
  177.  
  178.         return array('name' => $actionName'params' => $actionParams);
  179.     }
  180.  
  181.     /**
  182.      * Возвращает конфигурацию для указанного метода.
  183.      *
  184.      * @access public
  185.      * @param string $methodName имя метода
  186.      * @return SimpleXMLElement 
  187.      */
  188.     public function getMethodConfig($methodName{
  189.         $result false;
  190.         if (!$this->isEmpty()) {
  191.             $methodConfig $this->config->xpath(sprintf('/configuration/methods/method[@name=\'%s\']'$methodName));
  192.             if (!empty($methodConfig)) {
  193.                 $result $methodConfig[0];
  194.             }
  195.         }
  196.         return $result;
  197.     }
  198.  
  199.     /**
  200.      * Возвращает флаг, указывающий какой из предложенных паттернов более специфичен
  201.      * Вызывается как callback для uksort
  202.      *
  203.      * @access private
  204.      * @param string $patternA 
  205.      * @param string $patternB 
  206.      * @return int 
  207.      * @static
  208.      */
  209.  
  210.     static private function uriPatternsCmp($patternA$patternB{
  211.         $placeholders array('/[int]/''/[string]/''/[any]/');
  212.         if (in_array($patternA$placeholders)) {
  213.             $result 1;
  214.         }
  215.         elseif (in_array($patternB$placeholders)) {
  216.             $result = -1;
  217.         }
  218.         else {
  219.             $result = -(strlen($patternAstrlen($patternB));
  220.         }
  221.  
  222.         return $result;
  223.     }
  224.  
  225.     /**
  226.      * Аналог uksort
  227.      *
  228.      * @return array 
  229.      * @access public
  230.      */
  231.  
  232.     public function sortByKeys($data$callback{
  233.         $result array();
  234.         //Получаем исходное количество элементов в массиве
  235.         $arrayLength sizeof($data);
  236.  
  237.         //до тех пор пока размер результирующего массива меньше размера исходного масива
  238.         while (sizeof($result)<$arrayLength){
  239.             $currentElement array(key($data=> current($data));
  240.             do {
  241.                 if (($haveNext next($data)) && (call_user_func($callbackkey($currentElement)key($data))<0)){
  242.                     $currentElement array(key($data=> current($data));
  243.                 }
  244.             }
  245.             while($haveNext);
  246.  
  247.             $result array_merge($currentElement$result);
  248.             unset($data[key($currentElement)]);
  249.             reset($data);
  250.         }
  251.         return $result;
  252.     }
  253. }
В создании документации нам помог: phpDocumentor