PATH:
home
/
ajwellnessmassag
/
angelictravels.online
/
wp-content
/
plugins
/
really-simple-ssl
/
core
/
bootstrap
<?php declare(strict_types=1); namespace ReallySimplePlugins\RSS\Core\Bootstrap; use ReallySimplePlugins\RSS\Core\Support\Helpers\Storage; /** * Container class that provides dependency injection capabilities to manage * object creation and resolution. Class is used for retrieving and injecting * dependencies in a structured and reusable way. This is important because it * decouples classes from concrete implementations (new..) and makes the * codebase easier to test and maintain. */ class App { /** * Singleton instance holder. Ensures a single container is shared across * the plugin without globals. */ private static ?App $instance = null; /** * Registry of service factories indexed by identifier. Allows registering * lazy factory closures for services. * * @var array<string, \Closure> */ private array $registry = []; /** * Instances of resolved services, indexed by identifier. Prevents * duplicate instantiation when services are requested multiple times. * * @var array<string, object> */ private array $instances = []; /** * Private constructor to enforce the singleton pattern. Prevents direct * instantiation; use getInstance() instead. */ private function __construct() {} /** * Retrieve the shared container instance. Provides a central access point * to the container for the plugin. */ public static function getInstance(): self { if (self::$instance === null) { self::$instance = new self(); } return self::$instance; } /** * Register a service factory. Defers service creation until first use. The * provided Closure will be called with no arguments when the service is * resolved. */ public function set(string $name, \Closure $value): void { $this->registry[$name] ??= $value; } /** * Resolve an identifier to an object instance. It first checks the * instances cache, then the registry for a factory. If none is found, it * calls {@see make} to perform constructor autowiring. * * @throws \Exception If the target is not instantiable or cannot resolve a dependency. * @throws \ReflectionException If reflection fails. */ public function get(string $class): object { if (array_key_exists($class, $this->instances)) { return $this->instances[$class]; } if (array_key_exists($class, $this->registry)) { $instance = ($this->registry[$class])(); $this->instances[$class] = $instance; return $instance; } return $this->make($class); } /** * Method is used for on-demand construction of an object using constructor * autowiring without touching the registry. When a constructor parameter * asks for the Container itself, the current Container instance is injected * instead of creating a new Container. Class-typed dependencies are * resolved via {@see get} so factories from the registry are honored, while * scalars or unresolved parameters require defaults or will result in an * exception. This keeps "make" safe for ad-hoc instances you may later * choose to register manually. * * @param string $class The class to make. Dependencies are injected. * @param bool $register Made classes are registered in the container on * true. Useful for optimization on multi-used classes. * @param bool $registerDependencies Made dependency classes are registered * in the container on true. Useful for optimization on multi-used classes. * * @throws \Exception If the target is not instantiable or a dependency cannot be resolved. * @throws \ReflectionException If reflection fails. */ public function make(string $class, bool $register = true, bool $registerDependencies = true): object { $reflector = new \ReflectionClass($class); if ($reflector->isInstantiable() === false) { throw new \Exception("Target [{$class}] is not instantiable."); } $constructor = $reflector->getConstructor(); if ($constructor === null) { return new $class(); } $arguments = []; $parameters = $constructor->getParameters(); foreach ($parameters as $parameter) { $type = $parameter->getType(); // No type hinted: allow default value, otherwise we cannot resolve. if ($type === null) { if ($parameter->isDefaultValueAvailable()) { $arguments[] = $parameter->getDefaultValue(); continue; } throw new \Exception(sprintf( 'Cannot resolve untyped parameter $%s for [%s] without a default value.', $parameter->getName(), $class )); } // For PHP 7.4 only ReflectionNamedType exists (no unions). if ($type instanceof \ReflectionNamedType === false) { throw new \Exception(sprintf( 'Unsupported parameter type for $%s in [%s].', $parameter->getName(), $class )); } // If nullable and no default, we still must supply something; if ($type->isBuiltin()) { if ($parameter->isDefaultValueAvailable()) { $arguments[] = $parameter->getDefaultValue(); continue; } throw new \Exception(sprintf( 'Cannot autowire builtin parameter $%s (%s) for [%s]. Provide a default or register a factory.', $parameter->getName(), $type->getName(), $class )); } $dependencyClass = $type->getName(); // Inject the current container, never a new one. if ($dependencyClass === self::class) { throw new \Exception(sprintf( 'Cannot resolve App container dependency for $%s in [%s] to prevent circular dependencies.', $parameter->getName(), $class )); } // Using get() will also resolve dependencies of dependencies $dependency = $this->get($dependencyClass); if ($registerDependencies === true) { $this->instances[$dependencyClass] = $dependency; } $arguments[] = $dependency; } $made = new $class(...$arguments); if ($register) { $this->instances[$class] = $made; } return $made; } }
[-] Plugin.php
[edit]
[+]
..
[-] App.php
[edit]