%PDF- %PDF-
Direktori : /home/bitrix/www/bitrix/modules/main/classes/general/ |
Current File : /home/bitrix/www/bitrix/modules/main/classes/general/component_engine.php |
<?php /** * Bitrix Framework * @package bitrix * @subpackage main * @copyright 2001-2013 Bitrix */ class CComponentEngine { public $cacheSalt = ''; private $component = null; private $greedyParts = array(); private $resolveCallback = false; /** * Constructor. * * <p>Takes component as parameter and initializing the object.</p> * @param CBitrixComponent $component */ function __construct($component = null) { if ($component instanceof CBitrixComponent) $this->component = $component; } /** * Returns associated component. * * @return CBitrixComponent * */ public function getComponent() { return $this->component; } /** * Marks one of the page templates parts as greedy (may contain "/" separator). * * @param string $part * @return void * */ public function addGreedyPart($part) { $part = trim($part, " \t\n\r#"); if ($part != "") $this->greedyParts[$part] = preg_quote($part, "'"); } /** * Registers callback with will be called on page indetermination. * * @param callback $resolveCallback * @return void * */ public function setResolveCallback($resolveCallback) { if (is_callable($resolveCallback)) $this->resolveCallback = $resolveCallback; } /** * Checks if component name is valid. * * <p>Component name consists of namespace part, separator and name. Example: bitrix:news.list</p> * @param string $componentName * @return bool * */ public static function checkComponentName($componentName) { return ($componentName <> '' && preg_match("#^([A-Za-z0-9_.-]+:)?([A-Za-z0-9_-]+\\.)*([A-Za-z0-9_-]+)$#i", $componentName)); } /** * Makes filesystem relative path out of com name. * * @param string $componentName * @return string * */ public static function makeComponentPath($componentName) { if(!CComponentEngine::checkComponentName($componentName)) return ""; return "/".str_replace(":", "/", $componentName); } /** * Checks if page template has templates in it. * * @param string $pageTemplate * @return bool * */ public function hasNoVariables($pageTemplate) { return strpos($pageTemplate, "#") === false; } /** * Checks if page template.has greedy templates it it. * * @param string $pageTemplate * @return bool * */ public function hasGreedyParts($pageTemplate) { if ( !empty($this->greedyParts) && preg_match("'#(?:".implode("|", $this->greedyParts).")#'", $pageTemplate) ) return true; else return false; } /** * Sorts templates for inspection. * * <p>First will be templates without any variables. Then templates without greedy parts. Then greedy ones.</p> * @param array[string]string $arUrlTemplates * @param bool &$bHasGreedyPartsInTemplates * @return array[string]string * */ protected function sortUrlTemplates($arUrlTemplates, &$bHasGreedyPartsInTemplates) { $resultNoHash = array(); $resultWithHash = array(); $resultWithGreedy = array(); foreach ($arUrlTemplates as $pageID => $pageTemplate) { $pos = strpos($pageTemplate, "?"); if ($pos !== false) $pageTemplate = substr($pageTemplate, 0, $pos); if ($this->hasNoVariables($pageTemplate)) $resultNoHash[$pageID] = $pageTemplate; elseif ($this->hasGreedyParts($pageTemplate)) $resultWithGreedy[$pageID] = $pageTemplate; else $resultWithHash[$pageID] = $pageTemplate; } $bHasGreedyPartsInTemplates = !empty($resultWithGreedy); return array_merge($resultNoHash, $resultWithHash, $resultWithGreedy); } /** * Checks if page template matches current URL. * * <p>In case of succsessful match fills in parsed variables.</p> * @param string $pageTemplate * @param string $currentPageUrl * @param array[string]string &$arVariables * @return bool * */ protected function __checkPath4Template($pageTemplate, $currentPageUrl, &$arVariables) { if (!empty($this->greedyParts)) { $pageTemplateReg = preg_replace("'#(?:".implode("|", $this->greedyParts).")#'", "(.+?)", $pageTemplate); $pageTemplateReg = preg_replace("'#[^#]+?#'", "([^/]+?)", $pageTemplateReg); } else { $pageTemplateReg = preg_replace("'#[^#]+?#'", "([^/]+?)", $pageTemplate); } if (substr($pageTemplateReg, -1, 1) == "/") $pageTemplateReg .= "index\\.php"; $arValues = array(); if (preg_match("'^".$pageTemplateReg."$'", $currentPageUrl, $arValues)) { $arMatches = array(); if (preg_match_all("'#([^#]+?)#'", $pageTemplate, $arMatches)) { for ($i = 0, $cnt = count($arMatches[1]); $i < $cnt; $i++) $arVariables[$arMatches[1][$i]] = $arValues[$i + 1]; } return true; } return false; } /** * Finds match between requestURL and on of the url templates. * * @param string $folder404 * @param array[string]string $arUrlTemplates * @param array[string]string &$arVariables * @param string|bool $requestURL * @return string * */ public static function parseComponentPath($folder404, $arUrlTemplates, &$arVariables, $requestURL = false) { $engine = new CComponentEngine(); return $engine->guessComponentPath($folder404, $arUrlTemplates, $arVariables, $requestURL); } /** * Finds match between requestURL and on of the url templates. * * <p>Lets using the engine object and greedy templates.</p> * @param string $folder404 * @param array[string]string $arUrlTemplates * @param array[string]string &$arVariables * @param string|bool $requestURL * @return string * */ public function guessComponentPath($folder404, $arUrlTemplates, &$arVariables, $requestURL = false) { if (!isset($arVariables) || !is_array($arVariables)) $arVariables = array(); if ($requestURL === false) $requestURL = Bitrix\Main\Context::getCurrent()->getRequest()->getRequestedPage(); $folder404 = str_replace("\\", "/", $folder404); if ($folder404 != "/") $folder404 = "/".trim($folder404, "/ \t\n\r\0\x0B")."/"; //SEF base URL must match curent URL (several components on the same page) if(strpos($requestURL, $folder404) !== 0) return false; $currentPageUrl = substr($requestURL, strlen($folder404)); $this->cacheSalt = md5($currentPageUrl); $pageCandidates = array(); $arUrlTemplates = $this->sortUrlTemplates($arUrlTemplates, $bHasGreedyPartsInTemplates); if ( $bHasGreedyPartsInTemplates && is_callable($this->resolveCallback) ) { foreach ($arUrlTemplates as $pageID => $pageTemplate) { $arVariablesTmp = $arVariables; if ($this->__CheckPath4Template($pageTemplate, $currentPageUrl, $arVariablesTmp)) { if ($this->hasNoVariables($pageTemplate)) { $arVariables = $arVariablesTmp; return $pageID; } else { $pageCandidates[$pageID] = $arVariablesTmp; } } } } else { foreach ($arUrlTemplates as $pageID => $pageTemplate) { if ($this->__CheckPath4Template($pageTemplate, $currentPageUrl, $arVariables)) { return $pageID; } } } if (!empty($pageCandidates) && is_callable($this->resolveCallback)) { return call_user_func_array($this->resolveCallback, array($this, $pageCandidates, &$arVariables)); } return false; } /** * Initializes component variables from $_REQUEST based on component page selected. * * @param string $componentPage * @param array[string]string $arComponentVariables * @param array[string]string $arVariableAliases * @param array[string]string &$arVariables * @return void * */ public static function initComponentVariables($componentPage, $arComponentVariables, $arVariableAliases, &$arVariables) { if (!isset($arVariables) || !is_array($arVariables)) $arVariables = array(); if ($componentPage) { if (array_key_exists($componentPage, $arVariableAliases) && is_array($arVariableAliases[$componentPage])) { foreach ($arVariableAliases[$componentPage] as $variableName => $aliasName) if (!array_key_exists($variableName, $arVariables)) $arVariables[$variableName] = $_REQUEST[$aliasName]; } } else { foreach ($arVariableAliases as $variableName => $aliasName) if (!array_key_exists($variableName, $arVariables)) if (is_string($aliasName) && array_key_exists($aliasName, $_REQUEST)) $arVariables[$variableName] = $_REQUEST[$aliasName]; } if ($arComponentVariables && is_array($arComponentVariables)) { for ($i = 0, $cnt = count($arComponentVariables); $i < $cnt; $i++) { if (!array_key_exists($arComponentVariables[$i], $arVariables) && array_key_exists($arComponentVariables[$i], $_REQUEST)) { $arVariables[$arComponentVariables[$i]] = $_REQUEST[$arComponentVariables[$i]]; } } } } /** * Prepares templates based on default and provided. * * @param array[string]string $arDefaultUrlTemplates * @param array[string]string $arCustomUrlTemplates * @return array[string]string * */ public static function makeComponentUrlTemplates($arDefaultUrlTemplates, $arCustomUrlTemplates) { if (!is_array($arCustomUrlTemplates)) $arCustomUrlTemplates = array(); return array_merge($arDefaultUrlTemplates, $arCustomUrlTemplates); } /** * Prepares variables based on default and provided. * * @param array[string]string $arDefaultVariableAliases * @param array[string]string $arCustomVariableAliases * @return array[string]string * */ public static function makeComponentVariableAliases($arDefaultVariableAliases, $arCustomVariableAliases) { if (!is_array($arCustomVariableAliases)) $arCustomVariableAliases = array(); return array_merge($arDefaultVariableAliases, $arCustomVariableAliases); } /** * Replaces templates in provided string based on parameters * * @param string $template * @param array[string]string $arParams * @return string * */ public static function makePathFromTemplate($template, $arParams = array()) { $arPatterns = array("#SITE_DIR#", "#SITE#", "#SERVER_NAME#"); $arReplace = array(SITE_DIR, SITE_ID, SITE_SERVER_NAME); foreach ($arParams as $key => $value) { $arPatterns[] = "#".$key."#"; $arReplace[] = $value; } return str_replace($arPatterns, $arReplace, $template); } }