diff --git a/classes/Admin/ServiceProvider.php b/classes/Admin/ServiceProvider.php index 643159c11..08098d832 100644 --- a/classes/Admin/ServiceProvider.php +++ b/classes/Admin/ServiceProvider.php @@ -5,6 +5,7 @@ use Imagify\Dependencies\League\Container\ServiceProvider\AbstractServiceProvider; use Imagify\Dependencies\WPMedia\PluginFamily\Controller\PluginFamily; +use Imagify\User\User; /** * Service provider for Admin. @@ -16,10 +17,10 @@ class ServiceProvider extends AbstractServiceProvider { * @var array */ protected $provides = [ - 'admin_bar', - 'admin_subscriber', - 'plugin_family', - 'plugin_family_subscriber', + AdminBar::class, + AdminSubscriber::class, + PluginFamily::class, + PluginFamilySubscriber::class, ]; /** @@ -28,27 +29,36 @@ class ServiceProvider extends AbstractServiceProvider { * @var array */ public $subscribers = [ - 'admin_bar', - 'admin_subscriber', - 'plugin_family_subscriber', + AdminBar::class, + AdminSubscriber::class, + PluginFamilySubscriber::class, ]; + /** + * Check if the service provider provides a specific service. + * + * @param string $id The id of the service. + * + * @return bool + */ + public function provides( string $id ): bool { + return in_array( $id, $this->provides, true ); + } + /** * Registers the provided classes * * @return void */ - public function register() { - - $this->getContainer()->share( 'admin_bar', AdminBar::class ) - ->addArgument( $this->getContainer()->get( 'user' ) ); - $this->getContainer()->share( 'admin_subscriber', AdminSubscriber::class ) - ->addArgument( $this->getContainer()->get( 'user' ) ); - - $this->getContainer()->add( 'plugin_family', PluginFamily::class ); + public function register(): void { + $this->getContainer()->addShared( AdminBar::class ) + ->addArgument( User::class ); + $this->getContainer()->addShared( AdminSubscriber::class ) + ->addArgument( User::class ); - $this->getContainer()->add( 'plugin_family_subscriber', PluginFamilySubscriber::class ) - ->addArgument( $this->getContainer()->get( 'plugin_family' ) ); + $this->getContainer()->add( PluginFamily::class ); + $this->getContainer()->addShared( PluginFamilySubscriber::class ) + ->addArgument( PluginFamily::class ); } /** diff --git a/classes/Avif/ServiceProvider.php b/classes/Avif/ServiceProvider.php index 38b33a73b..417256539 100644 --- a/classes/Avif/ServiceProvider.php +++ b/classes/Avif/ServiceProvider.php @@ -16,8 +16,8 @@ class ServiceProvider extends AbstractServiceProvider { * @var array */ protected $provides = [ - 'avif_display', - 'avif_rewrite_rules', + Display::class, + RewriteRules::class, ]; /** @@ -26,18 +26,29 @@ class ServiceProvider extends AbstractServiceProvider { * @var array */ public $subscribers = [ - 'avif_display', - 'avif_rewrite_rules', + Display::class, + RewriteRules::class, ]; + /** + * Check if the service provider provides a specific service. + * + * @param string $id The id of the service. + * + * @return bool + */ + public function provides( string $id ): bool { + return in_array( $id, $this->provides, true ); + } + /** * Registers the provided classes * * @return void */ - public function register() { - $this->getContainer()->share( 'avif_display', Display::class ); - $this->getContainer()->share( 'avif_rewrite_rules', RewriteRules::class ); + public function register(): void { + $this->getContainer()->addShared( Display::class ); + $this->getContainer()->addShared( RewriteRules::class ); } /** diff --git a/classes/CDN/ServiceProvider.php b/classes/CDN/ServiceProvider.php index 094900d35..f5d0bd48f 100644 --- a/classes/CDN/ServiceProvider.php +++ b/classes/CDN/ServiceProvider.php @@ -15,7 +15,7 @@ class ServiceProvider extends AbstractServiceProvider { * @var array */ protected $provides = [ - 'cdn', + CDN::class, ]; /** @@ -24,16 +24,27 @@ class ServiceProvider extends AbstractServiceProvider { * @var array */ public $subscribers = [ - 'cdn', + CDN::class, ]; + /** + * Check if the service provider provides a specific service. + * + * @param string $id The id of the service. + * + * @return bool + */ + public function provides( string $id ): bool { + return in_array( $id, $this->provides, true ); + } + /** * Registers the provided classes * * @return void */ - public function register() { - $this->getContainer()->share( 'cdn', CDN::class ); + public function register(): void { + $this->getContainer()->addShared( CDN::class ); } /** diff --git a/classes/Dependencies/League/Container/Argument/RawArgumentInterface.php b/classes/Dependencies/League/Container/Argument/ArgumentInterface.php similarity index 53% rename from classes/Dependencies/League/Container/Argument/RawArgumentInterface.php rename to classes/Dependencies/League/Container/Argument/ArgumentInterface.php index 16fe992a9..2cdf82c0e 100644 --- a/classes/Dependencies/League/Container/Argument/RawArgumentInterface.php +++ b/classes/Dependencies/League/Container/Argument/ArgumentInterface.php @@ -1,12 +1,12 @@ -getValue(); - } elseif ($argument instanceof ClassNameInterface) { - $id = $argument->getClassName(); - } elseif (!is_string($argument)) { - return $argument; - } else { - $justStringValue = true; - $id = $argument; + try { + $container = $this->getContainer(); + } catch (ContainerException $e) { + $container = ($this instanceof ReflectionContainer) ? $this : null; + } + + foreach ($arguments as &$arg) { + // if we have a literal, we don't want to do anything more with it + if ($arg instanceof LiteralArgumentInterface) { + $arg = $arg->getValue(); + continue; } - $container = null; + if ($arg instanceof ArgumentInterface) { + $argValue = $arg->getValue(); + } else { + $argValue = $arg; + } - try { - $container = $this->getLeagueContainer(); - } catch (ContainerException $e) { - if ($this instanceof ReflectionContainer) { - $container = $this; - } + if (!is_string($argValue)) { + continue; } - if ($container !== null) { + // resolve the argument from the container, if it happens to be another + // argument wrapper, use that value + if ($container instanceof ContainerInterface && $container->has($argValue)) { try { - return $container->get($id); - } catch (NotFoundException $exception) { - if ($argument instanceof ClassNameWithOptionalValue) { - return $argument->getOptionalValue(); - } + $arg = $container->get($argValue); - if ($justStringValue) { - return $id; + if ($arg instanceof ArgumentInterface) { + $arg = $arg->getValue(); } - throw $exception; + continue; + } catch (NotFoundException $e) { } } - if ($argument instanceof ClassNameWithOptionalValue) { - return $argument->getOptionalValue(); + // if we have a default value, we use that, no more resolution as + // we expect a default/optional argument value to be literal + if ($arg instanceof DefaultValueInterface) { + $arg = $arg->getDefaultValue(); } + } - // Just a string value. - return $id; - }, $arguments); + return $arguments; } - /** - * {@inheritdoc} - */ - public function reflectArguments(ReflectionFunctionAbstract $method, array $args = []) : array + public function reflectArguments(ReflectionFunctionAbstract $method, array $args = []): array { - $arguments = array_map(function (ReflectionParameter $param) use ($method, $args) { + $params = $method->getParameters(); + $arguments = []; + + foreach ($params as $param) { $name = $param->getName(); - $type = $param->getType(); + // if we've been given a value for the argument, treat as literal if (array_key_exists($name, $args)) { - return new RawArgument($args[$name]); + $arguments[] = new LiteralArgument($args[$name]); + continue; } - if ($type) { - if (PHP_VERSION_ID >= 70100) { - $typeName = $type->getName(); - } else { - $typeName = (string) $type; - } + $type = $param->getType(); - $typeName = ltrim($typeName, '?'); + if ($type instanceof ReflectionNamedType) { + // in PHP 8, nullable arguments have "?" prefix + $typeHint = ltrim($type->getName(), '?'); if ($param->isDefaultValueAvailable()) { - return new ClassNameWithOptionalValue($typeName, $param->getDefaultValue()); + $arguments[] = new DefaultValueArgument($typeHint, $param->getDefaultValue()); + continue; } - return new ClassName($typeName); + $arguments[] = new ResolvableArgument($typeHint); + continue; } if ($param->isDefaultValueAvailable()) { - return new RawArgument($param->getDefaultValue()); + $arguments[] = new LiteralArgument($param->getDefaultValue()); + continue; } throw new NotFoundException(sprintf( @@ -103,18 +102,10 @@ public function reflectArguments(ReflectionFunctionAbstract $method, array $args $name, $method->getName() )); - }, $method->getParameters()); + } return $this->resolveArguments($arguments); } - /** - * @return ContainerInterface - */ - abstract public function getContainer() : ContainerInterface; - - /** - * @return Container - */ - abstract public function getLeagueContainer() : Container; + abstract public function getContainer(): DefinitionContainerInterface; } diff --git a/classes/Dependencies/League/Container/Argument/ClassName.php b/classes/Dependencies/League/Container/Argument/ClassName.php deleted file mode 100644 index 4d6ae395b..000000000 --- a/classes/Dependencies/League/Container/Argument/ClassName.php +++ /dev/null @@ -1,29 +0,0 @@ -value = $value; - } - - /** - * {@inheritdoc} - */ - public function getClassName() : string - { - return $this->value; - } -} diff --git a/classes/Dependencies/League/Container/Argument/ClassNameInterface.php b/classes/Dependencies/League/Container/Argument/ClassNameInterface.php deleted file mode 100644 index 5a923e08a..000000000 --- a/classes/Dependencies/League/Container/Argument/ClassNameInterface.php +++ /dev/null @@ -1,13 +0,0 @@ -className = $className; - $this->optionalValue = $optionalValue; - } - - /** - * @inheritDoc - */ - public function getClassName(): string - { - return $this->className; - } - - public function getOptionalValue() - { - return $this->optionalValue; - } -} diff --git a/classes/Dependencies/League/Container/Argument/DefaultValueArgument.php b/classes/Dependencies/League/Container/Argument/DefaultValueArgument.php new file mode 100644 index 000000000..0c50d7f6d --- /dev/null +++ b/classes/Dependencies/League/Container/Argument/DefaultValueArgument.php @@ -0,0 +1,24 @@ +defaultValue = $defaultValue; + parent::__construct($value); + } + + /** + * @return mixed|null + */ + public function getDefaultValue() + { + return $this->defaultValue; + } +} diff --git a/classes/Dependencies/League/Container/Argument/DefaultValueInterface.php b/classes/Dependencies/League/Container/Argument/DefaultValueInterface.php new file mode 100644 index 000000000..d421cbb13 --- /dev/null +++ b/classes/Dependencies/League/Container/Argument/DefaultValueInterface.php @@ -0,0 +1,13 @@ +value = $value; + } else { + throw new InvalidArgumentException('Incorrect type for value.'); + } + } + + /** + * {@inheritdoc} + */ + public function getValue() + { + return $this->value; + } +} diff --git a/classes/Dependencies/League/Container/Argument/LiteralArgumentInterface.php b/classes/Dependencies/League/Container/Argument/LiteralArgumentInterface.php new file mode 100644 index 000000000..b7b2466f1 --- /dev/null +++ b/classes/Dependencies/League/Container/Argument/LiteralArgumentInterface.php @@ -0,0 +1,9 @@ +value = $value; - } - - /** - * {@inheritdoc} - */ - public function getValue() - { - return $this->value; - } -} diff --git a/classes/Dependencies/League/Container/Argument/ResolvableArgument.php b/classes/Dependencies/League/Container/Argument/ResolvableArgument.php new file mode 100644 index 000000000..970edde06 --- /dev/null +++ b/classes/Dependencies/League/Container/Argument/ResolvableArgument.php @@ -0,0 +1,20 @@ +value = $value; + } + + public function getValue(): string + { + return $this->value; + } +} diff --git a/classes/Dependencies/League/Container/Argument/ResolvableArgumentInterface.php b/classes/Dependencies/League/Container/Argument/ResolvableArgumentInterface.php new file mode 100644 index 000000000..a4b5fb9b0 --- /dev/null +++ b/classes/Dependencies/League/Container/Argument/ResolvableArgumentInterface.php @@ -0,0 +1,10 @@ +definitions = $definitions ?? new DefinitionAggregate; - $this->providers = $providers ?? new ServiceProviderAggregate; - $this->inflectors = $inflectors ?? new InflectorAggregate; + $this->definitions = $definitions ?? new DefinitionAggregate(); + $this->providers = $providers ?? new ServiceProviderAggregate(); + $this->inflectors = $inflectors ?? new InflectorAggregate(); if ($this->definitions instanceof ContainerAwareInterface) { - $this->definitions->setLeagueContainer($this); + $this->definitions->setContainer($this); } if ($this->providers instanceof ContainerAwareInterface) { - $this->providers->setLeagueContainer($this); + $this->providers->setContainer($this); } if ($this->inflectors instanceof ContainerAwareInterface) { - $this->inflectors->setLeagueContainer($this); + $this->inflectors->setContainer($this); } } - /** - * Add an item to the container. - * - * @param string $id - * @param mixed $concrete - * @param boolean $shared - * - * @return DefinitionInterface - */ - public function add(string $id, $concrete = null, bool $shared = null) : DefinitionInterface + public function add(string $id, $concrete = null): DefinitionInterface { $concrete = $concrete ?? $id; - $shared = $shared ?? $this->defaultToShared; - return $this->definitions->add($id, $concrete, $shared); + if (true === $this->defaultToShared) { + return $this->addShared($id, $concrete); + } + + return $this->definitions->add($id, $concrete); } - /** - * Proxy to add with shared as true. - * - * @param string $id - * @param mixed $concrete - * - * @return DefinitionInterface - */ - public function share(string $id, $concrete = null) : DefinitionInterface + public function addShared(string $id, $concrete = null): DefinitionInterface { - return $this->add($id, $concrete, true); + $concrete = $concrete ?? $id; + return $this->definitions->addShared($id, $concrete); } - /** - * Whether the container should default to defining shared definitions. - * - * @param boolean $shared - * - * @return self - */ - public function defaultToShared(bool $shared = true) : ContainerInterface + public function defaultToShared(bool $shared = true): ContainerInterface { $this->defaultToShared = $shared; - return $this; } - /** - * Get a definition to extend. - * - * @param string $id [description] - * - * @return DefinitionInterface - */ - public function extend(string $id) : DefinitionInterface + public function extend(string $id): DefinitionInterface { if ($this->providers->provides($id)) { $this->providers->register($id); @@ -129,69 +94,43 @@ public function extend(string $id) : DefinitionInterface return $this->definitions->getDefinition($id); } - throw new NotFoundException( - sprintf('Unable to extend alias (%s) as it is not being managed as a definition', $id) - ); + throw new NotFoundException(sprintf( + 'Unable to extend alias (%s) as it is not being managed as a definition', + $id + )); } - /** - * Add a service provider. - * - * @param ServiceProviderInterface|string $provider - * - * @return self - */ - public function addServiceProvider($provider) : self + public function addServiceProvider(ServiceProviderInterface $provider): DefinitionContainerInterface { $this->providers->add($provider); - return $this; } /** - * {@inheritdoc} + * @template RequestedType + * + * @param class-string|string $id + * + * @return RequestedType|mixed */ - public function get($id, bool $new = false) + public function get($id) { - if ($this->definitions->has($id)) { - $resolved = $this->definitions->resolve($id, $new); - return $this->inflectors->inflect($resolved); - } - - if ($this->definitions->hasTag($id)) { - $arrayOf = $this->definitions->resolveTagged($id, $new); - - array_walk($arrayOf, function (&$resolved) { - $resolved = $this->inflectors->inflect($resolved); - }); - - return $arrayOf; - } - - if ($this->providers->provides($id)) { - $this->providers->register($id); - - if (!$this->definitions->has($id) && !$this->definitions->hasTag($id)) { - throw new ContainerException(sprintf('Service provider lied about providing (%s) service', $id)); - } - - return $this->get($id, $new); - } - - foreach ($this->delegates as $delegate) { - if ($delegate->has($id)) { - $resolved = $delegate->get($id); - return $this->inflectors->inflect($resolved); - } - } - - throw new NotFoundException(sprintf('Alias (%s) is not being managed by the container or delegates', $id)); + return $this->resolve($id); } /** - * {@inheritdoc} + * @template RequestedType + * + * @param class-string|string $id + * + * @return RequestedType|mixed */ - public function has($id) + public function getNew($id) + { + return $this->resolve($id, true); + } + + public function has($id): bool { if ($this->definitions->has($id)) { return true; @@ -214,35 +153,58 @@ public function has($id) return false; } - /** - * Allows for manipulation of specific types on resolution. - * - * @param string $type - * @param callable|null $callback - * - * @return InflectorInterface - */ - public function inflector(string $type, callable $callback = null) : InflectorInterface + public function inflector(string $type, ?callable $callback = null): InflectorInterface { return $this->inflectors->add($type, $callback); } - /** - * Delegate a backup container to be checked for services if it - * cannot be resolved via this container. - * - * @param ContainerInterface $container - * - * @return self - */ - public function delegate(ContainerInterface $container) : self + public function delegate(ContainerInterface $container): self { $this->delegates[] = $container; if ($container instanceof ContainerAwareInterface) { - $container->setLeagueContainer($this); + $container->setContainer($this); } return $this; } + + protected function resolve($id, bool $new = false) + { + if ($this->definitions->has($id)) { + $resolved = (true === $new) ? $this->definitions->resolveNew($id) : $this->definitions->resolve($id); + return $this->inflectors->inflect($resolved); + } + + if ($this->definitions->hasTag($id)) { + $arrayOf = (true === $new) + ? $this->definitions->resolveTaggedNew($id) + : $this->definitions->resolveTagged($id); + + array_walk($arrayOf, function (&$resolved) { + $resolved = $this->inflectors->inflect($resolved); + }); + + return $arrayOf; + } + + if ($this->providers->provides($id)) { + $this->providers->register($id); + + if (!$this->definitions->has($id) && !$this->definitions->hasTag($id)) { + throw new ContainerException(sprintf('Service provider lied about providing (%s) service', $id)); + } + + return $this->resolve($id, $new); + } + + foreach ($this->delegates as $delegate) { + if ($delegate->has($id)) { + $resolved = $delegate->get($id); + return $this->inflectors->inflect($resolved); + } + } + + throw new NotFoundException(sprintf('Alias (%s) is not being managed by the container or delegates', $id)); + } } diff --git a/classes/Dependencies/League/Container/ContainerAwareInterface.php b/classes/Dependencies/League/Container/ContainerAwareInterface.php index f79443177..4f2d46882 100644 --- a/classes/Dependencies/League/Container/ContainerAwareInterface.php +++ b/classes/Dependencies/League/Container/ContainerAwareInterface.php @@ -1,40 +1,11 @@ -container = $container; - return $this; - } - - /** - * Get the container. - * - * @return ContainerInterface - */ - public function getContainer() : ContainerInterface - { - if ($this->container instanceof ContainerInterface) { - return $this->container; + if ($this instanceof ContainerAwareInterface) { + return $this; } - throw new ContainerException('No container implementation has been set.'); + throw new BadMethodCallException(sprintf( + 'Attempt to use (%s) while not implementing (%s)', + ContainerAwareTrait::class, + ContainerAwareInterface::class + )); } - /** - * Set a container. - * - * @param Container $container - * - * @return self - */ - public function setLeagueContainer(Container $container) : ContainerAwareInterface + public function getContainer(): DefinitionContainerInterface { - $this->container = $container; - $this->leagueContainer = $container; - - return $this; - } - - /** - * Get the container. - * - * @return Container - */ - public function getLeagueContainer() : Container - { - if ($this->leagueContainer instanceof Container) { - return $this->leagueContainer; + if ($this->container instanceof DefinitionContainerInterface) { + return $this->container; } throw new ContainerException('No container implementation has been set.'); diff --git a/classes/Dependencies/League/Container/Definition/Definition.php b/classes/Dependencies/League/Container/Definition/Definition.php index 8128d7781..0918959e8 100644 --- a/classes/Dependencies/League/Container/Definition/Definition.php +++ b/classes/Dependencies/League/Container/Definition/Definition.php @@ -1,13 +1,20 @@ -alias = $id; $this->concrete = $concrete; } - /** - * {@inheritdoc} - */ - public function addTag(string $tag) : DefinitionInterface + public function addTag(string $tag): DefinitionInterface { $this->tags[$tag] = true; - return $this; } - /** - * {@inheritdoc} - */ - public function hasTag(string $tag) : bool + public function hasTag(string $tag): bool { return isset($this->tags[$tag]); } - /** - * {@inheritdoc} - */ - public function setAlias(string $id) : DefinitionInterface + public function setAlias(string $id): DefinitionInterface { - $this->alias = $id; + $id = static::normaliseAlias($id); + $this->alias = $id; return $this; } - /** - * {@inheritdoc} - */ - public function getAlias() : string + public function getAlias(): string { return $this->alias; } - /** - * {@inheritdoc} - */ - public function setShared(bool $shared = true) : DefinitionInterface + public function setShared(bool $shared = true): DefinitionInterface { $this->shared = $shared; - return $this; } - /** - * {@inheritdoc} - */ - public function isShared() : bool + public function isShared(): bool { return $this->shared; } - /** - * {@inheritdoc} - */ public function getConcrete() { return $this->concrete; } - /** - * {@inheritdoc} - */ - public function setConcrete($concrete) : DefinitionInterface + public function setConcrete($concrete): DefinitionInterface { $this->concrete = $concrete; $this->resolved = null; - return $this; } - /** - * {@inheritdoc} - */ - public function addArgument($arg) : DefinitionInterface + public function addArgument($arg): DefinitionInterface { $this->arguments[] = $arg; - return $this; } - /** - * {@inheritdoc} - */ - public function addArguments(array $args) : DefinitionInterface + public function addArguments(array $args): DefinitionInterface { foreach ($args as $arg) { $this->addArgument($arg); @@ -158,10 +136,7 @@ public function addArguments(array $args) : DefinitionInterface return $this; } - /** - * {@inheritdoc} - */ - public function addMethodCall(string $method, array $args = []) : DefinitionInterface + public function addMethodCall(string $method, array $args = []): DefinitionInterface { $this->methods[] = [ 'method' => $method, @@ -171,10 +146,7 @@ public function addMethodCall(string $method, array $args = []) : DefinitionInte return $this; } - /** - * {@inheritdoc} - */ - public function addMethodCalls(array $methods = []) : DefinitionInterface + public function addMethodCalls(array $methods = []): DefinitionInterface { foreach ($methods as $method => $args) { $this->addMethodCall($method, $args); @@ -183,29 +155,30 @@ public function addMethodCalls(array $methods = []) : DefinitionInterface return $this; } - /** - * {@inheritdoc} - */ - public function resolve(bool $new = false) + public function resolve() { - $concrete = $this->concrete; - - if ($this->isShared() && $this->resolved !== null && $new === false) { + if (null !== $this->resolved && $this->isShared()) { return $this->resolved; } + return $this->resolveNew(); + } + + public function resolveNew() + { + $concrete = $this->concrete; + if (is_callable($concrete)) { $concrete = $this->resolveCallable($concrete); } - if ($concrete instanceof RawArgumentInterface) { + if ($concrete instanceof LiteralArgumentInterface) { $this->resolved = $concrete->getValue(); - return $concrete->getValue(); } - if ($concrete instanceof ClassNameInterface) { - $concrete = $concrete->getClassName(); + if ($concrete instanceof ArgumentInterface) { + $concrete = $concrete->getValue(); } if (is_string($concrete) && class_exists($concrete)) { @@ -216,63 +189,63 @@ public function resolve(bool $new = false) $concrete = $this->invokeMethods($concrete); } - if (is_string($concrete) && $this->getContainer()->has($concrete)) { - $concrete = $this->getContainer()->get($concrete); + try { + $container = $this->getContainer(); + } catch (ContainerException $e) { + $container = null; } - $this->resolved = $concrete; + // stop recursive resolving + if (is_string($concrete) && in_array($concrete, $this->recursiveCheck)) { + $this->resolved = $concrete; + return $concrete; + } + + // if we still have a string, try to pull it from the container + // this allows for `alias -> alias -> ... -> concrete + if (is_string($concrete) && $container instanceof ContainerInterface && $container->has($concrete)) { + $this->recursiveCheck[] = $concrete; + $concrete = $container->get($concrete); + } + $this->resolved = $concrete; return $concrete; } /** - * Resolve a callable. - * * @param callable $concrete - * * @return mixed */ protected function resolveCallable(callable $concrete) { $resolved = $this->resolveArguments($this->arguments); - return call_user_func_array($concrete, $resolved); } - /** - * Resolve a class. - * - * @param string $concrete - * - * @return object - * - * @throws ReflectionException - */ - protected function resolveClass(string $concrete) + protected function resolveClass(string $concrete): object { $resolved = $this->resolveArguments($this->arguments); $reflection = new ReflectionClass($concrete); - return $reflection->newInstanceArgs($resolved); } - /** - * Invoke methods on resolved instance. - * - * @param object $instance - * - * @return object - */ - protected function invokeMethods($instance) + protected function invokeMethods(object $instance): object { foreach ($this->methods as $method) { $args = $this->resolveArguments($method['arguments']); - - /** @var callable $callable */ $callable = [$instance, $method['method']]; call_user_func_array($callable, $args); } return $instance; } + + public static function normaliseAlias(string $alias): string + { + if (strpos($alias, '\\') === 0) { + return substr($alias, 1); + } + + return $alias; + } } diff --git a/classes/Dependencies/League/Container/Definition/DefinitionAggregate.php b/classes/Dependencies/League/Container/Definition/DefinitionAggregate.php index 651c8c180..81709ea8d 100644 --- a/classes/Dependencies/League/Container/Definition/DefinitionAggregate.php +++ b/classes/Dependencies/League/Container/Definition/DefinitionAggregate.php @@ -1,4 +1,6 @@ -definitions = array_filter($definitions, function ($definition) { + $this->definitions = array_filter($definitions, static function ($definition) { return ($definition instanceof DefinitionInterface); }); } - /** - * {@inheritdoc} - */ - public function add(string $id, $definition, bool $shared = false) : DefinitionInterface + public function add(string $id, $definition): DefinitionInterface { - if (!$definition instanceof DefinitionInterface) { + if (false === ($definition instanceof DefinitionInterface)) { $definition = new Definition($id, $definition); } - $this->definitions[] = $definition - ->setAlias($id) - ->setShared($shared) - ; + $this->definitions[] = $definition->setAlias($id); return $definition; } - /** - * {@inheritdoc} - */ - public function has(string $id) : bool + public function addShared(string $id, $definition): DefinitionInterface { + $definition = $this->add($id, $definition); + return $definition->setShared(true); + } + + public function has(string $id): bool + { + $id = Definition::normaliseAlias($id); + foreach ($this->getIterator() as $definition) { if ($id === $definition->getAlias()) { return true; @@ -58,10 +54,7 @@ public function has(string $id) : bool return false; } - /** - * {@inheritdoc} - */ - public function hasTag(string $tag) : bool + public function hasTag(string $tag): bool { foreach ($this->getIterator() as $definition) { if ($definition->hasTag($tag)) { @@ -72,53 +65,57 @@ public function hasTag(string $tag) : bool return false; } - /** - * {@inheritdoc} - */ - public function getDefinition(string $id) : DefinitionInterface + public function getDefinition(string $id): DefinitionInterface { + $id = Definition::normaliseAlias($id); + foreach ($this->getIterator() as $definition) { if ($id === $definition->getAlias()) { - return $definition->setLeagueContainer($this->getLeagueContainer()); + return $definition->setContainer($this->getContainer()); } } throw new NotFoundException(sprintf('Alias (%s) is not being handled as a definition.', $id)); } - /** - * {@inheritdoc} - */ - public function resolve(string $id, bool $new = false) + public function resolve(string $id) { - return $this->getDefinition($id)->resolve($new); + return $this->getDefinition($id)->resolve(); } - /** - * {@inheritdoc} - */ - public function resolveTagged(string $tag, bool $new = false) : array + public function resolveNew(string $id) + { + return $this->getDefinition($id)->resolveNew(); + } + + public function resolveTagged(string $tag): array { $arrayOf = []; foreach ($this->getIterator() as $definition) { if ($definition->hasTag($tag)) { - $arrayOf[] = $definition->setLeagueContainer($this->getLeagueContainer())->resolve($new); + $arrayOf[] = $definition->setContainer($this->getContainer())->resolve(); } } return $arrayOf; } - /** - * {@inheritdoc} - */ - public function getIterator() : Generator + public function resolveTaggedNew(string $tag): array { - $count = count($this->definitions); + $arrayOf = []; - for ($i = 0; $i < $count; $i++) { - yield $this->definitions[$i]; + foreach ($this->getIterator() as $definition) { + if ($definition->hasTag($tag)) { + $arrayOf[] = $definition->setContainer($this->getContainer())->resolveNew(); + } } + + return $arrayOf; + } + + public function getIterator(): Generator + { + yield from $this->definitions; } } diff --git a/classes/Dependencies/League/Container/Definition/DefinitionAggregateInterface.php b/classes/Dependencies/League/Container/Definition/DefinitionAggregateInterface.php index e0c83a923..c72fbd5e7 100644 --- a/classes/Dependencies/League/Container/Definition/DefinitionAggregateInterface.php +++ b/classes/Dependencies/League/Container/Definition/DefinitionAggregateInterface.php @@ -1,4 +1,6 @@ -type = $type; + $this->type = $type; $this->callback = $callback; } - /** - * {@inheritdoc} - */ - public function getType() : string + public function getType(): string { return $this->type; } - /** - * {@inheritdoc} - */ - public function invokeMethod(string $name, array $args) : InflectorInterface + public function invokeMethod(string $name, array $args): InflectorInterface { $this->methods[$name] = $args; - return $this; } - /** - * {@inheritdoc} - */ - public function invokeMethods(array $methods) : InflectorInterface + public function invokeMethods(array $methods): InflectorInterface { foreach ($methods as $name => $args) { $this->invokeMethod($name, $args); @@ -73,20 +59,13 @@ public function invokeMethods(array $methods) : InflectorInterface return $this; } - /** - * {@inheritdoc} - */ - public function setProperty(string $property, $value) : InflectorInterface + public function setProperty(string $property, $value): InflectorInterface { $this->properties[$property] = $this->resolveArguments([$value])[0]; - return $this; } - /** - * {@inheritdoc} - */ - public function setProperties(array $properties) : InflectorInterface + public function setProperties(array $properties): InflectorInterface { foreach ($properties as $property => $value) { $this->setProperty($property, $value); @@ -95,10 +74,7 @@ public function setProperties(array $properties) : InflectorInterface return $this; } - /** - * {@inheritdoc} - */ - public function inflect($object) + public function inflect(object $object): void { $properties = $this->resolveArguments(array_values($this->properties)); $properties = array_combine(array_keys($this->properties), $properties); @@ -110,8 +86,6 @@ public function inflect($object) foreach ($this->methods as $method => $args) { $args = $this->resolveArguments($args); - - /** @var callable $callable */ $callable = [$object, $method]; call_user_func_array($callable, $args); } diff --git a/classes/Dependencies/League/Container/Inflector/InflectorAggregate.php b/classes/Dependencies/League/Container/Inflector/InflectorAggregate.php index f82c6696c..023aa6e07 100644 --- a/classes/Dependencies/League/Container/Inflector/InflectorAggregate.php +++ b/classes/Dependencies/League/Container/Inflector/InflectorAggregate.php @@ -1,4 +1,6 @@ -inflectors[] = $inflector; - return $inflector; } - /** - * {@inheritdoc} - */ - public function getIterator() : Generator - { - $count = count($this->inflectors); - - for ($i = 0; $i < $count; $i++) { - yield $this->inflectors[$i]; - } - } - - /** - * {@inheritdoc} - */ public function inflect($object) { foreach ($this->getIterator() as $inflector) { $type = $inflector->getType(); - if (! $object instanceof $type) { - continue; + if ($object instanceof $type) { + $inflector->setContainer($this->getContainer()); + $inflector->inflect($object); } - - $inflector->setLeagueContainer($this->getLeagueContainer()); - $inflector->inflect($object); } return $object; } + + public function getIterator(): Generator + { + yield from $this->inflectors; + } } diff --git a/classes/Dependencies/League/Container/Inflector/InflectorAggregateInterface.php b/classes/Dependencies/League/Container/Inflector/InflectorAggregateInterface.php index 0c2a57d15..2b5a9644e 100644 --- a/classes/Dependencies/League/Container/Inflector/InflectorAggregateInterface.php +++ b/classes/Dependencies/League/Container/Inflector/InflectorAggregateInterface.php @@ -1,4 +1,6 @@ -cacheResolutions = $cacheResolutions; + } + public function get($id, array $args = []) { if ($this->cacheResolutions === true && array_key_exists($id, $this->cache)) { return $this->cache[$id]; } - if (! $this->has($id)) { + if (!$this->has($id)) { throw new NotFoundException( sprintf('Alias (%s) is not an existing class and therefore cannot be resolved', $id) ); @@ -54,8 +54,8 @@ public function get($id, array $args = []) } $resolution = $construct === null - ? new $id - : $resolution = $reflector->newInstanceArgs($this->reflectArguments($construct, $args)) + ? new $id() + : $reflector->newInstanceArgs($this->reflectArguments($construct, $args)) ; if ($this->cacheResolutions === true) { @@ -65,24 +65,11 @@ public function get($id, array $args = []) return $resolution; } - /** - * {@inheritdoc} - */ - public function has($id) + public function has($id): bool { return class_exists($id); } - /** - * Invoke a callable via the container. - * - * @param callable $callable - * @param array $args - * - * @return mixed - * - * @throws ReflectionException - */ public function call(callable $callable, array $args = []) { if (is_string($callable) && strpos($callable, '::') !== false) { @@ -91,7 +78,12 @@ public function call(callable $callable, array $args = []) if (is_array($callable)) { if (is_string($callable[0])) { - $callable[0] = $this->getContainer()->get($callable[0]); + // if we have a definition container, try that first, otherwise, reflect + try { + $callable[0] = $this->getContainer()->get($callable[0]); + } catch (ContainerException $e) { + $callable[0] = $this->get($callable[0]); + } } $reflection = new ReflectionMethod($callable[0], $callable[1]); @@ -105,7 +97,6 @@ public function call(callable $callable, array $args = []) if (is_object($callable)) { $reflection = new ReflectionMethod($callable, '__invoke'); - return $reflection->invokeArgs($callable, $this->reflectArguments($reflection, $args)); } @@ -113,19 +104,4 @@ public function call(callable $callable, array $args = []) return $reflection->invokeArgs($this->reflectArguments($reflection, $args)); } - - /** - * Whether the container should default to caching resolutions and returning - * the cache on following calls. - * - * @param boolean $option - * - * @return self - */ - public function cacheResolutions(bool $option = true) : ContainerInterface - { - $this->cacheResolutions = $option; - - return $this; - } } diff --git a/classes/Dependencies/League/Container/ServiceProvider/AbstractServiceProvider.php b/classes/Dependencies/League/Container/ServiceProvider/AbstractServiceProvider.php index 64efcb27e..f436b1471 100644 --- a/classes/Dependencies/League/Container/ServiceProvider/AbstractServiceProvider.php +++ b/classes/Dependencies/League/Container/ServiceProvider/AbstractServiceProvider.php @@ -1,4 +1,6 @@ -provides, true); + return $this->identifier ?? get_class($this); } - /** - * {@inheritdoc} - */ - public function setIdentifier(string $id) : ServiceProviderInterface + public function setIdentifier(string $id): ServiceProviderInterface { $this->identifier = $id; - return $this; } - - /** - * {@inheritdoc} - */ - public function getIdentifier() : string - { - return $this->identifier ?? get_class($this); - } } diff --git a/classes/Dependencies/League/Container/ServiceProvider/BootableServiceProviderInterface.php b/classes/Dependencies/League/Container/ServiceProvider/BootableServiceProviderInterface.php index 29d147fcd..32bdd7add 100644 --- a/classes/Dependencies/League/Container/ServiceProvider/BootableServiceProviderInterface.php +++ b/classes/Dependencies/League/Container/ServiceProvider/BootableServiceProviderInterface.php @@ -1,4 +1,6 @@ -getContainer()->has($provider)) { - $provider = $this->getContainer()->get($provider); - } elseif (is_string($provider) && class_exists($provider)) { - $provider = new $provider; - } - if (in_array($provider, $this->providers, true)) { return $this; } - if ($provider instanceof ContainerAwareInterface) { - $provider->setLeagueContainer($this->getLeagueContainer()); - } + $provider->setContainer($this->getContainer()); if ($provider instanceof BootableServiceProviderInterface) { $provider->boot(); } - if ($provider instanceof ServiceProviderInterface) { - $this->providers[] = $provider; - - return $this; - } - - throw new ContainerException( - 'A service provider must be a fully qualified class name or instance ' . - 'of (\Imagify\Dependencies\League\Container\ServiceProvider\ServiceProviderInterface)' - ); + $this->providers[] = $provider; + return $this; } - /** - * {@inheritdoc} - */ - public function provides(string $service) : bool + public function provides(string $service): bool { foreach ($this->getIterator() as $provider) { if ($provider->provides($service)) { @@ -69,22 +49,12 @@ public function provides(string $service) : bool return false; } - /** - * {@inheritdoc} - */ - public function getIterator() : Generator + public function getIterator(): Generator { - $count = count($this->providers); - - for ($i = 0; $i < $count; $i++) { - yield $this->providers[$i]; - } + yield from $this->providers; } - /** - * {@inheritdoc} - */ - public function register(string $service) + public function register(string $service): void { if (false === $this->provides($service)) { throw new ContainerException( @@ -98,8 +68,8 @@ public function register(string $service) } if ($provider->provides($service)) { - $this->registered[] = $provider->getIdentifier(); $provider->register(); + $this->registered[] = $provider->getIdentifier(); } } } diff --git a/classes/Dependencies/League/Container/ServiceProvider/ServiceProviderAggregateInterface.php b/classes/Dependencies/League/Container/ServiceProvider/ServiceProviderAggregateInterface.php index a9e264887..85236dec7 100644 --- a/classes/Dependencies/League/Container/ServiceProvider/ServiceProviderAggregateInterface.php +++ b/classes/Dependencies/League/Container/ServiceProvider/ServiceProviderAggregateInterface.php @@ -1,4 +1,6 @@ -leagueContainer property or the `getLeagueContainer` method - * from the ContainerAwareTrait. - * - * @return void - */ - public function register(); - - /** - * Set a custom id for the service provider. This enables - * registering the same service provider multiple times. - * - * @param string $id - * - * @return self - */ - public function setIdentifier(string $id) : ServiceProviderInterface; - - /** - * The id of the service provider uniquely identifies it, so - * that we can quickly determine if it has already been registered. - * Defaults to get_class($provider). - * - * @return string - */ - public function getIdentifier() : string; + public function getIdentifier(): string; + public function provides(string $id): bool; + public function register(): void; + public function setIdentifier(string $id): ServiceProviderInterface; } diff --git a/classes/Dependencies/Psr/Container/ContainerInterface.php b/classes/Dependencies/Psr/Container/ContainerInterface.php index b90363894..f503efe0f 100644 --- a/classes/Dependencies/Psr/Container/ContainerInterface.php +++ b/classes/Dependencies/Psr/Container/ContainerInterface.php @@ -32,5 +32,5 @@ public function get(string $id); * * @return bool */ - public function has(string $id); + public function has(string $id): bool; } diff --git a/classes/Picture/ServiceProvider.php b/classes/Picture/ServiceProvider.php index 1e1f6efca..033d551c6 100644 --- a/classes/Picture/ServiceProvider.php +++ b/classes/Picture/ServiceProvider.php @@ -15,7 +15,7 @@ class ServiceProvider extends AbstractServiceProvider { * @var array */ protected $provides = [ - 'picture_display', + Display::class, ]; /** @@ -24,17 +24,28 @@ class ServiceProvider extends AbstractServiceProvider { * @var array */ public $subscribers = [ - 'picture_display', + Display::class, ]; + /** + * Check if the service provider provides a specific service. + * + * @param string $id The id of the service. + * + * @return bool + */ + public function provides( string $id ): bool { + return in_array( $id, $this->provides, true ); + } + /** * Registers the provided classes * * @return void */ - public function register() { - $this->getContainer()->share( 'picture_display', Display::class ) - ->addArgument( $this->getContainer()->get( 'filesystem' ) ); + public function register(): void { + $this->getContainer()->addShared( Display::class ) + ->addArgument( 'filesystem' ); } /** diff --git a/classes/Plugin.php b/classes/Plugin.php index 877fc0b9f..bf4e7f887 100644 --- a/classes/Plugin.php +++ b/classes/Plugin.php @@ -86,14 +86,14 @@ public function init( $providers ) { return; } - $this->container->share( + $this->container->addShared( 'event_manager', function () { return new EventManager(); } ); - $this->container->share( + $this->container->addShared( 'filesystem', function() { return new Imagify_Filesystem(); diff --git a/classes/Stats/ServiceProvider.php b/classes/Stats/ServiceProvider.php index afb855147..8ccae2364 100644 --- a/classes/Stats/ServiceProvider.php +++ b/classes/Stats/ServiceProvider.php @@ -15,7 +15,7 @@ class ServiceProvider extends AbstractServiceProvider { * @var array */ protected $provides = [ - 'optimized_media_without_next_gen', + OptimizedMediaWithoutNextGen::class, ]; /** @@ -24,16 +24,27 @@ class ServiceProvider extends AbstractServiceProvider { * @var array */ public $subscribers = [ - 'optimized_media_without_next_gen', + OptimizedMediaWithoutNextGen::class, ]; + /** + * Check if the service provider provides a specific service. + * + * @param string $id The id of the service. + * + * @return bool + */ + public function provides( string $id ): bool { + return in_array( $id, $this->provides, true ); + } + /** * Registers the provided classes * * @return void */ - public function register() { - $this->getContainer()->share( 'optimized_media_without_next_gen', OptimizedMediaWithoutNextGen::class ); + public function register(): void { + $this->getContainer()->addShared( OptimizedMediaWithoutNextGen::class ); } /** diff --git a/classes/User/ServiceProvider.php b/classes/User/ServiceProvider.php index c2b89bd8e..fe10e869c 100644 --- a/classes/User/ServiceProvider.php +++ b/classes/User/ServiceProvider.php @@ -15,16 +15,27 @@ class ServiceProvider extends AbstractServiceProvider { * @var array */ protected $provides = [ - 'user', + User::class, ]; + /** + * Check if the service provider provides a specific service. + * + * @param string $id The id of the service. + * + * @return bool + */ + public function provides( string $id ): bool { + return in_array( $id, $this->provides, true ); + } + /** * Registers the provided classes * * @return void */ - public function register() { - $this->getContainer()->add( 'user', User::class ); + public function register(): void { + $this->getContainer()->add( User::class ); } /** diff --git a/classes/Webp/ServiceProvider.php b/classes/Webp/ServiceProvider.php index 12d45ddfa..4ab171bf1 100644 --- a/classes/Webp/ServiceProvider.php +++ b/classes/Webp/ServiceProvider.php @@ -16,8 +16,8 @@ class ServiceProvider extends AbstractServiceProvider { * @var array */ protected $provides = [ - 'webp_display', - 'webp_rewrite_rules', + Display::class, + RewriteRules::class, ]; /** @@ -26,18 +26,29 @@ class ServiceProvider extends AbstractServiceProvider { * @var array */ public $subscribers = [ - 'webp_display', - 'webp_rewrite_rules', + Display::class, + RewriteRules::class, ]; + /** + * Check if the service provider provides a specific service. + * + * @param string $id The id of the service. + * + * @return bool + */ + public function provides( string $id ): bool { + return in_array( $id, $this->provides, true ); + } + /** * Registers the provided classes * * @return void */ - public function register() { - $this->getContainer()->share( 'webp_display', Display::class ); - $this->getContainer()->share( 'webp_rewrite_rules', RewriteRules::class ); + public function register(): void { + $this->getContainer()->addShared( Display::class ); + $this->getContainer()->addShared( RewriteRules::class ); } /** diff --git a/composer.json b/composer.json index c3df36cd4..781821789 100644 --- a/composer.json +++ b/composer.json @@ -43,14 +43,13 @@ "coenjacobs/mozart": "^0.7", "dealerdirect/phpcodesniffer-composer-installer": "^0.7.0", "deliciousbrains/wp-background-processing": "~1.0", - "league/container": "^3.0", + "league/container": "^4.2", "mnsami/composer-custom-directory-installer": "^2.0", "phpcompatibility/phpcompatibility-wp": "^2.0", "phpunit/phpunit": "^7.5 || ^8 || ^9", "roave/security-advisories": "dev-master", "woocommerce/action-scheduler": "^3.4", "wp-coding-standards/wpcs": "^2", - "wp-media/event-manager": "^3.1", "wp-media/phpunit": "3.0" }, "autoload": { @@ -88,7 +87,6 @@ "packages": [ "deliciousbrains/wp-background-processing", "league/container", - "wp-media/event-manager", "wp-media/plugin-family" ] } diff --git a/phpcs.xml b/phpcs.xml index 8655baccd..371cb4714 100644 --- a/phpcs.xml +++ b/phpcs.xml @@ -29,8 +29,8 @@ - - + +