Your IP : 3.133.119.96


Current Path : /home/bitrix/ext_www/klimatlend.ua/bitrix/modules/main/lib/engine/
Upload File :
Current File : /home/bitrix/ext_www/klimatlend.ua/bitrix/modules/main/lib/engine/router.php

<?php

namespace Bitrix\Main\Engine;


use Bitrix\Main\Component\ParameterSigner;
use Bitrix\Main\Config\Configuration;
use Bitrix\Main\Engine\Component\ComponentController;
use Bitrix\Main\Engine\Contract\Controllerable;
use Bitrix\Main\HttpRequest;
use Bitrix\Main\Loader;
use Bitrix\Main\Security;
use Bitrix\Main\SystemException;

final class Router
{
	const COMPONENT_MODE_AJAX  = 'ajax';
	const COMPONENT_MODE_CLASS = 'class';

	protected $module = 'main';
	protected $action = 'index';
	protected $component;
	protected $mode;

	/**
	 * @var HttpRequest
	 */
	private $request;

	/**
	 * Router constructor.
	 * @param HttpRequest $request
	 */
	public function __construct(HttpRequest $request)
	{
		$this->request = $request;

		$this->component = $this->request->get('c') ?: null;
		$this->mode = $this->request->get('mode') ?: null;

		$this->action = $this->request->get('action');
		if ($this->action && is_string($this->action) && !$this->component)
		{
			$actionParts = explode('.', $this->action);

			$this->module = array_shift($actionParts);
			$this->action = implode('.', $actionParts);
		}
	}

	/**
	 * @param $componentName
	 *
	 * @param string|null $signedParameters
	 *
	 * @param null $template
	 *
	 * @return Controllerable|null
	 * @throws Security\Sign\BadSignatureException
	 * @throws SystemException
	 * @throws \Bitrix\Main\ArgumentTypeException
	 */
	protected function buildComponent($componentName, $signedParameters = null, $template = null)
	{
		$class = \CBitrixComponent::includeComponentClass($componentName);
		if (!is_subclass_of($class, 'CBitrixComponent'))
		{
			return null;
		}

		$parameters = array();
		if ($signedParameters)
		{
			$parameters = ParameterSigner::unsignParameters($componentName, $signedParameters);
		}

		/** @var \CBitrixComponent $component */
		$component = new $class();

		if (!($component instanceof Controllerable))
		{
			throw new SystemException(
				"The component {$this->component} must be implement interface \Bitrix\Main\Engine\Contract\Controllerable"
			);
		}

		$component->initComponent($componentName, $template);
		$component->onIncludeComponentLang();
		$component->arParams = $component->onPrepareComponentParams($parameters);
		$component->__prepareComponentParams($component->arParams);

		return $component;
	}

	/**
	 * @return array
	 */
	public function getControllerAndAction()
	{
		if ($this->component)
		{
			return $this->getComponentControllerAndAction();
		}

		$this->includeModule($this->module);
		$controllerAndAction = Resolver::getControllerAndAction($this->module, $this->action);
		if ($controllerAndAction)
		{
			return $controllerAndAction;
		}
		//default ajax class
		$ajaxClass = DefaultController::className();

		/** @see \Bitrix\Main\Engine\Controller::__construct */
		return array(new $ajaxClass, $this->action);
	}

	private function getComponentControllerAndAction()
	{
		if ($this->mode === self::COMPONENT_MODE_CLASS)
		{
			$component = $this->buildComponent($this->component, $this->request->getPost('signedParameters'));
			if (!$component)
			{
				throw new SystemException("Could not build component instance {$this->component}");
			}

			return array(new ComponentController($component), $this->action);
		}
		elseif ($this->mode === self::COMPONENT_MODE_AJAX)
		{
			$ajaxClass = $this->includeComponentAjaxClass($this->component);

			/** @see \Bitrix\Main\Engine\Controller::__construct */
			return array(new $ajaxClass, $this->action);
		}
		else
		{
			$modeAsString = var_export($this->mode, true);
			throw new SystemException("Unknown ajax mode ({$modeAsString}) to work {$this->component}");
		}
	}
	
	private function includeModule($module)
	{
		if (!Configuration::getInstance($module)->get('controllers'))
		{
			throw new SystemException("There is no configuration in {$module} with 'controllers' value.");
		}

		if (!Loader::includeModule($module))
		{
			throw new SystemException("Could not find module {$module}");
		}
	}

	private function includeComponentAjaxClass($name)
	{
		$path2Comp = \CComponentEngine::makeComponentPath($name);
		if ($path2Comp === '')
		{
			throw new SystemException("{$name} is not a valid component name");
		}

		$componentPath = getLocalPath("components" . $path2Comp);
		$ajaxClass = $this->getAjaxClassForPath($componentPath);

		if (!$ajaxClass)
		{
			throw new SystemException("Could not find ajax class {$componentPath}");
		}

		return $ajaxClass;
	}

	private function getAjaxClassForPath($componentPath)
	{
		$filename = \Bitrix\Main\Application::getDocumentRoot() . $componentPath . '/ajax.php';
		if (!file_exists($filename) || !is_file($filename))
		{
			return null;
		}

		$beforeClasses = get_declared_classes();
		$beforeClassesCount = count($beforeClasses);
		include_once($filename);
		$afterClasses = get_declared_classes();
		$afterClassesCount = count($afterClasses);
		for ($i = $afterClassesCount - 1; $i >= $beforeClassesCount; $i--)
		{
			if (
				is_subclass_of($afterClasses[$i], Controller::className()) ||
				in_array(Controller::className(), class_parents($afterClasses[$i])) //5.3.9
			)
			{
				return $afterClasses[$i];
			}
		}

		return null;
	}

	/**
	 * @param HttpRequest $request
	 * @return $this
	 */
	public function setRequest(HttpRequest $request)
	{
		$this->request = $request;

		return $this;
	}
}