Current Path : /var/www/www-root/data/www/monolith-realty.ru/bitrix/modules/main/lib/engine/ |
Current File : /var/www/www-root/data/www/monolith-realty.ru/bitrix/modules/main/lib/engine/resolver.php |
<?php namespace Bitrix\Main\Engine; use Bitrix\Main\Config\Configuration; use Bitrix\Main\ObjectException; final class Resolver { const DEFAULT_VENDOR = 'bitrix'; /** * Returns list instance of controller and action in this controller. * * @param string $vendor * @param string $module * @param string $action * @param string $scope * * @return array|null */ public static function getControllerAndAction($vendor, $module, $action, $scope = Controller::SCOPE_AJAX) { $parts = explode('.', $action); $actionName = array_pop($parts); $controllerClass = self::buildControllerClassName($vendor, $module, $parts); if (!$controllerClass) { return null; } try { $controller = ControllerBuilder::build($controllerClass, [ 'scope' => $scope, 'currentUser' => CurrentUser::get(), ]); return [$controller, $actionName]; } catch (ObjectException $exception) {} return null; } private static function buildControllerClassName($vendor, $module, array $actionParts) { $controllerName = array_pop($actionParts); if (self::isOldFullQualifiedName($vendor, $module, $actionParts)) { $actionParts[] = $controllerName; $className = implode('\\', $actionParts); if (!self::checkClassUnderAllowedNamespaces($module, $className)) { return null; } return $className; } $namespaces = self::listAllowedNamespaces($module); $aliases = array_change_key_case($namespaces, CASE_LOWER); $probablyPrefix = mb_strtolower(reset($actionParts)); if (isset($aliases[$probablyPrefix])) { $alias = $aliases[$probablyPrefix]; array_shift($actionParts); //drop prefix array_push($actionParts, $controllerName); return $alias . '\\' . implode('\\', $actionParts); } $furtherControllerClassName = self::buildClassNameByAction( $vendor, $module, array_merge($actionParts, [$controllerName]) ); if (self::checkClassUnderAllowedNamespaces($module, $furtherControllerClassName)) { return $furtherControllerClassName; } $defaultNamespaceByModule = self::getDefaultNamespaceByModule($module); if (!$defaultNamespaceByModule) { return null; } $defaultPath = strtr($defaultNamespaceByModule, ['\\' => '.']); // do not lower if probably psr4 $firstLetter = mb_substr($controllerName, 0, 1); if ($firstLetter === mb_strtolower($firstLetter)) { $defaultPath = mb_strtolower($defaultPath); } array_unshift($actionParts, ...explode('.', $defaultPath)); array_push($actionParts, $controllerName); return implode('\\', $actionParts); } /** * Returns default namespace by module. * @param string $module Module id. * * @return null|string */ public static function getDefaultNamespaceByModule($module) { $controllersConfig = Configuration::getInstance($module); if (!$controllersConfig['controllers'] || !isset($controllersConfig['controllers']['defaultNamespace'])) { return null; } return $controllersConfig['controllers']['defaultNamespace']; } /** * Checks if the name of action is old full qualified name. * For example: disk.bitrix.disk.controller.file.get. * @param $vendor * @param $module * @param array $actionParts * * @return bool */ private static function isOldFullQualifiedName($vendor, $module, array $actionParts) { if ($vendor !== self::DEFAULT_VENDOR) { return false; } if (!isset($actionParts[0]) || !isset($actionParts[1])) { return false; } return $actionParts[0] === $vendor && $actionParts[1] === $module; } private static function listAllowedNamespaces($module) { $controllersConfig = Configuration::getInstance($module); if (!$controllersConfig['controllers']) { return []; } $namespaces = []; if (isset($controllersConfig['controllers']['namespaces'])) { foreach ($controllersConfig['controllers']['namespaces'] as $key => $namespace) { if (is_int($key)) { $namespaces[] = $namespace; } else { $namespaces[$namespace] = $key; } } } if (isset($controllersConfig['controllers']['defaultNamespace'])) { $namespaces[] = $controllersConfig['controllers']['defaultNamespace']; } return $namespaces; } private static function checkClassUnderAllowedNamespaces($module, $class) { $namespaces = self::listAllowedNamespaces($module); foreach ($namespaces as $namespace) { if (mb_stripos(trim($class, '\\'), trim($namespace, '\\') . '\\') === 0) { return true; } } return false; } /** * Builds class name by vendor and module. * @param $vendor * @param $module * @param array $actionParts * * @return string */ private static function buildClassNameByAction($vendor, $module, array $actionParts) { if($vendor === self::DEFAULT_VENDOR) { $namespace = "\\Bitrix\\$module"; } else { $namespace = "\\" . strtr($module, ['.' => '\\']); } if (!$actionParts) { return $namespace; } return "{$namespace}\\" . trim(implode('\\', $actionParts), '\\'); } /** * Returns name of controller for using in routing. * The name is built by rules: fully qualified name contains delimiters by dot. * Example: vendor:module.controller.action. * * @param Controller $controller Controller. * * @return string */ public static function getNameByController(Controller $controller) { $parts = explode('\\', get_class($controller)); $vendor = mb_strtolower(array_shift($parts)); //lower case for module name $parts[0] = mb_strtolower($parts[0]); return $vendor . ':' . implode('.', $parts); } }