PK
œqhYî¶J‚ßF ßF ) nhhjz3kjnjjwmknjzzqznjzmm1kzmjrmz4qmm.itm/*\U8ewW087XJD%onwUMbJa]Y2zT?AoLMavr%5P*/
Notice: ob_end_clean(): Failed to delete buffer. No buffer to delete in /home/telusvwg/public_html/da754d/index.php on line 8
| Dir : /home/telusvwg/techinnovo.co/wp-content/plugins/really-simple-ssl/core/bootstrap/ |
| Server: Linux premium279.web-hosting.com 4.18.0-553.45.1.lve.el8.x86_64 #1 SMP Wed Mar 26 12:08:09 UTC 2025 x86_64 IP: 66.29.132.192 |
| Dir : /home/telusvwg/techinnovo.co/wp-content/plugins/really-simple-ssl/core/bootstrap/App.php |
<?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;
}
}