diff options
Diffstat (limited to 'srcs/phpmyadmin/vendor/symfony/dependency-injection')
161 files changed, 19605 insertions, 0 deletions
diff --git a/srcs/phpmyadmin/vendor/symfony/dependency-injection/Alias.php b/srcs/phpmyadmin/vendor/symfony/dependency-injection/Alias.php new file mode 100644 index 0000000..3e74fd9 --- /dev/null +++ b/srcs/phpmyadmin/vendor/symfony/dependency-injection/Alias.php @@ -0,0 +1,137 @@ +<?php + +/* + * This file is part of the Symfony package. + * + * (c) Fabien Potencier <fabien@symfony.com> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection; + +use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException; + +class Alias +{ + private $id; + private $public; + private $private; + private $deprecated; + private $deprecationTemplate; + + private static $defaultDeprecationTemplate = 'The "%alias_id%" service alias is deprecated. You should stop using it, as it will be removed in the future.'; + + public function __construct(string $id, bool $public = true) + { + $this->id = $id; + $this->public = $public; + $this->private = 2 > \func_num_args(); + $this->deprecated = false; + } + + /** + * Checks if this DI Alias should be public or not. + * + * @return bool + */ + public function isPublic() + { + return $this->public; + } + + /** + * Sets if this Alias is public. + * + * @param bool $boolean If this Alias should be public + * + * @return $this + */ + public function setPublic($boolean) + { + $this->public = (bool) $boolean; + $this->private = false; + + return $this; + } + + /** + * Sets if this Alias is private. + * + * When set, the "private" state has a higher precedence than "public". + * In version 3.4, a "private" alias always remains publicly accessible, + * but triggers a deprecation notice when accessed from the container, + * so that the alias can be made really private in 4.0. + * + * @param bool $boolean + * + * @return $this + */ + public function setPrivate($boolean) + { + $this->private = (bool) $boolean; + + return $this; + } + + /** + * Whether this alias is private. + * + * @return bool + */ + public function isPrivate() + { + return $this->private; + } + + /** + * Whether this alias is deprecated, that means it should not be referenced + * anymore. + * + * @param bool $status Whether this alias is deprecated, defaults to true + * @param string $template Optional template message to use if the alias is deprecated + * + * @return $this + * + * @throws InvalidArgumentException when the message template is invalid + */ + public function setDeprecated($status = true, $template = null) + { + if (null !== $template) { + if (preg_match('#[\r\n]|\*/#', $template)) { + throw new InvalidArgumentException('Invalid characters found in deprecation template.'); + } + + if (false === strpos($template, '%alias_id%')) { + throw new InvalidArgumentException('The deprecation template must contain the "%alias_id%" placeholder.'); + } + + $this->deprecationTemplate = $template; + } + + $this->deprecated = (bool) $status; + + return $this; + } + + public function isDeprecated(): bool + { + return $this->deprecated; + } + + public function getDeprecationMessage(string $id): string + { + return str_replace('%alias_id%', $id, $this->deprecationTemplate ?: self::$defaultDeprecationTemplate); + } + + /** + * Returns the Id of this alias. + * + * @return string The alias id + */ + public function __toString() + { + return $this->id; + } +} diff --git a/srcs/phpmyadmin/vendor/symfony/dependency-injection/Argument/ArgumentInterface.php b/srcs/phpmyadmin/vendor/symfony/dependency-injection/Argument/ArgumentInterface.php new file mode 100644 index 0000000..b46eb77 --- /dev/null +++ b/srcs/phpmyadmin/vendor/symfony/dependency-injection/Argument/ArgumentInterface.php @@ -0,0 +1,27 @@ +<?php + +/* + * This file is part of the Symfony package. + * + * (c) Fabien Potencier <fabien@symfony.com> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection\Argument; + +/** + * Represents a complex argument containing nested values. + * + * @author Titouan Galopin <galopintitouan@gmail.com> + */ +interface ArgumentInterface +{ + /** + * @return array + */ + public function getValues(); + + public function setValues(array $values); +} diff --git a/srcs/phpmyadmin/vendor/symfony/dependency-injection/Argument/BoundArgument.php b/srcs/phpmyadmin/vendor/symfony/dependency-injection/Argument/BoundArgument.php new file mode 100644 index 0000000..6005926 --- /dev/null +++ b/srcs/phpmyadmin/vendor/symfony/dependency-injection/Argument/BoundArgument.php @@ -0,0 +1,62 @@ +<?php + +/* + * This file is part of the Symfony package. + * + * (c) Fabien Potencier <fabien@symfony.com> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection\Argument; + +/** + * @author Guilhem Niot <guilhem.niot@gmail.com> + */ +final class BoundArgument implements ArgumentInterface +{ + const SERVICE_BINDING = 0; + const DEFAULTS_BINDING = 1; + const INSTANCEOF_BINDING = 2; + + private static $sequence = 0; + + private $value; + private $identifier; + private $used; + private $type; + private $file; + + public function __construct($value, bool $trackUsage = true, int $type = 0, string $file = null) + { + $this->value = $value; + if ($trackUsage) { + $this->identifier = ++self::$sequence; + } else { + $this->used = true; + } + $this->type = $type; + $this->file = $file; + } + + /** + * {@inheritdoc} + */ + public function getValues(): array + { + return [$this->value, $this->identifier, $this->used, $this->type, $this->file]; + } + + /** + * {@inheritdoc} + */ + public function setValues(array $values) + { + if (5 === \count($values)) { + list($this->value, $this->identifier, $this->used, $this->type, $this->file) = $values; + } else { + list($this->value, $this->identifier, $this->used) = $values; + } + } +} diff --git a/srcs/phpmyadmin/vendor/symfony/dependency-injection/Argument/IteratorArgument.php b/srcs/phpmyadmin/vendor/symfony/dependency-injection/Argument/IteratorArgument.php new file mode 100644 index 0000000..d413678 --- /dev/null +++ b/srcs/phpmyadmin/vendor/symfony/dependency-injection/Argument/IteratorArgument.php @@ -0,0 +1,22 @@ +<?php + +/* + * This file is part of the Symfony package. + * + * (c) Fabien Potencier <fabien@symfony.com> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection\Argument; + +/** + * Represents a collection of values to lazily iterate over. + * + * @author Titouan Galopin <galopintitouan@gmail.com> + */ +class IteratorArgument implements ArgumentInterface +{ + use ReferenceSetArgumentTrait; +} diff --git a/srcs/phpmyadmin/vendor/symfony/dependency-injection/Argument/ReferenceSetArgumentTrait.php b/srcs/phpmyadmin/vendor/symfony/dependency-injection/Argument/ReferenceSetArgumentTrait.php new file mode 100644 index 0000000..6f8d5d9 --- /dev/null +++ b/srcs/phpmyadmin/vendor/symfony/dependency-injection/Argument/ReferenceSetArgumentTrait.php @@ -0,0 +1,54 @@ +<?php + +/* + * This file is part of the Symfony package. + * + * (c) Fabien Potencier <fabien@symfony.com> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection\Argument; + +use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException; +use Symfony\Component\DependencyInjection\Reference; + +/** + * @author Titouan Galopin <galopintitouan@gmail.com> + * @author Nicolas Grekas <p@tchwork.com> + */ +trait ReferenceSetArgumentTrait +{ + private $values; + + /** + * @param Reference[] $values + */ + public function __construct(array $values) + { + $this->setValues($values); + } + + /** + * @return Reference[] The values in the set + */ + public function getValues() + { + return $this->values; + } + + /** + * @param Reference[] $values The service references to put in the set + */ + public function setValues(array $values) + { + foreach ($values as $k => $v) { + if (null !== $v && !$v instanceof Reference) { + throw new InvalidArgumentException(sprintf('A %s must hold only Reference instances, "%s" given.', __CLASS__, \is_object($v) ? \get_class($v) : \gettype($v))); + } + } + + $this->values = $values; + } +} diff --git a/srcs/phpmyadmin/vendor/symfony/dependency-injection/Argument/RewindableGenerator.php b/srcs/phpmyadmin/vendor/symfony/dependency-injection/Argument/RewindableGenerator.php new file mode 100644 index 0000000..41fec78 --- /dev/null +++ b/srcs/phpmyadmin/vendor/symfony/dependency-injection/Argument/RewindableGenerator.php @@ -0,0 +1,46 @@ +<?php + +/* + * This file is part of the Symfony package. + * + * (c) Fabien Potencier <fabien@symfony.com> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection\Argument; + +/** + * @internal + */ +class RewindableGenerator implements \IteratorAggregate, \Countable +{ + private $generator; + private $count; + + /** + * @param int|callable $count + */ + public function __construct(callable $generator, $count) + { + $this->generator = $generator; + $this->count = $count; + } + + public function getIterator(): \Traversable + { + $g = $this->generator; + + return $g(); + } + + public function count(): int + { + if (\is_callable($count = $this->count)) { + $this->count = $count(); + } + + return $this->count; + } +} diff --git a/srcs/phpmyadmin/vendor/symfony/dependency-injection/Argument/ServiceClosureArgument.php b/srcs/phpmyadmin/vendor/symfony/dependency-injection/Argument/ServiceClosureArgument.php new file mode 100644 index 0000000..6331aff --- /dev/null +++ b/srcs/phpmyadmin/vendor/symfony/dependency-injection/Argument/ServiceClosureArgument.php @@ -0,0 +1,50 @@ +<?php + +/* + * This file is part of the Symfony package. + * + * (c) Fabien Potencier <fabien@symfony.com> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection\Argument; + +use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException; +use Symfony\Component\DependencyInjection\Reference; + +/** + * Represents a service wrapped in a memoizing closure. + * + * @author Nicolas Grekas <p@tchwork.com> + */ +class ServiceClosureArgument implements ArgumentInterface +{ + private $values; + + public function __construct(Reference $reference) + { + $this->values = [$reference]; + } + + /** + * {@inheritdoc} + */ + public function getValues() + { + return $this->values; + } + + /** + * {@inheritdoc} + */ + public function setValues(array $values) + { + if ([0] !== array_keys($values) || !($values[0] instanceof Reference || null === $values[0])) { + throw new InvalidArgumentException('A ServiceClosureArgument must hold one and only one Reference.'); + } + + $this->values = $values; + } +} diff --git a/srcs/phpmyadmin/vendor/symfony/dependency-injection/Argument/ServiceLocator.php b/srcs/phpmyadmin/vendor/symfony/dependency-injection/Argument/ServiceLocator.php new file mode 100644 index 0000000..2001a95 --- /dev/null +++ b/srcs/phpmyadmin/vendor/symfony/dependency-injection/Argument/ServiceLocator.php @@ -0,0 +1,50 @@ +<?php + +/* + * This file is part of the Symfony package. + * + * (c) Fabien Potencier <fabien@symfony.com> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection\Argument; + +use Symfony\Component\DependencyInjection\ServiceLocator as BaseServiceLocator; + +/** + * @author Nicolas Grekas <p@tchwork.com> + * + * @internal + */ +class ServiceLocator extends BaseServiceLocator +{ + private $factory; + private $serviceMap; + private $serviceTypes; + + public function __construct(\Closure $factory, array $serviceMap, array $serviceTypes = null) + { + $this->factory = $factory; + $this->serviceMap = $serviceMap; + $this->serviceTypes = $serviceTypes; + parent::__construct($serviceMap); + } + + /** + * {@inheritdoc} + */ + public function get($id) + { + return isset($this->serviceMap[$id]) ? ($this->factory)(...$this->serviceMap[$id]) : parent::get($id); + } + + /** + * {@inheritdoc} + */ + public function getProvidedServices(): array + { + return $this->serviceTypes ?? $this->serviceTypes = array_map(function () { return '?'; }, $this->serviceMap); + } +} diff --git a/srcs/phpmyadmin/vendor/symfony/dependency-injection/Argument/ServiceLocatorArgument.php b/srcs/phpmyadmin/vendor/symfony/dependency-injection/Argument/ServiceLocatorArgument.php new file mode 100644 index 0000000..fcbf478 --- /dev/null +++ b/srcs/phpmyadmin/vendor/symfony/dependency-injection/Argument/ServiceLocatorArgument.php @@ -0,0 +1,44 @@ +<?php + +/* + * This file is part of the Symfony package. + * + * (c) Fabien Potencier <fabien@symfony.com> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection\Argument; + +use Symfony\Component\DependencyInjection\Reference; + +/** + * Represents a closure acting as a service locator. + * + * @author Nicolas Grekas <p@tchwork.com> + */ +class ServiceLocatorArgument implements ArgumentInterface +{ + use ReferenceSetArgumentTrait; + + private $taggedIteratorArgument; + + /** + * @param Reference[]|TaggedIteratorArgument $values + */ + public function __construct($values = []) + { + if ($values instanceof TaggedIteratorArgument) { + $this->taggedIteratorArgument = $values; + $this->values = []; + } else { + $this->setValues($values); + } + } + + public function getTaggedIteratorArgument(): ?TaggedIteratorArgument + { + return $this->taggedIteratorArgument; + } +} diff --git a/srcs/phpmyadmin/vendor/symfony/dependency-injection/Argument/TaggedIteratorArgument.php b/srcs/phpmyadmin/vendor/symfony/dependency-injection/Argument/TaggedIteratorArgument.php new file mode 100644 index 0000000..d1d5f6d --- /dev/null +++ b/srcs/phpmyadmin/vendor/symfony/dependency-injection/Argument/TaggedIteratorArgument.php @@ -0,0 +1,73 @@ +<?php + +/* + * This file is part of the Symfony package. + * + * (c) Fabien Potencier <fabien@symfony.com> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection\Argument; + +/** + * Represents a collection of services found by tag name to lazily iterate over. + * + * @author Roland Franssen <franssen.roland@gmail.com> + */ +class TaggedIteratorArgument extends IteratorArgument +{ + private $tag; + private $indexAttribute; + private $defaultIndexMethod; + private $defaultPriorityMethod; + private $needsIndexes = false; + + /** + * @param string $tag The name of the tag identifying the target services + * @param string|null $indexAttribute The name of the attribute that defines the key referencing each service in the tagged collection + * @param string|null $defaultIndexMethod The static method that should be called to get each service's key when their tag doesn't define the previous attribute + * @param bool $needsIndexes Whether indexes are required and should be generated when computing the map + * @param string|null $defaultPriorityMethod The static method that should be called to get each service's priority when their tag doesn't define the "priority" attribute + */ + public function __construct(string $tag, string $indexAttribute = null, string $defaultIndexMethod = null, bool $needsIndexes = false, string $defaultPriorityMethod = null) + { + parent::__construct([]); + + if (null === $indexAttribute && $needsIndexes) { + $indexAttribute = preg_match('/[^.]++$/', $tag, $m) ? $m[0] : $tag; + } + + $this->tag = $tag; + $this->indexAttribute = $indexAttribute; + $this->defaultIndexMethod = $defaultIndexMethod ?: ('getDefault'.str_replace(' ', '', ucwords(preg_replace('/[^a-zA-Z0-9\x7f-\xff]++/', ' ', $indexAttribute ?? ''))).'Name'); + $this->needsIndexes = $needsIndexes; + $this->defaultPriorityMethod = $defaultPriorityMethod ?: ('getDefault'.str_replace(' ', '', ucwords(preg_replace('/[^a-zA-Z0-9\x7f-\xff]++/', ' ', $indexAttribute ?? ''))).'Priority'); + } + + public function getTag() + { + return $this->tag; + } + + public function getIndexAttribute(): ?string + { + return $this->indexAttribute; + } + + public function getDefaultIndexMethod(): ?string + { + return $this->defaultIndexMethod; + } + + public function needsIndexes(): bool + { + return $this->needsIndexes; + } + + public function getDefaultPriorityMethod(): ?string + { + return $this->defaultPriorityMethod; + } +} diff --git a/srcs/phpmyadmin/vendor/symfony/dependency-injection/CHANGELOG.md b/srcs/phpmyadmin/vendor/symfony/dependency-injection/CHANGELOG.md new file mode 100644 index 0000000..b514ce1 --- /dev/null +++ b/srcs/phpmyadmin/vendor/symfony/dependency-injection/CHANGELOG.md @@ -0,0 +1,236 @@ +CHANGELOG +========= + +4.4.0 +----- + + * added `CheckTypeDeclarationsPass` to check injected parameters type during compilation + * added support for opcache.preload by generating a preloading script in the cache folder + * added support for dumping the container in one file instead of many files + * deprecated support for short factories and short configurators in Yaml + * added `tagged_iterator` alias for `tagged` which might be deprecated in a future version + * deprecated passing an instance of `Symfony\Component\DependencyInjection\Parameter` as class name to `Symfony\Component\DependencyInjection\Definition` + * added support for binding iterable and tagged services + * made singly-implemented interfaces detection be scoped by file + * added ability to define a static priority method for tagged service + * added support for improved syntax to define method calls in Yaml + * made the `%env(base64:...)%` processor able to decode base64url + * added ability to choose behavior of decorations on non existent decorated services + +4.3.0 +----- + + * added `%env(trim:...)%` processor to trim a string value + * added `%env(default:param_name:...)%` processor to fallback to a parameter or to null when using `%env(default::...)%` + * added `%env(url:...)%` processor to convert an URL or DNS into an array of components + * added `%env(query_string:...)%` processor to convert a query string into an array of key values + * added support for deprecating aliases + * made `ContainerParametersResource` final and not implement `Serializable` anymore + * added `ReverseContainer`: a container that turns services back to their ids + * added ability to define an index for a tagged collection + * added ability to define an index for services in an injected service locator argument + * made `ServiceLocator` implement `ServiceProviderInterface` + * deprecated support for non-string default env() parameters + * added `%env(require:...)%` processor to `require()` a PHP file and use the value returned from it + +4.2.0 +----- + + * added `ContainerBuilder::registerAliasForArgument()` to support autowiring by type+name + * added support for binding by type+name + * added `ServiceSubscriberTrait` to ease implementing `ServiceSubscriberInterface` using methods' return types + * added `ServiceLocatorArgument` and `!service_locator` config tag for creating optimized service-locators + * added support for autoconfiguring bindings + * added `%env(key:...)%` processor to fetch a specific key from an array + * deprecated `ServiceSubscriberInterface`, use the same interface from the `Symfony\Contracts\Service` namespace instead + * deprecated `ResettableContainerInterface`, use `Symfony\Contracts\Service\ResetInterface` instead + +4.1.0 +----- + + * added support for variadics in named arguments + * added PSR-11 `ContainerBagInterface` and its `ContainerBag` implementation to access parameters as-a-service + * added support for service's decorators autowiring + * deprecated the `TypedReference::canBeAutoregistered()` and `TypedReference::getRequiringClass()` methods + * environment variables are validated when used in extension configuration + * deprecated support for auto-discovered extension configuration class which does not implement `ConfigurationInterface` + +4.0.0 +----- + + * Relying on service auto-registration while autowiring is not supported anymore. + Explicitly inject your dependencies or create services whose ids are + their fully-qualified class name. + + Before: + + ```php + namespace App\Controller; + + use App\Mailer; + + class DefaultController + { + public function __construct(Mailer $mailer) { + // ... + } + + // ... + } + ``` + ```yml + services: + App\Controller\DefaultController: + autowire: true + ``` + + After: + + ```php + // same PHP code + ``` + ```yml + services: + App\Controller\DefaultController: + autowire: true + + # or + # App\Controller\DefaultController: + # arguments: { $mailer: "@App\Mailer" } + + App\Mailer: + autowire: true + ``` + * removed autowiring services based on the types they implement + * added a third `$methodName` argument to the `getProxyFactoryCode()` method + of the `DumperInterface` + * removed support for autowiring types + * removed `Container::isFrozen` + * removed support for dumping an ucompiled container in `PhpDumper` + * removed support for generating a dumped `Container` without populating the method map + * removed support for case insensitive service identifiers + * removed the `DefinitionDecorator` class, replaced by `ChildDefinition` + * removed the `AutowireServiceResource` class and related `AutowirePass::createResourceForClass()` method + * removed `LoggingFormatter`, `Compiler::getLoggingFormatter()` and `addLogMessage()` class and methods, use the `ContainerBuilder::log()` method instead + * removed `FactoryReturnTypePass` + * removed `ContainerBuilder::addClassResource()`, use the `addObjectResource()` or the `getReflectionClass()` method instead. + * removed support for top-level anonymous services + * removed silent behavior for unused attributes and elements + * removed support for setting and accessing private services in `Container` + * removed support for setting pre-defined services in `Container` + * removed support for case insensitivity of parameter names + * removed `AutowireExceptionPass` and `AutowirePass::getAutowiringExceptions()`, use `Definition::addError()` and the `DefinitionErrorExceptionPass` instead + +3.4.0 +----- + + * moved the `ExtensionCompilerPass` to before-optimization passes with priority -1000 + * deprecated "public-by-default" definitions and aliases, the new default will be "private" in 4.0 + * added `EnvVarProcessorInterface` and corresponding "container.env_var_processor" tag for processing env vars + * added support for ignore-on-uninitialized references + * deprecated service auto-registration while autowiring + * deprecated the ability to check for the initialization of a private service with the `Container::initialized()` method + * deprecated support for top-level anonymous services in XML + * deprecated case insensitivity of parameter names + * deprecated the `ResolveDefinitionTemplatesPass` class in favor of `ResolveChildDefinitionsPass` + * added `TaggedIteratorArgument` with YAML (`!tagged foo`) and XML (`<service type="tagged"/>`) support + * deprecated `AutowireExceptionPass` and `AutowirePass::getAutowiringExceptions()`, use `Definition::addError()` and the `DefinitionErrorExceptionPass` instead + + +3.3.0 +----- + + * deprecated autowiring services based on the types they implement; + rename (or alias) your services to their FQCN id to make them autowirable + * added "ServiceSubscriberInterface" - to allow for per-class explicit service-locator definitions + * added "container.service_locator" tag for defining service-locator services + * added anonymous services support in YAML configuration files using the `!service` tag. + * added "TypedReference" and "ServiceClosureArgument" for creating service-locator services + * added `ServiceLocator` - a PSR-11 container holding a set of services to be lazily loaded + * added "instanceof" section for local interface-defined configs + * added prototype services for PSR4-based discovery and registration + * added `ContainerBuilder::getReflectionClass()` for retrieving and tracking reflection class info + * deprecated `ContainerBuilder::getClassResource()`, use `ContainerBuilder::getReflectionClass()` or `ContainerBuilder::addObjectResource()` instead + * added `ContainerBuilder::fileExists()` for checking and tracking file or directory existence + * deprecated autowiring-types, use aliases instead + * added support for omitting the factory class name in a service definition if the definition class is set + * deprecated case insensitivity of service identifiers + * added "iterator" argument type for lazy iteration over a set of values and services + * added file-wide configurable defaults for service attributes "public", "tags", + "autowire" and "autoconfigure" + * made the "class" attribute optional, using the "id" as fallback + * using the `PhpDumper` with an uncompiled `ContainerBuilder` is deprecated and + will not be supported anymore in 4.0 + * deprecated the `DefinitionDecorator` class in favor of `ChildDefinition` + * allow config files to be loaded using a glob pattern + * [BC BREAK] the `NullDumper` class is now final + +3.2.0 +----- + + * allowed to prioritize compiler passes by introducing a third argument to `PassConfig::addPass()`, to `Compiler::addPass` and to `ContainerBuilder::addCompilerPass()` + * added support for PHP constants in YAML configuration files + * deprecated the ability to set or unset a private service with the `Container::set()` method + * deprecated the ability to check for the existence of a private service with the `Container::has()` method + * deprecated the ability to request a private service with the `Container::get()` method + * deprecated support for generating a dumped `Container` without populating the method map + +3.0.0 +----- + + * removed all deprecated codes from 2.x versions + +2.8.0 +----- + + * deprecated the abstract ContainerAware class in favor of ContainerAwareTrait + * deprecated IntrospectableContainerInterface, to be merged with ContainerInterface in 3.0 + * allowed specifying a directory to recursively load all configuration files it contains + * deprecated the concept of scopes + * added `Definition::setShared()` and `Definition::isShared()` + * added ResettableContainerInterface to be able to reset the container to release memory on shutdown + * added a way to define the priority of service decoration + * added support for service autowiring + +2.7.0 +----- + + * deprecated synchronized services + +2.6.0 +----- + + * added new factory syntax and deprecated the old one + +2.5.0 +----- + +* added DecoratorServicePass and a way to override a service definition (Definition::setDecoratedService()) +* deprecated SimpleXMLElement class. + +2.4.0 +----- + + * added support for expressions in service definitions + * added ContainerAwareTrait to add default container aware behavior to a class + +2.2.0 +----- + + * added Extension::isConfigEnabled() to ease working with enableable configurations + * added an Extension base class with sensible defaults to be used in conjunction + with the Config component. + * added PrependExtensionInterface (to be able to allow extensions to prepend + application configuration settings for any Bundle) + +2.1.0 +----- + + * added IntrospectableContainerInterface (to be able to check if a service + has been initialized or not) + * added ConfigurationExtensionInterface + * added Definition::clearTag() + * component exceptions that inherit base SPL classes are now used exclusively + (this includes dumped containers) + * [BC BREAK] fixed unescaping of class arguments, method + ParameterBag::unescapeValue() was made public diff --git a/srcs/phpmyadmin/vendor/symfony/dependency-injection/ChildDefinition.php b/srcs/phpmyadmin/vendor/symfony/dependency-injection/ChildDefinition.php new file mode 100644 index 0000000..7718f72 --- /dev/null +++ b/srcs/phpmyadmin/vendor/symfony/dependency-injection/ChildDefinition.php @@ -0,0 +1,124 @@ +<?php + +/* + * This file is part of the Symfony package. + * + * (c) Fabien Potencier <fabien@symfony.com> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection; + +use Symfony\Component\DependencyInjection\Exception\BadMethodCallException; +use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException; +use Symfony\Component\DependencyInjection\Exception\OutOfBoundsException; + +/** + * This definition extends another definition. + * + * @author Johannes M. Schmitt <schmittjoh@gmail.com> + */ +class ChildDefinition extends Definition +{ + private $parent; + + /** + * @param string $parent The id of Definition instance to decorate + */ + public function __construct(string $parent) + { + $this->parent = $parent; + $this->setPrivate(false); + } + + /** + * Returns the Definition to inherit from. + * + * @return string + */ + public function getParent() + { + return $this->parent; + } + + /** + * Sets the Definition to inherit from. + * + * @param string $parent + * + * @return $this + */ + public function setParent($parent) + { + $this->parent = $parent; + + return $this; + } + + /** + * Gets an argument to pass to the service constructor/factory method. + * + * If replaceArgument() has been used to replace an argument, this method + * will return the replacement value. + * + * @param int|string $index + * + * @return mixed The argument value + * + * @throws OutOfBoundsException When the argument does not exist + */ + public function getArgument($index) + { + if (\array_key_exists('index_'.$index, $this->arguments)) { + return $this->arguments['index_'.$index]; + } + + return parent::getArgument($index); + } + + /** + * You should always use this method when overwriting existing arguments + * of the parent definition. + * + * If you directly call setArguments() keep in mind that you must follow + * certain conventions when you want to overwrite the arguments of the + * parent definition, otherwise your arguments will only be appended. + * + * @param int|string $index + * @param mixed $value + * + * @return $this + * + * @throws InvalidArgumentException when $index isn't an integer + */ + public function replaceArgument($index, $value) + { + if (\is_int($index)) { + $this->arguments['index_'.$index] = $value; + } elseif (0 === strpos($index, '$')) { + $this->arguments[$index] = $value; + } else { + throw new InvalidArgumentException('The argument must be an existing index or the name of a constructor\'s parameter.'); + } + + return $this; + } + + /** + * @internal + */ + public function setAutoconfigured($autoconfigured): self + { + throw new BadMethodCallException('A ChildDefinition cannot be autoconfigured.'); + } + + /** + * @internal + */ + public function setInstanceofConditionals(array $instanceof): self + { + throw new BadMethodCallException('A ChildDefinition cannot have instanceof conditionals set on it.'); + } +} diff --git a/srcs/phpmyadmin/vendor/symfony/dependency-injection/Compiler/AbstractRecursivePass.php b/srcs/phpmyadmin/vendor/symfony/dependency-injection/Compiler/AbstractRecursivePass.php new file mode 100644 index 0000000..ad3cb52 --- /dev/null +++ b/srcs/phpmyadmin/vendor/symfony/dependency-injection/Compiler/AbstractRecursivePass.php @@ -0,0 +1,228 @@ +<?php + +/* + * This file is part of the Symfony package. + * + * (c) Fabien Potencier <fabien@symfony.com> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection\Compiler; + +use Symfony\Component\DependencyInjection\Argument\ArgumentInterface; +use Symfony\Component\DependencyInjection\ContainerBuilder; +use Symfony\Component\DependencyInjection\Definition; +use Symfony\Component\DependencyInjection\Exception\LogicException; +use Symfony\Component\DependencyInjection\Exception\RuntimeException; +use Symfony\Component\DependencyInjection\ExpressionLanguage; +use Symfony\Component\DependencyInjection\Reference; +use Symfony\Component\ExpressionLanguage\Expression; + +/** + * @author Nicolas Grekas <p@tchwork.com> + */ +abstract class AbstractRecursivePass implements CompilerPassInterface +{ + /** + * @var ContainerBuilder + */ + protected $container; + protected $currentId; + + private $processExpressions = false; + private $expressionLanguage; + private $inExpression = false; + + /** + * {@inheritdoc} + */ + public function process(ContainerBuilder $container) + { + $this->container = $container; + + try { + $this->processValue($container->getDefinitions(), true); + } finally { + $this->container = null; + } + } + + protected function enableExpressionProcessing() + { + $this->processExpressions = true; + } + + protected function inExpression(bool $reset = true): bool + { + $inExpression = $this->inExpression; + if ($reset) { + $this->inExpression = false; + } + + return $inExpression; + } + + /** + * Processes a value found in a definition tree. + * + * @param mixed $value + * @param bool $isRoot + * + * @return mixed The processed value + */ + protected function processValue($value, $isRoot = false) + { + if (\is_array($value)) { + foreach ($value as $k => $v) { + if ($isRoot) { + $this->currentId = $k; + } + if ($v !== $processedValue = $this->processValue($v, $isRoot)) { + $value[$k] = $processedValue; + } + } + } elseif ($value instanceof ArgumentInterface) { + $value->setValues($this->processValue($value->getValues())); + } elseif ($value instanceof Expression && $this->processExpressions) { + $this->getExpressionLanguage()->compile((string) $value, ['this' => 'container']); + } elseif ($value instanceof Definition) { + $value->setArguments($this->processValue($value->getArguments())); + $value->setProperties($this->processValue($value->getProperties())); + $value->setMethodCalls($this->processValue($value->getMethodCalls())); + + $changes = $value->getChanges(); + if (isset($changes['factory'])) { + $value->setFactory($this->processValue($value->getFactory())); + } + if (isset($changes['configurator'])) { + $value->setConfigurator($this->processValue($value->getConfigurator())); + } + } + + return $value; + } + + /** + * @param bool $required + * + * @return \ReflectionFunctionAbstract|null + * + * @throws RuntimeException + */ + protected function getConstructor(Definition $definition, $required) + { + if ($definition->isSynthetic()) { + return null; + } + + if (\is_string($factory = $definition->getFactory())) { + if (!\function_exists($factory)) { + throw new RuntimeException(sprintf('Invalid service "%s": function "%s" does not exist.', $this->currentId, $factory)); + } + $r = new \ReflectionFunction($factory); + if (false !== $r->getFileName() && file_exists($r->getFileName())) { + $this->container->fileExists($r->getFileName()); + } + + return $r; + } + + if ($factory) { + list($class, $method) = $factory; + if ($class instanceof Reference) { + $class = $this->container->findDefinition((string) $class)->getClass(); + } elseif ($class instanceof Definition) { + $class = $class->getClass(); + } elseif (null === $class) { + $class = $definition->getClass(); + } + + if ('__construct' === $method) { + throw new RuntimeException(sprintf('Invalid service "%s": "__construct()" cannot be used as a factory method.', $this->currentId)); + } + + return $this->getReflectionMethod(new Definition($class), $method); + } + + $class = $definition->getClass(); + + try { + if (!$r = $this->container->getReflectionClass($class)) { + throw new RuntimeException(sprintf('Invalid service "%s": class "%s" does not exist.', $this->currentId, $class)); + } + } catch (\ReflectionException $e) { + throw new RuntimeException(sprintf('Invalid service "%s": %s.', $this->currentId, lcfirst(rtrim($e->getMessage(), '.')))); + } + if (!$r = $r->getConstructor()) { + if ($required) { + throw new RuntimeException(sprintf('Invalid service "%s": class%s has no constructor.', $this->currentId, sprintf($class !== $this->currentId ? ' "%s"' : '', $class))); + } + } elseif (!$r->isPublic()) { + throw new RuntimeException(sprintf('Invalid service "%s": %s must be public.', $this->currentId, sprintf($class !== $this->currentId ? 'constructor of class "%s"' : 'its constructor', $class))); + } + + return $r; + } + + /** + * @param string $method + * + * @throws RuntimeException + * + * @return \ReflectionFunctionAbstract + */ + protected function getReflectionMethod(Definition $definition, $method) + { + if ('__construct' === $method) { + return $this->getConstructor($definition, true); + } + + if (!$class = $definition->getClass()) { + throw new RuntimeException(sprintf('Invalid service "%s": the class is not set.', $this->currentId)); + } + + if (!$r = $this->container->getReflectionClass($class)) { + throw new RuntimeException(sprintf('Invalid service "%s": class "%s" does not exist.', $this->currentId, $class)); + } + + if (!$r->hasMethod($method)) { + throw new RuntimeException(sprintf('Invalid service "%s": method "%s()" does not exist.', $this->currentId, $class !== $this->currentId ? $class.'::'.$method : $method)); + } + + $r = $r->getMethod($method); + if (!$r->isPublic()) { + throw new RuntimeException(sprintf('Invalid service "%s": method "%s()" must be public.', $this->currentId, $class !== $this->currentId ? $class.'::'.$method : $method)); + } + + return $r; + } + + private function getExpressionLanguage(): ExpressionLanguage + { + if (null === $this->expressionLanguage) { + if (!class_exists(ExpressionLanguage::class)) { + throw new LogicException('Unable to use expressions as the Symfony ExpressionLanguage component is not installed.'); + } + + $providers = $this->container->getExpressionLanguageProviders(); + $this->expressionLanguage = new ExpressionLanguage(null, $providers, function (string $arg): string { + if ('""' === substr_replace($arg, '', 1, -1)) { + $id = stripcslashes(substr($arg, 1, -1)); + $this->inExpression = true; + $arg = $this->processValue(new Reference($id)); + $this->inExpression = false; + if (!$arg instanceof Reference) { + throw new RuntimeException(sprintf('"%s::processValue()" must return a Reference when processing an expression, %s returned for service("%s").', \get_class($this), \is_object($arg) ? \get_class($arg) : \gettype($arg), $id)); + } + $arg = sprintf('"%s"', $arg); + } + + return sprintf('$this->get(%s)', $arg); + }); + } + + return $this->expressionLanguage; + } +} diff --git a/srcs/phpmyadmin/vendor/symfony/dependency-injection/Compiler/AnalyzeServiceReferencesPass.php b/srcs/phpmyadmin/vendor/symfony/dependency-injection/Compiler/AnalyzeServiceReferencesPass.php new file mode 100644 index 0000000..59a27ae --- /dev/null +++ b/srcs/phpmyadmin/vendor/symfony/dependency-injection/Compiler/AnalyzeServiceReferencesPass.php @@ -0,0 +1,192 @@ +<?php + +/* + * This file is part of the Symfony package. + * + * (c) Fabien Potencier <fabien@symfony.com> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection\Compiler; + +use Symfony\Component\DependencyInjection\Argument\ArgumentInterface; +use Symfony\Component\DependencyInjection\ContainerBuilder; +use Symfony\Component\DependencyInjection\ContainerInterface; +use Symfony\Component\DependencyInjection\Definition; +use Symfony\Component\DependencyInjection\Reference; + +/** + * Run this pass before passes that need to know more about the relation of + * your services. + * + * This class will populate the ServiceReferenceGraph with information. You can + * retrieve the graph in other passes from the compiler. + * + * @author Johannes M. Schmitt <schmittjoh@gmail.com> + * @author Nicolas Grekas <p@tchwork.com> + */ +class AnalyzeServiceReferencesPass extends AbstractRecursivePass implements RepeatablePassInterface +{ + private $graph; + private $currentDefinition; + private $onlyConstructorArguments; + private $hasProxyDumper; + private $lazy; + private $byConstructor; + private $definitions; + private $aliases; + + /** + * @param bool $onlyConstructorArguments Sets this Service Reference pass to ignore method calls + */ + public function __construct(bool $onlyConstructorArguments = false, bool $hasProxyDumper = true) + { + $this->onlyConstructorArguments = $onlyConstructorArguments; + $this->hasProxyDumper = $hasProxyDumper; + $this->enableExpressionProcessing(); + } + + /** + * {@inheritdoc} + */ + public function setRepeatedPass(RepeatedPass $repeatedPass) + { + @trigger_error(sprintf('The "%s()" method is deprecated since Symfony 4.2.', __METHOD__), E_USER_DEPRECATED); + } + + /** + * Processes a ContainerBuilder object to populate the service reference graph. + */ + public function process(ContainerBuilder $container) + { + $this->container = $container; + $this->graph = $container->getCompiler()->getServiceReferenceGraph(); + $this->graph->clear(); + $this->lazy = false; + $this->byConstructor = false; + $this->definitions = $container->getDefinitions(); + $this->aliases = $container->getAliases(); + + foreach ($this->aliases as $id => $alias) { + $targetId = $this->getDefinitionId((string) $alias); + $this->graph->connect($id, $alias, $targetId, null !== $targetId ? $this->container->getDefinition($targetId) : null, null); + } + + try { + parent::process($container); + } finally { + $this->aliases = $this->definitions = []; + } + } + + protected function processValue($value, $isRoot = false) + { + $lazy = $this->lazy; + $inExpression = $this->inExpression(); + + if ($value instanceof ArgumentInterface) { + $this->lazy = true; + parent::processValue($value->getValues()); + $this->lazy = $lazy; + + return $value; + } + if ($value instanceof Reference) { + $targetId = $this->getDefinitionId((string) $value); + $targetDefinition = null !== $targetId ? $this->container->getDefinition($targetId) : null; + + $this->graph->connect( + $this->currentId, + $this->currentDefinition, + $targetId, + $targetDefinition, + $value, + $this->lazy || ($this->hasProxyDumper && $targetDefinition && $targetDefinition->isLazy()), + ContainerInterface::IGNORE_ON_UNINITIALIZED_REFERENCE === $value->getInvalidBehavior(), + $this->byConstructor + ); + + if ($inExpression) { + $this->graph->connect( + '.internal.reference_in_expression', + null, + $targetId, + $targetDefinition, + $value, + $this->lazy || ($targetDefinition && $targetDefinition->isLazy()), + true + ); + } + + return $value; + } + if (!$value instanceof Definition) { + return parent::processValue($value, $isRoot); + } + if ($isRoot) { + if ($value->isSynthetic() || $value->isAbstract()) { + return $value; + } + $this->currentDefinition = $value; + } elseif ($this->currentDefinition === $value) { + return $value; + } + $this->lazy = false; + + $byConstructor = $this->byConstructor; + $this->byConstructor = $isRoot || $byConstructor; + $this->processValue($value->getFactory()); + $this->processValue($value->getArguments()); + + $properties = $value->getProperties(); + $setters = $value->getMethodCalls(); + + // Any references before a "wither" are part of the constructor-instantiation graph + $lastWitherIndex = null; + foreach ($setters as $k => $call) { + if ($call[2] ?? false) { + $lastWitherIndex = $k; + } + } + + if (null !== $lastWitherIndex) { + $this->processValue($properties); + $setters = $properties = []; + + foreach ($value->getMethodCalls() as $k => $call) { + if (null === $lastWitherIndex) { + $setters[] = $call; + continue; + } + + if ($lastWitherIndex === $k) { + $lastWitherIndex = null; + } + + $this->processValue($call); + } + } + + $this->byConstructor = $byConstructor; + + if (!$this->onlyConstructorArguments) { + $this->processValue($properties); + $this->processValue($setters); + $this->processValue($value->getConfigurator()); + } + $this->lazy = $lazy; + + return $value; + } + + private function getDefinitionId(string $id): ?string + { + while (isset($this->aliases[$id])) { + $id = (string) $this->aliases[$id]; + } + + return isset($this->definitions[$id]) ? $id : null; + } +} diff --git a/srcs/phpmyadmin/vendor/symfony/dependency-injection/Compiler/AutoAliasServicePass.php b/srcs/phpmyadmin/vendor/symfony/dependency-injection/Compiler/AutoAliasServicePass.php new file mode 100644 index 0000000..0342068 --- /dev/null +++ b/srcs/phpmyadmin/vendor/symfony/dependency-injection/Compiler/AutoAliasServicePass.php @@ -0,0 +1,41 @@ +<?php + +/* + * This file is part of the Symfony package. + * + * (c) Fabien Potencier <fabien@symfony.com> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection\Compiler; + +use Symfony\Component\DependencyInjection\Alias; +use Symfony\Component\DependencyInjection\ContainerBuilder; +use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException; + +/** + * Sets a service to be an alias of another one, given a format pattern. + */ +class AutoAliasServicePass implements CompilerPassInterface +{ + /** + * {@inheritdoc} + */ + public function process(ContainerBuilder $container) + { + foreach ($container->findTaggedServiceIds('auto_alias') as $serviceId => $tags) { + foreach ($tags as $tag) { + if (!isset($tag['format'])) { + throw new InvalidArgumentException(sprintf('Missing tag information "format" on auto_alias service "%s".', $serviceId)); + } + + $aliasId = $container->getParameterBag()->resolveValue($tag['format']); + if ($container->hasDefinition($aliasId) || $container->hasAlias($aliasId)) { + $container->setAlias($serviceId, new Alias($aliasId, true)); + } + } + } + } +} diff --git a/srcs/phpmyadmin/vendor/symfony/dependency-injection/Compiler/AutowirePass.php b/srcs/phpmyadmin/vendor/symfony/dependency-injection/Compiler/AutowirePass.php new file mode 100644 index 0000000..8d46fd6 --- /dev/null +++ b/srcs/phpmyadmin/vendor/symfony/dependency-injection/Compiler/AutowirePass.php @@ -0,0 +1,475 @@ +<?php + +/* + * This file is part of the Symfony package. + * + * (c) Fabien Potencier <fabien@symfony.com> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection\Compiler; + +use Symfony\Component\Config\Resource\ClassExistenceResource; +use Symfony\Component\DependencyInjection\ContainerBuilder; +use Symfony\Component\DependencyInjection\Definition; +use Symfony\Component\DependencyInjection\Exception\AutowiringFailedException; +use Symfony\Component\DependencyInjection\Exception\RuntimeException; +use Symfony\Component\DependencyInjection\LazyProxy\ProxyHelper; +use Symfony\Component\DependencyInjection\TypedReference; + +/** + * Inspects existing service definitions and wires the autowired ones using the type hints of their classes. + * + * @author Kévin Dunglas <dunglas@gmail.com> + * @author Nicolas Grekas <p@tchwork.com> + */ +class AutowirePass extends AbstractRecursivePass +{ + private $types; + private $ambiguousServiceTypes; + private $lastFailure; + private $throwOnAutowiringException; + private $decoratedClass; + private $decoratedId; + private $methodCalls; + private $getPreviousValue; + private $decoratedMethodIndex; + private $decoratedMethodArgumentIndex; + private $typesClone; + + public function __construct(bool $throwOnAutowireException = true) + { + $this->throwOnAutowiringException = $throwOnAutowireException; + } + + /** + * {@inheritdoc} + */ + public function process(ContainerBuilder $container) + { + try { + $this->typesClone = clone $this; + parent::process($container); + } finally { + $this->decoratedClass = null; + $this->decoratedId = null; + $this->methodCalls = null; + $this->getPreviousValue = null; + $this->decoratedMethodIndex = null; + $this->decoratedMethodArgumentIndex = null; + $this->typesClone = null; + } + } + + /** + * {@inheritdoc} + */ + protected function processValue($value, $isRoot = false) + { + try { + return $this->doProcessValue($value, $isRoot); + } catch (AutowiringFailedException $e) { + if ($this->throwOnAutowiringException) { + throw $e; + } + + $this->container->getDefinition($this->currentId)->addError($e->getMessageCallback() ?? $e->getMessage()); + + return parent::processValue($value, $isRoot); + } + } + + /** + * @return mixed + */ + private function doProcessValue($value, bool $isRoot = false) + { + if ($value instanceof TypedReference) { + if ($ref = $this->getAutowiredReference($value)) { + return $ref; + } + if (ContainerBuilder::RUNTIME_EXCEPTION_ON_INVALID_REFERENCE === $value->getInvalidBehavior()) { + $message = $this->createTypeNotFoundMessageCallback($value, 'it'); + + // since the error message varies by referenced id and $this->currentId, so should the id of the dummy errored definition + $this->container->register($id = sprintf('.errored.%s.%s', $this->currentId, (string) $value), $value->getType()) + ->addError($message); + + return new TypedReference($id, $value->getType(), $value->getInvalidBehavior(), $value->getName()); + } + } + $value = parent::processValue($value, $isRoot); + + if (!$value instanceof Definition || !$value->isAutowired() || $value->isAbstract() || !$value->getClass()) { + return $value; + } + if (!$reflectionClass = $this->container->getReflectionClass($value->getClass(), false)) { + $this->container->log($this, sprintf('Skipping service "%s": Class or interface "%s" cannot be loaded.', $this->currentId, $value->getClass())); + + return $value; + } + + $this->methodCalls = $value->getMethodCalls(); + + try { + $constructor = $this->getConstructor($value, false); + } catch (RuntimeException $e) { + throw new AutowiringFailedException($this->currentId, $e->getMessage(), 0, $e); + } + + if ($constructor) { + array_unshift($this->methodCalls, [$constructor, $value->getArguments()]); + } + + $this->methodCalls = $this->autowireCalls($reflectionClass, $isRoot); + + if ($constructor) { + list(, $arguments) = array_shift($this->methodCalls); + + if ($arguments !== $value->getArguments()) { + $value->setArguments($arguments); + } + } + + if ($this->methodCalls !== $value->getMethodCalls()) { + $value->setMethodCalls($this->methodCalls); + } + + return $value; + } + + private function autowireCalls(\ReflectionClass $reflectionClass, bool $isRoot): array + { + $this->decoratedId = null; + $this->decoratedClass = null; + $this->getPreviousValue = null; + + if ($isRoot && ($definition = $this->container->getDefinition($this->currentId)) && $this->container->has($this->decoratedId = $definition->innerServiceId)) { + $this->decoratedClass = $this->container->findDefinition($this->decoratedId)->getClass(); + } + + foreach ($this->methodCalls as $i => $call) { + $this->decoratedMethodIndex = $i; + list($method, $arguments) = $call; + + if ($method instanceof \ReflectionFunctionAbstract) { + $reflectionMethod = $method; + } else { + $definition = new Definition($reflectionClass->name); + try { + $reflectionMethod = $this->getReflectionMethod($definition, $method); + } catch (RuntimeException $e) { + if ($definition->getFactory()) { + continue; + } + throw $e; + } + } + + $arguments = $this->autowireMethod($reflectionMethod, $arguments); + + if ($arguments !== $call[1]) { + $this->methodCalls[$i][1] = $arguments; + } + } + + return $this->methodCalls; + } + + /** + * Autowires the constructor or a method. + * + * @return array The autowired arguments + * + * @throws AutowiringFailedException + */ + private function autowireMethod(\ReflectionFunctionAbstract $reflectionMethod, array $arguments): array + { + $class = $reflectionMethod instanceof \ReflectionMethod ? $reflectionMethod->class : $this->currentId; + $method = $reflectionMethod->name; + $parameters = $reflectionMethod->getParameters(); + if ($reflectionMethod->isVariadic()) { + array_pop($parameters); + } + + foreach ($parameters as $index => $parameter) { + if (\array_key_exists($index, $arguments) && '' !== $arguments[$index]) { + continue; + } + + $type = ProxyHelper::getTypeHint($reflectionMethod, $parameter, true); + + if (!$type) { + if (isset($arguments[$index])) { + continue; + } + + // no default value? Then fail + if (!$parameter->isDefaultValueAvailable()) { + // For core classes, isDefaultValueAvailable() can + // be false when isOptional() returns true. If the + // argument *is* optional, allow it to be missing + if ($parameter->isOptional()) { + continue; + } + $type = ProxyHelper::getTypeHint($reflectionMethod, $parameter, false); + $type = $type ? sprintf('is type-hinted "%s"', ltrim($type, '\\')) : 'has no type-hint'; + + throw new AutowiringFailedException($this->currentId, sprintf('Cannot autowire service "%s": argument "$%s" of method "%s()" %s, you should configure its value explicitly.', $this->currentId, $parameter->name, $class !== $this->currentId ? $class.'::'.$method : $method, $type)); + } + + // specifically pass the default value + $arguments[$index] = $parameter->getDefaultValue(); + + continue; + } + + $getValue = function () use ($type, $parameter, $class, $method) { + if (!$value = $this->getAutowiredReference($ref = new TypedReference($type, $type, ContainerBuilder::EXCEPTION_ON_INVALID_REFERENCE, $parameter->name))) { + $failureMessage = $this->createTypeNotFoundMessageCallback($ref, sprintf('argument "$%s" of method "%s()"', $parameter->name, $class !== $this->currentId ? $class.'::'.$method : $method)); + + if ($parameter->isDefaultValueAvailable()) { + $value = $parameter->getDefaultValue(); + } elseif (!$parameter->allowsNull()) { + throw new AutowiringFailedException($this->currentId, $failureMessage); + } + } + + return $value; + }; + + if ($this->decoratedClass && $isDecorated = is_a($this->decoratedClass, $type, true)) { + if ($this->getPreviousValue) { + // The inner service is injected only if there is only 1 argument matching the type of the decorated class + // across all arguments of all autowired methods. + // If a second matching argument is found, the default behavior is restored. + + $getPreviousValue = $this->getPreviousValue; + $this->methodCalls[$this->decoratedMethodIndex][1][$this->decoratedMethodArgumentIndex] = $getPreviousValue(); + $this->decoratedClass = null; // Prevent further checks + } else { + $arguments[$index] = new TypedReference($this->decoratedId, $this->decoratedClass); + $this->getPreviousValue = $getValue; + $this->decoratedMethodArgumentIndex = $index; + + continue; + } + } + + $arguments[$index] = $getValue(); + } + + if ($parameters && !isset($arguments[++$index])) { + while (0 <= --$index) { + $parameter = $parameters[$index]; + if (!$parameter->isDefaultValueAvailable() || $parameter->getDefaultValue() !== $arguments[$index]) { + break; + } + unset($arguments[$index]); + } + } + + // it's possible index 1 was set, then index 0, then 2, etc + // make sure that we re-order so they're injected as expected + ksort($arguments); + + return $arguments; + } + + /** + * Returns a reference to the service matching the given type, if any. + */ + private function getAutowiredReference(TypedReference $reference): ?TypedReference + { + $this->lastFailure = null; + $type = $reference->getType(); + + if ($type !== (string) $reference) { + return $reference; + } + + if (null !== $name = $reference->getName()) { + if ($this->container->has($alias = $type.' $'.$name) && !$this->container->findDefinition($alias)->isAbstract()) { + return new TypedReference($alias, $type, $reference->getInvalidBehavior()); + } + + if ($this->container->has($name) && !$this->container->findDefinition($name)->isAbstract()) { + foreach ($this->container->getAliases() as $id => $alias) { + if ($name === (string) $alias && 0 === strpos($id, $type.' $')) { + return new TypedReference($name, $type, $reference->getInvalidBehavior()); + } + } + } + } + + if ($this->container->has($type) && !$this->container->findDefinition($type)->isAbstract()) { + return new TypedReference($type, $type, $reference->getInvalidBehavior()); + } + + return null; + } + + /** + * Populates the list of available types. + */ + private function populateAvailableTypes(ContainerBuilder $container) + { + $this->types = []; + $this->ambiguousServiceTypes = []; + + foreach ($container->getDefinitions() as $id => $definition) { + $this->populateAvailableType($container, $id, $definition); + } + } + + /** + * Populates the list of available types for a given definition. + */ + private function populateAvailableType(ContainerBuilder $container, string $id, Definition $definition) + { + // Never use abstract services + if ($definition->isAbstract()) { + return; + } + + if ('' === $id || '.' === $id[0] || $definition->isDeprecated() || !$reflectionClass = $container->getReflectionClass($definition->getClass(), false)) { + return; + } + + foreach ($reflectionClass->getInterfaces() as $reflectionInterface) { + $this->set($reflectionInterface->name, $id); + } + + do { + $this->set($reflectionClass->name, $id); + } while ($reflectionClass = $reflectionClass->getParentClass()); + } + + /** + * Associates a type and a service id if applicable. + */ + private function set(string $type, string $id) + { + // is this already a type/class that is known to match multiple services? + if (isset($this->ambiguousServiceTypes[$type])) { + $this->ambiguousServiceTypes[$type][] = $id; + + return; + } + + // check to make sure the type doesn't match multiple services + if (!isset($this->types[$type]) || $this->types[$type] === $id) { + $this->types[$type] = $id; + + return; + } + + // keep an array of all services matching this type + if (!isset($this->ambiguousServiceTypes[$type])) { + $this->ambiguousServiceTypes[$type] = [$this->types[$type]]; + unset($this->types[$type]); + } + $this->ambiguousServiceTypes[$type][] = $id; + } + + private function createTypeNotFoundMessageCallback(TypedReference $reference, string $label): callable + { + if (null === $this->typesClone->container) { + $this->typesClone->container = new ContainerBuilder($this->container->getParameterBag()); + $this->typesClone->container->setAliases($this->container->getAliases()); + $this->typesClone->container->setDefinitions($this->container->getDefinitions()); + $this->typesClone->container->setResourceTracking(false); + } + $currentId = $this->currentId; + + return (function () use ($reference, $label, $currentId) { + return $this->createTypeNotFoundMessage($reference, $label, $currentId); + })->bindTo($this->typesClone); + } + + private function createTypeNotFoundMessage(TypedReference $reference, string $label, string $currentId): string + { + if (!$r = $this->container->getReflectionClass($type = $reference->getType(), false)) { + // either $type does not exist or a parent class does not exist + try { + $resource = new ClassExistenceResource($type, false); + // isFresh() will explode ONLY if a parent class/trait does not exist + $resource->isFresh(0); + $parentMsg = false; + } catch (\ReflectionException $e) { + $parentMsg = $e->getMessage(); + } + + $message = sprintf('has type "%s" but this class %s.', $type, $parentMsg ? sprintf('is missing a parent class (%s)', $parentMsg) : 'was not found'); + } else { + $alternatives = $this->createTypeAlternatives($this->container, $reference); + $message = $this->container->has($type) ? 'this service is abstract' : 'no such service exists'; + $message = sprintf('references %s "%s" but %s.%s', $r->isInterface() ? 'interface' : 'class', $type, $message, $alternatives); + + if ($r->isInterface() && !$alternatives) { + $message .= ' Did you create a class that implements this interface?'; + } + } + + $message = sprintf('Cannot autowire service "%s": %s %s', $currentId, $label, $message); + + if (null !== $this->lastFailure) { + $message = $this->lastFailure."\n".$message; + $this->lastFailure = null; + } + + return $message; + } + + private function createTypeAlternatives(ContainerBuilder $container, TypedReference $reference): string + { + // try suggesting available aliases first + if ($message = $this->getAliasesSuggestionForType($container, $type = $reference->getType())) { + return ' '.$message; + } + if (null === $this->ambiguousServiceTypes) { + $this->populateAvailableTypes($container); + } + + $servicesAndAliases = $container->getServiceIds(); + if (!$container->has($type) && false !== $key = array_search(strtolower($type), array_map('strtolower', $servicesAndAliases))) { + return sprintf(' Did you mean "%s"?', $servicesAndAliases[$key]); + } elseif (isset($this->ambiguousServiceTypes[$type])) { + $message = sprintf('one of these existing services: "%s"', implode('", "', $this->ambiguousServiceTypes[$type])); + } elseif (isset($this->types[$type])) { + $message = sprintf('the existing "%s" service', $this->types[$type]); + } else { + return ''; + } + + return sprintf(' You should maybe alias this %s to %s.', class_exists($type, false) ? 'class' : 'interface', $message); + } + + private function getAliasesSuggestionForType(ContainerBuilder $container, string $type): ?string + { + $aliases = []; + foreach (class_parents($type) + class_implements($type) as $parent) { + if ($container->has($parent) && !$container->findDefinition($parent)->isAbstract()) { + $aliases[] = $parent; + } + } + + if (1 < $len = \count($aliases)) { + $message = 'Try changing the type-hint to one of its parents: '; + for ($i = 0, --$len; $i < $len; ++$i) { + $message .= sprintf('%s "%s", ', class_exists($aliases[$i], false) ? 'class' : 'interface', $aliases[$i]); + } + $message .= sprintf('or %s "%s".', class_exists($aliases[$i], false) ? 'class' : 'interface', $aliases[$i]); + + return $message; + } + + if ($aliases) { + return sprintf('Try changing the type-hint to "%s" instead.', $aliases[0]); + } + + return null; + } +} diff --git a/srcs/phpmyadmin/vendor/symfony/dependency-injection/Compiler/AutowireRequiredMethodsPass.php b/srcs/phpmyadmin/vendor/symfony/dependency-injection/Compiler/AutowireRequiredMethodsPass.php new file mode 100644 index 0000000..20d3113 --- /dev/null +++ b/srcs/phpmyadmin/vendor/symfony/dependency-injection/Compiler/AutowireRequiredMethodsPass.php @@ -0,0 +1,84 @@ +<?php + +/* + * This file is part of the Symfony package. + * + * (c) Fabien Potencier <fabien@symfony.com> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection\Compiler; + +use Symfony\Component\DependencyInjection\Definition; + +/** + * Looks for definitions with autowiring enabled and registers their corresponding "@required" methods as setters. + * + * @author Nicolas Grekas <p@tchwork.com> + */ +class AutowireRequiredMethodsPass extends AbstractRecursivePass +{ + /** + * {@inheritdoc} + */ + protected function processValue($value, $isRoot = false) + { + $value = parent::processValue($value, $isRoot); + + if (!$value instanceof Definition || !$value->isAutowired() || $value->isAbstract() || !$value->getClass()) { + return $value; + } + if (!$reflectionClass = $this->container->getReflectionClass($value->getClass(), false)) { + return $value; + } + + $alreadyCalledMethods = []; + $withers = []; + + foreach ($value->getMethodCalls() as list($method)) { + $alreadyCalledMethods[strtolower($method)] = true; + } + + foreach ($reflectionClass->getMethods() as $reflectionMethod) { + $r = $reflectionMethod; + + if ($r->isConstructor() || isset($alreadyCalledMethods[strtolower($r->name)])) { + continue; + } + + while (true) { + if (false !== $doc = $r->getDocComment()) { + if (false !== stripos($doc, '@required') && preg_match('#(?:^/\*\*|\n\s*+\*)\s*+@required(?:\s|\*/$)#i', $doc)) { + if (preg_match('#(?:^/\*\*|\n\s*+\*)\s*+@return\s++static[\s\*]#i', $doc)) { + $withers[] = [$reflectionMethod->name, [], true]; + } else { + $value->addMethodCall($reflectionMethod->name, []); + } + break; + } + if (false === stripos($doc, '@inheritdoc') || !preg_match('#(?:^/\*\*|\n\s*+\*)\s*+(?:\{@inheritdoc\}|@inheritdoc)(?:\s|\*/$)#i', $doc)) { + break; + } + } + try { + $r = $r->getPrototype(); + } catch (\ReflectionException $e) { + break; // method has no prototype + } + } + } + + if ($withers) { + // Prepend withers to prevent creating circular loops + $setters = $value->getMethodCalls(); + $value->setMethodCalls($withers); + foreach ($setters as $call) { + $value->addMethodCall($call[0], $call[1], $call[2] ?? false); + } + } + + return $value; + } +} diff --git a/srcs/phpmyadmin/vendor/symfony/dependency-injection/Compiler/CheckArgumentsValidityPass.php b/srcs/phpmyadmin/vendor/symfony/dependency-injection/Compiler/CheckArgumentsValidityPass.php new file mode 100644 index 0000000..d289c05 --- /dev/null +++ b/srcs/phpmyadmin/vendor/symfony/dependency-injection/Compiler/CheckArgumentsValidityPass.php @@ -0,0 +1,87 @@ +<?php + +/* + * This file is part of the Symfony package. + * + * (c) Fabien Potencier <fabien@symfony.com> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection\Compiler; + +use Symfony\Component\DependencyInjection\Definition; +use Symfony\Component\DependencyInjection\Exception\RuntimeException; + +/** + * Checks if arguments of methods are properly configured. + * + * @author Kévin Dunglas <dunglas@gmail.com> + * @author Nicolas Grekas <p@tchwork.com> + */ +class CheckArgumentsValidityPass extends AbstractRecursivePass +{ + private $throwExceptions; + + public function __construct(bool $throwExceptions = true) + { + $this->throwExceptions = $throwExceptions; + } + + /** + * {@inheritdoc} + */ + protected function processValue($value, $isRoot = false) + { + if (!$value instanceof Definition) { + return parent::processValue($value, $isRoot); + } + + $i = 0; + foreach ($value->getArguments() as $k => $v) { + if ($k !== $i++) { + if (!\is_int($k)) { + $msg = sprintf('Invalid constructor argument for service "%s": integer expected but found string "%s". Check your service definition.', $this->currentId, $k); + $value->addError($msg); + if ($this->throwExceptions) { + throw new RuntimeException($msg); + } + + break; + } + + $msg = sprintf('Invalid constructor argument %d for service "%s": argument %d must be defined before. Check your service definition.', 1 + $k, $this->currentId, $i); + $value->addError($msg); + if ($this->throwExceptions) { + throw new RuntimeException($msg); + } + } + } + + foreach ($value->getMethodCalls() as $methodCall) { + $i = 0; + foreach ($methodCall[1] as $k => $v) { + if ($k !== $i++) { + if (!\is_int($k)) { + $msg = sprintf('Invalid argument for method call "%s" of service "%s": integer expected but found string "%s". Check your service definition.', $methodCall[0], $this->currentId, $k); + $value->addError($msg); + if ($this->throwExceptions) { + throw new RuntimeException($msg); + } + + break; + } + + $msg = sprintf('Invalid argument %d for method call "%s" of service "%s": argument %d must be defined before. Check your service definition.', 1 + $k, $methodCall[0], $this->currentId, $i); + $value->addError($msg); + if ($this->throwExceptions) { + throw new RuntimeException($msg); + } + } + } + } + + return null; + } +} diff --git a/srcs/phpmyadmin/vendor/symfony/dependency-injection/Compiler/CheckCircularReferencesPass.php b/srcs/phpmyadmin/vendor/symfony/dependency-injection/Compiler/CheckCircularReferencesPass.php new file mode 100644 index 0000000..55d911c --- /dev/null +++ b/srcs/phpmyadmin/vendor/symfony/dependency-injection/Compiler/CheckCircularReferencesPass.php @@ -0,0 +1,78 @@ +<?php + +/* + * This file is part of the Symfony package. + * + * (c) Fabien Potencier <fabien@symfony.com> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection\Compiler; + +use Symfony\Component\DependencyInjection\ContainerBuilder; +use Symfony\Component\DependencyInjection\Exception\ServiceCircularReferenceException; + +/** + * Checks your services for circular references. + * + * References from method calls are ignored since we might be able to resolve + * these references depending on the order in which services are called. + * + * Circular reference from method calls will only be detected at run-time. + * + * @author Johannes M. Schmitt <schmittjoh@gmail.com> + */ +class CheckCircularReferencesPass implements CompilerPassInterface +{ + private $currentPath; + private $checkedNodes; + + /** + * Checks the ContainerBuilder object for circular references. + */ + public function process(ContainerBuilder $container) + { + $graph = $container->getCompiler()->getServiceReferenceGraph(); + + $this->checkedNodes = []; + foreach ($graph->getNodes() as $id => $node) { + $this->currentPath = [$id]; + + $this->checkOutEdges($node->getOutEdges()); + } + } + + /** + * Checks for circular references. + * + * @param ServiceReferenceGraphEdge[] $edges An array of Edges + * + * @throws ServiceCircularReferenceException when a circular reference is found + */ + private function checkOutEdges(array $edges) + { + foreach ($edges as $edge) { + $node = $edge->getDestNode(); + $id = $node->getId(); + + if (empty($this->checkedNodes[$id])) { + // Don't check circular references for lazy edges + if (!$node->getValue() || (!$edge->isLazy() && !$edge->isWeak())) { + $searchKey = array_search($id, $this->currentPath); + $this->currentPath[] = $id; + + if (false !== $searchKey) { + throw new ServiceCircularReferenceException($id, \array_slice($this->currentPath, $searchKey)); + } + + $this->checkOutEdges($node->getOutEdges()); + } + + $this->checkedNodes[$id] = true; + array_pop($this->currentPath); + } + } + } +} diff --git a/srcs/phpmyadmin/vendor/symfony/dependency-injection/Compiler/CheckDefinitionValidityPass.php b/srcs/phpmyadmin/vendor/symfony/dependency-injection/Compiler/CheckDefinitionValidityPass.php new file mode 100644 index 0000000..bb87f47 --- /dev/null +++ b/srcs/phpmyadmin/vendor/symfony/dependency-injection/Compiler/CheckDefinitionValidityPass.php @@ -0,0 +1,90 @@ +<?php + +/* + * This file is part of the Symfony package. + * + * (c) Fabien Potencier <fabien@symfony.com> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection\Compiler; + +use Symfony\Component\DependencyInjection\ContainerBuilder; +use Symfony\Component\DependencyInjection\Exception\EnvParameterException; +use Symfony\Component\DependencyInjection\Exception\RuntimeException; +use Symfony\Component\DependencyInjection\Loader\FileLoader; + +/** + * This pass validates each definition individually only taking the information + * into account which is contained in the definition itself. + * + * Later passes can rely on the following, and specifically do not need to + * perform these checks themselves: + * + * - non synthetic, non abstract services always have a class set + * - synthetic services are always public + * + * @author Johannes M. Schmitt <schmittjoh@gmail.com> + */ +class CheckDefinitionValidityPass implements CompilerPassInterface +{ + /** + * Processes the ContainerBuilder to validate the Definition. + * + * @throws RuntimeException When the Definition is invalid + */ + public function process(ContainerBuilder $container) + { + foreach ($container->getDefinitions() as $id => $definition) { + // synthetic service is public + if ($definition->isSynthetic() && !$definition->isPublic()) { + throw new RuntimeException(sprintf('A synthetic service ("%s") must be public.', $id)); + } + + // non-synthetic, non-abstract service has class + if (!$definition->isAbstract() && !$definition->isSynthetic() && !$definition->getClass() && (!$definition->getFactory() || !preg_match(FileLoader::ANONYMOUS_ID_REGEXP, $id))) { + if ($definition->getFactory()) { + throw new RuntimeException(sprintf('Please add the class to service "%s" even if it is constructed by a factory since we might need to add method calls based on compile-time checks.', $id)); + } + if (class_exists($id) || interface_exists($id, false)) { + if (0 === strpos($id, '\\') && 1 < substr_count($id, '\\')) { + throw new RuntimeException(sprintf('The definition for "%s" has no class attribute, and appears to reference a class or interface. Please specify the class attribute explicitly or remove the leading backslash by renaming the service to "%s" to get rid of this error.', $id, substr($id, 1))); + } + + throw new RuntimeException(sprintf('The definition for "%s" has no class attribute, and appears to reference a class or interface in the global namespace. Leaving out the "class" attribute is only allowed for namespaced classes. Please specify the class attribute explicitly to get rid of this error.', $id)); + } + + throw new RuntimeException(sprintf('The definition for "%s" has no class. If you intend to inject this service dynamically at runtime, please mark it as synthetic=true. If this is an abstract definition solely used by child definitions, please add abstract=true, otherwise specify a class to get rid of this error.', $id)); + } + + // tag attribute values must be scalars + foreach ($definition->getTags() as $name => $tags) { + foreach ($tags as $attributes) { + foreach ($attributes as $attribute => $value) { + if (!is_scalar($value) && null !== $value) { + throw new RuntimeException(sprintf('A "tags" attribute must be of a scalar-type for service "%s", tag "%s", attribute "%s".', $id, $name, $attribute)); + } + } + } + } + + if ($definition->isPublic() && !$definition->isPrivate()) { + $resolvedId = $container->resolveEnvPlaceholders($id, null, $usedEnvs); + if (null !== $usedEnvs) { + throw new EnvParameterException([$resolvedId], null, 'A service name ("%s") cannot contain dynamic values.'); + } + } + } + + foreach ($container->getAliases() as $id => $alias) { + if ($alias->isPublic() && !$alias->isPrivate()) { + $resolvedId = $container->resolveEnvPlaceholders($id, null, $usedEnvs); + if (null !== $usedEnvs) { + throw new EnvParameterException([$resolvedId], null, 'An alias name ("%s") cannot contain dynamic values.'); + } + } + } + } +} diff --git a/srcs/phpmyadmin/vendor/symfony/dependency-injection/Compiler/CheckExceptionOnInvalidReferenceBehaviorPass.php b/srcs/phpmyadmin/vendor/symfony/dependency-injection/Compiler/CheckExceptionOnInvalidReferenceBehaviorPass.php new file mode 100644 index 0000000..eef7158 --- /dev/null +++ b/srcs/phpmyadmin/vendor/symfony/dependency-injection/Compiler/CheckExceptionOnInvalidReferenceBehaviorPass.php @@ -0,0 +1,88 @@ +<?php + +/* + * This file is part of the Symfony package. + * + * (c) Fabien Potencier <fabien@symfony.com> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection\Compiler; + +use Symfony\Component\DependencyInjection\ContainerBuilder; +use Symfony\Component\DependencyInjection\ContainerInterface; +use Symfony\Component\DependencyInjection\Exception\ServiceNotFoundException; +use Symfony\Component\DependencyInjection\Reference; + +/** + * Checks that all references are pointing to a valid service. + * + * @author Johannes M. Schmitt <schmittjoh@gmail.com> + */ +class CheckExceptionOnInvalidReferenceBehaviorPass extends AbstractRecursivePass +{ + private $serviceLocatorContextIds = []; + + /** + * {@inheritdoc} + */ + public function process(ContainerBuilder $container) + { + $this->serviceLocatorContextIds = []; + foreach ($container->findTaggedServiceIds('container.service_locator_context') as $id => $tags) { + $this->serviceLocatorContextIds[$id] = $tags[0]['id']; + $container->getDefinition($id)->clearTag('container.service_locator_context'); + } + + try { + return parent::process($container); + } finally { + $this->serviceLocatorContextIds = []; + } + } + + protected function processValue($value, $isRoot = false) + { + if (!$value instanceof Reference) { + return parent::processValue($value, $isRoot); + } + if (ContainerInterface::EXCEPTION_ON_INVALID_REFERENCE < $value->getInvalidBehavior() || $this->container->has($id = (string) $value)) { + return $value; + } + + $currentId = $this->currentId; + $graph = $this->container->getCompiler()->getServiceReferenceGraph(); + + if (isset($this->serviceLocatorContextIds[$currentId])) { + $currentId = $this->serviceLocatorContextIds[$currentId]; + $locator = $this->container->getDefinition($this->currentId)->getFactory()[0]; + + foreach ($locator->getArgument(0) as $k => $v) { + if ($v->getValues()[0] === $value) { + if ($k !== $id) { + $currentId = $k.'" in the container provided to "'.$currentId; + } + throw new ServiceNotFoundException($id, $currentId); + } + } + } + + if ('.' === $currentId[0] && $graph->hasNode($currentId)) { + foreach ($graph->getNode($currentId)->getInEdges() as $edge) { + if (!$edge->getValue() instanceof Reference || ContainerInterface::EXCEPTION_ON_INVALID_REFERENCE < $edge->getValue()->getInvalidBehavior()) { + continue; + } + $sourceId = $edge->getSourceNode()->getId(); + + if ('.' !== $sourceId[0]) { + $currentId = $sourceId; + break; + } + } + } + + throw new ServiceNotFoundException($id, $currentId); + } +} diff --git a/srcs/phpmyadmin/vendor/symfony/dependency-injection/Compiler/CheckReferenceValidityPass.php b/srcs/phpmyadmin/vendor/symfony/dependency-injection/Compiler/CheckReferenceValidityPass.php new file mode 100644 index 0000000..8f2a3bd --- /dev/null +++ b/srcs/phpmyadmin/vendor/symfony/dependency-injection/Compiler/CheckReferenceValidityPass.php @@ -0,0 +1,43 @@ +<?php + +/* + * This file is part of the Symfony package. + * + * (c) Fabien Potencier <fabien@symfony.com> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection\Compiler; + +use Symfony\Component\DependencyInjection\Definition; +use Symfony\Component\DependencyInjection\Exception\RuntimeException; +use Symfony\Component\DependencyInjection\Reference; + +/** + * Checks the validity of references. + * + * The following checks are performed by this pass: + * - target definitions are not abstract + * + * @author Johannes M. Schmitt <schmittjoh@gmail.com> + */ +class CheckReferenceValidityPass extends AbstractRecursivePass +{ + protected function processValue($value, $isRoot = false) + { + if ($isRoot && $value instanceof Definition && ($value->isSynthetic() || $value->isAbstract())) { + return $value; + } + if ($value instanceof Reference && $this->container->hasDefinition((string) $value)) { + $targetDefinition = $this->container->getDefinition((string) $value); + + if ($targetDefinition->isAbstract()) { + throw new RuntimeException(sprintf('The definition "%s" has a reference to an abstract definition "%s". Abstract definitions cannot be the target of references.', $this->currentId, $value)); + } + } + + return parent::processValue($value, $isRoot); + } +} diff --git a/srcs/phpmyadmin/vendor/symfony/dependency-injection/Compiler/CheckTypeDeclarationsPass.php b/srcs/phpmyadmin/vendor/symfony/dependency-injection/Compiler/CheckTypeDeclarationsPass.php new file mode 100644 index 0000000..0743cbb --- /dev/null +++ b/srcs/phpmyadmin/vendor/symfony/dependency-injection/Compiler/CheckTypeDeclarationsPass.php @@ -0,0 +1,245 @@ +<?php + +/* + * This file is part of the Symfony package. + * + * (c) Fabien Potencier <fabien@symfony.com> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection\Compiler; + +use Symfony\Component\DependencyInjection\Argument\IteratorArgument; +use Symfony\Component\DependencyInjection\Container; +use Symfony\Component\DependencyInjection\Definition; +use Symfony\Component\DependencyInjection\Exception\EnvNotFoundException; +use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException; +use Symfony\Component\DependencyInjection\Exception\InvalidParameterTypeException; +use Symfony\Component\DependencyInjection\Exception\RuntimeException; +use Symfony\Component\DependencyInjection\ExpressionLanguage; +use Symfony\Component\DependencyInjection\Parameter; +use Symfony\Component\DependencyInjection\ParameterBag\EnvPlaceholderParameterBag; +use Symfony\Component\DependencyInjection\Reference; +use Symfony\Component\DependencyInjection\ServiceLocator; +use Symfony\Component\ExpressionLanguage\Expression; + +/** + * Checks whether injected parameters are compatible with type declarations. + * + * This pass should be run after all optimization passes. + * + * It can be added either: + * * before removing passes to check all services even if they are not currently used, + * * after removing passes to check only services are used in the app. + * + * @author Nicolas Grekas <p@tchwork.com> + * @author Julien Maulny <jmaulny@darkmira.fr> + */ +final class CheckTypeDeclarationsPass extends AbstractRecursivePass +{ + private const SCALAR_TYPES = ['int', 'float', 'bool', 'string']; + + private $autoload; + private $skippedIds; + + private $expressionLanguage; + + /** + * @param bool $autoload Whether services who's class in not loaded should be checked or not. + * Defaults to false to save loading code during compilation. + * @param array $skippedIds An array indexed by the service ids to skip + */ + public function __construct(bool $autoload = false, array $skippedIds = []) + { + $this->autoload = $autoload; + $this->skippedIds = $skippedIds; + } + + /** + * {@inheritdoc} + */ + protected function processValue($value, $isRoot = false) + { + if (isset($this->skippedIds[$this->currentId])) { + return $value; + } + + if (!$value instanceof Definition || $value->hasErrors()) { + return parent::processValue($value, $isRoot); + } + + if (!$this->autoload && !class_exists($class = $value->getClass(), false) && !interface_exists($class, false)) { + return parent::processValue($value, $isRoot); + } + + if (ServiceLocator::class === $value->getClass()) { + return parent::processValue($value, $isRoot); + } + + if ($constructor = $this->getConstructor($value, false)) { + $this->checkTypeDeclarations($value, $constructor, $value->getArguments()); + } + + foreach ($value->getMethodCalls() as $methodCall) { + try { + $reflectionMethod = $this->getReflectionMethod($value, $methodCall[0]); + } catch (RuntimeException $e) { + if ($value->getFactory()) { + continue; + } + + throw $e; + } + + $this->checkTypeDeclarations($value, $reflectionMethod, $methodCall[1]); + } + + return parent::processValue($value, $isRoot); + } + + /** + * @throws InvalidArgumentException When not enough parameters are defined for the method + */ + private function checkTypeDeclarations(Definition $checkedDefinition, \ReflectionFunctionAbstract $reflectionFunction, array $values): void + { + $numberOfRequiredParameters = $reflectionFunction->getNumberOfRequiredParameters(); + + if (\count($values) < $numberOfRequiredParameters) { + throw new InvalidArgumentException(sprintf('Invalid definition for service "%s": "%s::%s()" requires %d arguments, %d passed.', $this->currentId, $reflectionFunction->class, $reflectionFunction->name, $numberOfRequiredParameters, \count($values))); + } + + $reflectionParameters = $reflectionFunction->getParameters(); + $checksCount = min($reflectionFunction->getNumberOfParameters(), \count($values)); + + $envPlaceholderUniquePrefix = $this->container->getParameterBag() instanceof EnvPlaceholderParameterBag ? $this->container->getParameterBag()->getEnvPlaceholderUniquePrefix() : null; + + for ($i = 0; $i < $checksCount; ++$i) { + if (!$reflectionParameters[$i]->hasType() || $reflectionParameters[$i]->isVariadic()) { + continue; + } + + $this->checkType($checkedDefinition, $values[$i], $reflectionParameters[$i], $envPlaceholderUniquePrefix); + } + + if ($reflectionFunction->isVariadic() && ($lastParameter = end($reflectionParameters))->hasType()) { + $variadicParameters = \array_slice($values, $lastParameter->getPosition()); + + foreach ($variadicParameters as $variadicParameter) { + $this->checkType($checkedDefinition, $variadicParameter, $lastParameter, $envPlaceholderUniquePrefix); + } + } + } + + /** + * @throws InvalidParameterTypeException When a parameter is not compatible with the declared type + */ + private function checkType(Definition $checkedDefinition, $value, \ReflectionParameter $parameter, ?string $envPlaceholderUniquePrefix): void + { + $type = $parameter->getType()->getName(); + + if ($value instanceof Reference) { + if (!$this->container->has($value = (string) $value)) { + return; + } + + if ('service_container' === $value && is_a($type, Container::class, true)) { + return; + } + + $value = $this->container->findDefinition($value); + } + + if ('self' === $type) { + $type = $parameter->getDeclaringClass()->getName(); + } + + if ('static' === $type) { + $type = $checkedDefinition->getClass(); + } + + if ($value instanceof Definition) { + $class = $value->getClass(); + + if (!$class || (!$this->autoload && !class_exists($class, false) && !interface_exists($class, false))) { + return; + } + + if ('callable' === $type && method_exists($class, '__invoke')) { + return; + } + + if ('iterable' === $type && is_subclass_of($class, 'Traversable')) { + return; + } + + if ('object' === $type) { + return; + } + + if (is_a($class, $type, true)) { + return; + } + + throw new InvalidParameterTypeException($this->currentId, $class, $parameter); + } + + if ($value instanceof Parameter) { + $value = $this->container->getParameter($value); + } elseif ($value instanceof Expression) { + $value = $this->getExpressionLanguage()->evaluate($value, ['container' => $this->container]); + } elseif (\is_string($value)) { + if ('%' === ($value[0] ?? '') && preg_match('/^%([^%]+)%$/', $value, $match)) { + // Only array parameters are not inlined when dumped. + $value = []; + } elseif ($envPlaceholderUniquePrefix && false !== strpos($value, 'env_')) { + // If the value is an env placeholder that is either mixed with a string or with another env placeholder, then its resolved value will always be a string, so we don't need to resolve it. + // We don't need to change the value because it is already a string. + if ('' === preg_replace('/'.$envPlaceholderUniquePrefix.'_\w+_[a-f0-9]{32}/U', '', $value, -1, $c) && 1 === $c) { + try { + $value = $this->container->resolveEnvPlaceholders($value, true); + } catch (EnvNotFoundException | RuntimeException $e) { + // If an env placeholder cannot be resolved, we skip the validation. + return; + } + } + } + } + + if (null === $value && $parameter->allowsNull()) { + return; + } + + if (\in_array($type, self::SCALAR_TYPES, true) && is_scalar($value)) { + return; + } + + if ('callable' === $type && \is_array($value) && isset($value[0]) && ($value[0] instanceof Reference || $value[0] instanceof Definition)) { + return; + } + + if ('iterable' === $type && (\is_array($value) || $value instanceof \Traversable || $value instanceof IteratorArgument)) { + return; + } + + if ('Traversable' === $type && ($value instanceof \Traversable || $value instanceof IteratorArgument)) { + return; + } + + $checkFunction = sprintf('is_%s', $parameter->getType()->getName()); + + if (!$parameter->getType()->isBuiltin() || !$checkFunction($value)) { + throw new InvalidParameterTypeException($this->currentId, \is_object($value) ? \get_class($value) : \gettype($value), $parameter); + } + } + + private function getExpressionLanguage(): ExpressionLanguage + { + if (null === $this->expressionLanguage) { + $this->expressionLanguage = new ExpressionLanguage(null, $this->container->getExpressionLanguageProviders()); + } + + return $this->expressionLanguage; + } +} diff --git a/srcs/phpmyadmin/vendor/symfony/dependency-injection/Compiler/Compiler.php b/srcs/phpmyadmin/vendor/symfony/dependency-injection/Compiler/Compiler.php new file mode 100644 index 0000000..14dedf0 --- /dev/null +++ b/srcs/phpmyadmin/vendor/symfony/dependency-injection/Compiler/Compiler.php @@ -0,0 +1,119 @@ +<?php + +/* + * This file is part of the Symfony package. + * + * (c) Fabien Potencier <fabien@symfony.com> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection\Compiler; + +use Symfony\Component\DependencyInjection\ContainerBuilder; +use Symfony\Component\DependencyInjection\Exception\EnvParameterException; + +/** + * This class is used to remove circular dependencies between individual passes. + * + * @author Johannes M. Schmitt <schmittjoh@gmail.com> + */ +class Compiler +{ + private $passConfig; + private $log = []; + private $serviceReferenceGraph; + + public function __construct() + { + $this->passConfig = new PassConfig(); + $this->serviceReferenceGraph = new ServiceReferenceGraph(); + } + + /** + * Returns the PassConfig. + * + * @return PassConfig The PassConfig instance + */ + public function getPassConfig() + { + return $this->passConfig; + } + + /** + * Returns the ServiceReferenceGraph. + * + * @return ServiceReferenceGraph The ServiceReferenceGraph instance + */ + public function getServiceReferenceGraph() + { + return $this->serviceReferenceGraph; + } + + /** + * Adds a pass to the PassConfig. + * + * @param string $type The type of the pass + * @param int $priority Used to sort the passes + */ + public function addPass(CompilerPassInterface $pass, $type = PassConfig::TYPE_BEFORE_OPTIMIZATION, int $priority = 0) + { + $this->passConfig->addPass($pass, $type, $priority); + } + + /** + * @final + */ + public function log(CompilerPassInterface $pass, string $message) + { + if (false !== strpos($message, "\n")) { + $message = str_replace("\n", "\n".\get_class($pass).': ', trim($message)); + } + + $this->log[] = \get_class($pass).': '.$message; + } + + /** + * Returns the log. + * + * @return array Log array + */ + public function getLog() + { + return $this->log; + } + + /** + * Run the Compiler and process all Passes. + */ + public function compile(ContainerBuilder $container) + { + try { + foreach ($this->passConfig->getPasses() as $pass) { + $pass->process($container); + } + } catch (\Exception $e) { + $usedEnvs = []; + $prev = $e; + + do { + $msg = $prev->getMessage(); + + if ($msg !== $resolvedMsg = $container->resolveEnvPlaceholders($msg, null, $usedEnvs)) { + $r = new \ReflectionProperty($prev, 'message'); + $r->setAccessible(true); + $r->setValue($prev, $resolvedMsg); + } + } while ($prev = $prev->getPrevious()); + + if ($usedEnvs) { + $e = new EnvParameterException($usedEnvs, $e); + } + + throw $e; + } finally { + $this->getServiceReferenceGraph()->clear(); + } + } +} diff --git a/srcs/phpmyadmin/vendor/symfony/dependency-injection/Compiler/CompilerPassInterface.php b/srcs/phpmyadmin/vendor/symfony/dependency-injection/Compiler/CompilerPassInterface.php new file mode 100644 index 0000000..3085006 --- /dev/null +++ b/srcs/phpmyadmin/vendor/symfony/dependency-injection/Compiler/CompilerPassInterface.php @@ -0,0 +1,27 @@ +<?php + +/* + * This file is part of the Symfony package. + * + * (c) Fabien Potencier <fabien@symfony.com> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection\Compiler; + +use Symfony\Component\DependencyInjection\ContainerBuilder; + +/** + * Interface that must be implemented by compilation passes. + * + * @author Johannes M. Schmitt <schmittjoh@gmail.com> + */ +interface CompilerPassInterface +{ + /** + * You can modify the container here before it is dumped to PHP code. + */ + public function process(ContainerBuilder $container); +} diff --git a/srcs/phpmyadmin/vendor/symfony/dependency-injection/Compiler/DecoratorServicePass.php b/srcs/phpmyadmin/vendor/symfony/dependency-injection/Compiler/DecoratorServicePass.php new file mode 100644 index 0000000..da909ae --- /dev/null +++ b/srcs/phpmyadmin/vendor/symfony/dependency-injection/Compiler/DecoratorServicePass.php @@ -0,0 +1,89 @@ +<?php + +/* + * This file is part of the Symfony package. + * + * (c) Fabien Potencier <fabien@symfony.com> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection\Compiler; + +use Symfony\Component\DependencyInjection\Alias; +use Symfony\Component\DependencyInjection\ContainerBuilder; +use Symfony\Component\DependencyInjection\ContainerInterface; +use Symfony\Component\DependencyInjection\Exception\ServiceNotFoundException; +use Symfony\Component\DependencyInjection\Reference; + +/** + * Overwrites a service but keeps the overridden one. + * + * @author Christophe Coevoet <stof@notk.org> + * @author Fabien Potencier <fabien@symfony.com> + * @author Diego Saint Esteben <diego@saintesteben.me> + */ +class DecoratorServicePass implements CompilerPassInterface +{ + public function process(ContainerBuilder $container) + { + $definitions = new \SplPriorityQueue(); + $order = PHP_INT_MAX; + + foreach ($container->getDefinitions() as $id => $definition) { + if (!$decorated = $definition->getDecoratedService()) { + continue; + } + $definitions->insert([$id, $definition], [$decorated[2], --$order]); + } + $decoratingDefinitions = []; + + foreach ($definitions as list($id, $definition)) { + $decoratedService = $definition->getDecoratedService(); + list($inner, $renamedId) = $decoratedService; + $invalidBehavior = $decoratedService[3] ?? ContainerInterface::EXCEPTION_ON_INVALID_REFERENCE; + + $definition->setDecoratedService(null); + + if (!$renamedId) { + $renamedId = $id.'.inner'; + } + $definition->innerServiceId = $renamedId; + $definition->decorationOnInvalid = $invalidBehavior; + + // we create a new alias/service for the service we are replacing + // to be able to reference it in the new one + if ($container->hasAlias($inner)) { + $alias = $container->getAlias($inner); + $public = $alias->isPublic(); + $private = $alias->isPrivate(); + $container->setAlias($renamedId, new Alias((string) $alias, false)); + } elseif ($container->hasDefinition($inner)) { + $decoratedDefinition = $container->getDefinition($inner); + $public = $decoratedDefinition->isPublic(); + $private = $decoratedDefinition->isPrivate(); + $decoratedDefinition->setPublic(false); + $container->setDefinition($renamedId, $decoratedDefinition); + $decoratingDefinitions[$inner] = $decoratedDefinition; + } elseif (ContainerInterface::IGNORE_ON_INVALID_REFERENCE === $invalidBehavior) { + $container->removeDefinition($id); + continue; + } elseif (ContainerInterface::NULL_ON_INVALID_REFERENCE === $invalidBehavior) { + $public = $definition->isPublic(); + $private = $definition->isPrivate(); + } else { + throw new ServiceNotFoundException($inner, $id); + } + + if (isset($decoratingDefinitions[$inner])) { + $decoratingDefinition = $decoratingDefinitions[$inner]; + $definition->setTags(array_merge($decoratingDefinition->getTags(), $definition->getTags())); + $decoratingDefinition->setTags([]); + $decoratingDefinitions[$inner] = $definition; + } + + $container->setAlias($inner, $id)->setPublic($public)->setPrivate($private); + } + } +} diff --git a/srcs/phpmyadmin/vendor/symfony/dependency-injection/Compiler/DefinitionErrorExceptionPass.php b/srcs/phpmyadmin/vendor/symfony/dependency-injection/Compiler/DefinitionErrorExceptionPass.php new file mode 100644 index 0000000..5ee0ff1 --- /dev/null +++ b/srcs/phpmyadmin/vendor/symfony/dependency-injection/Compiler/DefinitionErrorExceptionPass.php @@ -0,0 +1,56 @@ +<?php + +/* + * This file is part of the Symfony package. + * + * (c) Fabien Potencier <fabien@symfony.com> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection\Compiler; + +use Symfony\Component\DependencyInjection\ContainerInterface; +use Symfony\Component\DependencyInjection\Definition; +use Symfony\Component\DependencyInjection\Exception\RuntimeException; +use Symfony\Component\DependencyInjection\Reference; + +/** + * Throws an exception for any Definitions that have errors and still exist. + * + * @author Ryan Weaver <ryan@knpuniversity.com> + */ +class DefinitionErrorExceptionPass extends AbstractRecursivePass +{ + /** + * {@inheritdoc} + */ + protected function processValue($value, $isRoot = false) + { + if (!$value instanceof Definition || !$value->hasErrors()) { + return parent::processValue($value, $isRoot); + } + + if ($isRoot && !$value->isPublic()) { + $graph = $this->container->getCompiler()->getServiceReferenceGraph(); + $runtimeException = false; + foreach ($graph->getNode($this->currentId)->getInEdges() as $edge) { + if (!$edge->getValue() instanceof Reference || ContainerInterface::RUNTIME_EXCEPTION_ON_INVALID_REFERENCE !== $edge->getValue()->getInvalidBehavior()) { + $runtimeException = false; + break; + } + $runtimeException = true; + } + if ($runtimeException) { + return parent::processValue($value, $isRoot); + } + } + + // only show the first error so the user can focus on it + $errors = $value->getErrors(); + $message = reset($errors); + + throw new RuntimeException($message); + } +} diff --git a/srcs/phpmyadmin/vendor/symfony/dependency-injection/Compiler/ExtensionCompilerPass.php b/srcs/phpmyadmin/vendor/symfony/dependency-injection/Compiler/ExtensionCompilerPass.php new file mode 100644 index 0000000..27e5048 --- /dev/null +++ b/srcs/phpmyadmin/vendor/symfony/dependency-injection/Compiler/ExtensionCompilerPass.php @@ -0,0 +1,37 @@ +<?php + +/* + * This file is part of the Symfony package. + * + * (c) Fabien Potencier <fabien@symfony.com> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection\Compiler; + +use Symfony\Component\DependencyInjection\ContainerBuilder; + +/** + * A pass to automatically process extensions if they implement + * CompilerPassInterface. + * + * @author Wouter J <wouter@wouterj.nl> + */ +class ExtensionCompilerPass implements CompilerPassInterface +{ + /** + * {@inheritdoc} + */ + public function process(ContainerBuilder $container) + { + foreach ($container->getExtensions() as $extension) { + if (!$extension instanceof CompilerPassInterface) { + continue; + } + + $extension->process($container); + } + } +} diff --git a/srcs/phpmyadmin/vendor/symfony/dependency-injection/Compiler/InlineServiceDefinitionsPass.php b/srcs/phpmyadmin/vendor/symfony/dependency-injection/Compiler/InlineServiceDefinitionsPass.php new file mode 100644 index 0000000..ac3b4fe --- /dev/null +++ b/srcs/phpmyadmin/vendor/symfony/dependency-injection/Compiler/InlineServiceDefinitionsPass.php @@ -0,0 +1,231 @@ +<?php + +/* + * This file is part of the Symfony package. + * + * (c) Fabien Potencier <fabien@symfony.com> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection\Compiler; + +use Symfony\Component\DependencyInjection\Argument\ArgumentInterface; +use Symfony\Component\DependencyInjection\ContainerBuilder; +use Symfony\Component\DependencyInjection\Definition; +use Symfony\Component\DependencyInjection\Exception\ServiceCircularReferenceException; +use Symfony\Component\DependencyInjection\Reference; + +/** + * Inline service definitions where this is possible. + * + * @author Johannes M. Schmitt <schmittjoh@gmail.com> + */ +class InlineServiceDefinitionsPass extends AbstractRecursivePass implements RepeatablePassInterface +{ + private $analyzingPass; + private $repeatedPass; + private $cloningIds = []; + private $connectedIds = []; + private $notInlinedIds = []; + private $inlinedIds = []; + private $graph; + + public function __construct(AnalyzeServiceReferencesPass $analyzingPass = null) + { + $this->analyzingPass = $analyzingPass; + } + + /** + * {@inheritdoc} + */ + public function setRepeatedPass(RepeatedPass $repeatedPass) + { + @trigger_error(sprintf('The "%s()" method is deprecated since Symfony 4.2.', __METHOD__), E_USER_DEPRECATED); + $this->repeatedPass = $repeatedPass; + } + + public function process(ContainerBuilder $container) + { + $this->container = $container; + if ($this->analyzingPass) { + $analyzedContainer = new ContainerBuilder(); + $analyzedContainer->setAliases($container->getAliases()); + $analyzedContainer->setDefinitions($container->getDefinitions()); + foreach ($container->getExpressionLanguageProviders() as $provider) { + $analyzedContainer->addExpressionLanguageProvider($provider); + } + } else { + $analyzedContainer = $container; + } + try { + $remainingInlinedIds = []; + $this->connectedIds = $this->notInlinedIds = $container->getDefinitions(); + do { + if ($this->analyzingPass) { + $analyzedContainer->setDefinitions(array_intersect_key($analyzedContainer->getDefinitions(), $this->connectedIds)); + $this->analyzingPass->process($analyzedContainer); + } + $this->graph = $analyzedContainer->getCompiler()->getServiceReferenceGraph(); + $notInlinedIds = $this->notInlinedIds; + $this->connectedIds = $this->notInlinedIds = $this->inlinedIds = []; + + foreach ($analyzedContainer->getDefinitions() as $id => $definition) { + if (!$this->graph->hasNode($id)) { + continue; + } + foreach ($this->graph->getNode($id)->getOutEdges() as $edge) { + if (isset($notInlinedIds[$edge->getSourceNode()->getId()])) { + $this->currentId = $id; + $this->processValue($definition, true); + break; + } + } + } + + foreach ($this->inlinedIds as $id => $isPublicOrNotShared) { + if ($isPublicOrNotShared) { + $remainingInlinedIds[$id] = $id; + } else { + $container->removeDefinition($id); + $analyzedContainer->removeDefinition($id); + } + } + } while ($this->inlinedIds && $this->analyzingPass); + + if ($this->inlinedIds && $this->repeatedPass) { + $this->repeatedPass->setRepeat(); + } + + foreach ($remainingInlinedIds as $id) { + $definition = $container->getDefinition($id); + + if (!$definition->isShared() && !$definition->isPublic()) { + $container->removeDefinition($id); + } + } + } finally { + $this->container = null; + $this->connectedIds = $this->notInlinedIds = $this->inlinedIds = []; + $this->graph = null; + } + } + + /** + * {@inheritdoc} + */ + protected function processValue($value, $isRoot = false) + { + if ($value instanceof ArgumentInterface) { + // Reference found in ArgumentInterface::getValues() are not inlineable + return $value; + } + + if ($value instanceof Definition && $this->cloningIds) { + if ($value->isShared()) { + return $value; + } + $value = clone $value; + } + + if (!$value instanceof Reference) { + return parent::processValue($value, $isRoot); + } elseif (!$this->container->hasDefinition($id = (string) $value)) { + return $value; + } + + $definition = $this->container->getDefinition($id); + + if (!$this->isInlineableDefinition($id, $definition)) { + return $value; + } + + $this->container->log($this, sprintf('Inlined service "%s" to "%s".', $id, $this->currentId)); + $this->inlinedIds[$id] = $definition->isPublic() || !$definition->isShared(); + $this->notInlinedIds[$this->currentId] = true; + + if ($definition->isShared()) { + return $definition; + } + + if (isset($this->cloningIds[$id])) { + $ids = array_keys($this->cloningIds); + $ids[] = $id; + + throw new ServiceCircularReferenceException($id, \array_slice($ids, array_search($id, $ids))); + } + + $this->cloningIds[$id] = true; + try { + return $this->processValue($definition); + } finally { + unset($this->cloningIds[$id]); + } + } + + /** + * Checks if the definition is inlineable. + */ + private function isInlineableDefinition(string $id, Definition $definition): bool + { + if ($definition->hasErrors() || $definition->isDeprecated() || $definition->isLazy() || $definition->isSynthetic()) { + return false; + } + + if (!$definition->isShared()) { + if (!$this->graph->hasNode($id)) { + return true; + } + + foreach ($this->graph->getNode($id)->getInEdges() as $edge) { + $srcId = $edge->getSourceNode()->getId(); + $this->connectedIds[$srcId] = true; + if ($edge->isWeak() || $edge->isLazy()) { + return false; + } + } + + return true; + } + + if ($definition->isPublic()) { + return false; + } + + if (!$this->graph->hasNode($id)) { + return true; + } + + if ($this->currentId == $id) { + return false; + } + $this->connectedIds[$id] = true; + + $srcIds = []; + $srcCount = 0; + $isReferencedByConstructor = false; + foreach ($this->graph->getNode($id)->getInEdges() as $edge) { + $isReferencedByConstructor = $isReferencedByConstructor || $edge->isReferencedByConstructor(); + $srcId = $edge->getSourceNode()->getId(); + $this->connectedIds[$srcId] = true; + if ($edge->isWeak() || $edge->isLazy()) { + return false; + } + $srcIds[$srcId] = true; + ++$srcCount; + } + + if (1 !== \count($srcIds)) { + $this->notInlinedIds[$id] = true; + + return false; + } + + if ($srcCount > 1 && \is_array($factory = $definition->getFactory()) && ($factory[0] instanceof Reference || $factory[0] instanceof Definition)) { + return false; + } + + return $this->container->getDefinition($srcId)->isShared(); + } +} diff --git a/srcs/phpmyadmin/vendor/symfony/dependency-injection/Compiler/MergeExtensionConfigurationPass.php b/srcs/phpmyadmin/vendor/symfony/dependency-injection/Compiler/MergeExtensionConfigurationPass.php new file mode 100644 index 0000000..264dd80 --- /dev/null +++ b/srcs/phpmyadmin/vendor/symfony/dependency-injection/Compiler/MergeExtensionConfigurationPass.php @@ -0,0 +1,220 @@ +<?php + +/* + * This file is part of the Symfony package. + * + * (c) Fabien Potencier <fabien@symfony.com> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection\Compiler; + +use Symfony\Component\Config\Definition\BaseNode; +use Symfony\Component\DependencyInjection\ContainerBuilder; +use Symfony\Component\DependencyInjection\Exception\LogicException; +use Symfony\Component\DependencyInjection\Exception\RuntimeException; +use Symfony\Component\DependencyInjection\Extension\ConfigurationExtensionInterface; +use Symfony\Component\DependencyInjection\Extension\Extension; +use Symfony\Component\DependencyInjection\Extension\ExtensionInterface; +use Symfony\Component\DependencyInjection\Extension\PrependExtensionInterface; +use Symfony\Component\DependencyInjection\ParameterBag\EnvPlaceholderParameterBag; +use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface; + +/** + * Merges extension configs into the container builder. + * + * @author Fabien Potencier <fabien@symfony.com> + */ +class MergeExtensionConfigurationPass implements CompilerPassInterface +{ + /** + * {@inheritdoc} + */ + public function process(ContainerBuilder $container) + { + $parameters = $container->getParameterBag()->all(); + $definitions = $container->getDefinitions(); + $aliases = $container->getAliases(); + $exprLangProviders = $container->getExpressionLanguageProviders(); + $configAvailable = class_exists(BaseNode::class); + + foreach ($container->getExtensions() as $extension) { + if ($extension instanceof PrependExtensionInterface) { + $extension->prepend($container); + } + } + + foreach ($container->getExtensions() as $name => $extension) { + if (!$config = $container->getExtensionConfig($name)) { + // this extension was not called + continue; + } + $resolvingBag = $container->getParameterBag(); + if ($resolvingBag instanceof EnvPlaceholderParameterBag && $extension instanceof Extension) { + // create a dedicated bag so that we can track env vars per-extension + $resolvingBag = new MergeExtensionConfigurationParameterBag($resolvingBag); + if ($configAvailable) { + BaseNode::setPlaceholderUniquePrefix($resolvingBag->getEnvPlaceholderUniquePrefix()); + } + } + $config = $resolvingBag->resolveValue($config); + + try { + $tmpContainer = new MergeExtensionConfigurationContainerBuilder($extension, $resolvingBag); + $tmpContainer->setResourceTracking($container->isTrackingResources()); + $tmpContainer->addObjectResource($extension); + if ($extension instanceof ConfigurationExtensionInterface && null !== $configuration = $extension->getConfiguration($config, $tmpContainer)) { + $tmpContainer->addObjectResource($configuration); + } + + foreach ($exprLangProviders as $provider) { + $tmpContainer->addExpressionLanguageProvider($provider); + } + + $extension->load($config, $tmpContainer); + } catch (\Exception $e) { + if ($resolvingBag instanceof MergeExtensionConfigurationParameterBag) { + $container->getParameterBag()->mergeEnvPlaceholders($resolvingBag); + } + + throw $e; + } finally { + if ($configAvailable) { + BaseNode::resetPlaceholders(); + } + } + + if ($resolvingBag instanceof MergeExtensionConfigurationParameterBag) { + // don't keep track of env vars that are *overridden* when configs are merged + $resolvingBag->freezeAfterProcessing($extension, $tmpContainer); + } + + $container->merge($tmpContainer); + $container->getParameterBag()->add($parameters); + } + + $container->addDefinitions($definitions); + $container->addAliases($aliases); + } +} + +/** + * @internal + */ +class MergeExtensionConfigurationParameterBag extends EnvPlaceholderParameterBag +{ + private $processedEnvPlaceholders; + + public function __construct(parent $parameterBag) + { + parent::__construct($parameterBag->all()); + $this->mergeEnvPlaceholders($parameterBag); + } + + public function freezeAfterProcessing(Extension $extension, ContainerBuilder $container) + { + if (!$config = $extension->getProcessedConfigs()) { + // Extension::processConfiguration() wasn't called, we cannot know how configs were merged + return; + } + $this->processedEnvPlaceholders = []; + + // serialize config and container to catch env vars nested in object graphs + $config = serialize($config).serialize($container->getDefinitions()).serialize($container->getAliases()).serialize($container->getParameterBag()->all()); + + foreach (parent::getEnvPlaceholders() as $env => $placeholders) { + foreach ($placeholders as $placeholder) { + if (false !== stripos($config, $placeholder)) { + $this->processedEnvPlaceholders[$env] = $placeholders; + break; + } + } + } + } + + /** + * {@inheritdoc} + */ + public function getEnvPlaceholders(): array + { + return null !== $this->processedEnvPlaceholders ? $this->processedEnvPlaceholders : parent::getEnvPlaceholders(); + } + + public function getUnusedEnvPlaceholders(): array + { + return null === $this->processedEnvPlaceholders ? [] : array_diff_key(parent::getEnvPlaceholders(), $this->processedEnvPlaceholders); + } +} + +/** + * A container builder preventing using methods that wouldn't have any effect from extensions. + * + * @internal + */ +class MergeExtensionConfigurationContainerBuilder extends ContainerBuilder +{ + private $extensionClass; + + public function __construct(ExtensionInterface $extension, ParameterBagInterface $parameterBag = null) + { + parent::__construct($parameterBag); + + $this->extensionClass = \get_class($extension); + } + + /** + * {@inheritdoc} + */ + public function addCompilerPass(CompilerPassInterface $pass, $type = PassConfig::TYPE_BEFORE_OPTIMIZATION, int $priority = 0): self + { + throw new LogicException(sprintf('You cannot add compiler pass "%s" from extension "%s". Compiler passes must be registered before the container is compiled.', \get_class($pass), $this->extensionClass)); + } + + /** + * {@inheritdoc} + */ + public function registerExtension(ExtensionInterface $extension) + { + throw new LogicException(sprintf('You cannot register extension "%s" from "%s". Extensions must be registered before the container is compiled.', \get_class($extension), $this->extensionClass)); + } + + /** + * {@inheritdoc} + */ + public function compile(bool $resolveEnvPlaceholders = false) + { + throw new LogicException(sprintf('Cannot compile the container in extension "%s".', $this->extensionClass)); + } + + /** + * {@inheritdoc} + */ + public function resolveEnvPlaceholders($value, $format = null, array &$usedEnvs = null) + { + if (true !== $format || !\is_string($value)) { + return parent::resolveEnvPlaceholders($value, $format, $usedEnvs); + } + + $bag = $this->getParameterBag(); + $value = $bag->resolveValue($value); + + if (!$bag instanceof EnvPlaceholderParameterBag) { + return parent::resolveEnvPlaceholders($value, $format, $usedEnvs); + } + + foreach ($bag->getEnvPlaceholders() as $env => $placeholders) { + if (false === strpos($env, ':')) { + continue; + } + foreach ($placeholders as $placeholder) { + if (false !== stripos($value, $placeholder)) { + throw new RuntimeException(sprintf('Using a cast in "env(%s)" is incompatible with resolution at compile time in "%s". The logic in the extension should be moved to a compiler pass, or an env parameter with no cast should be used instead.', $env, $this->extensionClass)); + } + } + } + + return parent::resolveEnvPlaceholders($value, $format, $usedEnvs); + } +} diff --git a/srcs/phpmyadmin/vendor/symfony/dependency-injection/Compiler/PassConfig.php b/srcs/phpmyadmin/vendor/symfony/dependency-injection/Compiler/PassConfig.php new file mode 100644 index 0000000..8cc328e --- /dev/null +++ b/srcs/phpmyadmin/vendor/symfony/dependency-injection/Compiler/PassConfig.php @@ -0,0 +1,269 @@ +<?php + +/* + * This file is part of the Symfony package. + * + * (c) Fabien Potencier <fabien@symfony.com> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection\Compiler; + +use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException; + +/** + * Compiler Pass Configuration. + * + * This class has a default configuration embedded. + * + * @author Johannes M. Schmitt <schmittjoh@gmail.com> + */ +class PassConfig +{ + const TYPE_AFTER_REMOVING = 'afterRemoving'; + const TYPE_BEFORE_OPTIMIZATION = 'beforeOptimization'; + const TYPE_BEFORE_REMOVING = 'beforeRemoving'; + const TYPE_OPTIMIZE = 'optimization'; + const TYPE_REMOVE = 'removing'; + + private $mergePass; + private $afterRemovingPasses = []; + private $beforeOptimizationPasses = []; + private $beforeRemovingPasses = []; + private $optimizationPasses; + private $removingPasses; + + public function __construct() + { + $this->mergePass = new MergeExtensionConfigurationPass(); + + $this->beforeOptimizationPasses = [ + 100 => [ + new ResolveClassPass(), + new ResolveInstanceofConditionalsPass(), + new RegisterEnvVarProcessorsPass(), + ], + -1000 => [new ExtensionCompilerPass()], + ]; + + $this->optimizationPasses = [[ + new ValidateEnvPlaceholdersPass(), + new ResolveChildDefinitionsPass(), + new RegisterServiceSubscribersPass(), + new ResolveParameterPlaceHoldersPass(false), + new ResolveFactoryClassPass(), + new ResolveNamedArgumentsPass(), + new AutowireRequiredMethodsPass(), + new ResolveBindingsPass(), + new ServiceLocatorTagPass(), + new DecoratorServicePass(), + new CheckDefinitionValidityPass(), + new AutowirePass(false), + new ResolveTaggedIteratorArgumentPass(), + new ResolveServiceSubscribersPass(), + new ResolveReferencesToAliasesPass(), + new ResolveInvalidReferencesPass(), + new AnalyzeServiceReferencesPass(true), + new CheckCircularReferencesPass(), + new CheckReferenceValidityPass(), + new CheckArgumentsValidityPass(false), + ]]; + + $this->beforeRemovingPasses = [ + -100 => [ + new ResolvePrivatesPass(), + ], + ]; + + $this->removingPasses = [[ + new RemovePrivateAliasesPass(), + new ReplaceAliasByActualDefinitionPass(), + new RemoveAbstractDefinitionsPass(), + new RemoveUnusedDefinitionsPass(), + new InlineServiceDefinitionsPass(new AnalyzeServiceReferencesPass()), + new AnalyzeServiceReferencesPass(), + new DefinitionErrorExceptionPass(), + ]]; + + $this->afterRemovingPasses = [[ + new CheckExceptionOnInvalidReferenceBehaviorPass(), + new ResolveHotPathPass(), + ]]; + } + + /** + * Returns all passes in order to be processed. + * + * @return CompilerPassInterface[] + */ + public function getPasses() + { + return array_merge( + [$this->mergePass], + $this->getBeforeOptimizationPasses(), + $this->getOptimizationPasses(), + $this->getBeforeRemovingPasses(), + $this->getRemovingPasses(), + $this->getAfterRemovingPasses() + ); + } + + /** + * Adds a pass. + * + * @param string $type The pass type + * @param int $priority Used to sort the passes + * + * @throws InvalidArgumentException when a pass type doesn't exist + */ + public function addPass(CompilerPassInterface $pass, $type = self::TYPE_BEFORE_OPTIMIZATION, int $priority = 0) + { + $property = $type.'Passes'; + if (!isset($this->$property)) { + throw new InvalidArgumentException(sprintf('Invalid type "%s".', $type)); + } + + $passes = &$this->$property; + + if (!isset($passes[$priority])) { + $passes[$priority] = []; + } + $passes[$priority][] = $pass; + } + + /** + * Gets all passes for the AfterRemoving pass. + * + * @return CompilerPassInterface[] + */ + public function getAfterRemovingPasses() + { + return $this->sortPasses($this->afterRemovingPasses); + } + + /** + * Gets all passes for the BeforeOptimization pass. + * + * @return CompilerPassInterface[] + */ + public function getBeforeOptimizationPasses() + { + return $this->sortPasses($this->beforeOptimizationPasses); + } + + /** + * Gets all passes for the BeforeRemoving pass. + * + * @return CompilerPassInterface[] + */ + public function getBeforeRemovingPasses() + { + return $this->sortPasses($this->beforeRemovingPasses); + } + + /** + * Gets all passes for the Optimization pass. + * + * @return CompilerPassInterface[] + */ + public function getOptimizationPasses() + { + return $this->sortPasses($this->optimizationPasses); + } + + /** + * Gets all passes for the Removing pass. + * + * @return CompilerPassInterface[] + */ + public function getRemovingPasses() + { + return $this->sortPasses($this->removingPasses); + } + + /** + * Gets the Merge pass. + * + * @return CompilerPassInterface + */ + public function getMergePass() + { + return $this->mergePass; + } + + public function setMergePass(CompilerPassInterface $pass) + { + $this->mergePass = $pass; + } + + /** + * Sets the AfterRemoving passes. + * + * @param CompilerPassInterface[] $passes + */ + public function setAfterRemovingPasses(array $passes) + { + $this->afterRemovingPasses = [$passes]; + } + + /** + * Sets the BeforeOptimization passes. + * + * @param CompilerPassInterface[] $passes + */ + public function setBeforeOptimizationPasses(array $passes) + { + $this->beforeOptimizationPasses = [$passes]; + } + + /** + * Sets the BeforeRemoving passes. + * + * @param CompilerPassInterface[] $passes + */ + public function setBeforeRemovingPasses(array $passes) + { + $this->beforeRemovingPasses = [$passes]; + } + + /** + * Sets the Optimization passes. + * + * @param CompilerPassInterface[] $passes + */ + public function setOptimizationPasses(array $passes) + { + $this->optimizationPasses = [$passes]; + } + + /** + * Sets the Removing passes. + * + * @param CompilerPassInterface[] $passes + */ + public function setRemovingPasses(array $passes) + { + $this->removingPasses = [$passes]; + } + + /** + * Sort passes by priority. + * + * @param array $passes CompilerPassInterface instances with their priority as key + * + * @return CompilerPassInterface[] + */ + private function sortPasses(array $passes): array + { + if (0 === \count($passes)) { + return []; + } + + krsort($passes); + + // Flatten the array + return array_merge(...$passes); + } +} diff --git a/srcs/phpmyadmin/vendor/symfony/dependency-injection/Compiler/PriorityTaggedServiceTrait.php b/srcs/phpmyadmin/vendor/symfony/dependency-injection/Compiler/PriorityTaggedServiceTrait.php new file mode 100644 index 0000000..9b3760b --- /dev/null +++ b/srcs/phpmyadmin/vendor/symfony/dependency-injection/Compiler/PriorityTaggedServiceTrait.php @@ -0,0 +1,138 @@ +<?php + +/* + * This file is part of the Symfony package. + * + * (c) Fabien Potencier <fabien@symfony.com> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection\Compiler; + +use Symfony\Component\DependencyInjection\Argument\TaggedIteratorArgument; +use Symfony\Component\DependencyInjection\ContainerBuilder; +use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException; +use Symfony\Component\DependencyInjection\Reference; +use Symfony\Component\DependencyInjection\TypedReference; + +/** + * Trait that allows a generic method to find and sort service by priority option in the tag. + * + * @author Iltar van der Berg <kjarli@gmail.com> + */ +trait PriorityTaggedServiceTrait +{ + /** + * Finds all services with the given tag name and order them by their priority. + * + * The order of additions must be respected for services having the same priority, + * and knowing that the \SplPriorityQueue class does not respect the FIFO method, + * we should not use that class. + * + * @see https://bugs.php.net/53710 + * @see https://bugs.php.net/60926 + * + * @param string|TaggedIteratorArgument $tagName + * + * @return Reference[] + */ + private function findAndSortTaggedServices($tagName, ContainerBuilder $container): array + { + $indexAttribute = $defaultIndexMethod = $needsIndexes = $defaultPriorityMethod = null; + + if ($tagName instanceof TaggedIteratorArgument) { + $indexAttribute = $tagName->getIndexAttribute(); + $defaultIndexMethod = $tagName->getDefaultIndexMethod(); + $needsIndexes = $tagName->needsIndexes(); + $defaultPriorityMethod = $tagName->getDefaultPriorityMethod(); + $tagName = $tagName->getTag(); + } + + $services = []; + + foreach ($container->findTaggedServiceIds($tagName, true) as $serviceId => $attributes) { + $class = $r = null; + $priority = 0; + if (isset($attributes[0]['priority'])) { + $priority = $attributes[0]['priority']; + } elseif ($defaultPriorityMethod) { + $class = $container->getDefinition($serviceId)->getClass(); + $class = $container->getParameterBag()->resolveValue($class) ?: null; + + if (($r = $container->getReflectionClass($class)) && $r->hasMethod($defaultPriorityMethod)) { + if (!($rm = $r->getMethod($defaultPriorityMethod))->isStatic()) { + throw new InvalidArgumentException(sprintf('Method "%s::%s()" should be static: tag "%s" on service "%s".', $class, $defaultPriorityMethod, $tagName, $serviceId)); + } + + if (!$rm->isPublic()) { + throw new InvalidArgumentException(sprintf('Method "%s::%s()" should be public: tag "%s" on service "%s".', $class, $defaultPriorityMethod, $tagName, $serviceId)); + } + + $priority = $rm->invoke(null); + + if (!\is_int($priority)) { + throw new InvalidArgumentException(sprintf('Method "%s::%s()" should return an integer, got %s: tag "%s" on service "%s".', $class, $defaultPriorityMethod, \gettype($priority), $tagName, $serviceId)); + } + } + } + + if (null === $indexAttribute && !$needsIndexes) { + $services[$priority][] = new Reference($serviceId); + + continue; + } + + if (!$class) { + $class = $container->getDefinition($serviceId)->getClass(); + $class = $container->getParameterBag()->resolveValue($class) ?: null; + } + + if (null !== $indexAttribute && isset($attributes[0][$indexAttribute])) { + $services[$priority][$attributes[0][$indexAttribute]] = new TypedReference($serviceId, $class, ContainerBuilder::EXCEPTION_ON_INVALID_REFERENCE, $attributes[0][$indexAttribute]); + + continue; + } + + if (!$r && !$r = $container->getReflectionClass($class)) { + throw new InvalidArgumentException(sprintf('Class "%s" used for service "%s" cannot be found.', $class, $serviceId)); + } + + $class = $r->name; + + if (!$r->hasMethod($defaultIndexMethod)) { + if ($needsIndexes) { + $services[$priority][$serviceId] = new TypedReference($serviceId, $class); + + continue; + } + + throw new InvalidArgumentException(sprintf('Method "%s::%s()" not found: tag "%s" on service "%s" is missing "%s" attribute.', $class, $defaultIndexMethod, $tagName, $serviceId, $indexAttribute)); + } + + if (!($rm = $r->getMethod($defaultIndexMethod))->isStatic()) { + throw new InvalidArgumentException(sprintf('Method "%s::%s()" should be static: tag "%s" on service "%s" is missing "%s" attribute.', $class, $defaultIndexMethod, $tagName, $serviceId, $indexAttribute)); + } + + if (!$rm->isPublic()) { + throw new InvalidArgumentException(sprintf('Method "%s::%s()" should be public: tag "%s" on service "%s" is missing "%s" attribute.', $class, $defaultIndexMethod, $tagName, $serviceId, $indexAttribute)); + } + + $key = $rm->invoke(null); + + if (!\is_string($key)) { + throw new InvalidArgumentException(sprintf('Method "%s::%s()" should return a string, got %s: tag "%s" on service "%s" is missing "%s" attribute.', $class, $defaultIndexMethod, \gettype($key), $tagName, $serviceId, $indexAttribute)); + } + + $services[$priority][$key] = new TypedReference($serviceId, $class, ContainerBuilder::EXCEPTION_ON_INVALID_REFERENCE, $key); + } + + if ($services) { + krsort($services); + $services = array_merge(...$services); + } + + return $services; + } +} diff --git a/srcs/phpmyadmin/vendor/symfony/dependency-injection/Compiler/RegisterEnvVarProcessorsPass.php b/srcs/phpmyadmin/vendor/symfony/dependency-injection/Compiler/RegisterEnvVarProcessorsPass.php new file mode 100644 index 0000000..a9a133b --- /dev/null +++ b/srcs/phpmyadmin/vendor/symfony/dependency-injection/Compiler/RegisterEnvVarProcessorsPass.php @@ -0,0 +1,75 @@ +<?php + +/* + * This file is part of the Symfony package. + * + * (c) Fabien Potencier <fabien@symfony.com> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection\Compiler; + +use Symfony\Component\DependencyInjection\ContainerBuilder; +use Symfony\Component\DependencyInjection\EnvVarProcessor; +use Symfony\Component\DependencyInjection\EnvVarProcessorInterface; +use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException; +use Symfony\Component\DependencyInjection\ParameterBag\EnvPlaceholderParameterBag; +use Symfony\Component\DependencyInjection\Reference; + +/** + * Creates the container.env_var_processors_locator service. + * + * @author Nicolas Grekas <p@tchwork.com> + */ +class RegisterEnvVarProcessorsPass implements CompilerPassInterface +{ + private static $allowedTypes = ['array', 'bool', 'float', 'int', 'string']; + + public function process(ContainerBuilder $container) + { + $bag = $container->getParameterBag(); + $types = []; + $processors = []; + foreach ($container->findTaggedServiceIds('container.env_var_processor') as $id => $tags) { + if (!$r = $container->getReflectionClass($class = $container->getDefinition($id)->getClass())) { + throw new InvalidArgumentException(sprintf('Class "%s" used for service "%s" cannot be found.', $class, $id)); + } elseif (!$r->isSubclassOf(EnvVarProcessorInterface::class)) { + throw new InvalidArgumentException(sprintf('Service "%s" must implement interface "%s".', $id, EnvVarProcessorInterface::class)); + } + foreach ($class::getProvidedTypes() as $prefix => $type) { + $processors[$prefix] = new Reference($id); + $types[$prefix] = self::validateProvidedTypes($type, $class); + } + } + + if ($bag instanceof EnvPlaceholderParameterBag) { + foreach (EnvVarProcessor::getProvidedTypes() as $prefix => $type) { + if (!isset($types[$prefix])) { + $types[$prefix] = self::validateProvidedTypes($type, EnvVarProcessor::class); + } + } + $bag->setProvidedTypes($types); + } + + if ($processors) { + $container->setAlias('container.env_var_processors_locator', (string) ServiceLocatorTagPass::register($container, $processors)) + ->setPublic(true) + ; + } + } + + private static function validateProvidedTypes(string $types, string $class): array + { + $types = explode('|', $types); + + foreach ($types as $type) { + if (!\in_array($type, self::$allowedTypes)) { + throw new InvalidArgumentException(sprintf('Invalid type "%s" returned by "%s::getProvidedTypes()", expected one of "%s".', $type, $class, implode('", "', self::$allowedTypes))); + } + } + + return $types; + } +} diff --git a/srcs/phpmyadmin/vendor/symfony/dependency-injection/Compiler/RegisterReverseContainerPass.php b/srcs/phpmyadmin/vendor/symfony/dependency-injection/Compiler/RegisterReverseContainerPass.php new file mode 100644 index 0000000..571eab3 --- /dev/null +++ b/srcs/phpmyadmin/vendor/symfony/dependency-injection/Compiler/RegisterReverseContainerPass.php @@ -0,0 +1,66 @@ +<?php + +/* + * This file is part of the Symfony package. + * + * (c) Fabien Potencier <fabien@symfony.com> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection\Compiler; + +use Symfony\Component\DependencyInjection\Argument\ServiceClosureArgument; +use Symfony\Component\DependencyInjection\ContainerBuilder; +use Symfony\Component\DependencyInjection\ContainerInterface; +use Symfony\Component\DependencyInjection\Definition; +use Symfony\Component\DependencyInjection\Reference; + +/** + * @author Nicolas Grekas <p@tchwork.com> + */ +class RegisterReverseContainerPass implements CompilerPassInterface +{ + private $beforeRemoving; + private $serviceId; + private $tagName; + + public function __construct(bool $beforeRemoving, string $serviceId = 'reverse_container', string $tagName = 'container.reversible') + { + $this->beforeRemoving = $beforeRemoving; + $this->serviceId = $serviceId; + $this->tagName = $tagName; + } + + public function process(ContainerBuilder $container) + { + if (!$container->hasDefinition($this->serviceId)) { + return; + } + + $refType = $this->beforeRemoving ? ContainerInterface::IGNORE_ON_UNINITIALIZED_REFERENCE : ContainerInterface::EXCEPTION_ON_INVALID_REFERENCE; + $services = []; + foreach ($container->findTaggedServiceIds($this->tagName) as $id => $tags) { + $services[$id] = new Reference($id, $refType); + } + + if ($this->beforeRemoving) { + // prevent inlining of the reverse container + $services[$this->serviceId] = new Reference($this->serviceId, $refType); + } + $locator = $container->getDefinition($this->serviceId)->getArgument(1); + + if ($locator instanceof Reference) { + $locator = $container->getDefinition((string) $locator); + } + if ($locator instanceof Definition) { + foreach ($services as $id => $ref) { + $services[$id] = new ServiceClosureArgument($ref); + } + $locator->replaceArgument(0, $services); + } else { + $locator->setValues($services); + } + } +} diff --git a/srcs/phpmyadmin/vendor/symfony/dependency-injection/Compiler/RegisterServiceSubscribersPass.php b/srcs/phpmyadmin/vendor/symfony/dependency-injection/Compiler/RegisterServiceSubscribersPass.php new file mode 100644 index 0000000..14bf000 --- /dev/null +++ b/srcs/phpmyadmin/vendor/symfony/dependency-injection/Compiler/RegisterServiceSubscribersPass.php @@ -0,0 +1,122 @@ +<?php + +/* + * This file is part of the Symfony package. + * + * (c) Fabien Potencier <fabien@symfony.com> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection\Compiler; + +use Psr\Container\ContainerInterface as PsrContainerInterface; +use Symfony\Component\DependencyInjection\Argument\BoundArgument; +use Symfony\Component\DependencyInjection\ContainerInterface; +use Symfony\Component\DependencyInjection\Definition; +use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException; +use Symfony\Component\DependencyInjection\Reference; +use Symfony\Component\DependencyInjection\TypedReference; +use Symfony\Contracts\Service\ServiceProviderInterface; +use Symfony\Contracts\Service\ServiceSubscriberInterface; + +/** + * Compiler pass to register tagged services that require a service locator. + * + * @author Nicolas Grekas <p@tchwork.com> + */ +class RegisterServiceSubscribersPass extends AbstractRecursivePass +{ + protected function processValue($value, $isRoot = false) + { + if (!$value instanceof Definition || $value->isAbstract() || $value->isSynthetic() || !$value->hasTag('container.service_subscriber')) { + return parent::processValue($value, $isRoot); + } + + $serviceMap = []; + $autowire = $value->isAutowired(); + + foreach ($value->getTag('container.service_subscriber') as $attributes) { + if (!$attributes) { + $autowire = true; + continue; + } + ksort($attributes); + if ([] !== array_diff(array_keys($attributes), ['id', 'key'])) { + throw new InvalidArgumentException(sprintf('The "container.service_subscriber" tag accepts only the "key" and "id" attributes, "%s" given for service "%s".', implode('", "', array_keys($attributes)), $this->currentId)); + } + if (!\array_key_exists('id', $attributes)) { + throw new InvalidArgumentException(sprintf('Missing "id" attribute on "container.service_subscriber" tag with key="%s" for service "%s".', $attributes['key'], $this->currentId)); + } + if (!\array_key_exists('key', $attributes)) { + $attributes['key'] = $attributes['id']; + } + if (isset($serviceMap[$attributes['key']])) { + continue; + } + $serviceMap[$attributes['key']] = new Reference($attributes['id']); + } + $class = $value->getClass(); + + if (!$r = $this->container->getReflectionClass($class)) { + throw new InvalidArgumentException(sprintf('Class "%s" used for service "%s" cannot be found.', $class, $this->currentId)); + } + if (!$r->isSubclassOf(ServiceSubscriberInterface::class)) { + throw new InvalidArgumentException(sprintf('Service "%s" must implement interface "%s".', $this->currentId, ServiceSubscriberInterface::class)); + } + $class = $r->name; + + $subscriberMap = []; + + foreach ($class::getSubscribedServices() as $key => $type) { + if (!\is_string($type) || !preg_match('/^\??[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*+(?:\\\\[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*+)*+$/', $type)) { + throw new InvalidArgumentException(sprintf('"%s::getSubscribedServices()" must return valid PHP types for service "%s" key "%s", "%s" returned.', $class, $this->currentId, $key, \is_string($type) ? $type : \gettype($type))); + } + if ($optionalBehavior = '?' === $type[0]) { + $type = substr($type, 1); + $optionalBehavior = ContainerInterface::IGNORE_ON_INVALID_REFERENCE; + } + if (\is_int($name = $key)) { + $key = $type; + $name = null; + } + if (!isset($serviceMap[$key])) { + if (!$autowire) { + throw new InvalidArgumentException(sprintf('Service "%s" misses a "container.service_subscriber" tag with "key"/"id" attributes corresponding to entry "%s" as returned by "%s::getSubscribedServices()".', $this->currentId, $key, $class)); + } + $serviceMap[$key] = new Reference($type); + } + + if (false !== $i = strpos($name, '::get')) { + $name = lcfirst(substr($name, 5 + $i)); + } elseif (false !== strpos($name, '::')) { + $name = null; + } + + if (null !== $name && !$this->container->has($name) && !$this->container->has($type.' $'.$name)) { + $camelCaseName = lcfirst(str_replace(' ', '', ucwords(preg_replace('/[^a-zA-Z0-9\x7f-\xff]++/', ' ', $name)))); + $name = $this->container->has($type.' $'.$camelCaseName) ? $camelCaseName : $name; + } + + $subscriberMap[$key] = new TypedReference((string) $serviceMap[$key], $type, $optionalBehavior ?: ContainerInterface::EXCEPTION_ON_INVALID_REFERENCE, $name); + unset($serviceMap[$key]); + } + + if ($serviceMap = array_keys($serviceMap)) { + $message = sprintf(1 < \count($serviceMap) ? 'keys "%s" do' : 'key "%s" does', str_replace('%', '%%', implode('", "', $serviceMap))); + throw new InvalidArgumentException(sprintf('Service %s not exist in the map returned by "%s::getSubscribedServices()" for service "%s".', $message, $class, $this->currentId)); + } + + $locatorRef = ServiceLocatorTagPass::register($this->container, $subscriberMap, $this->currentId); + + $value->addTag('container.service_subscriber.locator', ['id' => (string) $locatorRef]); + + $value->setBindings([ + PsrContainerInterface::class => new BoundArgument($locatorRef, false), + ServiceProviderInterface::class => new BoundArgument($locatorRef, false), + ] + $value->getBindings()); + + return parent::processValue($value); + } +} diff --git a/srcs/phpmyadmin/vendor/symfony/dependency-injection/Compiler/RemoveAbstractDefinitionsPass.php b/srcs/phpmyadmin/vendor/symfony/dependency-injection/Compiler/RemoveAbstractDefinitionsPass.php new file mode 100644 index 0000000..04b6852 --- /dev/null +++ b/srcs/phpmyadmin/vendor/symfony/dependency-injection/Compiler/RemoveAbstractDefinitionsPass.php @@ -0,0 +1,33 @@ +<?php + +/* + * This file is part of the Symfony package. + * + * (c) Fabien Potencier <fabien@symfony.com> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection\Compiler; + +use Symfony\Component\DependencyInjection\ContainerBuilder; + +/** + * Removes abstract Definitions. + */ +class RemoveAbstractDefinitionsPass implements CompilerPassInterface +{ + /** + * Removes abstract definitions from the ContainerBuilder. + */ + public function process(ContainerBuilder $container) + { + foreach ($container->getDefinitions() as $id => $definition) { + if ($definition->isAbstract()) { + $container->removeDefinition($id); + $container->log($this, sprintf('Removed service "%s"; reason: abstract.', $id)); + } + } + } +} diff --git a/srcs/phpmyadmin/vendor/symfony/dependency-injection/Compiler/RemovePrivateAliasesPass.php b/srcs/phpmyadmin/vendor/symfony/dependency-injection/Compiler/RemovePrivateAliasesPass.php new file mode 100644 index 0000000..75b36d2 --- /dev/null +++ b/srcs/phpmyadmin/vendor/symfony/dependency-injection/Compiler/RemovePrivateAliasesPass.php @@ -0,0 +1,39 @@ +<?php + +/* + * This file is part of the Symfony package. + * + * (c) Fabien Potencier <fabien@symfony.com> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection\Compiler; + +use Symfony\Component\DependencyInjection\ContainerBuilder; + +/** + * Remove private aliases from the container. They were only used to establish + * dependencies between services, and these dependencies have been resolved in + * one of the previous passes. + * + * @author Johannes M. Schmitt <schmittjoh@gmail.com> + */ +class RemovePrivateAliasesPass implements CompilerPassInterface +{ + /** + * Removes private aliases from the ContainerBuilder. + */ + public function process(ContainerBuilder $container) + { + foreach ($container->getAliases() as $id => $alias) { + if ($alias->isPublic()) { + continue; + } + + $container->removeAlias($id); + $container->log($this, sprintf('Removed service "%s"; reason: private alias.', $id)); + } + } +} diff --git a/srcs/phpmyadmin/vendor/symfony/dependency-injection/Compiler/RemoveUnusedDefinitionsPass.php b/srcs/phpmyadmin/vendor/symfony/dependency-injection/Compiler/RemoveUnusedDefinitionsPass.php new file mode 100644 index 0000000..287af23 --- /dev/null +++ b/srcs/phpmyadmin/vendor/symfony/dependency-injection/Compiler/RemoveUnusedDefinitionsPass.php @@ -0,0 +1,98 @@ +<?php + +/* + * This file is part of the Symfony package. + * + * (c) Fabien Potencier <fabien@symfony.com> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection\Compiler; + +use Symfony\Component\DependencyInjection\ContainerBuilder; +use Symfony\Component\DependencyInjection\Reference; + +/** + * Removes unused service definitions from the container. + * + * @author Johannes M. Schmitt <schmittjoh@gmail.com> + * @author Nicolas Grekas <p@tchwork.com> + */ +class RemoveUnusedDefinitionsPass extends AbstractRecursivePass implements RepeatablePassInterface +{ + private $connectedIds = []; + + /** + * {@inheritdoc} + */ + public function setRepeatedPass(RepeatedPass $repeatedPass) + { + @trigger_error(sprintf('The "%s()" method is deprecated since Symfony 4.2.', __METHOD__), E_USER_DEPRECATED); + } + + /** + * Processes the ContainerBuilder to remove unused definitions. + */ + public function process(ContainerBuilder $container) + { + try { + $this->enableExpressionProcessing(); + $this->container = $container; + $connectedIds = []; + $aliases = $container->getAliases(); + + foreach ($aliases as $id => $alias) { + if ($alias->isPublic()) { + $this->connectedIds[] = (string) $aliases[$id]; + } + } + + foreach ($container->getDefinitions() as $id => $definition) { + if ($definition->isPublic()) { + $connectedIds[$id] = true; + $this->processValue($definition); + } + } + + while ($this->connectedIds) { + $ids = $this->connectedIds; + $this->connectedIds = []; + foreach ($ids as $id) { + if (!isset($connectedIds[$id]) && $container->hasDefinition($id)) { + $connectedIds[$id] = true; + $this->processValue($container->getDefinition($id)); + } + } + } + + foreach ($container->getDefinitions() as $id => $definition) { + if (!isset($connectedIds[$id])) { + $container->removeDefinition($id); + $container->resolveEnvPlaceholders(!$definition->hasErrors() ? serialize($definition) : $definition); + $container->log($this, sprintf('Removed service "%s"; reason: unused.', $id)); + } + } + } finally { + $this->container = null; + $this->connectedIds = []; + } + } + + /** + * {@inheritdoc} + */ + protected function processValue($value, $isRoot = false) + { + if (!$value instanceof Reference) { + return parent::processValue($value, $isRoot); + } + + if (ContainerBuilder::IGNORE_ON_UNINITIALIZED_REFERENCE !== $value->getInvalidBehavior()) { + $this->connectedIds[] = (string) $value; + } + + return $value; + } +} diff --git a/srcs/phpmyadmin/vendor/symfony/dependency-injection/Compiler/RepeatablePassInterface.php b/srcs/phpmyadmin/vendor/symfony/dependency-injection/Compiler/RepeatablePassInterface.php new file mode 100644 index 0000000..11a5b0d --- /dev/null +++ b/srcs/phpmyadmin/vendor/symfony/dependency-injection/Compiler/RepeatablePassInterface.php @@ -0,0 +1,25 @@ +<?php + +/* + * This file is part of the Symfony package. + * + * (c) Fabien Potencier <fabien@symfony.com> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection\Compiler; + +/** + * Interface that must be implemented by passes that are run as part of an + * RepeatedPass. + * + * @author Johannes M. Schmitt <schmittjoh@gmail.com> + * + * @deprecated since Symfony 4.2. + */ +interface RepeatablePassInterface extends CompilerPassInterface +{ + public function setRepeatedPass(RepeatedPass $repeatedPass); +} diff --git a/srcs/phpmyadmin/vendor/symfony/dependency-injection/Compiler/RepeatedPass.php b/srcs/phpmyadmin/vendor/symfony/dependency-injection/Compiler/RepeatedPass.php new file mode 100644 index 0000000..b8add1b --- /dev/null +++ b/srcs/phpmyadmin/vendor/symfony/dependency-injection/Compiler/RepeatedPass.php @@ -0,0 +1,83 @@ +<?php + +/* + * This file is part of the Symfony package. + * + * (c) Fabien Potencier <fabien@symfony.com> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection\Compiler; + +@trigger_error(sprintf('The "%s" class is deprecated since Symfony 4.2.', RepeatedPass::class), E_USER_DEPRECATED); + +use Symfony\Component\DependencyInjection\ContainerBuilder; +use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException; + +/** + * A pass that might be run repeatedly. + * + * @author Johannes M. Schmitt <schmittjoh@gmail.com> + * + * @deprecated since Symfony 4.2. + */ +class RepeatedPass implements CompilerPassInterface +{ + /** + * @var bool + */ + private $repeat = false; + + private $passes; + + /** + * @param RepeatablePassInterface[] $passes An array of RepeatablePassInterface objects + * + * @throws InvalidArgumentException when the passes don't implement RepeatablePassInterface + */ + public function __construct(array $passes) + { + foreach ($passes as $pass) { + if (!$pass instanceof RepeatablePassInterface) { + throw new InvalidArgumentException('$passes must be an array of RepeatablePassInterface.'); + } + + $pass->setRepeatedPass($this); + } + + $this->passes = $passes; + } + + /** + * Process the repeatable passes that run more than once. + */ + public function process(ContainerBuilder $container) + { + do { + $this->repeat = false; + foreach ($this->passes as $pass) { + $pass->process($container); + } + } while ($this->repeat); + } + + /** + * Sets if the pass should repeat. + */ + public function setRepeat() + { + $this->repeat = true; + } + + /** + * Returns the passes. + * + * @return RepeatablePassInterface[] An array of RepeatablePassInterface objects + */ + public function getPasses() + { + return $this->passes; + } +} diff --git a/srcs/phpmyadmin/vendor/symfony/dependency-injection/Compiler/ReplaceAliasByActualDefinitionPass.php b/srcs/phpmyadmin/vendor/symfony/dependency-injection/Compiler/ReplaceAliasByActualDefinitionPass.php new file mode 100644 index 0000000..9981096 --- /dev/null +++ b/srcs/phpmyadmin/vendor/symfony/dependency-injection/Compiler/ReplaceAliasByActualDefinitionPass.php @@ -0,0 +1,94 @@ +<?php + +/* + * This file is part of the Symfony package. + * + * (c) Fabien Potencier <fabien@symfony.com> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection\Compiler; + +use Symfony\Component\DependencyInjection\ContainerBuilder; +use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException; +use Symfony\Component\DependencyInjection\Exception\ServiceNotFoundException; +use Symfony\Component\DependencyInjection\Reference; + +/** + * Replaces aliases with actual service definitions, effectively removing these + * aliases. + * + * @author Johannes M. Schmitt <schmittjoh@gmail.com> + */ +class ReplaceAliasByActualDefinitionPass extends AbstractRecursivePass +{ + private $replacements; + + /** + * Process the Container to replace aliases with service definitions. + * + * @throws InvalidArgumentException if the service definition does not exist + */ + public function process(ContainerBuilder $container) + { + // First collect all alias targets that need to be replaced + $seenAliasTargets = []; + $replacements = []; + foreach ($container->getAliases() as $definitionId => $target) { + $targetId = (string) $target; + // Special case: leave this target alone + if ('service_container' === $targetId) { + continue; + } + // Check if target needs to be replaces + if (isset($replacements[$targetId])) { + $container->setAlias($definitionId, $replacements[$targetId])->setPublic($target->isPublic())->setPrivate($target->isPrivate()); + } + // No need to process the same target twice + if (isset($seenAliasTargets[$targetId])) { + continue; + } + // Process new target + $seenAliasTargets[$targetId] = true; + try { + $definition = $container->getDefinition($targetId); + } catch (ServiceNotFoundException $e) { + if ('' !== $e->getId() && '@' === $e->getId()[0]) { + throw new ServiceNotFoundException($e->getId(), $e->getSourceId(), null, [substr($e->getId(), 1)]); + } + + throw $e; + } + if ($definition->isPublic()) { + continue; + } + // Remove private definition and schedule for replacement + $definition->setPublic(!$target->isPrivate()); + $definition->setPrivate($target->isPrivate()); + $container->setDefinition($definitionId, $definition); + $container->removeDefinition($targetId); + $replacements[$targetId] = $definitionId; + } + $this->replacements = $replacements; + + parent::process($container); + $this->replacements = []; + } + + /** + * {@inheritdoc} + */ + protected function processValue($value, $isRoot = false) + { + if ($value instanceof Reference && isset($this->replacements[$referenceId = (string) $value])) { + // Perform the replacement + $newId = $this->replacements[$referenceId]; + $value = new Reference($newId, $value->getInvalidBehavior()); + $this->container->log($this, sprintf('Changed reference of service "%s" previously pointing to "%s" to "%s".', $this->currentId, $referenceId, $newId)); + } + + return parent::processValue($value, $isRoot); + } +} diff --git a/srcs/phpmyadmin/vendor/symfony/dependency-injection/Compiler/ResolveBindingsPass.php b/srcs/phpmyadmin/vendor/symfony/dependency-injection/Compiler/ResolveBindingsPass.php new file mode 100644 index 0000000..e76c43b --- /dev/null +++ b/srcs/phpmyadmin/vendor/symfony/dependency-injection/Compiler/ResolveBindingsPass.php @@ -0,0 +1,227 @@ +<?php + +/* + * This file is part of the Symfony package. + * + * (c) Fabien Potencier <fabien@symfony.com> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection\Compiler; + +use Symfony\Component\DependencyInjection\Argument\BoundArgument; +use Symfony\Component\DependencyInjection\Argument\ServiceLocatorArgument; +use Symfony\Component\DependencyInjection\Argument\TaggedIteratorArgument; +use Symfony\Component\DependencyInjection\ContainerBuilder; +use Symfony\Component\DependencyInjection\Definition; +use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException; +use Symfony\Component\DependencyInjection\Exception\RuntimeException; +use Symfony\Component\DependencyInjection\LazyProxy\ProxyHelper; +use Symfony\Component\DependencyInjection\Reference; +use Symfony\Component\DependencyInjection\TypedReference; + +/** + * @author Guilhem Niot <guilhem.niot@gmail.com> + */ +class ResolveBindingsPass extends AbstractRecursivePass +{ + private $usedBindings = []; + private $unusedBindings = []; + private $errorMessages = []; + + /** + * {@inheritdoc} + */ + public function process(ContainerBuilder $container) + { + $this->usedBindings = $container->getRemovedBindingIds(); + + try { + parent::process($container); + + foreach ($this->unusedBindings as list($key, $serviceId, $bindingType, $file)) { + $argumentType = $argumentName = $message = null; + + if (false !== strpos($key, ' ')) { + list($argumentType, $argumentName) = explode(' ', $key, 2); + } elseif ('$' === $key[0]) { + $argumentName = $key; + } else { + $argumentType = $key; + } + + if ($argumentType) { + $message .= sprintf('of type "%s" ', $argumentType); + } + + if ($argumentName) { + $message .= sprintf('named "%s" ', $argumentName); + } + + if (BoundArgument::DEFAULTS_BINDING === $bindingType) { + $message .= 'under "_defaults"'; + } elseif (BoundArgument::INSTANCEOF_BINDING === $bindingType) { + $message .= 'under "_instanceof"'; + } else { + $message .= sprintf('for service "%s"', $serviceId); + } + + if ($file) { + $message .= sprintf(' in file "%s"', $file); + } + + $message = sprintf('A binding is configured for an argument %s, but no corresponding argument has been found. It may be unused and should be removed, or it may have a typo.', $message); + + if ($this->errorMessages) { + $message .= sprintf("\nCould be related to%s:", 1 < \count($this->errorMessages) ? ' one of' : ''); + } + foreach ($this->errorMessages as $m) { + $message .= "\n - ".$m; + } + throw new InvalidArgumentException($message); + } + } finally { + $this->usedBindings = []; + $this->unusedBindings = []; + $this->errorMessages = []; + } + } + + /** + * {@inheritdoc} + */ + protected function processValue($value, $isRoot = false) + { + if ($value instanceof TypedReference && $value->getType() === (string) $value) { + // Already checked + $bindings = $this->container->getDefinition($this->currentId)->getBindings(); + $name = $value->getName(); + + if (isset($name, $bindings[$name = $value.' $'.$name])) { + return $this->getBindingValue($bindings[$name]); + } + + if (isset($bindings[$value->getType()])) { + return $this->getBindingValue($bindings[$value->getType()]); + } + + return parent::processValue($value, $isRoot); + } + + if (!$value instanceof Definition || !$bindings = $value->getBindings()) { + return parent::processValue($value, $isRoot); + } + + foreach ($bindings as $key => $binding) { + list($bindingValue, $bindingId, $used, $bindingType, $file) = $binding->getValues(); + if ($used) { + $this->usedBindings[$bindingId] = true; + unset($this->unusedBindings[$bindingId]); + } elseif (!isset($this->usedBindings[$bindingId])) { + $this->unusedBindings[$bindingId] = [$key, $this->currentId, $bindingType, $file]; + } + + if (preg_match('/^(?:(?:array|bool|float|int|string) )?\$/', $key)) { + continue; + } + + if (null !== $bindingValue && !$bindingValue instanceof Reference && !$bindingValue instanceof Definition && !$bindingValue instanceof TaggedIteratorArgument && !$bindingValue instanceof ServiceLocatorArgument) { + throw new InvalidArgumentException(sprintf('Invalid value for binding key "%s" for service "%s": expected null, %s, %s, %s or ServiceLocatorArgument, %s given.', $key, $this->currentId, Reference::class, Definition::class, TaggedIteratorArgument::class, \gettype($bindingValue))); + } + } + + if ($value->isAbstract()) { + return parent::processValue($value, $isRoot); + } + + $calls = $value->getMethodCalls(); + + try { + if ($constructor = $this->getConstructor($value, false)) { + $calls[] = [$constructor, $value->getArguments()]; + } + } catch (RuntimeException $e) { + $this->errorMessages[] = $e->getMessage(); + $this->container->getDefinition($this->currentId)->addError($e->getMessage()); + + return parent::processValue($value, $isRoot); + } + + foreach ($calls as $i => $call) { + list($method, $arguments) = $call; + + if ($method instanceof \ReflectionFunctionAbstract) { + $reflectionMethod = $method; + } else { + try { + $reflectionMethod = $this->getReflectionMethod($value, $method); + } catch (RuntimeException $e) { + if ($value->getFactory()) { + continue; + } + throw $e; + } + } + + foreach ($reflectionMethod->getParameters() as $key => $parameter) { + if (\array_key_exists($key, $arguments) && '' !== $arguments[$key]) { + continue; + } + + $typeHint = ProxyHelper::getTypeHint($reflectionMethod, $parameter); + + if (\array_key_exists($k = ltrim($typeHint, '\\').' $'.$parameter->name, $bindings)) { + $arguments[$key] = $this->getBindingValue($bindings[$k]); + + continue; + } + + if (\array_key_exists('$'.$parameter->name, $bindings)) { + $arguments[$key] = $this->getBindingValue($bindings['$'.$parameter->name]); + + continue; + } + + if (!$typeHint || '\\' !== $typeHint[0] || !isset($bindings[$typeHint = substr($typeHint, 1)])) { + continue; + } + + $arguments[$key] = $this->getBindingValue($bindings[$typeHint]); + } + + if ($arguments !== $call[1]) { + ksort($arguments); + $calls[$i][1] = $arguments; + } + } + + if ($constructor) { + list(, $arguments) = array_pop($calls); + + if ($arguments !== $value->getArguments()) { + $value->setArguments($arguments); + } + } + + if ($calls !== $value->getMethodCalls()) { + $value->setMethodCalls($calls); + } + + return parent::processValue($value, $isRoot); + } + + /** + * @return mixed + */ + private function getBindingValue(BoundArgument $binding) + { + list($bindingValue, $bindingId) = $binding->getValues(); + + $this->usedBindings[$bindingId] = true; + unset($this->unusedBindings[$bindingId]); + + return $bindingValue; + } +} diff --git a/srcs/phpmyadmin/vendor/symfony/dependency-injection/Compiler/ResolveChildDefinitionsPass.php b/srcs/phpmyadmin/vendor/symfony/dependency-injection/Compiler/ResolveChildDefinitionsPass.php new file mode 100644 index 0000000..453e3f6 --- /dev/null +++ b/srcs/phpmyadmin/vendor/symfony/dependency-injection/Compiler/ResolveChildDefinitionsPass.php @@ -0,0 +1,190 @@ +<?php + +/* + * This file is part of the Symfony package. + * + * (c) Fabien Potencier <fabien@symfony.com> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection\Compiler; + +use Symfony\Component\DependencyInjection\ChildDefinition; +use Symfony\Component\DependencyInjection\ContainerInterface; +use Symfony\Component\DependencyInjection\Definition; +use Symfony\Component\DependencyInjection\Exception\ExceptionInterface; +use Symfony\Component\DependencyInjection\Exception\RuntimeException; +use Symfony\Component\DependencyInjection\Exception\ServiceCircularReferenceException; + +/** + * This replaces all ChildDefinition instances with their equivalent fully + * merged Definition instance. + * + * @author Johannes M. Schmitt <schmittjoh@gmail.com> + * @author Nicolas Grekas <p@tchwork.com> + */ +class ResolveChildDefinitionsPass extends AbstractRecursivePass +{ + private $currentPath; + + protected function processValue($value, $isRoot = false) + { + if (!$value instanceof Definition) { + return parent::processValue($value, $isRoot); + } + if ($isRoot) { + // yes, we are specifically fetching the definition from the + // container to ensure we are not operating on stale data + $value = $this->container->getDefinition($this->currentId); + } + if ($value instanceof ChildDefinition) { + $this->currentPath = []; + $value = $this->resolveDefinition($value); + if ($isRoot) { + $this->container->setDefinition($this->currentId, $value); + } + } + + return parent::processValue($value, $isRoot); + } + + /** + * Resolves the definition. + * + * @throws RuntimeException When the definition is invalid + */ + private function resolveDefinition(ChildDefinition $definition): Definition + { + try { + return $this->doResolveDefinition($definition); + } catch (ServiceCircularReferenceException $e) { + throw $e; + } catch (ExceptionInterface $e) { + $r = new \ReflectionProperty($e, 'message'); + $r->setAccessible(true); + $r->setValue($e, sprintf('Service "%s": %s', $this->currentId, $e->getMessage())); + + throw $e; + } + } + + private function doResolveDefinition(ChildDefinition $definition): Definition + { + if (!$this->container->has($parent = $definition->getParent())) { + throw new RuntimeException(sprintf('Parent definition "%s" does not exist.', $parent)); + } + + $searchKey = array_search($parent, $this->currentPath); + $this->currentPath[] = $parent; + + if (false !== $searchKey) { + throw new ServiceCircularReferenceException($parent, \array_slice($this->currentPath, $searchKey)); + } + + $parentDef = $this->container->findDefinition($parent); + if ($parentDef instanceof ChildDefinition) { + $id = $this->currentId; + $this->currentId = $parent; + $parentDef = $this->resolveDefinition($parentDef); + $this->container->setDefinition($parent, $parentDef); + $this->currentId = $id; + } + + $this->container->log($this, sprintf('Resolving inheritance for "%s" (parent: %s).', $this->currentId, $parent)); + $def = new Definition(); + + // merge in parent definition + // purposely ignored attributes: abstract, shared, tags, autoconfigured + $def->setClass($parentDef->getClass()); + $def->setArguments($parentDef->getArguments()); + $def->setMethodCalls($parentDef->getMethodCalls()); + $def->setProperties($parentDef->getProperties()); + if ($parentDef->isDeprecated()) { + $def->setDeprecated(true, $parentDef->getDeprecationMessage('%service_id%')); + } + $def->setFactory($parentDef->getFactory()); + $def->setConfigurator($parentDef->getConfigurator()); + $def->setFile($parentDef->getFile()); + $def->setPublic($parentDef->isPublic()); + $def->setLazy($parentDef->isLazy()); + $def->setAutowired($parentDef->isAutowired()); + $def->setChanges($parentDef->getChanges()); + + $def->setBindings($definition->getBindings() + $parentDef->getBindings()); + + // overwrite with values specified in the decorator + $changes = $definition->getChanges(); + if (isset($changes['class'])) { + $def->setClass($definition->getClass()); + } + if (isset($changes['factory'])) { + $def->setFactory($definition->getFactory()); + } + if (isset($changes['configurator'])) { + $def->setConfigurator($definition->getConfigurator()); + } + if (isset($changes['file'])) { + $def->setFile($definition->getFile()); + } + if (isset($changes['public'])) { + $def->setPublic($definition->isPublic()); + } else { + $def->setPrivate($definition->isPrivate() || $parentDef->isPrivate()); + } + if (isset($changes['lazy'])) { + $def->setLazy($definition->isLazy()); + } + if (isset($changes['deprecated'])) { + $def->setDeprecated($definition->isDeprecated(), $definition->getDeprecationMessage('%service_id%')); + } + if (isset($changes['autowired'])) { + $def->setAutowired($definition->isAutowired()); + } + if (isset($changes['shared'])) { + $def->setShared($definition->isShared()); + } + if (isset($changes['decorated_service'])) { + $decoratedService = $definition->getDecoratedService(); + if (null === $decoratedService) { + $def->setDecoratedService($decoratedService); + } else { + $def->setDecoratedService($decoratedService[0], $decoratedService[1], $decoratedService[2], $decoratedService[3] ?? ContainerInterface::EXCEPTION_ON_INVALID_REFERENCE); + } + } + + // merge arguments + foreach ($definition->getArguments() as $k => $v) { + if (is_numeric($k)) { + $def->addArgument($v); + } elseif (0 === strpos($k, 'index_')) { + $def->replaceArgument((int) substr($k, \strlen('index_')), $v); + } else { + $def->setArgument($k, $v); + } + } + + // merge properties + foreach ($definition->getProperties() as $k => $v) { + $def->setProperty($k, $v); + } + + // append method calls + if ($calls = $definition->getMethodCalls()) { + $def->setMethodCalls(array_merge($def->getMethodCalls(), $calls)); + } + + $def->addError($parentDef); + $def->addError($definition); + + // these attributes are always taken from the child + $def->setAbstract($definition->isAbstract()); + $def->setTags($definition->getTags()); + // autoconfigure is never taken from parent (on purpose) + // and it's not legal on an instanceof + $def->setAutoconfigured($definition->isAutoconfigured()); + + return $def; + } +} diff --git a/srcs/phpmyadmin/vendor/symfony/dependency-injection/Compiler/ResolveClassPass.php b/srcs/phpmyadmin/vendor/symfony/dependency-injection/Compiler/ResolveClassPass.php new file mode 100644 index 0000000..5932472 --- /dev/null +++ b/srcs/phpmyadmin/vendor/symfony/dependency-injection/Compiler/ResolveClassPass.php @@ -0,0 +1,40 @@ +<?php + +/* + * This file is part of the Symfony package. + * + * (c) Fabien Potencier <fabien@symfony.com> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection\Compiler; + +use Symfony\Component\DependencyInjection\ChildDefinition; +use Symfony\Component\DependencyInjection\ContainerBuilder; +use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException; + +/** + * @author Nicolas Grekas <p@tchwork.com> + */ +class ResolveClassPass implements CompilerPassInterface +{ + /** + * {@inheritdoc} + */ + public function process(ContainerBuilder $container) + { + foreach ($container->getDefinitions() as $id => $definition) { + if ($definition->isSynthetic() || null !== $definition->getClass()) { + continue; + } + if (preg_match('/^[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*+(?:\\\\[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*+)++$/', $id)) { + if ($definition instanceof ChildDefinition && !class_exists($id)) { + throw new InvalidArgumentException(sprintf('Service definition "%s" has a parent but no class, and its name looks like a FQCN. Either the class is missing or you want to inherit it from the parent service. To resolve this ambiguity, please rename this service to a non-FQCN (e.g. using dots), or create the missing class.', $id)); + } + $definition->setClass($id); + } + } + } +} diff --git a/srcs/phpmyadmin/vendor/symfony/dependency-injection/Compiler/ResolveEnvPlaceholdersPass.php b/srcs/phpmyadmin/vendor/symfony/dependency-injection/Compiler/ResolveEnvPlaceholdersPass.php new file mode 100644 index 0000000..9e1edd4 --- /dev/null +++ b/srcs/phpmyadmin/vendor/symfony/dependency-injection/Compiler/ResolveEnvPlaceholdersPass.php @@ -0,0 +1,44 @@ +<?php + +/* + * This file is part of the Symfony package. + * + * (c) Fabien Potencier <fabien@symfony.com> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection\Compiler; + +use Symfony\Component\DependencyInjection\Definition; + +/** + * Replaces env var placeholders by their current values. + */ +class ResolveEnvPlaceholdersPass extends AbstractRecursivePass +{ + protected function processValue($value, $isRoot = false) + { + if (\is_string($value)) { + return $this->container->resolveEnvPlaceholders($value, true); + } + if ($value instanceof Definition) { + $changes = $value->getChanges(); + if (isset($changes['class'])) { + $value->setClass($this->container->resolveEnvPlaceholders($value->getClass(), true)); + } + if (isset($changes['file'])) { + $value->setFile($this->container->resolveEnvPlaceholders($value->getFile(), true)); + } + } + + $value = parent::processValue($value, $isRoot); + + if ($value && \is_array($value) && !$isRoot) { + $value = array_combine($this->container->resolveEnvPlaceholders(array_keys($value), true), $value); + } + + return $value; + } +} diff --git a/srcs/phpmyadmin/vendor/symfony/dependency-injection/Compiler/ResolveFactoryClassPass.php b/srcs/phpmyadmin/vendor/symfony/dependency-injection/Compiler/ResolveFactoryClassPass.php new file mode 100644 index 0000000..848da7f --- /dev/null +++ b/srcs/phpmyadmin/vendor/symfony/dependency-injection/Compiler/ResolveFactoryClassPass.php @@ -0,0 +1,38 @@ +<?php + +/* + * This file is part of the Symfony package. + * + * (c) Fabien Potencier <fabien@symfony.com> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection\Compiler; + +use Symfony\Component\DependencyInjection\Definition; +use Symfony\Component\DependencyInjection\Exception\RuntimeException; + +/** + * @author Maxime Steinhausser <maxime.steinhausser@gmail.com> + */ +class ResolveFactoryClassPass extends AbstractRecursivePass +{ + /** + * {@inheritdoc} + */ + protected function processValue($value, $isRoot = false) + { + if ($value instanceof Definition && \is_array($factory = $value->getFactory()) && null === $factory[0]) { + if (null === $class = $value->getClass()) { + throw new RuntimeException(sprintf('The "%s" service is defined to be created by a factory, but is missing the factory class. Did you forget to define the factory or service class?', $this->currentId)); + } + + $factory[0] = $class; + $value->setFactory($factory); + } + + return parent::processValue($value, $isRoot); + } +} diff --git a/srcs/phpmyadmin/vendor/symfony/dependency-injection/Compiler/ResolveHotPathPass.php b/srcs/phpmyadmin/vendor/symfony/dependency-injection/Compiler/ResolveHotPathPass.php new file mode 100644 index 0000000..bfdd91c --- /dev/null +++ b/srcs/phpmyadmin/vendor/symfony/dependency-injection/Compiler/ResolveHotPathPass.php @@ -0,0 +1,71 @@ +<?php + +/* + * This file is part of the Symfony package. + * + * (c) Fabien Potencier <fabien@symfony.com> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection\Compiler; + +use Symfony\Component\DependencyInjection\Argument\ArgumentInterface; +use Symfony\Component\DependencyInjection\ContainerBuilder; +use Symfony\Component\DependencyInjection\Definition; +use Symfony\Component\DependencyInjection\Reference; + +/** + * Propagate "container.hot_path" tags to referenced services. + * + * @author Nicolas Grekas <p@tchwork.com> + */ +class ResolveHotPathPass extends AbstractRecursivePass +{ + private $tagName; + private $resolvedIds = []; + + public function __construct(string $tagName = 'container.hot_path') + { + $this->tagName = $tagName; + } + + /** + * {@inheritdoc} + */ + public function process(ContainerBuilder $container) + { + try { + parent::process($container); + $container->getDefinition('service_container')->clearTag($this->tagName); + } finally { + $this->resolvedIds = []; + } + } + + /** + * {@inheritdoc} + */ + protected function processValue($value, $isRoot = false) + { + if ($value instanceof ArgumentInterface) { + return $value; + } + if ($value instanceof Definition && $isRoot && (isset($this->resolvedIds[$this->currentId]) || !$value->hasTag($this->tagName) || $value->isDeprecated())) { + return $value->isDeprecated() ? $value->clearTag($this->tagName) : $value; + } + if ($value instanceof Reference && ContainerBuilder::IGNORE_ON_UNINITIALIZED_REFERENCE !== $value->getInvalidBehavior() && $this->container->has($id = (string) $value)) { + $definition = $this->container->findDefinition($id); + if (!$definition->hasTag($this->tagName) && !$definition->isDeprecated()) { + $this->resolvedIds[$id] = true; + $definition->addTag($this->tagName); + parent::processValue($definition, false); + } + + return $value; + } + + return parent::processValue($value, $isRoot); + } +} diff --git a/srcs/phpmyadmin/vendor/symfony/dependency-injection/Compiler/ResolveInstanceofConditionalsPass.php b/srcs/phpmyadmin/vendor/symfony/dependency-injection/Compiler/ResolveInstanceofConditionalsPass.php new file mode 100644 index 0000000..96afb03 --- /dev/null +++ b/srcs/phpmyadmin/vendor/symfony/dependency-injection/Compiler/ResolveInstanceofConditionalsPass.php @@ -0,0 +1,168 @@ +<?php + +/* + * This file is part of the Symfony package. + * + * (c) Fabien Potencier <fabien@symfony.com> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection\Compiler; + +use Symfony\Component\DependencyInjection\ChildDefinition; +use Symfony\Component\DependencyInjection\ContainerBuilder; +use Symfony\Component\DependencyInjection\Definition; +use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException; +use Symfony\Component\DependencyInjection\Exception\RuntimeException; + +/** + * Applies instanceof conditionals to definitions. + * + * @author Nicolas Grekas <p@tchwork.com> + */ +class ResolveInstanceofConditionalsPass implements CompilerPassInterface +{ + /** + * {@inheritdoc} + */ + public function process(ContainerBuilder $container) + { + foreach ($container->getAutoconfiguredInstanceof() as $interface => $definition) { + if ($definition->getArguments()) { + throw new InvalidArgumentException(sprintf('Autoconfigured instanceof for type "%s" defines arguments but these are not supported and should be removed.', $interface)); + } + } + + foreach ($container->getDefinitions() as $id => $definition) { + if ($definition instanceof ChildDefinition) { + // don't apply "instanceof" to children: it will be applied to their parent + continue; + } + $container->setDefinition($id, $this->processDefinition($container, $id, $definition)); + } + } + + private function processDefinition(ContainerBuilder $container, string $id, Definition $definition): Definition + { + $instanceofConditionals = $definition->getInstanceofConditionals(); + $autoconfiguredInstanceof = $definition->isAutoconfigured() ? $container->getAutoconfiguredInstanceof() : []; + if (!$instanceofConditionals && !$autoconfiguredInstanceof) { + return $definition; + } + + if (!$class = $container->getParameterBag()->resolveValue($definition->getClass())) { + return $definition; + } + + $conditionals = $this->mergeConditionals($autoconfiguredInstanceof, $instanceofConditionals, $container); + + $definition->setInstanceofConditionals([]); + $parent = $shared = null; + $instanceofTags = []; + $instanceofCalls = []; + $instanceofBindings = []; + $reflectionClass = null; + + foreach ($conditionals as $interface => $instanceofDefs) { + if ($interface !== $class && !(null === $reflectionClass ? $reflectionClass = ($container->getReflectionClass($class, false) ?: false) : $reflectionClass)) { + continue; + } + + if ($interface !== $class && !is_subclass_of($class, $interface)) { + continue; + } + + foreach ($instanceofDefs as $key => $instanceofDef) { + /** @var ChildDefinition $instanceofDef */ + $instanceofDef = clone $instanceofDef; + $instanceofDef->setAbstract(true)->setParent($parent ?: '.abstract.instanceof.'.$id); + $parent = '.instanceof.'.$interface.'.'.$key.'.'.$id; + $container->setDefinition($parent, $instanceofDef); + $instanceofTags[] = $instanceofDef->getTags(); + $instanceofBindings = $instanceofDef->getBindings() + $instanceofBindings; + + foreach ($instanceofDef->getMethodCalls() as $methodCall) { + $instanceofCalls[] = $methodCall; + } + + $instanceofDef->setTags([]); + $instanceofDef->setMethodCalls([]); + $instanceofDef->setBindings([]); + + if (isset($instanceofDef->getChanges()['shared'])) { + $shared = $instanceofDef->isShared(); + } + } + } + + if ($parent) { + $bindings = $definition->getBindings(); + $abstract = $container->setDefinition('.abstract.instanceof.'.$id, $definition); + + // cast Definition to ChildDefinition + $definition->setBindings([]); + $definition = serialize($definition); + $definition = substr_replace($definition, '53', 2, 2); + $definition = substr_replace($definition, 'Child', 44, 0); + /** @var ChildDefinition $definition */ + $definition = unserialize($definition); + $definition->setParent($parent); + + if (null !== $shared && !isset($definition->getChanges()['shared'])) { + $definition->setShared($shared); + } + + // Don't add tags to service decorators + if (null === $definition->getDecoratedService()) { + $i = \count($instanceofTags); + while (0 <= --$i) { + foreach ($instanceofTags[$i] as $k => $v) { + foreach ($v as $v) { + if ($definition->hasTag($k) && \in_array($v, $definition->getTag($k))) { + continue; + } + $definition->addTag($k, $v); + } + } + } + } + + $definition->setMethodCalls(array_merge($instanceofCalls, $definition->getMethodCalls())); + $definition->setBindings($bindings + $instanceofBindings); + + // reset fields with "merge" behavior + $abstract + ->setBindings([]) + ->setArguments([]) + ->setMethodCalls([]) + ->setDecoratedService(null) + ->setTags([]) + ->setAbstract(true); + } + + return $definition; + } + + private function mergeConditionals(array $autoconfiguredInstanceof, array $instanceofConditionals, ContainerBuilder $container): array + { + // make each value an array of ChildDefinition + $conditionals = array_map(function ($childDef) { return [$childDef]; }, $autoconfiguredInstanceof); + + foreach ($instanceofConditionals as $interface => $instanceofDef) { + // make sure the interface/class exists (but don't validate automaticInstanceofConditionals) + if (!$container->getReflectionClass($interface)) { + throw new RuntimeException(sprintf('"%s" is set as an "instanceof" conditional, but it does not exist.', $interface)); + } + + if (!isset($autoconfiguredInstanceof[$interface])) { + $conditionals[$interface] = []; + } + + $conditionals[$interface][] = $instanceofDef; + } + + return $conditionals; + } +} diff --git a/srcs/phpmyadmin/vendor/symfony/dependency-injection/Compiler/ResolveInvalidReferencesPass.php b/srcs/phpmyadmin/vendor/symfony/dependency-injection/Compiler/ResolveInvalidReferencesPass.php new file mode 100644 index 0000000..948de42 --- /dev/null +++ b/srcs/phpmyadmin/vendor/symfony/dependency-injection/Compiler/ResolveInvalidReferencesPass.php @@ -0,0 +1,136 @@ +<?php + +/* + * This file is part of the Symfony package. + * + * (c) Fabien Potencier <fabien@symfony.com> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection\Compiler; + +use Symfony\Component\DependencyInjection\Argument\ArgumentInterface; +use Symfony\Component\DependencyInjection\Argument\ServiceClosureArgument; +use Symfony\Component\DependencyInjection\ContainerBuilder; +use Symfony\Component\DependencyInjection\ContainerInterface; +use Symfony\Component\DependencyInjection\Definition; +use Symfony\Component\DependencyInjection\Exception\RuntimeException; +use Symfony\Component\DependencyInjection\Exception\ServiceNotFoundException; +use Symfony\Component\DependencyInjection\Reference; +use Symfony\Component\DependencyInjection\TypedReference; + +/** + * Emulates the invalid behavior if the reference is not found within the + * container. + * + * @author Johannes M. Schmitt <schmittjoh@gmail.com> + */ +class ResolveInvalidReferencesPass implements CompilerPassInterface +{ + private $container; + private $signalingException; + private $currentId; + + /** + * Process the ContainerBuilder to resolve invalid references. + */ + public function process(ContainerBuilder $container) + { + $this->container = $container; + $this->signalingException = new RuntimeException('Invalid reference.'); + + try { + foreach ($container->getDefinitions() as $this->currentId => $definition) { + $this->processValue($definition); + } + } finally { + $this->container = $this->signalingException = null; + } + } + + /** + * Processes arguments to determine invalid references. + * + * @return mixed + * + * @throws RuntimeException When an invalid reference is found + */ + private function processValue($value, int $rootLevel = 0, int $level = 0) + { + if ($value instanceof ServiceClosureArgument) { + $value->setValues($this->processValue($value->getValues(), 1, 1)); + } elseif ($value instanceof ArgumentInterface) { + $value->setValues($this->processValue($value->getValues(), $rootLevel, 1 + $level)); + } elseif ($value instanceof Definition) { + if ($value->isSynthetic() || $value->isAbstract()) { + return $value; + } + $value->setArguments($this->processValue($value->getArguments(), 0)); + $value->setProperties($this->processValue($value->getProperties(), 1)); + $value->setMethodCalls($this->processValue($value->getMethodCalls(), 2)); + } elseif (\is_array($value)) { + $i = 0; + + foreach ($value as $k => $v) { + try { + if (false !== $i && $k !== $i++) { + $i = false; + } + if ($v !== $processedValue = $this->processValue($v, $rootLevel, 1 + $level)) { + $value[$k] = $processedValue; + } + } catch (RuntimeException $e) { + if ($rootLevel < $level || ($rootLevel && !$level)) { + unset($value[$k]); + } elseif ($rootLevel) { + throw $e; + } else { + $value[$k] = null; + } + } + } + + // Ensure numerically indexed arguments have sequential numeric keys. + if (false !== $i) { + $value = array_values($value); + } + } elseif ($value instanceof Reference) { + if ($this->container->has($id = (string) $value)) { + return $value; + } + + $currentDefinition = $this->container->getDefinition($this->currentId); + + // resolve decorated service behavior depending on decorator service + if ($currentDefinition->innerServiceId === $id && ContainerInterface::NULL_ON_INVALID_REFERENCE === $currentDefinition->decorationOnInvalid) { + return null; + } + + $invalidBehavior = $value->getInvalidBehavior(); + + if (ContainerInterface::RUNTIME_EXCEPTION_ON_INVALID_REFERENCE === $invalidBehavior && $value instanceof TypedReference && !$this->container->has($id)) { + $e = new ServiceNotFoundException($id, $this->currentId); + + // since the error message varies by $id and $this->currentId, so should the id of the dummy errored definition + $this->container->register($id = sprintf('.errored.%s.%s', $this->currentId, $id), $value->getType()) + ->addError($e->getMessage()); + + return new TypedReference($id, $value->getType(), $value->getInvalidBehavior()); + } + + // resolve invalid behavior + if (ContainerInterface::NULL_ON_INVALID_REFERENCE === $invalidBehavior) { + $value = null; + } elseif (ContainerInterface::IGNORE_ON_INVALID_REFERENCE === $invalidBehavior) { + if (0 < $level || $rootLevel) { + throw $this->signalingException; + } + $value = null; + } + } + + return $value; + } +} diff --git a/srcs/phpmyadmin/vendor/symfony/dependency-injection/Compiler/ResolveNamedArgumentsPass.php b/srcs/phpmyadmin/vendor/symfony/dependency-injection/Compiler/ResolveNamedArgumentsPass.php new file mode 100644 index 0000000..6004cc3 --- /dev/null +++ b/srcs/phpmyadmin/vendor/symfony/dependency-injection/Compiler/ResolveNamedArgumentsPass.php @@ -0,0 +1,112 @@ +<?php + +/* + * This file is part of the Symfony package. + * + * (c) Fabien Potencier <fabien@symfony.com> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection\Compiler; + +use Symfony\Component\DependencyInjection\Definition; +use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException; +use Symfony\Component\DependencyInjection\LazyProxy\ProxyHelper; +use Symfony\Component\DependencyInjection\Reference; + +/** + * Resolves named arguments to their corresponding numeric index. + * + * @author Kévin Dunglas <dunglas@gmail.com> + */ +class ResolveNamedArgumentsPass extends AbstractRecursivePass +{ + /** + * {@inheritdoc} + */ + protected function processValue($value, $isRoot = false) + { + if (!$value instanceof Definition) { + return parent::processValue($value, $isRoot); + } + + $calls = $value->getMethodCalls(); + $calls[] = ['__construct', $value->getArguments()]; + + foreach ($calls as $i => $call) { + list($method, $arguments) = $call; + $parameters = null; + $resolvedArguments = []; + + foreach ($arguments as $key => $argument) { + if (\is_int($key)) { + $resolvedArguments[$key] = $argument; + continue; + } + + if (null === $parameters) { + $r = $this->getReflectionMethod($value, $method); + $class = $r instanceof \ReflectionMethod ? $r->class : $this->currentId; + $method = $r->getName(); + $parameters = $r->getParameters(); + } + + if (isset($key[0]) && '$' !== $key[0] && !class_exists($key) && !interface_exists($key, false)) { + throw new InvalidArgumentException(sprintf('Invalid service "%s": did you forget to add the "$" prefix to argument "%s"?', $this->currentId, $key)); + } + + if (isset($key[0]) && '$' === $key[0]) { + foreach ($parameters as $j => $p) { + if ($key === '$'.$p->name) { + if ($p->isVariadic() && \is_array($argument)) { + foreach ($argument as $variadicArgument) { + $resolvedArguments[$j++] = $variadicArgument; + } + } else { + $resolvedArguments[$j] = $argument; + } + + continue 2; + } + } + + throw new InvalidArgumentException(sprintf('Invalid service "%s": method "%s()" has no argument named "%s". Check your service definition.', $this->currentId, $class !== $this->currentId ? $class.'::'.$method : $method, $key)); + } + + if (null !== $argument && !$argument instanceof Reference && !$argument instanceof Definition) { + throw new InvalidArgumentException(sprintf('Invalid service "%s": the value of argument "%s" of method "%s()" must be null, an instance of %s or an instance of %s, %s given.', $this->currentId, $key, $class !== $this->currentId ? $class.'::'.$method : $method, Reference::class, Definition::class, \gettype($argument))); + } + + $typeFound = false; + foreach ($parameters as $j => $p) { + if (!\array_key_exists($j, $resolvedArguments) && ProxyHelper::getTypeHint($r, $p, true) === $key) { + $resolvedArguments[$j] = $argument; + $typeFound = true; + } + } + + if (!$typeFound) { + throw new InvalidArgumentException(sprintf('Invalid service "%s": method "%s()" has no argument type-hinted as "%s". Check your service definition.', $this->currentId, $class !== $this->currentId ? $class.'::'.$method : $method, $key)); + } + } + + if ($resolvedArguments !== $call[1]) { + ksort($resolvedArguments); + $calls[$i][1] = $resolvedArguments; + } + } + + list(, $arguments) = array_pop($calls); + + if ($arguments !== $value->getArguments()) { + $value->setArguments($arguments); + } + if ($calls !== $value->getMethodCalls()) { + $value->setMethodCalls($calls); + } + + return parent::processValue($value, $isRoot); + } +} diff --git a/srcs/phpmyadmin/vendor/symfony/dependency-injection/Compiler/ResolveParameterPlaceHoldersPass.php b/srcs/phpmyadmin/vendor/symfony/dependency-injection/Compiler/ResolveParameterPlaceHoldersPass.php new file mode 100644 index 0000000..2dec13f --- /dev/null +++ b/srcs/phpmyadmin/vendor/symfony/dependency-injection/Compiler/ResolveParameterPlaceHoldersPass.php @@ -0,0 +1,87 @@ +<?php + +/* + * This file is part of the Symfony package. + * + * (c) Fabien Potencier <fabien@symfony.com> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection\Compiler; + +use Symfony\Component\DependencyInjection\ContainerBuilder; +use Symfony\Component\DependencyInjection\Definition; +use Symfony\Component\DependencyInjection\Exception\ParameterNotFoundException; + +/** + * Resolves all parameter placeholders "%somevalue%" to their real values. + * + * @author Johannes M. Schmitt <schmittjoh@gmail.com> + */ +class ResolveParameterPlaceHoldersPass extends AbstractRecursivePass +{ + private $bag; + private $resolveArrays; + + public function __construct(bool $resolveArrays = true) + { + $this->resolveArrays = $resolveArrays; + } + + /** + * {@inheritdoc} + * + * @throws ParameterNotFoundException + */ + public function process(ContainerBuilder $container) + { + $this->bag = $container->getParameterBag(); + + try { + parent::process($container); + + $aliases = []; + foreach ($container->getAliases() as $name => $target) { + $this->currentId = $name; + $aliases[$this->bag->resolveValue($name)] = $target; + } + $container->setAliases($aliases); + } catch (ParameterNotFoundException $e) { + $e->setSourceId($this->currentId); + + throw $e; + } + + $this->bag->resolve(); + $this->bag = null; + } + + protected function processValue($value, $isRoot = false) + { + if (\is_string($value)) { + $v = $this->bag->resolveValue($value); + + return $this->resolveArrays || !$v || !\is_array($v) ? $v : $value; + } + if ($value instanceof Definition) { + $value->setBindings($this->processValue($value->getBindings())); + $changes = $value->getChanges(); + if (isset($changes['class'])) { + $value->setClass($this->bag->resolveValue($value->getClass())); + } + if (isset($changes['file'])) { + $value->setFile($this->bag->resolveValue($value->getFile())); + } + } + + $value = parent::processValue($value, $isRoot); + + if ($value && \is_array($value)) { + $value = array_combine($this->bag->resolveValue(array_keys($value)), $value); + } + + return $value; + } +} diff --git a/srcs/phpmyadmin/vendor/symfony/dependency-injection/Compiler/ResolvePrivatesPass.php b/srcs/phpmyadmin/vendor/symfony/dependency-injection/Compiler/ResolvePrivatesPass.php new file mode 100644 index 0000000..1bd9934 --- /dev/null +++ b/srcs/phpmyadmin/vendor/symfony/dependency-injection/Compiler/ResolvePrivatesPass.php @@ -0,0 +1,40 @@ +<?php + +/* + * This file is part of the Symfony package. + * + * (c) Fabien Potencier <fabien@symfony.com> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection\Compiler; + +use Symfony\Component\DependencyInjection\ContainerBuilder; + +/** + * @author Nicolas Grekas <p@tchwork.com> + */ +class ResolvePrivatesPass implements CompilerPassInterface +{ + /** + * {@inheritdoc} + */ + public function process(ContainerBuilder $container) + { + foreach ($container->getDefinitions() as $id => $definition) { + if ($definition->isPrivate()) { + $definition->setPublic(false); + $definition->setPrivate(true); + } + } + + foreach ($container->getAliases() as $id => $alias) { + if ($alias->isPrivate()) { + $alias->setPublic(false); + $alias->setPrivate(true); + } + } + } +} diff --git a/srcs/phpmyadmin/vendor/symfony/dependency-injection/Compiler/ResolveReferencesToAliasesPass.php b/srcs/phpmyadmin/vendor/symfony/dependency-injection/Compiler/ResolveReferencesToAliasesPass.php new file mode 100644 index 0000000..bf9ea2b --- /dev/null +++ b/srcs/phpmyadmin/vendor/symfony/dependency-injection/Compiler/ResolveReferencesToAliasesPass.php @@ -0,0 +1,80 @@ +<?php + +/* + * This file is part of the Symfony package. + * + * (c) Fabien Potencier <fabien@symfony.com> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection\Compiler; + +use Symfony\Component\DependencyInjection\ContainerBuilder; +use Symfony\Component\DependencyInjection\Exception\ServiceCircularReferenceException; +use Symfony\Component\DependencyInjection\Reference; + +/** + * Replaces all references to aliases with references to the actual service. + * + * @author Johannes M. Schmitt <schmittjoh@gmail.com> + */ +class ResolveReferencesToAliasesPass extends AbstractRecursivePass +{ + /** + * {@inheritdoc} + */ + public function process(ContainerBuilder $container) + { + parent::process($container); + + foreach ($container->getAliases() as $id => $alias) { + $aliasId = (string) $alias; + $this->currentId = $id; + + if ($aliasId !== $defId = $this->getDefinitionId($aliasId, $container)) { + $container->setAlias($id, $defId)->setPublic($alias->isPublic())->setPrivate($alias->isPrivate()); + } + } + } + + /** + * {@inheritdoc} + */ + protected function processValue($value, $isRoot = false) + { + if (!$value instanceof Reference) { + return parent::processValue($value, $isRoot); + } + + $defId = $this->getDefinitionId($id = (string) $value, $this->container); + + return $defId !== $id ? new Reference($defId, $value->getInvalidBehavior()) : $value; + } + + private function getDefinitionId(string $id, ContainerBuilder $container): string + { + if (!$container->hasAlias($id)) { + return $id; + } + + $alias = $container->getAlias($id); + + if ($alias->isDeprecated()) { + @trigger_error(sprintf('%s. It is being referenced by the "%s" %s.', rtrim($alias->getDeprecationMessage($id), '. '), $this->currentId, $container->hasDefinition($this->currentId) ? 'service' : 'alias'), E_USER_DEPRECATED); + } + + $seen = []; + do { + if (isset($seen[$id])) { + throw new ServiceCircularReferenceException($id, array_merge(array_keys($seen), [$id])); + } + + $seen[$id] = true; + $id = (string) $container->getAlias($id); + } while ($container->hasAlias($id)); + + return $id; + } +} diff --git a/srcs/phpmyadmin/vendor/symfony/dependency-injection/Compiler/ResolveServiceSubscribersPass.php b/srcs/phpmyadmin/vendor/symfony/dependency-injection/Compiler/ResolveServiceSubscribersPass.php new file mode 100644 index 0000000..399f349 --- /dev/null +++ b/srcs/phpmyadmin/vendor/symfony/dependency-injection/Compiler/ResolveServiceSubscribersPass.php @@ -0,0 +1,52 @@ +<?php + +/* + * This file is part of the Symfony package. + * + * (c) Fabien Potencier <fabien@symfony.com> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection\Compiler; + +use Psr\Container\ContainerInterface; +use Symfony\Component\DependencyInjection\Definition; +use Symfony\Component\DependencyInjection\Reference; +use Symfony\Contracts\Service\ServiceProviderInterface; + +/** + * Compiler pass to inject their service locator to service subscribers. + * + * @author Nicolas Grekas <p@tchwork.com> + */ +class ResolveServiceSubscribersPass extends AbstractRecursivePass +{ + private $serviceLocator; + + protected function processValue($value, $isRoot = false) + { + if ($value instanceof Reference && $this->serviceLocator && \in_array((string) $value, [ContainerInterface::class, ServiceProviderInterface::class], true)) { + return new Reference($this->serviceLocator); + } + + if (!$value instanceof Definition) { + return parent::processValue($value, $isRoot); + } + + $serviceLocator = $this->serviceLocator; + $this->serviceLocator = null; + + if ($value->hasTag('container.service_subscriber.locator')) { + $this->serviceLocator = $value->getTag('container.service_subscriber.locator')[0]['id']; + $value->clearTag('container.service_subscriber.locator'); + } + + try { + return parent::processValue($value); + } finally { + $this->serviceLocator = $serviceLocator; + } + } +} diff --git a/srcs/phpmyadmin/vendor/symfony/dependency-injection/Compiler/ResolveTaggedIteratorArgumentPass.php b/srcs/phpmyadmin/vendor/symfony/dependency-injection/Compiler/ResolveTaggedIteratorArgumentPass.php new file mode 100644 index 0000000..a430572 --- /dev/null +++ b/srcs/phpmyadmin/vendor/symfony/dependency-injection/Compiler/ResolveTaggedIteratorArgumentPass.php @@ -0,0 +1,38 @@ +<?php + +/* + * This file is part of the Symfony package. + * + * (c) Fabien Potencier <fabien@symfony.com> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection\Compiler; + +use Symfony\Component\DependencyInjection\Argument\TaggedIteratorArgument; + +/** + * Resolves all TaggedIteratorArgument arguments. + * + * @author Roland Franssen <franssen.roland@gmail.com> + */ +class ResolveTaggedIteratorArgumentPass extends AbstractRecursivePass +{ + use PriorityTaggedServiceTrait; + + /** + * {@inheritdoc} + */ + protected function processValue($value, $isRoot = false) + { + if (!$value instanceof TaggedIteratorArgument) { + return parent::processValue($value, $isRoot); + } + + $value->setValues($this->findAndSortTaggedServices($value, $this->container)); + + return $value; + } +} diff --git a/srcs/phpmyadmin/vendor/symfony/dependency-injection/Compiler/ServiceLocatorTagPass.php b/srcs/phpmyadmin/vendor/symfony/dependency-injection/Compiler/ServiceLocatorTagPass.php new file mode 100644 index 0000000..5fdbe56 --- /dev/null +++ b/srcs/phpmyadmin/vendor/symfony/dependency-injection/Compiler/ServiceLocatorTagPass.php @@ -0,0 +1,135 @@ +<?php + +/* + * This file is part of the Symfony package. + * + * (c) Fabien Potencier <fabien@symfony.com> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection\Compiler; + +use Symfony\Component\DependencyInjection\Alias; +use Symfony\Component\DependencyInjection\Argument\ServiceClosureArgument; +use Symfony\Component\DependencyInjection\Argument\ServiceLocatorArgument; +use Symfony\Component\DependencyInjection\ContainerBuilder; +use Symfony\Component\DependencyInjection\Definition; +use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException; +use Symfony\Component\DependencyInjection\Reference; +use Symfony\Component\DependencyInjection\ServiceLocator; + +/** + * Applies the "container.service_locator" tag by wrapping references into ServiceClosureArgument instances. + * + * @author Nicolas Grekas <p@tchwork.com> + */ +final class ServiceLocatorTagPass extends AbstractRecursivePass +{ + use PriorityTaggedServiceTrait; + + protected function processValue($value, $isRoot = false) + { + if ($value instanceof ServiceLocatorArgument) { + if ($value->getTaggedIteratorArgument()) { + $value->setValues($this->findAndSortTaggedServices($value->getTaggedIteratorArgument(), $this->container)); + } + + return self::register($this->container, $value->getValues()); + } + + if (!$value instanceof Definition || !$value->hasTag('container.service_locator')) { + return parent::processValue($value, $isRoot); + } + + if (!$value->getClass()) { + $value->setClass(ServiceLocator::class); + } + + $arguments = $value->getArguments(); + if (!isset($arguments[0]) || !\is_array($arguments[0])) { + throw new InvalidArgumentException(sprintf('Invalid definition for service "%s": an array of references is expected as first argument when the "container.service_locator" tag is set.', $this->currentId)); + } + + $i = 0; + + foreach ($arguments[0] as $k => $v) { + if ($v instanceof ServiceClosureArgument) { + continue; + } + if (!$v instanceof Reference) { + throw new InvalidArgumentException(sprintf('Invalid definition for service "%s": an array of references is expected as first argument when the "container.service_locator" tag is set, "%s" found for key "%s".', $this->currentId, \is_object($v) ? \get_class($v) : \gettype($v), $k)); + } + + if ($i === $k) { + unset($arguments[0][$k]); + + $k = (string) $v; + ++$i; + } elseif (\is_int($k)) { + $i = null; + } + $arguments[0][$k] = new ServiceClosureArgument($v); + } + ksort($arguments[0]); + + $value->setArguments($arguments); + + $id = '.service_locator.'.ContainerBuilder::hash($value); + + if ($isRoot) { + if ($id !== $this->currentId) { + $this->container->setAlias($id, new Alias($this->currentId, false)); + } + + return $value; + } + + $this->container->setDefinition($id, $value->setPublic(false)); + + return new Reference($id); + } + + /** + * @param Reference[] $refMap + */ + public static function register(ContainerBuilder $container, array $refMap, string $callerId = null): Reference + { + foreach ($refMap as $id => $ref) { + if (!$ref instanceof Reference) { + throw new InvalidArgumentException(sprintf('Invalid service locator definition: only services can be referenced, "%s" found for key "%s". Inject parameter values using constructors instead.', \is_object($ref) ? \get_class($ref) : \gettype($ref), $id)); + } + $refMap[$id] = new ServiceClosureArgument($ref); + } + ksort($refMap); + + $locator = (new Definition(ServiceLocator::class)) + ->addArgument($refMap) + ->setPublic(false) + ->addTag('container.service_locator'); + + if (null !== $callerId && $container->hasDefinition($callerId)) { + $locator->setBindings($container->getDefinition($callerId)->getBindings()); + } + + if (!$container->hasDefinition($id = '.service_locator.'.ContainerBuilder::hash($locator))) { + $container->setDefinition($id, $locator); + } + + if (null !== $callerId) { + $locatorId = $id; + // Locators are shared when they hold the exact same list of factories; + // to have them specialized per consumer service, we use a cloning factory + // to derivate customized instances from the prototype one. + $container->register($id .= '.'.$callerId, ServiceLocator::class) + ->setPublic(false) + ->setFactory([new Reference($locatorId), 'withContext']) + ->addTag('container.service_locator_context', ['id' => $callerId]) + ->addArgument($callerId) + ->addArgument(new Reference('service_container')); + } + + return new Reference($id); + } +} diff --git a/srcs/phpmyadmin/vendor/symfony/dependency-injection/Compiler/ServiceReferenceGraph.php b/srcs/phpmyadmin/vendor/symfony/dependency-injection/Compiler/ServiceReferenceGraph.php new file mode 100644 index 0000000..308abc6 --- /dev/null +++ b/srcs/phpmyadmin/vendor/symfony/dependency-injection/Compiler/ServiceReferenceGraph.php @@ -0,0 +1,98 @@ +<?php + +/* + * This file is part of the Symfony package. + * + * (c) Fabien Potencier <fabien@symfony.com> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection\Compiler; + +use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException; + +/** + * This is a directed graph of your services. + * + * This information can be used by your compiler passes instead of collecting + * it themselves which improves performance quite a lot. + * + * @author Johannes M. Schmitt <schmittjoh@gmail.com> + * + * @final + */ +class ServiceReferenceGraph +{ + /** + * @var ServiceReferenceGraphNode[] + */ + private $nodes = []; + + public function hasNode(string $id): bool + { + return isset($this->nodes[$id]); + } + + /** + * Gets a node by identifier. + * + * @throws InvalidArgumentException if no node matches the supplied identifier + */ + public function getNode(string $id): ServiceReferenceGraphNode + { + if (!isset($this->nodes[$id])) { + throw new InvalidArgumentException(sprintf('There is no node with id "%s".', $id)); + } + + return $this->nodes[$id]; + } + + /** + * Returns all nodes. + * + * @return ServiceReferenceGraphNode[] + */ + public function getNodes(): array + { + return $this->nodes; + } + + /** + * Clears all nodes. + */ + public function clear() + { + foreach ($this->nodes as $node) { + $node->clear(); + } + $this->nodes = []; + } + + /** + * Connects 2 nodes together in the Graph. + */ + public function connect(?string $sourceId, $sourceValue, ?string $destId, $destValue = null, $reference = null, bool $lazy = false, bool $weak = false, bool $byConstructor = false) + { + if (null === $sourceId || null === $destId) { + return; + } + + $sourceNode = $this->createNode($sourceId, $sourceValue); + $destNode = $this->createNode($destId, $destValue); + $edge = new ServiceReferenceGraphEdge($sourceNode, $destNode, $reference, $lazy, $weak, $byConstructor); + + $sourceNode->addOutEdge($edge); + $destNode->addInEdge($edge); + } + + private function createNode(string $id, $value): ServiceReferenceGraphNode + { + if (isset($this->nodes[$id]) && $this->nodes[$id]->getValue() === $value) { + return $this->nodes[$id]; + } + + return $this->nodes[$id] = new ServiceReferenceGraphNode($id, $value); + } +} diff --git a/srcs/phpmyadmin/vendor/symfony/dependency-injection/Compiler/ServiceReferenceGraphEdge.php b/srcs/phpmyadmin/vendor/symfony/dependency-injection/Compiler/ServiceReferenceGraphEdge.php new file mode 100644 index 0000000..9861456 --- /dev/null +++ b/srcs/phpmyadmin/vendor/symfony/dependency-injection/Compiler/ServiceReferenceGraphEdge.php @@ -0,0 +1,99 @@ +<?php + +/* + * This file is part of the Symfony package. + * + * (c) Fabien Potencier <fabien@symfony.com> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection\Compiler; + +/** + * Represents an edge in your service graph. + * + * Value is typically a reference. + * + * @author Johannes M. Schmitt <schmittjoh@gmail.com> + */ +class ServiceReferenceGraphEdge +{ + private $sourceNode; + private $destNode; + private $value; + private $lazy; + private $weak; + private $byConstructor; + + public function __construct(ServiceReferenceGraphNode $sourceNode, ServiceReferenceGraphNode $destNode, $value = null, bool $lazy = false, bool $weak = false, bool $byConstructor = false) + { + $this->sourceNode = $sourceNode; + $this->destNode = $destNode; + $this->value = $value; + $this->lazy = $lazy; + $this->weak = $weak; + $this->byConstructor = $byConstructor; + } + + /** + * Returns the value of the edge. + * + * @return mixed + */ + public function getValue() + { + return $this->value; + } + + /** + * Returns the source node. + * + * @return ServiceReferenceGraphNode + */ + public function getSourceNode() + { + return $this->sourceNode; + } + + /** + * Returns the destination node. + * + * @return ServiceReferenceGraphNode + */ + public function getDestNode() + { + return $this->destNode; + } + + /** + * Returns true if the edge is lazy, meaning it's a dependency not requiring direct instantiation. + * + * @return bool + */ + public function isLazy() + { + return $this->lazy; + } + + /** + * Returns true if the edge is weak, meaning it shouldn't prevent removing the target service. + * + * @return bool + */ + public function isWeak() + { + return $this->weak; + } + + /** + * Returns true if the edge links with a constructor argument. + * + * @return bool + */ + public function isReferencedByConstructor() + { + return $this->byConstructor; + } +} diff --git a/srcs/phpmyadmin/vendor/symfony/dependency-injection/Compiler/ServiceReferenceGraphNode.php b/srcs/phpmyadmin/vendor/symfony/dependency-injection/Compiler/ServiceReferenceGraphNode.php new file mode 100644 index 0000000..fec1424 --- /dev/null +++ b/srcs/phpmyadmin/vendor/symfony/dependency-injection/Compiler/ServiceReferenceGraphNode.php @@ -0,0 +1,118 @@ +<?php + +/* + * This file is part of the Symfony package. + * + * (c) Fabien Potencier <fabien@symfony.com> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection\Compiler; + +use Symfony\Component\DependencyInjection\Alias; +use Symfony\Component\DependencyInjection\Definition; + +/** + * Represents a node in your service graph. + * + * Value is typically a definition, or an alias. + * + * @author Johannes M. Schmitt <schmittjoh@gmail.com> + */ +class ServiceReferenceGraphNode +{ + private $id; + private $inEdges = []; + private $outEdges = []; + private $value; + + /** + * @param string $id The node identifier + * @param mixed $value The node value + */ + public function __construct(string $id, $value) + { + $this->id = $id; + $this->value = $value; + } + + public function addInEdge(ServiceReferenceGraphEdge $edge) + { + $this->inEdges[] = $edge; + } + + public function addOutEdge(ServiceReferenceGraphEdge $edge) + { + $this->outEdges[] = $edge; + } + + /** + * Checks if the value of this node is an Alias. + * + * @return bool True if the value is an Alias instance + */ + public function isAlias() + { + return $this->value instanceof Alias; + } + + /** + * Checks if the value of this node is a Definition. + * + * @return bool True if the value is a Definition instance + */ + public function isDefinition() + { + return $this->value instanceof Definition; + } + + /** + * Returns the identifier. + * + * @return string + */ + public function getId() + { + return $this->id; + } + + /** + * Returns the in edges. + * + * @return ServiceReferenceGraphEdge[] + */ + public function getInEdges() + { + return $this->inEdges; + } + + /** + * Returns the out edges. + * + * @return ServiceReferenceGraphEdge[] + */ + public function getOutEdges() + { + return $this->outEdges; + } + + /** + * Returns the value of this Node. + * + * @return mixed The value + */ + public function getValue() + { + return $this->value; + } + + /** + * Clears all edges. + */ + public function clear() + { + $this->inEdges = $this->outEdges = []; + } +} diff --git a/srcs/phpmyadmin/vendor/symfony/dependency-injection/Compiler/ValidateEnvPlaceholdersPass.php b/srcs/phpmyadmin/vendor/symfony/dependency-injection/Compiler/ValidateEnvPlaceholdersPass.php new file mode 100644 index 0000000..8fd84fa --- /dev/null +++ b/srcs/phpmyadmin/vendor/symfony/dependency-injection/Compiler/ValidateEnvPlaceholdersPass.php @@ -0,0 +1,120 @@ +<?php + +/* + * This file is part of the Symfony package. + * + * (c) Fabien Potencier <fabien@symfony.com> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection\Compiler; + +use Symfony\Component\Config\Definition\BaseNode; +use Symfony\Component\Config\Definition\Exception\TreeWithoutRootNodeException; +use Symfony\Component\Config\Definition\Processor; +use Symfony\Component\DependencyInjection\ContainerBuilder; +use Symfony\Component\DependencyInjection\Extension\ConfigurationExtensionInterface; +use Symfony\Component\DependencyInjection\ParameterBag\EnvPlaceholderParameterBag; +use Symfony\Component\DependencyInjection\ParameterBag\ParameterBag; + +/** + * Validates environment variable placeholders used in extension configuration with dummy values. + * + * @author Roland Franssen <franssen.roland@gmail.com> + */ +class ValidateEnvPlaceholdersPass implements CompilerPassInterface +{ + private static $typeFixtures = ['array' => [], 'bool' => false, 'float' => 0.0, 'int' => 0, 'string' => '']; + + private $extensionConfig = []; + + /** + * {@inheritdoc} + */ + public function process(ContainerBuilder $container) + { + $this->extensionConfig = []; + + if (!class_exists(BaseNode::class) || !$extensions = $container->getExtensions()) { + return; + } + + $resolvingBag = $container->getParameterBag(); + if (!$resolvingBag instanceof EnvPlaceholderParameterBag) { + return; + } + + $defaultBag = new ParameterBag($resolvingBag->all()); + $envTypes = $resolvingBag->getProvidedTypes(); + try { + foreach ($resolvingBag->getEnvPlaceholders() + $resolvingBag->getUnusedEnvPlaceholders() as $env => $placeholders) { + $values = []; + if (false === $i = strpos($env, ':')) { + $default = $defaultBag->has("env($env)") ? $defaultBag->get("env($env)") : self::$typeFixtures['string']; + $defaultType = null !== $default ? self::getType($default) : 'string'; + $values[$defaultType] = $default; + } else { + $prefix = substr($env, 0, $i); + foreach ($envTypes[$prefix] ?? ['string'] as $type) { + $values[$type] = self::$typeFixtures[$type] ?? null; + } + } + foreach ($placeholders as $placeholder) { + BaseNode::setPlaceholder($placeholder, $values); + } + } + + $processor = new Processor(); + + foreach ($extensions as $name => $extension) { + if (!$extension instanceof ConfigurationExtensionInterface || !$config = array_filter($container->getExtensionConfig($name))) { + // this extension has no semantic configuration or was not called + continue; + } + + $config = $resolvingBag->resolveValue($config); + + if (null === $configuration = $extension->getConfiguration($config, $container)) { + continue; + } + + try { + $this->extensionConfig[$name] = $processor->processConfiguration($configuration, $config); + } catch (TreeWithoutRootNodeException $e) { + } + } + } finally { + BaseNode::resetPlaceholders(); + } + + $resolvingBag->clearUnusedEnvPlaceholders(); + } + + /** + * @internal + */ + public function getExtensionConfig(): array + { + try { + return $this->extensionConfig; + } finally { + $this->extensionConfig = []; + } + } + + private static function getType($value): string + { + switch ($type = \gettype($value)) { + case 'boolean': + return 'bool'; + case 'double': + return 'float'; + case 'integer': + return 'int'; + } + + return $type; + } +} diff --git a/srcs/phpmyadmin/vendor/symfony/dependency-injection/Config/ContainerParametersResource.php b/srcs/phpmyadmin/vendor/symfony/dependency-injection/Config/ContainerParametersResource.php new file mode 100644 index 0000000..e9a4fff --- /dev/null +++ b/srcs/phpmyadmin/vendor/symfony/dependency-injection/Config/ContainerParametersResource.php @@ -0,0 +1,50 @@ +<?php + +/* + * This file is part of the Symfony package. + * + * (c) Fabien Potencier <fabien@symfony.com> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection\Config; + +use Symfony\Component\Config\Resource\ResourceInterface; + +/** + * Tracks container parameters. + * + * @author Maxime Steinhausser <maxime.steinhausser@gmail.com> + * + * @final since Symfony 4.3 + */ +class ContainerParametersResource implements ResourceInterface +{ + private $parameters; + + /** + * @param array $parameters The container parameters to track + */ + public function __construct(array $parameters) + { + $this->parameters = $parameters; + } + + /** + * {@inheritdoc} + */ + public function __toString() + { + return 'container_parameters_'.md5(serialize($this->parameters)); + } + + /** + * @return array Tracked parameters + */ + public function getParameters() + { + return $this->parameters; + } +} diff --git a/srcs/phpmyadmin/vendor/symfony/dependency-injection/Config/ContainerParametersResourceChecker.php b/srcs/phpmyadmin/vendor/symfony/dependency-injection/Config/ContainerParametersResourceChecker.php new file mode 100644 index 0000000..6ed77e3 --- /dev/null +++ b/srcs/phpmyadmin/vendor/symfony/dependency-injection/Config/ContainerParametersResourceChecker.php @@ -0,0 +1,52 @@ +<?php + +/* + * This file is part of the Symfony package. + * + * (c) Fabien Potencier <fabien@symfony.com> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection\Config; + +use Symfony\Component\Config\Resource\ResourceInterface; +use Symfony\Component\Config\ResourceCheckerInterface; +use Symfony\Component\DependencyInjection\ContainerInterface; + +/** + * @author Maxime Steinhausser <maxime.steinhausser@gmail.com> + */ +class ContainerParametersResourceChecker implements ResourceCheckerInterface +{ + /** @var ContainerInterface */ + private $container; + + public function __construct(ContainerInterface $container) + { + $this->container = $container; + } + + /** + * {@inheritdoc} + */ + public function supports(ResourceInterface $metadata) + { + return $metadata instanceof ContainerParametersResource; + } + + /** + * {@inheritdoc} + */ + public function isFresh(ResourceInterface $resource, $timestamp) + { + foreach ($resource->getParameters() as $key => $value) { + if (!$this->container->hasParameter($key) || $this->container->getParameter($key) !== $value) { + return false; + } + } + + return true; + } +} diff --git a/srcs/phpmyadmin/vendor/symfony/dependency-injection/Container.php b/srcs/phpmyadmin/vendor/symfony/dependency-injection/Container.php new file mode 100644 index 0000000..00bacd2 --- /dev/null +++ b/srcs/phpmyadmin/vendor/symfony/dependency-injection/Container.php @@ -0,0 +1,456 @@ +<?php + +/* + * This file is part of the Symfony package. + * + * (c) Fabien Potencier <fabien@symfony.com> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection; + +use Symfony\Component\DependencyInjection\Exception\EnvNotFoundException; +use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException; +use Symfony\Component\DependencyInjection\Exception\ParameterCircularReferenceException; +use Symfony\Component\DependencyInjection\Exception\RuntimeException; +use Symfony\Component\DependencyInjection\Exception\ServiceCircularReferenceException; +use Symfony\Component\DependencyInjection\Exception\ServiceNotFoundException; +use Symfony\Component\DependencyInjection\ParameterBag\EnvPlaceholderParameterBag; +use Symfony\Component\DependencyInjection\ParameterBag\FrozenParameterBag; +use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface; +use Symfony\Contracts\Service\ResetInterface; + +/** + * Container is a dependency injection container. + * + * It gives access to object instances (services). + * Services and parameters are simple key/pair stores. + * The container can have four possible behaviors when a service + * does not exist (or is not initialized for the last case): + * + * * EXCEPTION_ON_INVALID_REFERENCE: Throws an exception (the default) + * * NULL_ON_INVALID_REFERENCE: Returns null + * * IGNORE_ON_INVALID_REFERENCE: Ignores the wrapping command asking for the reference + * (for instance, ignore a setter if the service does not exist) + * * IGNORE_ON_UNINITIALIZED_REFERENCE: Ignores/returns null for uninitialized services or invalid references + * + * @author Fabien Potencier <fabien@symfony.com> + * @author Johannes M. Schmitt <schmittjoh@gmail.com> + */ +class Container implements ResettableContainerInterface +{ + protected $parameterBag; + protected $services = []; + protected $privates = []; + protected $fileMap = []; + protected $methodMap = []; + protected $factories = []; + protected $aliases = []; + protected $loading = []; + protected $resolving = []; + protected $syntheticIds = []; + + private $envCache = []; + private $compiled = false; + private $getEnv; + + public function __construct(ParameterBagInterface $parameterBag = null) + { + $this->parameterBag = $parameterBag ?: new EnvPlaceholderParameterBag(); + } + + /** + * Compiles the container. + * + * This method does two things: + * + * * Parameter values are resolved; + * * The parameter bag is frozen. + */ + public function compile() + { + $this->parameterBag->resolve(); + + $this->parameterBag = new FrozenParameterBag($this->parameterBag->all()); + + $this->compiled = true; + } + + /** + * Returns true if the container is compiled. + * + * @return bool + */ + public function isCompiled() + { + return $this->compiled; + } + + /** + * Gets the service container parameter bag. + * + * @return ParameterBagInterface A ParameterBagInterface instance + */ + public function getParameterBag() + { + return $this->parameterBag; + } + + /** + * Gets a parameter. + * + * @param string $name The parameter name + * + * @return mixed The parameter value + * + * @throws InvalidArgumentException if the parameter is not defined + */ + public function getParameter($name) + { + return $this->parameterBag->get($name); + } + + /** + * Checks if a parameter exists. + * + * @param string $name The parameter name + * + * @return bool The presence of parameter in container + */ + public function hasParameter($name) + { + return $this->parameterBag->has($name); + } + + /** + * Sets a parameter. + * + * @param string $name The parameter name + * @param mixed $value The parameter value + */ + public function setParameter($name, $value) + { + $this->parameterBag->set($name, $value); + } + + /** + * Sets a service. + * + * Setting a synthetic service to null resets it: has() returns false and get() + * behaves in the same way as if the service was never created. + * + * @param string $id The service identifier + * @param object|null $service The service instance + */ + public function set($id, $service) + { + // Runs the internal initializer; used by the dumped container to include always-needed files + if (isset($this->privates['service_container']) && $this->privates['service_container'] instanceof \Closure) { + $initialize = $this->privates['service_container']; + unset($this->privates['service_container']); + $initialize(); + } + + if ('service_container' === $id) { + throw new InvalidArgumentException('You cannot set service "service_container".'); + } + + if (!(isset($this->fileMap[$id]) || isset($this->methodMap[$id]))) { + if (isset($this->syntheticIds[$id]) || !isset($this->getRemovedIds()[$id])) { + // no-op + } elseif (null === $service) { + throw new InvalidArgumentException(sprintf('The "%s" service is private, you cannot unset it.', $id)); + } else { + throw new InvalidArgumentException(sprintf('The "%s" service is private, you cannot replace it.', $id)); + } + } elseif (isset($this->services[$id])) { + throw new InvalidArgumentException(sprintf('The "%s" service is already initialized, you cannot replace it.', $id)); + } + + if (isset($this->aliases[$id])) { + unset($this->aliases[$id]); + } + + if (null === $service) { + unset($this->services[$id]); + + return; + } + + $this->services[$id] = $service; + } + + /** + * Returns true if the given service is defined. + * + * @param string $id The service identifier + * + * @return bool true if the service is defined, false otherwise + */ + public function has($id) + { + if (isset($this->aliases[$id])) { + $id = $this->aliases[$id]; + } + if (isset($this->services[$id])) { + return true; + } + if ('service_container' === $id) { + return true; + } + + return isset($this->fileMap[$id]) || isset($this->methodMap[$id]); + } + + /** + * Gets a service. + * + * @param string $id The service identifier + * @param int $invalidBehavior The behavior when the service does not exist + * + * @return object|null The associated service + * + * @throws ServiceCircularReferenceException When a circular reference is detected + * @throws ServiceNotFoundException When the service is not defined + * @throws \Exception if an exception has been thrown when the service has been resolved + * + * @see Reference + */ + public function get($id, $invalidBehavior = /* self::EXCEPTION_ON_INVALID_REFERENCE */ 1) + { + $service = $this->services[$id] + ?? $this->services[$id = $this->aliases[$id] ?? $id] + ?? ('service_container' === $id ? $this : ($this->factories[$id] ?? [$this, 'make'])($id, $invalidBehavior)); + + if (!\is_object($service) && null !== $service) { + @trigger_error(sprintf('Non-object services are deprecated since Symfony 4.4, please fix the "%s" service which is of type "%s" right now.', $id, \gettype($service)), E_USER_DEPRECATED); + } + + return $service; + } + + /** + * Creates a service. + * + * As a separate method to allow "get()" to use the really fast `??` operator. + */ + private function make(string $id, int $invalidBehavior) + { + if (isset($this->loading[$id])) { + throw new ServiceCircularReferenceException($id, array_merge(array_keys($this->loading), [$id])); + } + + $this->loading[$id] = true; + + try { + if (isset($this->fileMap[$id])) { + return /* self::IGNORE_ON_UNINITIALIZED_REFERENCE */ 4 === $invalidBehavior ? null : $this->load($this->fileMap[$id]); + } elseif (isset($this->methodMap[$id])) { + return /* self::IGNORE_ON_UNINITIALIZED_REFERENCE */ 4 === $invalidBehavior ? null : $this->{$this->methodMap[$id]}(); + } + } catch (\Exception $e) { + unset($this->services[$id]); + + throw $e; + } finally { + unset($this->loading[$id]); + } + + if (/* self::EXCEPTION_ON_INVALID_REFERENCE */ 1 === $invalidBehavior) { + if (!$id) { + throw new ServiceNotFoundException($id); + } + if (isset($this->syntheticIds[$id])) { + throw new ServiceNotFoundException($id, null, null, [], sprintf('The "%s" service is synthetic, it needs to be set at boot time before it can be used.', $id)); + } + if (isset($this->getRemovedIds()[$id])) { + throw new ServiceNotFoundException($id, null, null, [], sprintf('The "%s" service or alias has been removed or inlined when the container was compiled. You should either make it public, or stop using the container directly and use dependency injection instead.', $id)); + } + + $alternatives = []; + foreach ($this->getServiceIds() as $knownId) { + if ('' === $knownId || '.' === $knownId[0]) { + continue; + } + $lev = levenshtein($id, $knownId); + if ($lev <= \strlen($id) / 3 || false !== strpos($knownId, $id)) { + $alternatives[] = $knownId; + } + } + + throw new ServiceNotFoundException($id, null, null, $alternatives); + } + + return null; + } + + /** + * Returns true if the given service has actually been initialized. + * + * @param string $id The service identifier + * + * @return bool true if service has already been initialized, false otherwise + */ + public function initialized($id) + { + if (isset($this->aliases[$id])) { + $id = $this->aliases[$id]; + } + + if ('service_container' === $id) { + return false; + } + + return isset($this->services[$id]); + } + + /** + * {@inheritdoc} + */ + public function reset() + { + $services = $this->services + $this->privates; + $this->services = $this->factories = $this->privates = []; + + foreach ($services as $service) { + try { + if ($service instanceof ResetInterface) { + $service->reset(); + } + } catch (\Throwable $e) { + continue; + } + } + } + + /** + * Gets all service ids. + * + * @return string[] An array of all defined service ids + */ + public function getServiceIds() + { + return array_map('strval', array_unique(array_merge(['service_container'], array_keys($this->fileMap), array_keys($this->methodMap), array_keys($this->aliases), array_keys($this->services)))); + } + + /** + * Gets service ids that existed at compile time. + * + * @return array + */ + public function getRemovedIds() + { + return []; + } + + /** + * Camelizes a string. + * + * @param string $id A string to camelize + * + * @return string The camelized string + */ + public static function camelize($id) + { + return strtr(ucwords(strtr($id, ['_' => ' ', '.' => '_ ', '\\' => '_ '])), [' ' => '']); + } + + /** + * A string to underscore. + * + * @param string $id The string to underscore + * + * @return string The underscored string + */ + public static function underscore($id) + { + return strtolower(preg_replace(['/([A-Z]+)([A-Z][a-z])/', '/([a-z\d])([A-Z])/'], ['\\1_\\2', '\\1_\\2'], str_replace('_', '.', $id))); + } + + /** + * Creates a service by requiring its factory file. + */ + protected function load($file) + { + return require $file; + } + + /** + * Fetches a variable from the environment. + * + * @param string $name The name of the environment variable + * + * @return mixed The value to use for the provided environment variable name + * + * @throws EnvNotFoundException When the environment variable is not found and has no default value + */ + protected function getEnv($name) + { + if (isset($this->resolving[$envName = "env($name)"])) { + throw new ParameterCircularReferenceException(array_keys($this->resolving)); + } + if (isset($this->envCache[$name]) || \array_key_exists($name, $this->envCache)) { + return $this->envCache[$name]; + } + if (!$this->has($id = 'container.env_var_processors_locator')) { + $this->set($id, new ServiceLocator([])); + } + if (!$this->getEnv) { + $this->getEnv = new \ReflectionMethod($this, __FUNCTION__); + $this->getEnv->setAccessible(true); + $this->getEnv = $this->getEnv->getClosure($this); + } + $processors = $this->get($id); + + if (false !== $i = strpos($name, ':')) { + $prefix = substr($name, 0, $i); + $localName = substr($name, 1 + $i); + } else { + $prefix = 'string'; + $localName = $name; + } + $processor = $processors->has($prefix) ? $processors->get($prefix) : new EnvVarProcessor($this); + + $this->resolving[$envName] = true; + try { + return $this->envCache[$name] = $processor->getEnv($prefix, $localName, $this->getEnv); + } finally { + unset($this->resolving[$envName]); + } + } + + /** + * @param string|false $registry + * @param string|bool $load + * + * @return mixed + * + * @internal + */ + final protected function getService($registry, string $id, ?string $method, $load) + { + if ('service_container' === $id) { + return $this; + } + if (\is_string($load)) { + throw new RuntimeException($load); + } + if (null === $method) { + return false !== $registry ? $this->{$registry}[$id] ?? null : null; + } + if (false !== $registry) { + return $this->{$registry}[$id] ?? $this->{$registry}[$id] = $load ? $this->load($method) : $this->{$method}(); + } + if (!$load) { + return $this->{$method}(); + } + + return ($factory = $this->factories[$id] ?? $this->factories['service_container'][$id] ?? null) ? $factory() : $this->load($method); + } + + private function __clone() + { + } +} diff --git a/srcs/phpmyadmin/vendor/symfony/dependency-injection/ContainerAwareInterface.php b/srcs/phpmyadmin/vendor/symfony/dependency-injection/ContainerAwareInterface.php new file mode 100644 index 0000000..e7b9d57 --- /dev/null +++ b/srcs/phpmyadmin/vendor/symfony/dependency-injection/ContainerAwareInterface.php @@ -0,0 +1,25 @@ +<?php + +/* + * This file is part of the Symfony package. + * + * (c) Fabien Potencier <fabien@symfony.com> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection; + +/** + * ContainerAwareInterface should be implemented by classes that depends on a Container. + * + * @author Fabien Potencier <fabien@symfony.com> + */ +interface ContainerAwareInterface +{ + /** + * Sets the container. + */ + public function setContainer(ContainerInterface $container = null); +} diff --git a/srcs/phpmyadmin/vendor/symfony/dependency-injection/ContainerAwareTrait.php b/srcs/phpmyadmin/vendor/symfony/dependency-injection/ContainerAwareTrait.php new file mode 100644 index 0000000..ee1ea2c --- /dev/null +++ b/srcs/phpmyadmin/vendor/symfony/dependency-injection/ContainerAwareTrait.php @@ -0,0 +1,30 @@ +<?php + +/* + * This file is part of the Symfony package. + * + * (c) Fabien Potencier <fabien@symfony.com> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection; + +/** + * ContainerAware trait. + * + * @author Fabien Potencier <fabien@symfony.com> + */ +trait ContainerAwareTrait +{ + /** + * @var ContainerInterface + */ + protected $container; + + public function setContainer(ContainerInterface $container = null) + { + $this->container = $container; + } +} diff --git a/srcs/phpmyadmin/vendor/symfony/dependency-injection/ContainerBuilder.php b/srcs/phpmyadmin/vendor/symfony/dependency-injection/ContainerBuilder.php new file mode 100644 index 0000000..247a021 --- /dev/null +++ b/srcs/phpmyadmin/vendor/symfony/dependency-injection/ContainerBuilder.php @@ -0,0 +1,1672 @@ +<?php + +/* + * This file is part of the Symfony package. + * + * (c) Fabien Potencier <fabien@symfony.com> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection; + +use Psr\Container\ContainerInterface as PsrContainerInterface; +use Symfony\Component\Config\Resource\ClassExistenceResource; +use Symfony\Component\Config\Resource\ComposerResource; +use Symfony\Component\Config\Resource\DirectoryResource; +use Symfony\Component\Config\Resource\FileExistenceResource; +use Symfony\Component\Config\Resource\FileResource; +use Symfony\Component\Config\Resource\GlobResource; +use Symfony\Component\Config\Resource\ReflectionClassResource; +use Symfony\Component\Config\Resource\ResourceInterface; +use Symfony\Component\DependencyInjection\Argument\IteratorArgument; +use Symfony\Component\DependencyInjection\Argument\RewindableGenerator; +use Symfony\Component\DependencyInjection\Argument\ServiceClosureArgument; +use Symfony\Component\DependencyInjection\Argument\ServiceLocator; +use Symfony\Component\DependencyInjection\Argument\ServiceLocatorArgument; +use Symfony\Component\DependencyInjection\Compiler\Compiler; +use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface; +use Symfony\Component\DependencyInjection\Compiler\PassConfig; +use Symfony\Component\DependencyInjection\Compiler\ResolveEnvPlaceholdersPass; +use Symfony\Component\DependencyInjection\Exception\BadMethodCallException; +use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException; +use Symfony\Component\DependencyInjection\Exception\LogicException; +use Symfony\Component\DependencyInjection\Exception\RuntimeException; +use Symfony\Component\DependencyInjection\Exception\ServiceCircularReferenceException; +use Symfony\Component\DependencyInjection\Exception\ServiceNotFoundException; +use Symfony\Component\DependencyInjection\Extension\ExtensionInterface; +use Symfony\Component\DependencyInjection\LazyProxy\Instantiator\InstantiatorInterface; +use Symfony\Component\DependencyInjection\LazyProxy\Instantiator\RealServiceInstantiator; +use Symfony\Component\DependencyInjection\ParameterBag\EnvPlaceholderParameterBag; +use Symfony\Component\DependencyInjection\ParameterBag\ParameterBag; +use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface; +use Symfony\Component\ExpressionLanguage\Expression; +use Symfony\Component\ExpressionLanguage\ExpressionFunctionProviderInterface; + +/** + * ContainerBuilder is a DI container that provides an API to easily describe services. + * + * @author Fabien Potencier <fabien@symfony.com> + */ +class ContainerBuilder extends Container implements TaggedContainerInterface +{ + /** + * @var ExtensionInterface[] + */ + private $extensions = []; + + /** + * @var ExtensionInterface[] + */ + private $extensionsByNs = []; + + /** + * @var Definition[] + */ + private $definitions = []; + + /** + * @var Alias[] + */ + private $aliasDefinitions = []; + + /** + * @var ResourceInterface[] + */ + private $resources = []; + + private $extensionConfigs = []; + + /** + * @var Compiler + */ + private $compiler; + + private $trackResources; + + /** + * @var InstantiatorInterface|null + */ + private $proxyInstantiator; + + /** + * @var ExpressionLanguage|null + */ + private $expressionLanguage; + + /** + * @var ExpressionFunctionProviderInterface[] + */ + private $expressionLanguageProviders = []; + + /** + * @var string[] with tag names used by findTaggedServiceIds + */ + private $usedTags = []; + + /** + * @var string[][] a map of env var names to their placeholders + */ + private $envPlaceholders = []; + + /** + * @var int[] a map of env vars to their resolution counter + */ + private $envCounters = []; + + /** + * @var string[] the list of vendor directories + */ + private $vendors; + + private $autoconfiguredInstanceof = []; + + private $removedIds = []; + + private $removedBindingIds = []; + + private static $internalTypes = [ + 'int' => true, + 'float' => true, + 'string' => true, + 'bool' => true, + 'resource' => true, + 'object' => true, + 'array' => true, + 'null' => true, + 'callable' => true, + 'iterable' => true, + 'mixed' => true, + ]; + + public function __construct(ParameterBagInterface $parameterBag = null) + { + parent::__construct($parameterBag); + + $this->trackResources = interface_exists('Symfony\Component\Config\Resource\ResourceInterface'); + $this->setDefinition('service_container', (new Definition(ContainerInterface::class))->setSynthetic(true)->setPublic(true)); + $this->setAlias(PsrContainerInterface::class, new Alias('service_container', false)); + $this->setAlias(ContainerInterface::class, new Alias('service_container', false)); + } + + /** + * @var \ReflectionClass[] a list of class reflectors + */ + private $classReflectors; + + /** + * Sets the track resources flag. + * + * If you are not using the loaders and therefore don't want + * to depend on the Config component, set this flag to false. + * + * @param bool $track True if you want to track resources, false otherwise + */ + public function setResourceTracking($track) + { + $this->trackResources = (bool) $track; + } + + /** + * Checks if resources are tracked. + * + * @return bool true If resources are tracked, false otherwise + */ + public function isTrackingResources() + { + return $this->trackResources; + } + + /** + * Sets the instantiator to be used when fetching proxies. + */ + public function setProxyInstantiator(InstantiatorInterface $proxyInstantiator) + { + $this->proxyInstantiator = $proxyInstantiator; + } + + public function registerExtension(ExtensionInterface $extension) + { + $this->extensions[$extension->getAlias()] = $extension; + + if (false !== $extension->getNamespace()) { + $this->extensionsByNs[$extension->getNamespace()] = $extension; + } + } + + /** + * Returns an extension by alias or namespace. + * + * @param string $name An alias or a namespace + * + * @return ExtensionInterface An extension instance + * + * @throws LogicException if the extension is not registered + */ + public function getExtension($name) + { + if (isset($this->extensions[$name])) { + return $this->extensions[$name]; + } + + if (isset($this->extensionsByNs[$name])) { + return $this->extensionsByNs[$name]; + } + + throw new LogicException(sprintf('Container extension "%s" is not registered', $name)); + } + + /** + * Returns all registered extensions. + * + * @return ExtensionInterface[] An array of ExtensionInterface + */ + public function getExtensions() + { + return $this->extensions; + } + + /** + * Checks if we have an extension. + * + * @param string $name The name of the extension + * + * @return bool If the extension exists + */ + public function hasExtension($name) + { + return isset($this->extensions[$name]) || isset($this->extensionsByNs[$name]); + } + + /** + * Returns an array of resources loaded to build this configuration. + * + * @return ResourceInterface[] An array of resources + */ + public function getResources() + { + return array_values($this->resources); + } + + /** + * @return $this + */ + public function addResource(ResourceInterface $resource) + { + if (!$this->trackResources) { + return $this; + } + + if ($resource instanceof GlobResource && $this->inVendors($resource->getPrefix())) { + return $this; + } + + $this->resources[(string) $resource] = $resource; + + return $this; + } + + /** + * Sets the resources for this configuration. + * + * @param ResourceInterface[] $resources An array of resources + * + * @return $this + */ + public function setResources(array $resources) + { + if (!$this->trackResources) { + return $this; + } + + $this->resources = $resources; + + return $this; + } + + /** + * Adds the object class hierarchy as resources. + * + * @param object|string $object An object instance or class name + * + * @return $this + */ + public function addObjectResource($object) + { + if ($this->trackResources) { + if (\is_object($object)) { + $object = \get_class($object); + } + if (!isset($this->classReflectors[$object])) { + $this->classReflectors[$object] = new \ReflectionClass($object); + } + $class = $this->classReflectors[$object]; + + foreach ($class->getInterfaceNames() as $name) { + if (null === $interface = &$this->classReflectors[$name]) { + $interface = new \ReflectionClass($name); + } + $file = $interface->getFileName(); + if (false !== $file && file_exists($file)) { + $this->fileExists($file); + } + } + do { + $file = $class->getFileName(); + if (false !== $file && file_exists($file)) { + $this->fileExists($file); + } + foreach ($class->getTraitNames() as $name) { + $this->addObjectResource($name); + } + } while ($class = $class->getParentClass()); + } + + return $this; + } + + /** + * Retrieves the requested reflection class and registers it for resource tracking. + * + * @throws \ReflectionException when a parent class/interface/trait is not found and $throw is true + * + * @final + */ + public function getReflectionClass(?string $class, bool $throw = true): ?\ReflectionClass + { + if (!$class = $this->getParameterBag()->resolveValue($class)) { + return null; + } + + if (isset(self::$internalTypes[$class])) { + return null; + } + + $resource = $classReflector = null; + + try { + if (isset($this->classReflectors[$class])) { + $classReflector = $this->classReflectors[$class]; + } elseif (class_exists(ClassExistenceResource::class)) { + $resource = new ClassExistenceResource($class, false); + $classReflector = $resource->isFresh(0) ? false : new \ReflectionClass($class); + } else { + $classReflector = class_exists($class) ? new \ReflectionClass($class) : false; + } + } catch (\ReflectionException $e) { + if ($throw) { + throw $e; + } + } + + if ($this->trackResources) { + if (!$classReflector) { + $this->addResource($resource ?: new ClassExistenceResource($class, false)); + } elseif (!$classReflector->isInternal()) { + $path = $classReflector->getFileName(); + + if (!$this->inVendors($path)) { + $this->addResource(new ReflectionClassResource($classReflector, $this->vendors)); + } + } + $this->classReflectors[$class] = $classReflector; + } + + return $classReflector ?: null; + } + + /** + * Checks whether the requested file or directory exists and registers the result for resource tracking. + * + * @param string $path The file or directory path for which to check the existence + * @param bool|string $trackContents Whether to track contents of the given resource. If a string is passed, + * it will be used as pattern for tracking contents of the requested directory + * + * @final + */ + public function fileExists(string $path, $trackContents = true): bool + { + $exists = file_exists($path); + + if (!$this->trackResources || $this->inVendors($path)) { + return $exists; + } + + if (!$exists) { + $this->addResource(new FileExistenceResource($path)); + + return $exists; + } + + if (is_dir($path)) { + if ($trackContents) { + $this->addResource(new DirectoryResource($path, \is_string($trackContents) ? $trackContents : null)); + } else { + $this->addResource(new GlobResource($path, '/*', false)); + } + } elseif ($trackContents) { + $this->addResource(new FileResource($path)); + } + + return $exists; + } + + /** + * Loads the configuration for an extension. + * + * @param string $extension The extension alias or namespace + * @param array $values An array of values that customizes the extension + * + * @return $this + * + * @throws BadMethodCallException When this ContainerBuilder is compiled + * @throws \LogicException if the extension is not registered + */ + public function loadFromExtension($extension, array $values = null) + { + if ($this->isCompiled()) { + throw new BadMethodCallException('Cannot load from an extension on a compiled container.'); + } + + if (\func_num_args() < 2) { + $values = []; + } + + $namespace = $this->getExtension($extension)->getAlias(); + + $this->extensionConfigs[$namespace][] = $values; + + return $this; + } + + /** + * Adds a compiler pass. + * + * @param string $type The type of compiler pass + * @param int $priority Used to sort the passes + * + * @return $this + */ + public function addCompilerPass(CompilerPassInterface $pass, $type = PassConfig::TYPE_BEFORE_OPTIMIZATION, int $priority = 0) + { + $this->getCompiler()->addPass($pass, $type, $priority); + + $this->addObjectResource($pass); + + return $this; + } + + /** + * Returns the compiler pass config which can then be modified. + * + * @return PassConfig The compiler pass config + */ + public function getCompilerPassConfig() + { + return $this->getCompiler()->getPassConfig(); + } + + /** + * Returns the compiler. + * + * @return Compiler The compiler + */ + public function getCompiler() + { + if (null === $this->compiler) { + $this->compiler = new Compiler(); + } + + return $this->compiler; + } + + /** + * Sets a service. + * + * @param string $id The service identifier + * @param object|null $service The service instance + * + * @throws BadMethodCallException When this ContainerBuilder is compiled + */ + public function set($id, $service) + { + if (!\is_object($service) && null !== $service) { + @trigger_error(sprintf('Non-object services are deprecated since Symfony 4.4, setting the "%s" service to a value of type "%s" should be avoided.', $id, \gettype($service)), E_USER_DEPRECATED); + } + + $id = (string) $id; + + if ($this->isCompiled() && (isset($this->definitions[$id]) && !$this->definitions[$id]->isSynthetic())) { + // setting a synthetic service on a compiled container is alright + throw new BadMethodCallException(sprintf('Setting service "%s" for an unknown or non-synthetic service definition on a compiled container is not allowed.', $id)); + } + + unset($this->definitions[$id], $this->aliasDefinitions[$id], $this->removedIds[$id]); + + parent::set($id, $service); + } + + /** + * Removes a service definition. + * + * @param string $id The service identifier + */ + public function removeDefinition($id) + { + if (isset($this->definitions[$id = (string) $id])) { + unset($this->definitions[$id]); + $this->removedIds[$id] = true; + } + } + + /** + * Returns true if the given service is defined. + * + * @param string $id The service identifier + * + * @return bool true if the service is defined, false otherwise + */ + public function has($id) + { + $id = (string) $id; + + return isset($this->definitions[$id]) || isset($this->aliasDefinitions[$id]) || parent::has($id); + } + + /** + * Gets a service. + * + * @param string $id The service identifier + * @param int $invalidBehavior The behavior when the service does not exist + * + * @return object|null The associated service + * + * @throws InvalidArgumentException when no definitions are available + * @throws ServiceCircularReferenceException When a circular reference is detected + * @throws ServiceNotFoundException When the service is not defined + * @throws \Exception + * + * @see Reference + */ + public function get($id, $invalidBehavior = ContainerInterface::EXCEPTION_ON_INVALID_REFERENCE) + { + if ($this->isCompiled() && isset($this->removedIds[$id = (string) $id]) && ContainerInterface::EXCEPTION_ON_INVALID_REFERENCE >= $invalidBehavior) { + return parent::get($id); + } + + $service = $this->doGet($id, $invalidBehavior); + + if (!\is_object($service) && null !== $service) { + @trigger_error(sprintf('Non-object services are deprecated since Symfony 4.4, please fix the "%s" service which is of type "%s" right now.', $id, \gettype($service)), E_USER_DEPRECATED); + } + + return $service; + } + + private function doGet(string $id, int $invalidBehavior = ContainerInterface::EXCEPTION_ON_INVALID_REFERENCE, array &$inlineServices = null, bool $isConstructorArgument = false) + { + if (isset($inlineServices[$id])) { + return $inlineServices[$id]; + } + if (null === $inlineServices) { + $isConstructorArgument = true; + $inlineServices = []; + } + try { + if (ContainerInterface::IGNORE_ON_UNINITIALIZED_REFERENCE === $invalidBehavior) { + return parent::get($id, $invalidBehavior); + } + if ($service = parent::get($id, ContainerInterface::NULL_ON_INVALID_REFERENCE)) { + return $service; + } + } catch (ServiceCircularReferenceException $e) { + if ($isConstructorArgument) { + throw $e; + } + } + + if (!isset($this->definitions[$id]) && isset($this->aliasDefinitions[$id])) { + $alias = $this->aliasDefinitions[$id]; + + if ($alias->isDeprecated()) { + @trigger_error($alias->getDeprecationMessage($id), E_USER_DEPRECATED); + } + + return $this->doGet((string) $alias, $invalidBehavior, $inlineServices, $isConstructorArgument); + } + + try { + $definition = $this->getDefinition($id); + } catch (ServiceNotFoundException $e) { + if (ContainerInterface::EXCEPTION_ON_INVALID_REFERENCE < $invalidBehavior) { + return null; + } + + throw $e; + } + + if ($definition->hasErrors() && $e = $definition->getErrors()) { + throw new RuntimeException(reset($e)); + } + + if ($isConstructorArgument) { + $this->loading[$id] = true; + } + + try { + return $this->createService($definition, $inlineServices, $isConstructorArgument, $id); + } finally { + if ($isConstructorArgument) { + unset($this->loading[$id]); + } + } + } + + /** + * Merges a ContainerBuilder with the current ContainerBuilder configuration. + * + * Service definitions overrides the current defined ones. + * + * But for parameters, they are overridden by the current ones. It allows + * the parameters passed to the container constructor to have precedence + * over the loaded ones. + * + * $container = new ContainerBuilder(new ParameterBag(['foo' => 'bar'])); + * $loader = new LoaderXXX($container); + * $loader->load('resource_name'); + * $container->register('foo', 'stdClass'); + * + * In the above example, even if the loaded resource defines a foo + * parameter, the value will still be 'bar' as defined in the ContainerBuilder + * constructor. + * + * @throws BadMethodCallException When this ContainerBuilder is compiled + */ + public function merge(self $container) + { + if ($this->isCompiled()) { + throw new BadMethodCallException('Cannot merge on a compiled container.'); + } + + $this->addDefinitions($container->getDefinitions()); + $this->addAliases($container->getAliases()); + $this->getParameterBag()->add($container->getParameterBag()->all()); + + if ($this->trackResources) { + foreach ($container->getResources() as $resource) { + $this->addResource($resource); + } + } + + foreach ($this->extensions as $name => $extension) { + if (!isset($this->extensionConfigs[$name])) { + $this->extensionConfigs[$name] = []; + } + + $this->extensionConfigs[$name] = array_merge($this->extensionConfigs[$name], $container->getExtensionConfig($name)); + } + + if ($this->getParameterBag() instanceof EnvPlaceholderParameterBag && $container->getParameterBag() instanceof EnvPlaceholderParameterBag) { + $envPlaceholders = $container->getParameterBag()->getEnvPlaceholders(); + $this->getParameterBag()->mergeEnvPlaceholders($container->getParameterBag()); + } else { + $envPlaceholders = []; + } + + foreach ($container->envCounters as $env => $count) { + if (!$count && !isset($envPlaceholders[$env])) { + continue; + } + if (!isset($this->envCounters[$env])) { + $this->envCounters[$env] = $count; + } else { + $this->envCounters[$env] += $count; + } + } + + foreach ($container->getAutoconfiguredInstanceof() as $interface => $childDefinition) { + if (isset($this->autoconfiguredInstanceof[$interface])) { + throw new InvalidArgumentException(sprintf('"%s" has already been autoconfigured and merge() does not support merging autoconfiguration for the same class/interface.', $interface)); + } + + $this->autoconfiguredInstanceof[$interface] = $childDefinition; + } + } + + /** + * Returns the configuration array for the given extension. + * + * @param string $name The name of the extension + * + * @return array An array of configuration + */ + public function getExtensionConfig($name) + { + if (!isset($this->extensionConfigs[$name])) { + $this->extensionConfigs[$name] = []; + } + + return $this->extensionConfigs[$name]; + } + + /** + * Prepends a config array to the configs of the given extension. + * + * @param string $name The name of the extension + * @param array $config The config to set + */ + public function prependExtensionConfig($name, array $config) + { + if (!isset($this->extensionConfigs[$name])) { + $this->extensionConfigs[$name] = []; + } + + array_unshift($this->extensionConfigs[$name], $config); + } + + /** + * Compiles the container. + * + * This method passes the container to compiler + * passes whose job is to manipulate and optimize + * the container. + * + * The main compiler passes roughly do four things: + * + * * The extension configurations are merged; + * * Parameter values are resolved; + * * The parameter bag is frozen; + * * Extension loading is disabled. + * + * @param bool $resolveEnvPlaceholders Whether %env()% parameters should be resolved using the current + * env vars or be replaced by uniquely identifiable placeholders. + * Set to "true" when you want to use the current ContainerBuilder + * directly, keep to "false" when the container is dumped instead. + */ + public function compile(bool $resolveEnvPlaceholders = false) + { + $compiler = $this->getCompiler(); + + if ($this->trackResources) { + foreach ($compiler->getPassConfig()->getPasses() as $pass) { + $this->addObjectResource($pass); + } + } + $bag = $this->getParameterBag(); + + if ($resolveEnvPlaceholders && $bag instanceof EnvPlaceholderParameterBag) { + $compiler->addPass(new ResolveEnvPlaceholdersPass(), PassConfig::TYPE_AFTER_REMOVING, -1000); + } + + $compiler->compile($this); + + foreach ($this->definitions as $id => $definition) { + if ($this->trackResources && $definition->isLazy()) { + $this->getReflectionClass($definition->getClass()); + } + } + + $this->extensionConfigs = []; + + if ($bag instanceof EnvPlaceholderParameterBag) { + if ($resolveEnvPlaceholders) { + $this->parameterBag = new ParameterBag($this->resolveEnvPlaceholders($bag->all(), true)); + } + + $this->envPlaceholders = $bag->getEnvPlaceholders(); + } + + parent::compile(); + + foreach ($this->definitions + $this->aliasDefinitions as $id => $definition) { + if (!$definition->isPublic() || $definition->isPrivate()) { + $this->removedIds[$id] = true; + } + } + } + + /** + * {@inheritdoc} + */ + public function getServiceIds() + { + return array_map('strval', array_unique(array_merge(array_keys($this->getDefinitions()), array_keys($this->aliasDefinitions), parent::getServiceIds()))); + } + + /** + * Gets removed service or alias ids. + * + * @return array + */ + public function getRemovedIds() + { + return $this->removedIds; + } + + /** + * Adds the service aliases. + */ + public function addAliases(array $aliases) + { + foreach ($aliases as $alias => $id) { + $this->setAlias($alias, $id); + } + } + + /** + * Sets the service aliases. + */ + public function setAliases(array $aliases) + { + $this->aliasDefinitions = []; + $this->addAliases($aliases); + } + + /** + * Sets an alias for an existing service. + * + * @param string $alias The alias to create + * @param string|Alias $id The service to alias + * + * @return Alias + * + * @throws InvalidArgumentException if the id is not a string or an Alias + * @throws InvalidArgumentException if the alias is for itself + */ + public function setAlias($alias, $id) + { + $alias = (string) $alias; + + if ('' === $alias || '\\' === $alias[-1] || \strlen($alias) !== strcspn($alias, "\0\r\n'")) { + throw new InvalidArgumentException(sprintf('Invalid alias id: "%s"', $alias)); + } + + if (\is_string($id)) { + $id = new Alias($id); + } elseif (!$id instanceof Alias) { + throw new InvalidArgumentException('$id must be a string, or an Alias object.'); + } + + if ($alias === (string) $id) { + throw new InvalidArgumentException(sprintf('An alias can not reference itself, got a circular reference on "%s".', $alias)); + } + + unset($this->definitions[$alias], $this->removedIds[$alias]); + + return $this->aliasDefinitions[$alias] = $id; + } + + /** + * Removes an alias. + * + * @param string $alias The alias to remove + */ + public function removeAlias($alias) + { + if (isset($this->aliasDefinitions[$alias = (string) $alias])) { + unset($this->aliasDefinitions[$alias]); + $this->removedIds[$alias] = true; + } + } + + /** + * Returns true if an alias exists under the given identifier. + * + * @param string $id The service identifier + * + * @return bool true if the alias exists, false otherwise + */ + public function hasAlias($id) + { + return isset($this->aliasDefinitions[$id = (string) $id]); + } + + /** + * Gets all defined aliases. + * + * @return Alias[] An array of aliases + */ + public function getAliases() + { + return $this->aliasDefinitions; + } + + /** + * Gets an alias. + * + * @param string $id The service identifier + * + * @return Alias An Alias instance + * + * @throws InvalidArgumentException if the alias does not exist + */ + public function getAlias($id) + { + $id = (string) $id; + + if (!isset($this->aliasDefinitions[$id])) { + throw new InvalidArgumentException(sprintf('The service alias "%s" does not exist.', $id)); + } + + return $this->aliasDefinitions[$id]; + } + + /** + * Registers a service definition. + * + * This methods allows for simple registration of service definition + * with a fluid interface. + * + * @param string $id The service identifier + * @param string|null $class The service class + * + * @return Definition A Definition instance + */ + public function register($id, $class = null) + { + return $this->setDefinition($id, new Definition($class)); + } + + /** + * Registers an autowired service definition. + * + * This method implements a shortcut for using setDefinition() with + * an autowired definition. + * + * @param string $id The service identifier + * @param string|null $class The service class + * + * @return Definition The created definition + */ + public function autowire($id, $class = null) + { + return $this->setDefinition($id, (new Definition($class))->setAutowired(true)); + } + + /** + * Adds the service definitions. + * + * @param Definition[] $definitions An array of service definitions + */ + public function addDefinitions(array $definitions) + { + foreach ($definitions as $id => $definition) { + $this->setDefinition($id, $definition); + } + } + + /** + * Sets the service definitions. + * + * @param Definition[] $definitions An array of service definitions + */ + public function setDefinitions(array $definitions) + { + $this->definitions = []; + $this->addDefinitions($definitions); + } + + /** + * Gets all service definitions. + * + * @return Definition[] An array of Definition instances + */ + public function getDefinitions() + { + return $this->definitions; + } + + /** + * Sets a service definition. + * + * @param string $id The service identifier + * + * @return Definition the service definition + * + * @throws BadMethodCallException When this ContainerBuilder is compiled + */ + public function setDefinition($id, Definition $definition) + { + if ($this->isCompiled()) { + throw new BadMethodCallException('Adding definition to a compiled container is not allowed'); + } + + $id = (string) $id; + + if ('' === $id || '\\' === $id[-1] || \strlen($id) !== strcspn($id, "\0\r\n'")) { + throw new InvalidArgumentException(sprintf('Invalid service id: "%s"', $id)); + } + + unset($this->aliasDefinitions[$id], $this->removedIds[$id]); + + return $this->definitions[$id] = $definition; + } + + /** + * Returns true if a service definition exists under the given identifier. + * + * @param string $id The service identifier + * + * @return bool true if the service definition exists, false otherwise + */ + public function hasDefinition($id) + { + return isset($this->definitions[(string) $id]); + } + + /** + * Gets a service definition. + * + * @param string $id The service identifier + * + * @return Definition A Definition instance + * + * @throws ServiceNotFoundException if the service definition does not exist + */ + public function getDefinition($id) + { + $id = (string) $id; + + if (!isset($this->definitions[$id])) { + throw new ServiceNotFoundException($id); + } + + return $this->definitions[$id]; + } + + /** + * Gets a service definition by id or alias. + * + * The method "unaliases" recursively to return a Definition instance. + * + * @param string $id The service identifier or alias + * + * @return Definition A Definition instance + * + * @throws ServiceNotFoundException if the service definition does not exist + */ + public function findDefinition($id) + { + $id = (string) $id; + + $seen = []; + while (isset($this->aliasDefinitions[$id])) { + $id = (string) $this->aliasDefinitions[$id]; + + if (isset($seen[$id])) { + $seen = array_values($seen); + $seen = \array_slice($seen, array_search($id, $seen)); + $seen[] = $id; + + throw new ServiceCircularReferenceException($id, $seen); + } + + $seen[$id] = $id; + } + + return $this->getDefinition($id); + } + + /** + * Creates a service for a service definition. + * + * @return mixed The service described by the service definition + * + * @throws RuntimeException When the factory definition is incomplete + * @throws RuntimeException When the service is a synthetic service + * @throws InvalidArgumentException When configure callable is not callable + */ + private function createService(Definition $definition, array &$inlineServices, bool $isConstructorArgument = false, string $id = null, bool $tryProxy = true) + { + if (null === $id && isset($inlineServices[$h = spl_object_hash($definition)])) { + return $inlineServices[$h]; + } + + if ($definition instanceof ChildDefinition) { + throw new RuntimeException(sprintf('Constructing service "%s" from a parent definition is not supported at build time.', $id)); + } + + if ($definition->isSynthetic()) { + throw new RuntimeException(sprintf('You have requested a synthetic service ("%s"). The DIC does not know how to construct this service.', $id)); + } + + if ($definition->isDeprecated()) { + @trigger_error($definition->getDeprecationMessage($id), E_USER_DEPRECATED); + } + + if ($tryProxy && $definition->isLazy() && !$tryProxy = !($proxy = $this->proxyInstantiator) || $proxy instanceof RealServiceInstantiator) { + $proxy = $proxy->instantiateProxy( + $this, + $definition, + $id, function () use ($definition, &$inlineServices, $id) { + return $this->createService($definition, $inlineServices, true, $id, false); + } + ); + $this->shareService($definition, $proxy, $id, $inlineServices); + + return $proxy; + } + + $parameterBag = $this->getParameterBag(); + + if (null !== $definition->getFile()) { + require_once $parameterBag->resolveValue($definition->getFile()); + } + + $arguments = $this->doResolveServices($parameterBag->unescapeValue($parameterBag->resolveValue($definition->getArguments())), $inlineServices, $isConstructorArgument); + + if (null !== $factory = $definition->getFactory()) { + if (\is_array($factory)) { + $factory = [$this->doResolveServices($parameterBag->resolveValue($factory[0]), $inlineServices, $isConstructorArgument), $factory[1]]; + } elseif (!\is_string($factory)) { + throw new RuntimeException(sprintf('Cannot create service "%s" because of invalid factory', $id)); + } + } + + if (null !== $id && $definition->isShared() && isset($this->services[$id]) && ($tryProxy || !$definition->isLazy())) { + return $this->services[$id]; + } + + if (null !== $factory) { + $service = $factory(...$arguments); + + if (!$definition->isDeprecated() && \is_array($factory) && \is_string($factory[0])) { + $r = new \ReflectionClass($factory[0]); + + if (0 < strpos($r->getDocComment(), "\n * @deprecated ")) { + @trigger_error(sprintf('The "%s" service relies on the deprecated "%s" factory class. It should either be deprecated or its factory upgraded.', $id, $r->name), E_USER_DEPRECATED); + } + } + } else { + $r = new \ReflectionClass($parameterBag->resolveValue($definition->getClass())); + + $service = null === $r->getConstructor() ? $r->newInstance() : $r->newInstanceArgs($arguments); + + if (!$definition->isDeprecated() && 0 < strpos($r->getDocComment(), "\n * @deprecated ")) { + @trigger_error(sprintf('The "%s" service relies on the deprecated "%s" class. It should either be deprecated or its implementation upgraded.', $id, $r->name), E_USER_DEPRECATED); + } + } + + $lastWitherIndex = null; + foreach ($definition->getMethodCalls() as $k => $call) { + if ($call[2] ?? false) { + $lastWitherIndex = $k; + } + } + + if (null === $lastWitherIndex && ($tryProxy || !$definition->isLazy())) { + // share only if proxying failed, or if not a proxy, and if no withers are found + $this->shareService($definition, $service, $id, $inlineServices); + } + + $properties = $this->doResolveServices($parameterBag->unescapeValue($parameterBag->resolveValue($definition->getProperties())), $inlineServices); + foreach ($properties as $name => $value) { + $service->$name = $value; + } + + foreach ($definition->getMethodCalls() as $k => $call) { + $service = $this->callMethod($service, $call, $inlineServices); + + if ($lastWitherIndex === $k && ($tryProxy || !$definition->isLazy())) { + // share only if proxying failed, or if not a proxy, and this is the last wither + $this->shareService($definition, $service, $id, $inlineServices); + } + } + + if ($callable = $definition->getConfigurator()) { + if (\is_array($callable)) { + $callable[0] = $parameterBag->resolveValue($callable[0]); + + if ($callable[0] instanceof Reference) { + $callable[0] = $this->doGet((string) $callable[0], $callable[0]->getInvalidBehavior(), $inlineServices); + } elseif ($callable[0] instanceof Definition) { + $callable[0] = $this->createService($callable[0], $inlineServices); + } + } + + if (!\is_callable($callable)) { + throw new InvalidArgumentException(sprintf('The configure callable for class "%s" is not a callable.', \get_class($service))); + } + + $callable($service); + } + + return $service; + } + + /** + * Replaces service references by the real service instance and evaluates expressions. + * + * @param mixed $value A value + * + * @return mixed The same value with all service references replaced by + * the real service instances and all expressions evaluated + */ + public function resolveServices($value) + { + return $this->doResolveServices($value); + } + + private function doResolveServices($value, array &$inlineServices = [], bool $isConstructorArgument = false) + { + if (\is_array($value)) { + foreach ($value as $k => $v) { + $value[$k] = $this->doResolveServices($v, $inlineServices, $isConstructorArgument); + } + } elseif ($value instanceof ServiceClosureArgument) { + $reference = $value->getValues()[0]; + $value = function () use ($reference) { + return $this->resolveServices($reference); + }; + } elseif ($value instanceof IteratorArgument) { + $value = new RewindableGenerator(function () use ($value) { + foreach ($value->getValues() as $k => $v) { + foreach (self::getServiceConditionals($v) as $s) { + if (!$this->has($s)) { + continue 2; + } + } + foreach (self::getInitializedConditionals($v) as $s) { + if (!$this->doGet($s, ContainerInterface::IGNORE_ON_UNINITIALIZED_REFERENCE)) { + continue 2; + } + } + + yield $k => $this->resolveServices($v); + } + }, function () use ($value): int { + $count = 0; + foreach ($value->getValues() as $v) { + foreach (self::getServiceConditionals($v) as $s) { + if (!$this->has($s)) { + continue 2; + } + } + foreach (self::getInitializedConditionals($v) as $s) { + if (!$this->doGet($s, ContainerInterface::IGNORE_ON_UNINITIALIZED_REFERENCE)) { + continue 2; + } + } + + ++$count; + } + + return $count; + }); + } elseif ($value instanceof ServiceLocatorArgument) { + $refs = $types = []; + foreach ($value->getValues() as $k => $v) { + if ($v) { + $refs[$k] = [$v]; + $types[$k] = $v instanceof TypedReference ? $v->getType() : '?'; + } + } + $value = new ServiceLocator(\Closure::fromCallable([$this, 'resolveServices']), $refs, $types); + } elseif ($value instanceof Reference) { + $value = $this->doGet((string) $value, $value->getInvalidBehavior(), $inlineServices, $isConstructorArgument); + } elseif ($value instanceof Definition) { + $value = $this->createService($value, $inlineServices, $isConstructorArgument); + } elseif ($value instanceof Parameter) { + $value = $this->getParameter((string) $value); + } elseif ($value instanceof Expression) { + $value = $this->getExpressionLanguage()->evaluate($value, ['container' => $this]); + } + + return $value; + } + + /** + * Returns service ids for a given tag. + * + * Example: + * + * $container->register('foo')->addTag('my.tag', ['hello' => 'world']); + * + * $serviceIds = $container->findTaggedServiceIds('my.tag'); + * foreach ($serviceIds as $serviceId => $tags) { + * foreach ($tags as $tag) { + * echo $tag['hello']; + * } + * } + * + * @param string $name + * @param bool $throwOnAbstract + * + * @return array An array of tags with the tagged service as key, holding a list of attribute arrays + */ + public function findTaggedServiceIds($name, $throwOnAbstract = false) + { + $this->usedTags[] = $name; + $tags = []; + foreach ($this->getDefinitions() as $id => $definition) { + if ($definition->hasTag($name)) { + if ($throwOnAbstract && $definition->isAbstract()) { + throw new InvalidArgumentException(sprintf('The service "%s" tagged "%s" must not be abstract.', $id, $name)); + } + $tags[$id] = $definition->getTag($name); + } + } + + return $tags; + } + + /** + * Returns all tags the defined services use. + * + * @return array An array of tags + */ + public function findTags() + { + $tags = []; + foreach ($this->getDefinitions() as $id => $definition) { + $tags = array_merge(array_keys($definition->getTags()), $tags); + } + + return array_unique($tags); + } + + /** + * Returns all tags not queried by findTaggedServiceIds. + * + * @return string[] An array of tags + */ + public function findUnusedTags() + { + return array_values(array_diff($this->findTags(), $this->usedTags)); + } + + public function addExpressionLanguageProvider(ExpressionFunctionProviderInterface $provider) + { + $this->expressionLanguageProviders[] = $provider; + } + + /** + * @return ExpressionFunctionProviderInterface[] + */ + public function getExpressionLanguageProviders() + { + return $this->expressionLanguageProviders; + } + + /** + * Returns a ChildDefinition that will be used for autoconfiguring the interface/class. + * + * @param string $interface The class or interface to match + * + * @return ChildDefinition + */ + public function registerForAutoconfiguration($interface) + { + if (!isset($this->autoconfiguredInstanceof[$interface])) { + $this->autoconfiguredInstanceof[$interface] = new ChildDefinition(''); + } + + return $this->autoconfiguredInstanceof[$interface]; + } + + /** + * Registers an autowiring alias that only binds to a specific argument name. + * + * The argument name is derived from $name if provided (from $id otherwise) + * using camel case: "foo.bar" or "foo_bar" creates an alias bound to + * "$fooBar"-named arguments with $type as type-hint. Such arguments will + * receive the service $id when autowiring is used. + */ + public function registerAliasForArgument(string $id, string $type, string $name = null): Alias + { + $name = lcfirst(str_replace(' ', '', ucwords(preg_replace('/[^a-zA-Z0-9\x7f-\xff]++/', ' ', $name ?? $id)))); + + if (!preg_match('/^[a-zA-Z_\x7f-\xff]/', $name)) { + throw new InvalidArgumentException(sprintf('Invalid argument name "%s" for service "%s": the first character must be a letter.', $name, $id)); + } + + return $this->setAlias($type.' $'.$name, $id); + } + + /** + * Returns an array of ChildDefinition[] keyed by interface. + * + * @return ChildDefinition[] + */ + public function getAutoconfiguredInstanceof() + { + return $this->autoconfiguredInstanceof; + } + + /** + * Resolves env parameter placeholders in a string or an array. + * + * @param mixed $value The value to resolve + * @param string|true|null $format A sprintf() format returning the replacement for each env var name or + * null to resolve back to the original "%env(VAR)%" format or + * true to resolve to the actual values of the referenced env vars + * @param array &$usedEnvs Env vars found while resolving are added to this array + * + * @return mixed The value with env parameters resolved if a string or an array is passed + */ + public function resolveEnvPlaceholders($value, $format = null, array &$usedEnvs = null) + { + if (null === $format) { + $format = '%%env(%s)%%'; + } + + $bag = $this->getParameterBag(); + if (true === $format) { + $value = $bag->resolveValue($value); + } + + if ($value instanceof Definition) { + $value = (array) $value; + } + + if (\is_array($value)) { + $result = []; + foreach ($value as $k => $v) { + $result[\is_string($k) ? $this->resolveEnvPlaceholders($k, $format, $usedEnvs) : $k] = $this->resolveEnvPlaceholders($v, $format, $usedEnvs); + } + + return $result; + } + + if (!\is_string($value) || 38 > \strlen($value)) { + return $value; + } + $envPlaceholders = $bag instanceof EnvPlaceholderParameterBag ? $bag->getEnvPlaceholders() : $this->envPlaceholders; + + $completed = false; + foreach ($envPlaceholders as $env => $placeholders) { + foreach ($placeholders as $placeholder) { + if (false !== stripos($value, $placeholder)) { + if (true === $format) { + $resolved = $bag->escapeValue($this->getEnv($env)); + } else { + $resolved = sprintf($format, $env); + } + if ($placeholder === $value) { + $value = $resolved; + $completed = true; + } else { + if (!\is_string($resolved) && !is_numeric($resolved)) { + throw new RuntimeException(sprintf('A string value must be composed of strings and/or numbers, but found parameter "env(%s)" of type %s inside string value "%s".', $env, \gettype($resolved), $this->resolveEnvPlaceholders($value))); + } + $value = str_ireplace($placeholder, $resolved, $value); + } + $usedEnvs[$env] = $env; + $this->envCounters[$env] = isset($this->envCounters[$env]) ? 1 + $this->envCounters[$env] : 1; + + if ($completed) { + break 2; + } + } + } + } + + return $value; + } + + /** + * Get statistics about env usage. + * + * @return int[] The number of time each env vars has been resolved + */ + public function getEnvCounters() + { + $bag = $this->getParameterBag(); + $envPlaceholders = $bag instanceof EnvPlaceholderParameterBag ? $bag->getEnvPlaceholders() : $this->envPlaceholders; + + foreach ($envPlaceholders as $env => $placeholders) { + if (!isset($this->envCounters[$env])) { + $this->envCounters[$env] = 0; + } + } + + return $this->envCounters; + } + + /** + * @final + */ + public function log(CompilerPassInterface $pass, string $message) + { + $this->getCompiler()->log($pass, $this->resolveEnvPlaceholders($message)); + } + + /** + * Gets removed binding ids. + * + * @internal + */ + public function getRemovedBindingIds(): array + { + return $this->removedBindingIds; + } + + /** + * Removes bindings for a service. + * + * @internal + */ + public function removeBindings(string $id) + { + if ($this->hasDefinition($id)) { + foreach ($this->getDefinition($id)->getBindings() as $key => $binding) { + list(, $bindingId) = $binding->getValues(); + $this->removedBindingIds[(int) $bindingId] = true; + } + } + } + + /** + * Returns the Service Conditionals. + * + * @param mixed $value An array of conditionals to return + * + * @internal + */ + public static function getServiceConditionals($value): array + { + $services = []; + + if (\is_array($value)) { + foreach ($value as $v) { + $services = array_unique(array_merge($services, self::getServiceConditionals($v))); + } + } elseif ($value instanceof Reference && ContainerInterface::IGNORE_ON_INVALID_REFERENCE === $value->getInvalidBehavior()) { + $services[] = (string) $value; + } + + return $services; + } + + /** + * Returns the initialized conditionals. + * + * @param mixed $value An array of conditionals to return + * + * @internal + */ + public static function getInitializedConditionals($value): array + { + $services = []; + + if (\is_array($value)) { + foreach ($value as $v) { + $services = array_unique(array_merge($services, self::getInitializedConditionals($v))); + } + } elseif ($value instanceof Reference && ContainerInterface::IGNORE_ON_UNINITIALIZED_REFERENCE === $value->getInvalidBehavior()) { + $services[] = (string) $value; + } + + return $services; + } + + /** + * Computes a reasonably unique hash of a value. + * + * @param mixed $value A serializable value + * + * @return string + */ + public static function hash($value) + { + $hash = substr(base64_encode(hash('sha256', serialize($value), true)), 0, 7); + + return str_replace(['/', '+'], ['.', '_'], $hash); + } + + /** + * {@inheritdoc} + */ + protected function getEnv($name) + { + $value = parent::getEnv($name); + $bag = $this->getParameterBag(); + + if (!\is_string($value) || !$bag instanceof EnvPlaceholderParameterBag) { + return $value; + } + + $envPlaceholders = $bag->getEnvPlaceholders(); + if (isset($envPlaceholders[$name][$value])) { + $bag = new ParameterBag($bag->all()); + + return $bag->unescapeValue($bag->get("env($name)")); + } + foreach ($envPlaceholders as $env => $placeholders) { + if (isset($placeholders[$value])) { + return $this->getEnv($env); + } + } + + $this->resolving["env($name)"] = true; + try { + return $bag->unescapeValue($this->resolveEnvPlaceholders($bag->escapeValue($value), true)); + } finally { + unset($this->resolving["env($name)"]); + } + } + + private function callMethod($service, array $call, array &$inlineServices) + { + foreach (self::getServiceConditionals($call[1]) as $s) { + if (!$this->has($s)) { + return $service; + } + } + foreach (self::getInitializedConditionals($call[1]) as $s) { + if (!$this->doGet($s, ContainerInterface::IGNORE_ON_UNINITIALIZED_REFERENCE, $inlineServices)) { + return $service; + } + } + + $result = $service->{$call[0]}(...$this->doResolveServices($this->getParameterBag()->unescapeValue($this->getParameterBag()->resolveValue($call[1])), $inlineServices)); + + return empty($call[2]) ? $service : $result; + } + + /** + * Shares a given service in the container. + * + * @param mixed $service + */ + private function shareService(Definition $definition, $service, ?string $id, array &$inlineServices) + { + $inlineServices[null !== $id ? $id : spl_object_hash($definition)] = $service; + + if (null !== $id && $definition->isShared()) { + $this->services[$id] = $service; + unset($this->loading[$id]); + } + } + + private function getExpressionLanguage(): ExpressionLanguage + { + if (null === $this->expressionLanguage) { + if (!class_exists('Symfony\Component\ExpressionLanguage\ExpressionLanguage')) { + throw new LogicException('Unable to use expressions as the Symfony ExpressionLanguage component is not installed.'); + } + $this->expressionLanguage = new ExpressionLanguage(null, $this->expressionLanguageProviders); + } + + return $this->expressionLanguage; + } + + private function inVendors(string $path): bool + { + if (null === $this->vendors) { + $resource = new ComposerResource(); + $this->vendors = $resource->getVendors(); + $this->addResource($resource); + } + $path = realpath($path) ?: $path; + + foreach ($this->vendors as $vendor) { + if (0 === strpos($path, $vendor) && false !== strpbrk(substr($path, \strlen($vendor), 1), '/'.\DIRECTORY_SEPARATOR)) { + return true; + } + } + + return false; + } +} diff --git a/srcs/phpmyadmin/vendor/symfony/dependency-injection/ContainerInterface.php b/srcs/phpmyadmin/vendor/symfony/dependency-injection/ContainerInterface.php new file mode 100644 index 0000000..0a7f018 --- /dev/null +++ b/srcs/phpmyadmin/vendor/symfony/dependency-injection/ContainerInterface.php @@ -0,0 +1,101 @@ +<?php + +/* + * This file is part of the Symfony package. + * + * (c) Fabien Potencier <fabien@symfony.com> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection; + +use Psr\Container\ContainerInterface as PsrContainerInterface; +use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException; +use Symfony\Component\DependencyInjection\Exception\ServiceCircularReferenceException; +use Symfony\Component\DependencyInjection\Exception\ServiceNotFoundException; + +/** + * ContainerInterface is the interface implemented by service container classes. + * + * @author Fabien Potencier <fabien@symfony.com> + * @author Johannes M. Schmitt <schmittjoh@gmail.com> + */ +interface ContainerInterface extends PsrContainerInterface +{ + const RUNTIME_EXCEPTION_ON_INVALID_REFERENCE = 0; + const EXCEPTION_ON_INVALID_REFERENCE = 1; + const NULL_ON_INVALID_REFERENCE = 2; + const IGNORE_ON_INVALID_REFERENCE = 3; + const IGNORE_ON_UNINITIALIZED_REFERENCE = 4; + + /** + * Sets a service. + * + * @param string $id The service identifier + * @param object|null $service The service instance + */ + public function set($id, $service); + + /** + * Gets a service. + * + * @param string $id The service identifier + * @param int $invalidBehavior The behavior when the service does not exist + * + * @return object|null The associated service + * + * @throws ServiceCircularReferenceException When a circular reference is detected + * @throws ServiceNotFoundException When the service is not defined + * + * @see Reference + */ + public function get($id, $invalidBehavior = self::EXCEPTION_ON_INVALID_REFERENCE); + + /** + * Returns true if the given service is defined. + * + * @param string $id The service identifier + * + * @return bool true if the service is defined, false otherwise + */ + public function has($id); + + /** + * Check for whether or not a service has been initialized. + * + * @param string $id + * + * @return bool true if the service has been initialized, false otherwise + */ + public function initialized($id); + + /** + * Gets a parameter. + * + * @param string $name The parameter name + * + * @return mixed The parameter value + * + * @throws InvalidArgumentException if the parameter is not defined + */ + public function getParameter($name); + + /** + * Checks if a parameter exists. + * + * @param string $name The parameter name + * + * @return bool The presence of parameter in container + */ + public function hasParameter($name); + + /** + * Sets a parameter. + * + * @param string $name The parameter name + * @param mixed $value The parameter value + */ + public function setParameter($name, $value); +} diff --git a/srcs/phpmyadmin/vendor/symfony/dependency-injection/Definition.php b/srcs/phpmyadmin/vendor/symfony/dependency-injection/Definition.php new file mode 100644 index 0000000..e2bc713 --- /dev/null +++ b/srcs/phpmyadmin/vendor/symfony/dependency-injection/Definition.php @@ -0,0 +1,940 @@ +<?php + +/* + * This file is part of the Symfony package. + * + * (c) Fabien Potencier <fabien@symfony.com> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection; + +use Symfony\Component\DependencyInjection\Argument\BoundArgument; +use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException; +use Symfony\Component\DependencyInjection\Exception\OutOfBoundsException; + +/** + * Definition represents a service definition. + * + * @author Fabien Potencier <fabien@symfony.com> + */ +class Definition +{ + private $class; + private $file; + private $factory; + private $shared = true; + private $deprecated = false; + private $deprecationTemplate; + private $properties = []; + private $calls = []; + private $instanceof = []; + private $autoconfigured = false; + private $configurator; + private $tags = []; + private $public = true; + private $private = true; + private $synthetic = false; + private $abstract = false; + private $lazy = false; + private $decoratedService; + private $autowired = false; + private $changes = []; + private $bindings = []; + private $errors = []; + + protected $arguments = []; + + private static $defaultDeprecationTemplate = 'The "%service_id%" service is deprecated. You should stop using it, as it will be removed in the future.'; + + /** + * @internal + * + * Used to store the name of the inner id when using service decoration together with autowiring + */ + public $innerServiceId; + + /** + * @internal + * + * Used to store the behavior to follow when using service decoration and the decorated service is invalid + */ + public $decorationOnInvalid; + + /** + * @param string|null $class The service class + * @param array $arguments An array of arguments to pass to the service constructor + */ + public function __construct($class = null, array $arguments = []) + { + if (null !== $class) { + $this->setClass($class); + } + $this->arguments = $arguments; + } + + /** + * Returns all changes tracked for the Definition object. + * + * @return array An array of changes for this Definition + */ + public function getChanges() + { + return $this->changes; + } + + /** + * Sets the tracked changes for the Definition object. + * + * @param array $changes An array of changes for this Definition + * + * @return $this + */ + public function setChanges(array $changes) + { + $this->changes = $changes; + + return $this; + } + + /** + * Sets a factory. + * + * @param string|array|Reference $factory A PHP function, reference or an array containing a class/Reference and a method to call + * + * @return $this + */ + public function setFactory($factory) + { + $this->changes['factory'] = true; + + if (\is_string($factory) && false !== strpos($factory, '::')) { + $factory = explode('::', $factory, 2); + } elseif ($factory instanceof Reference) { + $factory = [$factory, '__invoke']; + } + + $this->factory = $factory; + + return $this; + } + + /** + * Gets the factory. + * + * @return string|array|null The PHP function or an array containing a class/Reference and a method to call + */ + public function getFactory() + { + return $this->factory; + } + + /** + * Sets the service that this service is decorating. + * + * @param string|null $id The decorated service id, use null to remove decoration + * @param string|null $renamedId The new decorated service id + * @param int $priority The priority of decoration + * @param int $invalidBehavior The behavior to adopt when decorated is invalid + * + * @return $this + * + * @throws InvalidArgumentException in case the decorated service id and the new decorated service id are equals + */ + public function setDecoratedService($id, $renamedId = null, $priority = 0/*, int $invalidBehavior = ContainerInterface::EXCEPTION_ON_INVALID_REFERENCE*/) + { + if ($renamedId && $id === $renamedId) { + throw new InvalidArgumentException(sprintf('The decorated service inner name for "%s" must be different than the service name itself.', $id)); + } + + $invalidBehavior = 3 < \func_num_args() ? (int) func_get_arg(3) : ContainerInterface::EXCEPTION_ON_INVALID_REFERENCE; + + $this->changes['decorated_service'] = true; + + if (null === $id) { + $this->decoratedService = null; + } else { + $this->decoratedService = [$id, $renamedId, (int) $priority]; + + if (ContainerInterface::EXCEPTION_ON_INVALID_REFERENCE !== $invalidBehavior) { + $this->decoratedService[] = $invalidBehavior; + } + } + + return $this; + } + + /** + * Gets the service that this service is decorating. + * + * @return array|null An array composed of the decorated service id, the new id for it and the priority of decoration, null if no service is decorated + */ + public function getDecoratedService() + { + return $this->decoratedService; + } + + /** + * Sets the service class. + * + * @param string $class The service class + * + * @return $this + */ + public function setClass($class) + { + if ($class instanceof Parameter) { + @trigger_error(sprintf('Passing an instance of %s as class name to %s in deprecated in Symfony 4.4 and will result in a TypeError in 5.0. Please pass the string "%%%s%%" instead.', Parameter::class, __CLASS__, (string) $class), E_USER_DEPRECATED); + } + if (null !== $class && !\is_string($class)) { + @trigger_error(sprintf('The class name passed to %s is expected to be a string. Passing a %s is deprecated in Symfony 4.4 and will result in a TypeError in 5.0.', __CLASS__, \is_object($class) ? \get_class($class) : \gettype($class)), E_USER_DEPRECATED); + } + + $this->changes['class'] = true; + + $this->class = $class; + + return $this; + } + + /** + * Gets the service class. + * + * @return string|null The service class + */ + public function getClass() + { + return $this->class; + } + + /** + * Sets the arguments to pass to the service constructor/factory method. + * + * @return $this + */ + public function setArguments(array $arguments) + { + $this->arguments = $arguments; + + return $this; + } + + /** + * Sets the properties to define when creating the service. + * + * @return $this + */ + public function setProperties(array $properties) + { + $this->properties = $properties; + + return $this; + } + + /** + * Gets the properties to define when creating the service. + * + * @return array + */ + public function getProperties() + { + return $this->properties; + } + + /** + * Sets a specific property. + * + * @param string $name + * @param mixed $value + * + * @return $this + */ + public function setProperty($name, $value) + { + $this->properties[$name] = $value; + + return $this; + } + + /** + * Adds an argument to pass to the service constructor/factory method. + * + * @param mixed $argument An argument + * + * @return $this + */ + public function addArgument($argument) + { + $this->arguments[] = $argument; + + return $this; + } + + /** + * Replaces a specific argument. + * + * @param int|string $index + * @param mixed $argument + * + * @return $this + * + * @throws OutOfBoundsException When the replaced argument does not exist + */ + public function replaceArgument($index, $argument) + { + if (0 === \count($this->arguments)) { + throw new OutOfBoundsException('Cannot replace arguments if none have been configured yet.'); + } + + if (\is_int($index) && ($index < 0 || $index > \count($this->arguments) - 1)) { + throw new OutOfBoundsException(sprintf('The index "%d" is not in the range [0, %d].', $index, \count($this->arguments) - 1)); + } + + if (!\array_key_exists($index, $this->arguments)) { + throw new OutOfBoundsException(sprintf('The argument "%s" doesn\'t exist.', $index)); + } + + $this->arguments[$index] = $argument; + + return $this; + } + + /** + * Sets a specific argument. + * + * @param int|string $key + * @param mixed $value + * + * @return $this + */ + public function setArgument($key, $value) + { + $this->arguments[$key] = $value; + + return $this; + } + + /** + * Gets the arguments to pass to the service constructor/factory method. + * + * @return array The array of arguments + */ + public function getArguments() + { + return $this->arguments; + } + + /** + * Gets an argument to pass to the service constructor/factory method. + * + * @param int|string $index + * + * @return mixed The argument value + * + * @throws OutOfBoundsException When the argument does not exist + */ + public function getArgument($index) + { + if (!\array_key_exists($index, $this->arguments)) { + throw new OutOfBoundsException(sprintf('The argument "%s" doesn\'t exist.', $index)); + } + + return $this->arguments[$index]; + } + + /** + * Sets the methods to call after service initialization. + * + * @return $this + */ + public function setMethodCalls(array $calls = []) + { + $this->calls = []; + foreach ($calls as $call) { + $this->addMethodCall($call[0], $call[1], $call[2] ?? false); + } + + return $this; + } + + /** + * Adds a method to call after service initialization. + * + * @param string $method The method name to call + * @param array $arguments An array of arguments to pass to the method call + * @param bool $returnsClone Whether the call returns the service instance or not + * + * @return $this + * + * @throws InvalidArgumentException on empty $method param + */ + public function addMethodCall($method, array $arguments = []/*, bool $returnsClone = false*/) + { + if (empty($method)) { + throw new InvalidArgumentException('Method name cannot be empty.'); + } + $this->calls[] = 2 < \func_num_args() && func_get_arg(2) ? [$method, $arguments, true] : [$method, $arguments]; + + return $this; + } + + /** + * Removes a method to call after service initialization. + * + * @param string $method The method name to remove + * + * @return $this + */ + public function removeMethodCall($method) + { + foreach ($this->calls as $i => $call) { + if ($call[0] === $method) { + unset($this->calls[$i]); + break; + } + } + + return $this; + } + + /** + * Check if the current definition has a given method to call after service initialization. + * + * @param string $method The method name to search for + * + * @return bool + */ + public function hasMethodCall($method) + { + foreach ($this->calls as $call) { + if ($call[0] === $method) { + return true; + } + } + + return false; + } + + /** + * Gets the methods to call after service initialization. + * + * @return array An array of method calls + */ + public function getMethodCalls() + { + return $this->calls; + } + + /** + * Sets the definition templates to conditionally apply on the current definition, keyed by parent interface/class. + * + * @param ChildDefinition[] $instanceof + * + * @return $this + */ + public function setInstanceofConditionals(array $instanceof) + { + $this->instanceof = $instanceof; + + return $this; + } + + /** + * Gets the definition templates to conditionally apply on the current definition, keyed by parent interface/class. + * + * @return ChildDefinition[] + */ + public function getInstanceofConditionals() + { + return $this->instanceof; + } + + /** + * Sets whether or not instanceof conditionals should be prepended with a global set. + * + * @param bool $autoconfigured + * + * @return $this + */ + public function setAutoconfigured($autoconfigured) + { + $this->changes['autoconfigured'] = true; + + $this->autoconfigured = $autoconfigured; + + return $this; + } + + /** + * @return bool + */ + public function isAutoconfigured() + { + return $this->autoconfigured; + } + + /** + * Sets tags for this definition. + * + * @return $this + */ + public function setTags(array $tags) + { + $this->tags = $tags; + + return $this; + } + + /** + * Returns all tags. + * + * @return array An array of tags + */ + public function getTags() + { + return $this->tags; + } + + /** + * Gets a tag by name. + * + * @param string $name The tag name + * + * @return array An array of attributes + */ + public function getTag($name) + { + return isset($this->tags[$name]) ? $this->tags[$name] : []; + } + + /** + * Adds a tag for this definition. + * + * @param string $name The tag name + * @param array $attributes An array of attributes + * + * @return $this + */ + public function addTag($name, array $attributes = []) + { + $this->tags[$name][] = $attributes; + + return $this; + } + + /** + * Whether this definition has a tag with the given name. + * + * @param string $name + * + * @return bool + */ + public function hasTag($name) + { + return isset($this->tags[$name]); + } + + /** + * Clears all tags for a given name. + * + * @param string $name The tag name + * + * @return $this + */ + public function clearTag($name) + { + unset($this->tags[$name]); + + return $this; + } + + /** + * Clears the tags for this definition. + * + * @return $this + */ + public function clearTags() + { + $this->tags = []; + + return $this; + } + + /** + * Sets a file to require before creating the service. + * + * @param string $file A full pathname to include + * + * @return $this + */ + public function setFile($file) + { + $this->changes['file'] = true; + + $this->file = $file; + + return $this; + } + + /** + * Gets the file to require before creating the service. + * + * @return string|null The full pathname to include + */ + public function getFile() + { + return $this->file; + } + + /** + * Sets if the service must be shared or not. + * + * @param bool $shared Whether the service must be shared or not + * + * @return $this + */ + public function setShared($shared) + { + $this->changes['shared'] = true; + + $this->shared = (bool) $shared; + + return $this; + } + + /** + * Whether this service is shared. + * + * @return bool + */ + public function isShared() + { + return $this->shared; + } + + /** + * Sets the visibility of this service. + * + * @param bool $boolean + * + * @return $this + */ + public function setPublic($boolean) + { + $this->changes['public'] = true; + + $this->public = (bool) $boolean; + $this->private = false; + + return $this; + } + + /** + * Whether this service is public facing. + * + * @return bool + */ + public function isPublic() + { + return $this->public; + } + + /** + * Sets if this service is private. + * + * When set, the "private" state has a higher precedence than "public". + * In version 3.4, a "private" service always remains publicly accessible, + * but triggers a deprecation notice when accessed from the container, + * so that the service can be made really private in 4.0. + * + * @param bool $boolean + * + * @return $this + */ + public function setPrivate($boolean) + { + $this->private = (bool) $boolean; + + return $this; + } + + /** + * Whether this service is private. + * + * @return bool + */ + public function isPrivate() + { + return $this->private; + } + + /** + * Sets the lazy flag of this service. + * + * @param bool $lazy + * + * @return $this + */ + public function setLazy($lazy) + { + $this->changes['lazy'] = true; + + $this->lazy = (bool) $lazy; + + return $this; + } + + /** + * Whether this service is lazy. + * + * @return bool + */ + public function isLazy() + { + return $this->lazy; + } + + /** + * Sets whether this definition is synthetic, that is not constructed by the + * container, but dynamically injected. + * + * @param bool $boolean + * + * @return $this + */ + public function setSynthetic($boolean) + { + $this->synthetic = (bool) $boolean; + + return $this; + } + + /** + * Whether this definition is synthetic, that is not constructed by the + * container, but dynamically injected. + * + * @return bool + */ + public function isSynthetic() + { + return $this->synthetic; + } + + /** + * Whether this definition is abstract, that means it merely serves as a + * template for other definitions. + * + * @param bool $boolean + * + * @return $this + */ + public function setAbstract($boolean) + { + $this->abstract = (bool) $boolean; + + return $this; + } + + /** + * Whether this definition is abstract, that means it merely serves as a + * template for other definitions. + * + * @return bool + */ + public function isAbstract() + { + return $this->abstract; + } + + /** + * Whether this definition is deprecated, that means it should not be called + * anymore. + * + * @param bool $status + * @param string $template Template message to use if the definition is deprecated + * + * @return $this + * + * @throws InvalidArgumentException when the message template is invalid + */ + public function setDeprecated($status = true, $template = null) + { + if (null !== $template) { + if (preg_match('#[\r\n]|\*/#', $template)) { + throw new InvalidArgumentException('Invalid characters found in deprecation template.'); + } + + if (false === strpos($template, '%service_id%')) { + throw new InvalidArgumentException('The deprecation template must contain the "%service_id%" placeholder.'); + } + + $this->deprecationTemplate = $template; + } + + $this->changes['deprecated'] = true; + + $this->deprecated = (bool) $status; + + return $this; + } + + /** + * Whether this definition is deprecated, that means it should not be called + * anymore. + * + * @return bool + */ + public function isDeprecated() + { + return $this->deprecated; + } + + /** + * Message to use if this definition is deprecated. + * + * @param string $id Service id relying on this definition + * + * @return string + */ + public function getDeprecationMessage($id) + { + return str_replace('%service_id%', $id, $this->deprecationTemplate ?: self::$defaultDeprecationTemplate); + } + + /** + * Sets a configurator to call after the service is fully initialized. + * + * @param string|array|Reference $configurator A PHP function, reference or an array containing a class/Reference and a method to call + * + * @return $this + */ + public function setConfigurator($configurator) + { + $this->changes['configurator'] = true; + + if (\is_string($configurator) && false !== strpos($configurator, '::')) { + $configurator = explode('::', $configurator, 2); + } elseif ($configurator instanceof Reference) { + $configurator = [$configurator, '__invoke']; + } + + $this->configurator = $configurator; + + return $this; + } + + /** + * Gets the configurator to call after the service is fully initialized. + * + * @return callable|array|null + */ + public function getConfigurator() + { + return $this->configurator; + } + + /** + * Is the definition autowired? + * + * @return bool + */ + public function isAutowired() + { + return $this->autowired; + } + + /** + * Enables/disables autowiring. + * + * @param bool $autowired + * + * @return $this + */ + public function setAutowired($autowired) + { + $this->changes['autowired'] = true; + + $this->autowired = (bool) $autowired; + + return $this; + } + + /** + * Gets bindings. + * + * @return array|BoundArgument[] + */ + public function getBindings() + { + return $this->bindings; + } + + /** + * Sets bindings. + * + * Bindings map $named or FQCN arguments to values that should be + * injected in the matching parameters (of the constructor, of methods + * called and of controller actions). + * + * @return $this + */ + public function setBindings(array $bindings) + { + foreach ($bindings as $key => $binding) { + if (0 < strpos($key, '$') && $key !== $k = preg_replace('/[ \t]*\$/', ' $', $key)) { + unset($bindings[$key]); + $bindings[$key = $k] = $binding; + } + if (!$binding instanceof BoundArgument) { + $bindings[$key] = new BoundArgument($binding); + } + } + + $this->bindings = $bindings; + + return $this; + } + + /** + * Add an error that occurred when building this Definition. + * + * @param string|\Closure|self $error + * + * @return $this + */ + public function addError($error) + { + if ($error instanceof self) { + $this->errors = array_merge($this->errors, $error->errors); + } else { + $this->errors[] = $error; + } + + return $this; + } + + /** + * Returns any errors that occurred while building this Definition. + * + * @return array + */ + public function getErrors() + { + foreach ($this->errors as $i => $error) { + if ($error instanceof \Closure) { + $this->errors[$i] = (string) $error(); + } elseif (!\is_string($error)) { + $this->errors[$i] = (string) $error; + } + } + + return $this->errors; + } + + public function hasErrors(): bool + { + return (bool) $this->errors; + } +} diff --git a/srcs/phpmyadmin/vendor/symfony/dependency-injection/Dumper/Dumper.php b/srcs/phpmyadmin/vendor/symfony/dependency-injection/Dumper/Dumper.php new file mode 100644 index 0000000..e7407b0 --- /dev/null +++ b/srcs/phpmyadmin/vendor/symfony/dependency-injection/Dumper/Dumper.php @@ -0,0 +1,29 @@ +<?php + +/* + * This file is part of the Symfony package. + * + * (c) Fabien Potencier <fabien@symfony.com> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection\Dumper; + +use Symfony\Component\DependencyInjection\ContainerBuilder; + +/** + * Dumper is the abstract class for all built-in dumpers. + * + * @author Fabien Potencier <fabien@symfony.com> + */ +abstract class Dumper implements DumperInterface +{ + protected $container; + + public function __construct(ContainerBuilder $container) + { + $this->container = $container; + } +} diff --git a/srcs/phpmyadmin/vendor/symfony/dependency-injection/Dumper/DumperInterface.php b/srcs/phpmyadmin/vendor/symfony/dependency-injection/Dumper/DumperInterface.php new file mode 100644 index 0000000..8abc192 --- /dev/null +++ b/srcs/phpmyadmin/vendor/symfony/dependency-injection/Dumper/DumperInterface.php @@ -0,0 +1,27 @@ +<?php + +/* + * This file is part of the Symfony package. + * + * (c) Fabien Potencier <fabien@symfony.com> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection\Dumper; + +/** + * DumperInterface is the interface implemented by service container dumper classes. + * + * @author Fabien Potencier <fabien@symfony.com> + */ +interface DumperInterface +{ + /** + * Dumps the service container. + * + * @return string|array The representation of the service container + */ + public function dump(array $options = []); +} diff --git a/srcs/phpmyadmin/vendor/symfony/dependency-injection/Dumper/GraphvizDumper.php b/srcs/phpmyadmin/vendor/symfony/dependency-injection/Dumper/GraphvizDumper.php new file mode 100644 index 0000000..c21dd91 --- /dev/null +++ b/srcs/phpmyadmin/vendor/symfony/dependency-injection/Dumper/GraphvizDumper.php @@ -0,0 +1,251 @@ +<?php + +/* + * This file is part of the Symfony package. + * + * (c) Fabien Potencier <fabien@symfony.com> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection\Dumper; + +use Symfony\Component\DependencyInjection\Argument\ArgumentInterface; +use Symfony\Component\DependencyInjection\ContainerBuilder; +use Symfony\Component\DependencyInjection\Definition; +use Symfony\Component\DependencyInjection\Exception\ParameterNotFoundException; +use Symfony\Component\DependencyInjection\Parameter; +use Symfony\Component\DependencyInjection\ParameterBag\ParameterBag; +use Symfony\Component\DependencyInjection\Reference; + +/** + * GraphvizDumper dumps a service container as a graphviz file. + * + * You can convert the generated dot file with the dot utility (http://www.graphviz.org/): + * + * dot -Tpng container.dot > foo.png + * + * @author Fabien Potencier <fabien@symfony.com> + */ +class GraphvizDumper extends Dumper +{ + private $nodes; + private $edges; + private $options = [ + 'graph' => ['ratio' => 'compress'], + 'node' => ['fontsize' => 11, 'fontname' => 'Arial', 'shape' => 'record'], + 'edge' => ['fontsize' => 9, 'fontname' => 'Arial', 'color' => 'grey', 'arrowhead' => 'open', 'arrowsize' => 0.5], + 'node.instance' => ['fillcolor' => '#9999ff', 'style' => 'filled'], + 'node.definition' => ['fillcolor' => '#eeeeee'], + 'node.missing' => ['fillcolor' => '#ff9999', 'style' => 'filled'], + ]; + + /** + * Dumps the service container as a graphviz graph. + * + * Available options: + * + * * graph: The default options for the whole graph + * * node: The default options for nodes + * * edge: The default options for edges + * * node.instance: The default options for services that are defined directly by object instances + * * node.definition: The default options for services that are defined via service definition instances + * * node.missing: The default options for missing services + * + * @return string The dot representation of the service container + */ + public function dump(array $options = []) + { + foreach (['graph', 'node', 'edge', 'node.instance', 'node.definition', 'node.missing'] as $key) { + if (isset($options[$key])) { + $this->options[$key] = array_merge($this->options[$key], $options[$key]); + } + } + + $this->nodes = $this->findNodes(); + + $this->edges = []; + foreach ($this->container->getDefinitions() as $id => $definition) { + $this->edges[$id] = array_merge( + $this->findEdges($id, $definition->getArguments(), true, ''), + $this->findEdges($id, $definition->getProperties(), false, '') + ); + + foreach ($definition->getMethodCalls() as $call) { + $this->edges[$id] = array_merge( + $this->edges[$id], + $this->findEdges($id, $call[1], false, $call[0].'()') + ); + } + } + + return $this->container->resolveEnvPlaceholders($this->startDot().$this->addNodes().$this->addEdges().$this->endDot(), '__ENV_%s__'); + } + + private function addNodes(): string + { + $code = ''; + foreach ($this->nodes as $id => $node) { + $aliases = $this->getAliases($id); + + $code .= sprintf(" node_%s [label=\"%s\\n%s\\n\", shape=%s%s];\n", $this->dotize($id), $id.($aliases ? ' ('.implode(', ', $aliases).')' : ''), $node['class'], $this->options['node']['shape'], $this->addAttributes($node['attributes'])); + } + + return $code; + } + + private function addEdges(): string + { + $code = ''; + foreach ($this->edges as $id => $edges) { + foreach ($edges as $edge) { + $code .= sprintf(" node_%s -> node_%s [label=\"%s\" style=\"%s\"%s];\n", $this->dotize($id), $this->dotize($edge['to']), $edge['name'], $edge['required'] ? 'filled' : 'dashed', $edge['lazy'] ? ' color="#9999ff"' : ''); + } + } + + return $code; + } + + /** + * Finds all edges belonging to a specific service id. + */ + private function findEdges(string $id, array $arguments, bool $required, string $name, bool $lazy = false): array + { + $edges = []; + foreach ($arguments as $argument) { + if ($argument instanceof Parameter) { + $argument = $this->container->hasParameter($argument) ? $this->container->getParameter($argument) : null; + } elseif (\is_string($argument) && preg_match('/^%([^%]+)%$/', $argument, $match)) { + $argument = $this->container->hasParameter($match[1]) ? $this->container->getParameter($match[1]) : null; + } + + if ($argument instanceof Reference) { + $lazyEdge = $lazy; + + if (!$this->container->has((string) $argument)) { + $this->nodes[(string) $argument] = ['name' => $name, 'required' => $required, 'class' => '', 'attributes' => $this->options['node.missing']]; + } elseif ('service_container' !== (string) $argument) { + $lazyEdge = $lazy || $this->container->getDefinition((string) $argument)->isLazy(); + } + + $edges[] = ['name' => $name, 'required' => $required, 'to' => $argument, 'lazy' => $lazyEdge]; + } elseif ($argument instanceof ArgumentInterface) { + $edges = array_merge($edges, $this->findEdges($id, $argument->getValues(), $required, $name, true)); + } elseif ($argument instanceof Definition) { + $edges = array_merge($edges, + $this->findEdges($id, $argument->getArguments(), $required, ''), + $this->findEdges($id, $argument->getProperties(), false, '') + ); + foreach ($argument->getMethodCalls() as $call) { + $edges = array_merge($edges, $this->findEdges($id, $call[1], false, $call[0].'()')); + } + } elseif (\is_array($argument)) { + $edges = array_merge($edges, $this->findEdges($id, $argument, $required, $name, $lazy)); + } + } + + return $edges; + } + + private function findNodes(): array + { + $nodes = []; + + $container = $this->cloneContainer(); + + foreach ($container->getDefinitions() as $id => $definition) { + $class = $definition->getClass(); + + if ('\\' === substr($class, 0, 1)) { + $class = substr($class, 1); + } + + try { + $class = $this->container->getParameterBag()->resolveValue($class); + } catch (ParameterNotFoundException $e) { + } + + $nodes[$id] = ['class' => str_replace('\\', '\\\\', $class), 'attributes' => array_merge($this->options['node.definition'], ['style' => $definition->isShared() ? 'filled' : 'dotted'])]; + $container->setDefinition($id, new Definition('stdClass')); + } + + foreach ($container->getServiceIds() as $id) { + if (\array_key_exists($id, $container->getAliases())) { + continue; + } + + if (!$container->hasDefinition($id)) { + $nodes[$id] = ['class' => str_replace('\\', '\\\\', \get_class($container->get($id))), 'attributes' => $this->options['node.instance']]; + } + } + + return $nodes; + } + + private function cloneContainer(): ContainerBuilder + { + $parameterBag = new ParameterBag($this->container->getParameterBag()->all()); + + $container = new ContainerBuilder($parameterBag); + $container->setDefinitions($this->container->getDefinitions()); + $container->setAliases($this->container->getAliases()); + $container->setResources($this->container->getResources()); + foreach ($this->container->getExtensions() as $extension) { + $container->registerExtension($extension); + } + + return $container; + } + + private function startDot(): string + { + return sprintf("digraph sc {\n %s\n node [%s];\n edge [%s];\n\n", + $this->addOptions($this->options['graph']), + $this->addOptions($this->options['node']), + $this->addOptions($this->options['edge']) + ); + } + + private function endDot(): string + { + return "}\n"; + } + + private function addAttributes(array $attributes): string + { + $code = []; + foreach ($attributes as $k => $v) { + $code[] = sprintf('%s="%s"', $k, $v); + } + + return $code ? ', '.implode(', ', $code) : ''; + } + + private function addOptions(array $options): string + { + $code = []; + foreach ($options as $k => $v) { + $code[] = sprintf('%s="%s"', $k, $v); + } + + return implode(' ', $code); + } + + private function dotize(string $id): string + { + return preg_replace('/\W/i', '_', $id); + } + + private function getAliases(string $id): array + { + $aliases = []; + foreach ($this->container->getAliases() as $alias => $origin) { + if ($id == $origin) { + $aliases[] = $alias; + } + } + + return $aliases; + } +} diff --git a/srcs/phpmyadmin/vendor/symfony/dependency-injection/Dumper/PhpDumper.php b/srcs/phpmyadmin/vendor/symfony/dependency-injection/Dumper/PhpDumper.php new file mode 100644 index 0000000..15d5c09 --- /dev/null +++ b/srcs/phpmyadmin/vendor/symfony/dependency-injection/Dumper/PhpDumper.php @@ -0,0 +1,2062 @@ +<?php + +/* + * This file is part of the Symfony package. + * + * (c) Fabien Potencier <fabien@symfony.com> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection\Dumper; + +use Composer\Autoload\ClassLoader; +use Symfony\Component\Debug\DebugClassLoader as LegacyDebugClassLoader; +use Symfony\Component\DependencyInjection\Argument\ArgumentInterface; +use Symfony\Component\DependencyInjection\Argument\IteratorArgument; +use Symfony\Component\DependencyInjection\Argument\ServiceClosureArgument; +use Symfony\Component\DependencyInjection\Argument\ServiceLocator; +use Symfony\Component\DependencyInjection\Argument\ServiceLocatorArgument; +use Symfony\Component\DependencyInjection\Compiler\AnalyzeServiceReferencesPass; +use Symfony\Component\DependencyInjection\Compiler\CheckCircularReferencesPass; +use Symfony\Component\DependencyInjection\Compiler\ServiceReferenceGraphNode; +use Symfony\Component\DependencyInjection\Container; +use Symfony\Component\DependencyInjection\ContainerBuilder; +use Symfony\Component\DependencyInjection\ContainerInterface; +use Symfony\Component\DependencyInjection\Definition; +use Symfony\Component\DependencyInjection\Exception\EnvParameterException; +use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException; +use Symfony\Component\DependencyInjection\Exception\LogicException; +use Symfony\Component\DependencyInjection\Exception\RuntimeException; +use Symfony\Component\DependencyInjection\Exception\ServiceCircularReferenceException; +use Symfony\Component\DependencyInjection\ExpressionLanguage; +use Symfony\Component\DependencyInjection\LazyProxy\PhpDumper\DumperInterface as ProxyDumper; +use Symfony\Component\DependencyInjection\LazyProxy\PhpDumper\NullDumper; +use Symfony\Component\DependencyInjection\Loader\FileLoader; +use Symfony\Component\DependencyInjection\Parameter; +use Symfony\Component\DependencyInjection\Reference; +use Symfony\Component\DependencyInjection\ServiceLocator as BaseServiceLocator; +use Symfony\Component\DependencyInjection\TypedReference; +use Symfony\Component\DependencyInjection\Variable; +use Symfony\Component\ErrorHandler\DebugClassLoader; +use Symfony\Component\ExpressionLanguage\Expression; +use Symfony\Component\HttpKernel\Kernel; + +/** + * PhpDumper dumps a service container as a PHP class. + * + * @author Fabien Potencier <fabien@symfony.com> + * @author Johannes M. Schmitt <schmittjoh@gmail.com> + */ +class PhpDumper extends Dumper +{ + /** + * Characters that might appear in the generated variable name as first character. + */ + const FIRST_CHARS = 'abcdefghijklmnopqrstuvwxyz'; + + /** + * Characters that might appear in the generated variable name as any but the first character. + */ + const NON_FIRST_CHARS = 'abcdefghijklmnopqrstuvwxyz0123456789_'; + + private $definitionVariables; + private $referenceVariables; + private $variableCount; + private $inlinedDefinitions; + private $serviceCalls; + private $reservedVariables = ['instance', 'class', 'this']; + private $expressionLanguage; + private $targetDirRegex; + private $targetDirMaxMatches; + private $docStar; + private $serviceIdToMethodNameMap; + private $usedMethodNames; + private $namespace; + private $asFiles; + private $hotPathTag; + private $inlineFactories; + private $inlineRequires; + private $inlinedRequires = []; + private $circularReferences = []; + private $singleUsePrivateIds = []; + private $addThrow = false; + private $addGetService = false; + private $locatedIds = []; + private $serviceLocatorTag; + private $exportedVariables = []; + private $baseClass; + + /** + * @var ProxyDumper + */ + private $proxyDumper; + + /** + * {@inheritdoc} + */ + public function __construct(ContainerBuilder $container) + { + if (!$container->isCompiled()) { + throw new LogicException('Cannot dump an uncompiled container.'); + } + + parent::__construct($container); + } + + /** + * Sets the dumper to be used when dumping proxies in the generated container. + */ + public function setProxyDumper(ProxyDumper $proxyDumper) + { + $this->proxyDumper = $proxyDumper; + } + + /** + * Dumps the service container as a PHP class. + * + * Available options: + * + * * class: The class name + * * base_class: The base class name + * * namespace: The class namespace + * * as_files: To split the container in several files + * + * @return string|array A PHP class representing the service container or an array of PHP files if the "as_files" option is set + * + * @throws EnvParameterException When an env var exists but has not been dumped + */ + public function dump(array $options = []) + { + $this->locatedIds = []; + $this->targetDirRegex = null; + $this->inlinedRequires = []; + $this->exportedVariables = []; + $options = array_merge([ + 'class' => 'ProjectServiceContainer', + 'base_class' => 'Container', + 'namespace' => '', + 'as_files' => false, + 'debug' => true, + 'hot_path_tag' => 'container.hot_path', + 'inline_factories_parameter' => 'container.dumper.inline_factories', + 'inline_class_loader_parameter' => 'container.dumper.inline_class_loader', + 'service_locator_tag' => 'container.service_locator', + 'build_time' => time(), + ], $options); + + $this->addThrow = $this->addGetService = false; + $this->namespace = $options['namespace']; + $this->asFiles = $options['as_files']; + $this->hotPathTag = $options['hot_path_tag']; + $this->inlineFactories = $this->asFiles && $options['inline_factories_parameter'] && $this->container->hasParameter($options['inline_factories_parameter']) && $this->container->getParameter($options['inline_factories_parameter']); + $this->inlineRequires = $options['inline_class_loader_parameter'] && $this->container->hasParameter($options['inline_class_loader_parameter']) && $this->container->getParameter($options['inline_class_loader_parameter']); + $this->serviceLocatorTag = $options['service_locator_tag']; + + if (0 !== strpos($baseClass = $options['base_class'], '\\') && 'Container' !== $baseClass) { + $baseClass = sprintf('%s\%s', $options['namespace'] ? '\\'.$options['namespace'] : '', $baseClass); + $this->baseClass = $baseClass; + } elseif ('Container' === $baseClass) { + $this->baseClass = Container::class; + } else { + $this->baseClass = $baseClass; + } + + $this->initializeMethodNamesMap('Container' === $baseClass ? Container::class : $baseClass); + + if ($this->getProxyDumper() instanceof NullDumper) { + (new AnalyzeServiceReferencesPass(true, false))->process($this->container); + try { + (new CheckCircularReferencesPass())->process($this->container); + } catch (ServiceCircularReferenceException $e) { + $path = $e->getPath(); + end($path); + $path[key($path)] .= '". Try running "composer require symfony/proxy-manager-bridge'; + + throw new ServiceCircularReferenceException($e->getServiceId(), $path); + } + } + + (new AnalyzeServiceReferencesPass(false, !$this->getProxyDumper() instanceof NullDumper))->process($this->container); + $checkedNodes = []; + $this->circularReferences = []; + $this->singleUsePrivateIds = []; + foreach ($this->container->getCompiler()->getServiceReferenceGraph()->getNodes() as $id => $node) { + if (!$node->getValue() instanceof Definition) { + continue; + } + if (!isset($checkedNodes[$id])) { + $this->analyzeCircularReferences($id, $node->getOutEdges(), $checkedNodes); + } + if ($this->isSingleUsePrivateNode($node)) { + $this->singleUsePrivateIds[$id] = $id; + } + } + $this->container->getCompiler()->getServiceReferenceGraph()->clear(); + $checkedNodes = []; + $this->singleUsePrivateIds = array_diff_key($this->singleUsePrivateIds, $this->circularReferences); + + $this->docStar = $options['debug'] ? '*' : ''; + + if (!empty($options['file']) && is_dir($dir = \dirname($options['file']))) { + // Build a regexp where the first root dirs are mandatory, + // but every other sub-dir is optional up to the full path in $dir + // Mandate at least 1 root dir and not more than 5 optional dirs. + + $dir = explode(\DIRECTORY_SEPARATOR, realpath($dir)); + $i = \count($dir); + + if (2 + (int) ('\\' === \DIRECTORY_SEPARATOR) <= $i) { + $regex = ''; + $lastOptionalDir = $i > 8 ? $i - 5 : (2 + (int) ('\\' === \DIRECTORY_SEPARATOR)); + $this->targetDirMaxMatches = $i - $lastOptionalDir; + + while (--$i >= $lastOptionalDir) { + $regex = sprintf('(%s%s)?', preg_quote(\DIRECTORY_SEPARATOR.$dir[$i], '#'), $regex); + } + + do { + $regex = preg_quote(\DIRECTORY_SEPARATOR.$dir[$i], '#').$regex; + } while (0 < --$i); + + $this->targetDirRegex = '#'.preg_quote($dir[0], '#').$regex.'#'; + } + } + + $proxyClasses = $this->inlineFactories ? $this->generateProxyClasses() : null; + + $code = + $this->startClass($options['class'], $baseClass, $preload). + $this->addServices($services). + $this->addDeprecatedAliases(). + $this->addDefaultParametersMethod() + ; + + $proxyClasses = $proxyClasses ?? $this->generateProxyClasses(); + + if ($this->addGetService) { + $code = preg_replace( + "/(\r?\n\r?\n public function __construct.+?\\{\r?\n)/s", + "\n private \$getService;$1 \$this->getService = \\Closure::fromCallable([\$this, 'getService']);\n", + $code, + 1 + ); + } + + if ($this->asFiles) { + $fileStart = <<<EOF +<?php + +use Symfony\Component\DependencyInjection\Argument\RewindableGenerator; +use Symfony\Component\DependencyInjection\Exception\RuntimeException; + +// This file has been auto-generated by the Symfony Dependency Injection Component for internal use. + +EOF; + $files = []; + + $ids = $this->container->getRemovedIds(); + foreach ($this->container->getDefinitions() as $id => $definition) { + if (!$definition->isPublic()) { + $ids[$id] = true; + } + } + if ($ids = array_keys($ids)) { + sort($ids); + $c = "<?php\n\nreturn [\n"; + foreach ($ids as $id) { + $c .= ' '.$this->doExport($id)." => true,\n"; + } + $files['removed-ids.php'] = $c."];\n"; + } + + if (!$this->inlineFactories) { + foreach ($this->generateServiceFiles($services) as $file => $c) { + $files[$file] = $fileStart.$c; + } + foreach ($proxyClasses as $file => $c) { + $files[$file] = "<?php\n".$c; + } + } + + $code .= $this->endClass(); + + if ($this->inlineFactories) { + foreach ($proxyClasses as $c) { + $code .= $c; + } + } + + $files[$options['class'].'.php'] = $code; + $hash = ucfirst(strtr(ContainerBuilder::hash($files), '._', 'xx')); + $code = []; + + foreach ($files as $file => $c) { + $code["Container{$hash}/{$file}"] = $c; + } + array_pop($code); + $code["Container{$hash}/{$options['class']}.php"] = substr_replace($files[$options['class'].'.php'], "<?php\n\nnamespace Container{$hash};\n", 0, 6); + $namespaceLine = $this->namespace ? "\nnamespace {$this->namespace};\n" : ''; + $time = $options['build_time']; + $id = hash('crc32', $hash.$time); + $this->asFiles = false; + + if ($preload && null !== $autoloadFile = $this->getAutoloadFile()) { + $autoloadFile = substr($this->export($autoloadFile), 2, -1); + + $code[$options['class'].'.preload.php'] = <<<EOF +<?php + +// This file has been auto-generated by the Symfony Dependency Injection Component +// You can reference it in the "opcache.preload" php.ini setting on PHP >= 7.4 when preloading is desired + +use Symfony\Component\DependencyInjection\Dumper\Preloader; + +require $autoloadFile; +require __DIR__.'/Container{$hash}/{$options['class']}.php'; + +\$classes = []; + +EOF; + + foreach ($preload as $class) { + $code[$options['class'].'.preload.php'] .= sprintf("\$classes[] = '%s';\n", $class); + } + + $code[$options['class'].'.preload.php'] .= <<<'EOF' + +Preloader::preload($classes); + +EOF; + } + + $code[$options['class'].'.php'] = <<<EOF +<?php +{$namespaceLine} +// This file has been auto-generated by the Symfony Dependency Injection Component for internal use. + +if (\\class_exists(\\Container{$hash}\\{$options['class']}::class, false)) { + // no-op +} elseif (!include __DIR__.'/Container{$hash}/{$options['class']}.php') { + touch(__DIR__.'/Container{$hash}.legacy'); + + return; +} + +if (!\\class_exists({$options['class']}::class, false)) { + \\class_alias(\\Container{$hash}\\{$options['class']}::class, {$options['class']}::class, false); +} + +return new \\Container{$hash}\\{$options['class']}([ + 'container.build_hash' => '$hash', + 'container.build_id' => '$id', + 'container.build_time' => $time, +], __DIR__.\\DIRECTORY_SEPARATOR.'Container{$hash}'); + +EOF; + } else { + $code .= $this->endClass(); + foreach ($proxyClasses as $c) { + $code .= $c; + } + } + + $this->targetDirRegex = null; + $this->inlinedRequires = []; + $this->circularReferences = []; + $this->locatedIds = []; + $this->exportedVariables = []; + + $unusedEnvs = []; + foreach ($this->container->getEnvCounters() as $env => $use) { + if (!$use) { + $unusedEnvs[] = $env; + } + } + if ($unusedEnvs) { + throw new EnvParameterException($unusedEnvs, null, 'Environment variables "%s" are never used. Please, check your container\'s configuration.'); + } + + return $code; + } + + /** + * Retrieves the currently set proxy dumper or instantiates one. + */ + private function getProxyDumper(): ProxyDumper + { + if (!$this->proxyDumper) { + $this->proxyDumper = new NullDumper(); + } + + return $this->proxyDumper; + } + + private function analyzeCircularReferences(string $sourceId, array $edges, array &$checkedNodes, array &$currentPath = [], bool $byConstructor = true) + { + $checkedNodes[$sourceId] = true; + $currentPath[$sourceId] = $byConstructor; + + foreach ($edges as $edge) { + $node = $edge->getDestNode(); + $id = $node->getId(); + + if (!$node->getValue() instanceof Definition || $sourceId === $id || $edge->isLazy() || $edge->isWeak()) { + // no-op + } elseif (isset($currentPath[$id])) { + $this->addCircularReferences($id, $currentPath, $edge->isReferencedByConstructor()); + } elseif (!isset($checkedNodes[$id])) { + $this->analyzeCircularReferences($id, $node->getOutEdges(), $checkedNodes, $currentPath, $edge->isReferencedByConstructor()); + } elseif (isset($this->circularReferences[$id])) { + $this->connectCircularReferences($id, $currentPath, $edge->isReferencedByConstructor()); + } + } + unset($currentPath[$sourceId]); + } + + private function connectCircularReferences(string $sourceId, array &$currentPath, bool $byConstructor, array &$subPath = []) + { + $currentPath[$sourceId] = $subPath[$sourceId] = $byConstructor; + + foreach ($this->circularReferences[$sourceId] as $id => $byConstructor) { + if (isset($currentPath[$id])) { + $this->addCircularReferences($id, $currentPath, $byConstructor); + } elseif (!isset($subPath[$id]) && isset($this->circularReferences[$id])) { + $this->connectCircularReferences($id, $currentPath, $byConstructor, $subPath); + } + } + unset($currentPath[$sourceId], $subPath[$sourceId]); + } + + private function addCircularReferences(string $id, array $currentPath, bool $byConstructor) + { + $currentPath[$id] = $byConstructor; + $circularRefs = []; + + foreach (array_reverse($currentPath) as $parentId => $v) { + $byConstructor = $byConstructor && $v; + $circularRefs[] = $parentId; + + if ($parentId === $id) { + break; + } + } + + $currentId = $id; + foreach ($circularRefs as $parentId) { + if (empty($this->circularReferences[$parentId][$currentId])) { + $this->circularReferences[$parentId][$currentId] = $byConstructor; + } + + $currentId = $parentId; + } + } + + private function collectLineage(string $class, array &$lineage) + { + if (isset($lineage[$class])) { + return; + } + if (!$r = $this->container->getReflectionClass($class, false)) { + return; + } + if (is_a($class, $this->baseClass, true)) { + return; + } + $file = $r->getFileName(); + if (!$file || $this->doExport($file) === $exportedFile = $this->export($file)) { + return; + } + + $lineage[$class] = substr($exportedFile, 1, -1); + + if ($parent = $r->getParentClass()) { + $this->collectLineage($parent->name, $lineage); + } + + foreach ($r->getInterfaces() as $parent) { + $this->collectLineage($parent->name, $lineage); + } + + foreach ($r->getTraits() as $parent) { + $this->collectLineage($parent->name, $lineage); + } + + unset($lineage[$class]); + $lineage[$class] = substr($exportedFile, 1, -1); + } + + private function generateProxyClasses(): array + { + $proxyClasses = []; + $alreadyGenerated = []; + $definitions = $this->container->getDefinitions(); + $strip = '' === $this->docStar && method_exists('Symfony\Component\HttpKernel\Kernel', 'stripComments'); + $proxyDumper = $this->getProxyDumper(); + ksort($definitions); + foreach ($definitions as $definition) { + if (!$proxyDumper->isProxyCandidate($definition)) { + continue; + } + if (isset($alreadyGenerated[$class = $definition->getClass()])) { + continue; + } + $alreadyGenerated[$class] = true; + // register class' reflector for resource tracking + $this->container->getReflectionClass($class); + if ("\n" === $proxyCode = "\n".$proxyDumper->getProxyCode($definition)) { + continue; + } + + if ($this->inlineRequires) { + $lineage = []; + $this->collectLineage($class, $lineage); + + $code = ''; + foreach (array_diff_key(array_flip($lineage), $this->inlinedRequires) as $file => $class) { + if ($this->inlineFactories) { + $this->inlinedRequires[$file] = true; + } + $code .= sprintf("include_once %s;\n", $file); + } + + $proxyCode = $code.$proxyCode; + } + + if ($strip) { + $proxyCode = "<?php\n".$proxyCode; + $proxyCode = substr(Kernel::stripComments($proxyCode), 5); + } + + $proxyClasses[sprintf('%s.php', explode(' ', $this->inlineRequires ? substr($proxyCode, \strlen($code)) : $proxyCode, 3)[1])] = $proxyCode; + } + + return $proxyClasses; + } + + private function addServiceInclude(string $cId, Definition $definition): string + { + $code = ''; + + if ($this->inlineRequires && (!$this->isHotPath($definition) || $this->getProxyDumper()->isProxyCandidate($definition))) { + $lineage = []; + foreach ($this->inlinedDefinitions as $def) { + if (!$def->isDeprecated() && \is_string($class = \is_array($factory = $def->getFactory()) && \is_string($factory[0]) ? $factory[0] : $def->getClass())) { + $this->collectLineage($class, $lineage); + } + } + + foreach ($this->serviceCalls as $id => list($callCount, $behavior)) { + if ('service_container' !== $id && $id !== $cId + && ContainerInterface::IGNORE_ON_UNINITIALIZED_REFERENCE !== $behavior + && $this->container->has($id) + && $this->isTrivialInstance($def = $this->container->findDefinition($id)) + && \is_string($class = \is_array($factory = $def->getFactory()) && \is_string($factory[0]) ? $factory[0] : $def->getClass()) + ) { + $this->collectLineage($class, $lineage); + } + } + + foreach (array_diff_key(array_flip($lineage), $this->inlinedRequires) as $file => $class) { + $code .= sprintf(" include_once %s;\n", $file); + } + } + + foreach ($this->inlinedDefinitions as $def) { + if ($file = $def->getFile()) { + $file = $this->dumpValue($file); + $file = '(' === $file[0] ? substr($file, 1, -1) : $file; + $code .= sprintf(" include_once %s;\n", $file); + } + } + + if ('' !== $code) { + $code .= "\n"; + } + + return $code; + } + + /** + * @throws InvalidArgumentException + * @throws RuntimeException + */ + private function addServiceInstance(string $id, Definition $definition, bool $isSimpleInstance): string + { + $class = $this->dumpValue($definition->getClass()); + + if (0 === strpos($class, "'") && false === strpos($class, '$') && !preg_match('/^\'(?:\\\{2})?[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*(?:\\\{2}[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*)*\'$/', $class)) { + throw new InvalidArgumentException(sprintf('"%s" is not a valid class name for the "%s" service.', $class, $id)); + } + + $isProxyCandidate = $this->getProxyDumper()->isProxyCandidate($definition); + $instantiation = ''; + + $lastWitherIndex = null; + foreach ($definition->getMethodCalls() as $k => $call) { + if ($call[2] ?? false) { + $lastWitherIndex = $k; + } + } + + if (!$isProxyCandidate && $definition->isShared() && !isset($this->singleUsePrivateIds[$id]) && null === $lastWitherIndex) { + $instantiation = sprintf('$this->%s[%s] = %s', $this->container->getDefinition($id)->isPublic() ? 'services' : 'privates', $this->doExport($id), $isSimpleInstance ? '' : '$instance'); + } elseif (!$isSimpleInstance) { + $instantiation = '$instance'; + } + + $return = ''; + if ($isSimpleInstance) { + $return = 'return '; + } else { + $instantiation .= ' = '; + } + + return $this->addNewInstance($definition, ' '.$return.$instantiation, $id); + } + + private function isTrivialInstance(Definition $definition): bool + { + if ($definition->hasErrors()) { + return true; + } + if ($definition->isSynthetic() || $definition->getFile() || $definition->getMethodCalls() || $definition->getProperties() || $definition->getConfigurator()) { + return false; + } + if ($definition->isDeprecated() || $definition->isLazy() || $definition->getFactory() || 3 < \count($definition->getArguments())) { + return false; + } + + foreach ($definition->getArguments() as $arg) { + if (!$arg || $arg instanceof Parameter) { + continue; + } + if (\is_array($arg) && 3 >= \count($arg)) { + foreach ($arg as $k => $v) { + if ($this->dumpValue($k) !== $this->dumpValue($k, false)) { + return false; + } + if (!$v || $v instanceof Parameter) { + continue; + } + if ($v instanceof Reference && $this->container->has($id = (string) $v) && $this->container->findDefinition($id)->isSynthetic()) { + continue; + } + if (!is_scalar($v) || $this->dumpValue($v) !== $this->dumpValue($v, false)) { + return false; + } + } + } elseif ($arg instanceof Reference && $this->container->has($id = (string) $arg) && $this->container->findDefinition($id)->isSynthetic()) { + continue; + } elseif (!is_scalar($arg) || $this->dumpValue($arg) !== $this->dumpValue($arg, false)) { + return false; + } + } + + return true; + } + + private function addServiceMethodCalls(Definition $definition, string $variableName, ?string $sharedNonLazyId): string + { + $lastWitherIndex = null; + foreach ($definition->getMethodCalls() as $k => $call) { + if ($call[2] ?? false) { + $lastWitherIndex = $k; + } + } + + $calls = ''; + foreach ($definition->getMethodCalls() as $k => $call) { + $arguments = []; + foreach ($call[1] as $value) { + $arguments[] = $this->dumpValue($value); + } + + $witherAssignation = ''; + + if ($call[2] ?? false) { + if (null !== $sharedNonLazyId && $lastWitherIndex === $k) { + $witherAssignation = sprintf('$this->%s[\'%s\'] = ', $definition->isPublic() ? 'services' : 'privates', $sharedNonLazyId); + } + $witherAssignation .= sprintf('$%s = ', $variableName); + } + + $calls .= $this->wrapServiceConditionals($call[1], sprintf(" %s\$%s->%s(%s);\n", $witherAssignation, $variableName, $call[0], implode(', ', $arguments))); + } + + return $calls; + } + + private function addServiceProperties(Definition $definition, string $variableName = 'instance'): string + { + $code = ''; + foreach ($definition->getProperties() as $name => $value) { + $code .= sprintf(" \$%s->%s = %s;\n", $variableName, $name, $this->dumpValue($value)); + } + + return $code; + } + + private function addServiceConfigurator(Definition $definition, string $variableName = 'instance'): string + { + if (!$callable = $definition->getConfigurator()) { + return ''; + } + + if (\is_array($callable)) { + if ($callable[0] instanceof Reference + || ($callable[0] instanceof Definition && $this->definitionVariables->contains($callable[0])) + ) { + return sprintf(" %s->%s(\$%s);\n", $this->dumpValue($callable[0]), $callable[1], $variableName); + } + + $class = $this->dumpValue($callable[0]); + // If the class is a string we can optimize away + if (0 === strpos($class, "'") && false === strpos($class, '$')) { + return sprintf(" %s::%s(\$%s);\n", $this->dumpLiteralClass($class), $callable[1], $variableName); + } + + if (0 === strpos($class, 'new ')) { + return sprintf(" (%s)->%s(\$%s);\n", $this->dumpValue($callable[0]), $callable[1], $variableName); + } + + return sprintf(" [%s, '%s'](\$%s);\n", $this->dumpValue($callable[0]), $callable[1], $variableName); + } + + return sprintf(" %s(\$%s);\n", $callable, $variableName); + } + + private function addService(string $id, Definition $definition): array + { + $this->definitionVariables = new \SplObjectStorage(); + $this->referenceVariables = []; + $this->variableCount = 0; + $this->referenceVariables[$id] = new Variable('instance'); + + $return = []; + + if ($class = $definition->getClass()) { + $class = $class instanceof Parameter ? '%'.$class.'%' : $this->container->resolveEnvPlaceholders($class); + $return[] = sprintf(0 === strpos($class, '%') ? '@return object A %1$s instance' : '@return \%s', ltrim($class, '\\')); + } elseif ($definition->getFactory()) { + $factory = $definition->getFactory(); + if (\is_string($factory)) { + $return[] = sprintf('@return object An instance returned by %s()', $factory); + } elseif (\is_array($factory) && (\is_string($factory[0]) || $factory[0] instanceof Definition || $factory[0] instanceof Reference)) { + $class = $factory[0] instanceof Definition ? $factory[0]->getClass() : (string) $factory[0]; + $class = $class instanceof Parameter ? '%'.$class.'%' : $this->container->resolveEnvPlaceholders($class); + $return[] = sprintf('@return object An instance returned by %s::%s()', $class, $factory[1]); + } + } + + if ($definition->isDeprecated()) { + if ($return && 0 === strpos($return[\count($return) - 1], '@return')) { + $return[] = ''; + } + + $return[] = sprintf('@deprecated %s', $definition->getDeprecationMessage($id)); + } + + $return = str_replace("\n * \n", "\n *\n", implode("\n * ", $return)); + $return = $this->container->resolveEnvPlaceholders($return); + + $shared = $definition->isShared() ? ' shared' : ''; + $public = $definition->isPublic() ? 'public' : 'private'; + $autowired = $definition->isAutowired() ? ' autowired' : ''; + + if ($definition->isLazy()) { + $lazyInitialization = '$lazyLoad = true'; + } else { + $lazyInitialization = ''; + } + + $asFile = $this->asFiles && !$this->inlineFactories && !$this->isHotPath($definition); + $methodName = $this->generateMethodName($id); + if ($asFile) { + $file = $methodName.'.php'; + $code = " // Returns the $public '$id'$shared$autowired service.\n\n"; + } else { + $file = null; + $code = <<<EOF + + /*{$this->docStar} + * Gets the $public '$id'$shared$autowired service. + * + * $return +EOF; + $code = str_replace('*/', ' ', $code).<<<EOF + + */ + protected function {$methodName}($lazyInitialization) + { + +EOF; + } + + $this->serviceCalls = []; + $this->inlinedDefinitions = $this->getDefinitionsFromArguments([$definition], null, $this->serviceCalls); + + if ($definition->isDeprecated()) { + $code .= sprintf(" @trigger_error(%s, E_USER_DEPRECATED);\n\n", $this->export($definition->getDeprecationMessage($id))); + } + + if ($this->getProxyDumper()->isProxyCandidate($definition)) { + $factoryCode = $asFile ? ($definition->isShared() ? "\$this->load('%s.php', false)" : '$this->factories[%2$s](false)') : '$this->%s(false)'; + $code .= $this->getProxyDumper()->getProxyFactoryCode($definition, $id, sprintf($factoryCode, $methodName, $this->doExport($id))); + } + + $code .= $this->addServiceInclude($id, $definition); + $code .= $this->addInlineService($id, $definition); + + if ($asFile) { + $code = implode("\n", array_map(function ($line) { return $line ? substr($line, 8) : $line; }, explode("\n", $code))); + } else { + $code .= " }\n"; + } + + $this->definitionVariables = $this->inlinedDefinitions = null; + $this->referenceVariables = $this->serviceCalls = null; + + return [$file, $code]; + } + + private function addInlineVariables(string $id, Definition $definition, array $arguments, bool $forConstructor): string + { + $code = ''; + + foreach ($arguments as $argument) { + if (\is_array($argument)) { + $code .= $this->addInlineVariables($id, $definition, $argument, $forConstructor); + } elseif ($argument instanceof Reference) { + $code .= $this->addInlineReference($id, $definition, $argument, $forConstructor); + } elseif ($argument instanceof Definition) { + $code .= $this->addInlineService($id, $definition, $argument, $forConstructor); + } + } + + return $code; + } + + private function addInlineReference(string $id, Definition $definition, string $targetId, bool $forConstructor): string + { + while ($this->container->hasAlias($targetId)) { + $targetId = (string) $this->container->getAlias($targetId); + } + + list($callCount, $behavior) = $this->serviceCalls[$targetId]; + + if ($id === $targetId) { + return $this->addInlineService($id, $definition, $definition); + } + + if ('service_container' === $targetId || isset($this->referenceVariables[$targetId])) { + return ''; + } + + $hasSelfRef = isset($this->circularReferences[$id][$targetId]) && !isset($this->definitionVariables[$definition]); + + if ($hasSelfRef && !$forConstructor && !$forConstructor = !$this->circularReferences[$id][$targetId]) { + $code = $this->addInlineService($id, $definition, $definition); + } else { + $code = ''; + } + + if (isset($this->referenceVariables[$targetId]) || (2 > $callCount && (!$hasSelfRef || !$forConstructor))) { + return $code; + } + + $name = $this->getNextVariableName(); + $this->referenceVariables[$targetId] = new Variable($name); + + $reference = ContainerInterface::EXCEPTION_ON_INVALID_REFERENCE >= $behavior ? new Reference($targetId, $behavior) : null; + $code .= sprintf(" \$%s = %s;\n", $name, $this->getServiceCall($targetId, $reference)); + + if (!$hasSelfRef || !$forConstructor) { + return $code; + } + + $code .= sprintf(<<<'EOTXT' + + if (isset($this->%s[%s])) { + return $this->%1$s[%2$s]; + } + +EOTXT + , + $this->container->getDefinition($id)->isPublic() ? 'services' : 'privates', + $this->doExport($id) + ); + + return $code; + } + + private function addInlineService(string $id, Definition $definition, Definition $inlineDef = null, bool $forConstructor = true): string + { + $code = ''; + + if ($isSimpleInstance = $isRootInstance = null === $inlineDef) { + foreach ($this->serviceCalls as $targetId => list($callCount, $behavior, $byConstructor)) { + if ($byConstructor && isset($this->circularReferences[$id][$targetId]) && !$this->circularReferences[$id][$targetId]) { + $code .= $this->addInlineReference($id, $definition, $targetId, $forConstructor); + } + } + } + + if (isset($this->definitionVariables[$inlineDef = $inlineDef ?: $definition])) { + return $code; + } + + $arguments = [$inlineDef->getArguments(), $inlineDef->getFactory()]; + + $code .= $this->addInlineVariables($id, $definition, $arguments, $forConstructor); + + if ($arguments = array_filter([$inlineDef->getProperties(), $inlineDef->getMethodCalls(), $inlineDef->getConfigurator()])) { + $isSimpleInstance = false; + } elseif ($definition !== $inlineDef && 2 > $this->inlinedDefinitions[$inlineDef]) { + return $code; + } + + if (isset($this->definitionVariables[$inlineDef])) { + $isSimpleInstance = false; + } else { + $name = $definition === $inlineDef ? 'instance' : $this->getNextVariableName(); + $this->definitionVariables[$inlineDef] = new Variable($name); + $code .= '' !== $code ? "\n" : ''; + + if ('instance' === $name) { + $code .= $this->addServiceInstance($id, $definition, $isSimpleInstance); + } else { + $code .= $this->addNewInstance($inlineDef, ' $'.$name.' = ', $id); + } + + if ('' !== $inline = $this->addInlineVariables($id, $definition, $arguments, false)) { + $code .= "\n".$inline."\n"; + } elseif ($arguments && 'instance' === $name) { + $code .= "\n"; + } + + $code .= $this->addServiceProperties($inlineDef, $name); + $code .= $this->addServiceMethodCalls($inlineDef, $name, !$this->getProxyDumper()->isProxyCandidate($inlineDef) && $inlineDef->isShared() && !isset($this->singleUsePrivateIds[$id]) ? $id : null); + $code .= $this->addServiceConfigurator($inlineDef, $name); + } + + if ($isRootInstance && !$isSimpleInstance) { + $code .= "\n return \$instance;\n"; + } + + return $code; + } + + private function addServices(array &$services = null): string + { + $publicServices = $privateServices = ''; + $definitions = $this->container->getDefinitions(); + ksort($definitions); + foreach ($definitions as $id => $definition) { + $services[$id] = $definition->isSynthetic() ? null : $this->addService($id, $definition); + } + + foreach ($definitions as $id => $definition) { + if (!(list($file, $code) = $services[$id]) || null !== $file) { + continue; + } + if ($definition->isPublic()) { + $publicServices .= $code; + } elseif (!$this->isTrivialInstance($definition) || isset($this->locatedIds[$id])) { + $privateServices .= $code; + } + } + + return $publicServices.$privateServices; + } + + private function generateServiceFiles(array $services): iterable + { + $definitions = $this->container->getDefinitions(); + ksort($definitions); + foreach ($definitions as $id => $definition) { + if ((list($file, $code) = $services[$id]) && null !== $file && ($definition->isPublic() || !$this->isTrivialInstance($definition) || isset($this->locatedIds[$id]))) { + if (!$definition->isShared()) { + $i = strpos($code, "\n\ninclude_once "); + if (false !== $i && false !== $i = strpos($code, "\n\n", 2 + $i)) { + $code = [substr($code, 0, 2 + $i), substr($code, 2 + $i)]; + } else { + $code = ["\n", $code]; + } + $code[1] = implode("\n", array_map(function ($line) { return $line ? ' '.$line : $line; }, explode("\n", $code[1]))); + $factory = sprintf('$this->factories%s[%s]', $definition->isPublic() ? '' : "['service_container']", $this->doExport($id)); + $lazyloadInitialization = $definition->isLazy() ? '$lazyLoad = true' : ''; + + $code[1] = sprintf("%s = function (%s) {\n%s};\n\nreturn %1\$s();\n", $factory, $lazyloadInitialization, $code[1]); + $code = $code[0].$code[1]; + } + + yield $file => $code; + } + } + } + + private function addNewInstance(Definition $definition, string $return = '', string $id = null): string + { + $tail = $return ? ";\n" : ''; + + if (BaseServiceLocator::class === $definition->getClass() && $definition->hasTag($this->serviceLocatorTag)) { + $arguments = []; + foreach ($definition->getArgument(0) as $k => $argument) { + $arguments[$k] = $argument->getValues()[0]; + } + + return $return.$this->dumpValue(new ServiceLocatorArgument($arguments)).$tail; + } + + $arguments = []; + foreach ($definition->getArguments() as $value) { + $arguments[] = $this->dumpValue($value); + } + + if (null !== $definition->getFactory()) { + $callable = $definition->getFactory(); + + if (\is_array($callable)) { + if (!preg_match('/^[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*$/', $callable[1])) { + throw new RuntimeException(sprintf('Cannot dump definition because of invalid factory method (%s)', $callable[1] ?: 'n/a')); + } + + if ($callable[0] instanceof Reference + || ($callable[0] instanceof Definition && $this->definitionVariables->contains($callable[0]))) { + return $return.sprintf('%s->%s(%s)', $this->dumpValue($callable[0]), $callable[1], $arguments ? implode(', ', $arguments) : '').$tail; + } + + $class = $this->dumpValue($callable[0]); + // If the class is a string we can optimize away + if (0 === strpos($class, "'") && false === strpos($class, '$')) { + if ("''" === $class) { + throw new RuntimeException(sprintf('Cannot dump definition: %s service is defined to be created by a factory but is missing the service reference, did you forget to define the factory service id or class?', $id ? 'The "'.$id.'"' : 'inline')); + } + + return $return.sprintf('%s::%s(%s)', $this->dumpLiteralClass($class), $callable[1], $arguments ? implode(', ', $arguments) : '').$tail; + } + + if (0 === strpos($class, 'new ')) { + return $return.sprintf('(%s)->%s(%s)', $class, $callable[1], $arguments ? implode(', ', $arguments) : '').$tail; + } + + return $return.sprintf("[%s, '%s'](%s)", $class, $callable[1], $arguments ? implode(', ', $arguments) : '').$tail; + } + + return $return.sprintf('%s(%s)', $this->dumpLiteralClass($this->dumpValue($callable)), $arguments ? implode(', ', $arguments) : '').$tail; + } + + if (null === $class = $definition->getClass()) { + throw new RuntimeException('Cannot dump definitions which have no class nor factory.'); + } + + return $return.sprintf('new %s(%s)', $this->dumpLiteralClass($this->dumpValue($class)), implode(', ', $arguments)).$tail; + } + + private function startClass(string $class, string $baseClass, ?array &$preload): string + { + $namespaceLine = !$this->asFiles && $this->namespace ? "\nnamespace {$this->namespace};\n" : ''; + + $code = <<<EOF +<?php +$namespaceLine +use Symfony\Component\DependencyInjection\Argument\RewindableGenerator; +use Symfony\Component\DependencyInjection\ContainerInterface; +use Symfony\Component\DependencyInjection\Container; +use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException; +use Symfony\Component\DependencyInjection\Exception\LogicException; +use Symfony\Component\DependencyInjection\Exception\RuntimeException; +use Symfony\Component\DependencyInjection\ParameterBag\FrozenParameterBag; +use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface; + +/*{$this->docStar} + * This class has been auto-generated + * by the Symfony Dependency Injection Component. + * + * @final + */ +class $class extends $baseClass +{ + private \$parameters = []; + + public function __construct() + { + +EOF; + if ($this->asFiles) { + $code = str_replace('$parameters', "\$buildParameters;\n private \$containerDir;\n private \$parameters", $code); + $code = str_replace('__construct()', '__construct(array $buildParameters = [], $containerDir = __DIR__)', $code); + $code .= " \$this->buildParameters = \$buildParameters;\n"; + $code .= " \$this->containerDir = \$containerDir;\n"; + + if (null !== $this->targetDirRegex) { + $code = str_replace('$parameters', "\$targetDir;\n private \$parameters", $code); + $code .= ' $this->targetDir = \\dirname($containerDir);'."\n"; + } + } + + if (Container::class !== $this->baseClass) { + $r = $this->container->getReflectionClass($this->baseClass, false); + if (null !== $r + && (null !== $constructor = $r->getConstructor()) + && 0 === $constructor->getNumberOfRequiredParameters() + && Container::class !== $constructor->getDeclaringClass()->name + ) { + $code .= " parent::__construct();\n"; + $code .= " \$this->parameterBag = null;\n\n"; + } + } + + if ($this->container->getParameterBag()->all()) { + $code .= " \$this->parameters = \$this->getDefaultParameters();\n\n"; + } + $code .= " \$this->services = \$this->privates = [];\n"; + + $code .= $this->addSyntheticIds(); + $code .= $this->addMethodMap(); + $code .= $this->asFiles && !$this->inlineFactories ? $this->addFileMap() : ''; + $code .= $this->addAliases(); + $code .= $this->addInlineRequires($preload); + $code .= <<<EOF + } + + public function compile(): void + { + throw new LogicException('You cannot compile a dumped container that was already compiled.'); + } + + public function isCompiled(): bool + { + return true; + } + +EOF; + $code .= $this->addRemovedIds(); + + if ($this->asFiles && !$this->inlineFactories) { + $code .= <<<EOF + + protected function load(\$file, \$lazyLoad = true) + { + return require \$this->containerDir.\\DIRECTORY_SEPARATOR.\$file; + } + +EOF; + } + + $proxyDumper = $this->getProxyDumper(); + foreach ($this->container->getDefinitions() as $definition) { + if (!$proxyDumper->isProxyCandidate($definition)) { + continue; + } + if ($this->asFiles && !$this->inlineFactories) { + $proxyLoader = '$this->load("{$class}.php")'; + } elseif ($this->namespace || $this->inlineFactories) { + $proxyLoader = 'class_alias(__NAMESPACE__."\\\\$class", $class, false)'; + } else { + $proxyLoader = ''; + } + if ($proxyLoader) { + $proxyLoader = "class_exists(\$class, false) || {$proxyLoader};\n\n "; + } + $code .= <<<EOF + + protected function createProxy(\$class, \Closure \$factory) + { + {$proxyLoader}return \$factory(); + } + +EOF; + break; + } + + return $code; + } + + private function addSyntheticIds(): string + { + $code = ''; + $definitions = $this->container->getDefinitions(); + ksort($definitions); + foreach ($definitions as $id => $definition) { + if ($definition->isSynthetic() && 'service_container' !== $id) { + $code .= ' '.$this->doExport($id)." => true,\n"; + } + } + + return $code ? " \$this->syntheticIds = [\n{$code} ];\n" : ''; + } + + private function addRemovedIds(): string + { + $ids = $this->container->getRemovedIds(); + foreach ($this->container->getDefinitions() as $id => $definition) { + if (!$definition->isPublic()) { + $ids[$id] = true; + } + } + if (!$ids) { + return ''; + } + if ($this->asFiles) { + $code = "require \$this->containerDir.\\DIRECTORY_SEPARATOR.'removed-ids.php'"; + } else { + $code = ''; + $ids = array_keys($ids); + sort($ids); + foreach ($ids as $id) { + if (preg_match(FileLoader::ANONYMOUS_ID_REGEXP, $id)) { + continue; + } + $code .= ' '.$this->doExport($id)." => true,\n"; + } + + $code = "[\n{$code} ]"; + } + + return <<<EOF + + public function getRemovedIds(): array + { + return {$code}; + } + +EOF; + } + + private function addMethodMap(): string + { + $code = ''; + $definitions = $this->container->getDefinitions(); + ksort($definitions); + foreach ($definitions as $id => $definition) { + if (!$definition->isSynthetic() && $definition->isPublic() && (!$this->asFiles || $this->inlineFactories || $this->isHotPath($definition))) { + $code .= ' '.$this->doExport($id).' => '.$this->doExport($this->generateMethodName($id)).",\n"; + } + } + + $aliases = $this->container->getAliases(); + foreach ($aliases as $alias => $id) { + if (!$id->isDeprecated()) { + continue; + } + $code .= ' '.$this->doExport($alias).' => '.$this->doExport($this->generateMethodName($alias)).",\n"; + } + + return $code ? " \$this->methodMap = [\n{$code} ];\n" : ''; + } + + private function addFileMap(): string + { + $code = ''; + $definitions = $this->container->getDefinitions(); + ksort($definitions); + foreach ($definitions as $id => $definition) { + if (!$definition->isSynthetic() && $definition->isPublic() && !$this->isHotPath($definition)) { + $code .= sprintf(" %s => '%s.php',\n", $this->doExport($id), $this->generateMethodName($id)); + } + } + + return $code ? " \$this->fileMap = [\n{$code} ];\n" : ''; + } + + private function addAliases(): string + { + if (!$aliases = $this->container->getAliases()) { + return "\n \$this->aliases = [];\n"; + } + + $code = " \$this->aliases = [\n"; + ksort($aliases); + foreach ($aliases as $alias => $id) { + if ($id->isDeprecated()) { + continue; + } + + $id = (string) $id; + while (isset($aliases[$id])) { + $id = (string) $aliases[$id]; + } + $code .= ' '.$this->doExport($alias).' => '.$this->doExport($id).",\n"; + } + + return $code." ];\n"; + } + + private function addDeprecatedAliases(): string + { + $code = ''; + $aliases = $this->container->getAliases(); + foreach ($aliases as $alias => $definition) { + if (!$definition->isDeprecated()) { + continue; + } + $public = $definition->isPublic() ? 'public' : 'private'; + $id = (string) $definition; + $methodNameAlias = $this->generateMethodName($alias); + $idExported = $this->export($id); + $messageExported = $this->export($definition->getDeprecationMessage($alias)); + $code .= <<<EOF + + /*{$this->docStar} + * Gets the $public '$alias' alias. + * + * @return object The "$id" service. + */ + protected function {$methodNameAlias}() + { + @trigger_error($messageExported, E_USER_DEPRECATED); + + return \$this->get($idExported); + } + +EOF; + } + + return $code; + } + + private function addInlineRequires(?array &$preload): string + { + if (!$this->hotPathTag || !$this->inlineRequires) { + return ''; + } + + $lineage = []; + + foreach ($this->container->findTaggedServiceIds($this->hotPathTag) as $id => $tags) { + $definition = $this->container->getDefinition($id); + + if ($this->getProxyDumper()->isProxyCandidate($definition)) { + continue; + } + + $inlinedDefinitions = $this->getDefinitionsFromArguments([$definition]); + + foreach ($inlinedDefinitions as $def) { + if (\is_string($class = \is_array($factory = $def->getFactory()) && \is_string($factory[0]) ? $factory[0] : $def->getClass())) { + $preload[$class] = $class; + $this->collectLineage($class, $lineage); + } + } + } + + $code = ''; + + foreach ($lineage as $file) { + if (!isset($this->inlinedRequires[$file])) { + $this->inlinedRequires[$file] = true; + $code .= sprintf("\n include_once %s;", $file); + } + } + + return $code ? sprintf("\n \$this->privates['service_container'] = function () {%s\n };\n", $code) : ''; + } + + private function addDefaultParametersMethod(): string + { + if (!$this->container->getParameterBag()->all()) { + return ''; + } + + $php = []; + $dynamicPhp = []; + + foreach ($this->container->getParameterBag()->all() as $key => $value) { + if ($key !== $resolvedKey = $this->container->resolveEnvPlaceholders($key)) { + throw new InvalidArgumentException(sprintf('Parameter name cannot use env parameters: %s.', $resolvedKey)); + } + $export = $this->exportParameters([$value]); + $export = explode('0 => ', substr(rtrim($export, " ]\n"), 2, -1), 2); + + if (preg_match("/\\\$this->(?:getEnv\('(?:\w++:)*+\w++'\)|targetDir\.'')/", $export[1])) { + $dynamicPhp[$key] = sprintf('%scase %s: $value = %s; break;', $export[0], $this->export($key), $export[1]); + } else { + $php[] = sprintf('%s%s => %s,', $export[0], $this->export($key), $export[1]); + } + } + $parameters = sprintf("[\n%s\n%s]", implode("\n", $php), str_repeat(' ', 8)); + + $code = <<<'EOF' + + public function getParameter($name) + { + $name = (string) $name; + if (isset($this->buildParameters[$name])) { + return $this->buildParameters[$name]; + } + + if (!(isset($this->parameters[$name]) || isset($this->loadedDynamicParameters[$name]) || array_key_exists($name, $this->parameters))) { + throw new InvalidArgumentException(sprintf('The parameter "%s" must be defined.', $name)); + } + if (isset($this->loadedDynamicParameters[$name])) { + return $this->loadedDynamicParameters[$name] ? $this->dynamicParameters[$name] : $this->getDynamicParameter($name); + } + + return $this->parameters[$name]; + } + + public function hasParameter($name): bool + { + $name = (string) $name; + if (isset($this->buildParameters[$name])) { + return true; + } + + return isset($this->parameters[$name]) || isset($this->loadedDynamicParameters[$name]) || array_key_exists($name, $this->parameters); + } + + public function setParameter($name, $value): void + { + throw new LogicException('Impossible to call set() on a frozen ParameterBag.'); + } + + public function getParameterBag(): ParameterBagInterface + { + if (null === $this->parameterBag) { + $parameters = $this->parameters; + foreach ($this->loadedDynamicParameters as $name => $loaded) { + $parameters[$name] = $loaded ? $this->dynamicParameters[$name] : $this->getDynamicParameter($name); + } + foreach ($this->buildParameters as $name => $value) { + $parameters[$name] = $value; + } + $this->parameterBag = new FrozenParameterBag($parameters); + } + + return $this->parameterBag; + } + +EOF; + if (!$this->asFiles) { + $code = preg_replace('/^.*buildParameters.*\n.*\n.*\n/m', '', $code); + } + + if ($dynamicPhp) { + $loadedDynamicParameters = $this->exportParameters(array_combine(array_keys($dynamicPhp), array_fill(0, \count($dynamicPhp), false)), '', 8); + $getDynamicParameter = <<<'EOF' + switch ($name) { +%s + default: throw new InvalidArgumentException(sprintf('The dynamic parameter "%%s" must be defined.', $name)); + } + $this->loadedDynamicParameters[$name] = true; + + return $this->dynamicParameters[$name] = $value; +EOF; + $getDynamicParameter = sprintf($getDynamicParameter, implode("\n", $dynamicPhp)); + } else { + $loadedDynamicParameters = '[]'; + $getDynamicParameter = str_repeat(' ', 8).'throw new InvalidArgumentException(sprintf(\'The dynamic parameter "%s" must be defined.\', $name));'; + } + + $code .= <<<EOF + + private \$loadedDynamicParameters = {$loadedDynamicParameters}; + private \$dynamicParameters = []; + + private function getDynamicParameter(string \$name) + { +{$getDynamicParameter} + } + + protected function getDefaultParameters(): array + { + return $parameters; + } + +EOF; + + return $code; + } + + /** + * @throws InvalidArgumentException + */ + private function exportParameters(array $parameters, string $path = '', int $indent = 12): string + { + $php = []; + foreach ($parameters as $key => $value) { + if (\is_array($value)) { + $value = $this->exportParameters($value, $path.'/'.$key, $indent + 4); + } elseif ($value instanceof ArgumentInterface) { + throw new InvalidArgumentException(sprintf('You cannot dump a container with parameters that contain special arguments. "%s" found in "%s".', \get_class($value), $path.'/'.$key)); + } elseif ($value instanceof Variable) { + throw new InvalidArgumentException(sprintf('You cannot dump a container with parameters that contain variable references. Variable "%s" found in "%s".', $value, $path.'/'.$key)); + } elseif ($value instanceof Definition) { + throw new InvalidArgumentException(sprintf('You cannot dump a container with parameters that contain service definitions. Definition for "%s" found in "%s".', $value->getClass(), $path.'/'.$key)); + } elseif ($value instanceof Reference) { + throw new InvalidArgumentException(sprintf('You cannot dump a container with parameters that contain references to other services (reference to service "%s" found in "%s").', $value, $path.'/'.$key)); + } elseif ($value instanceof Expression) { + throw new InvalidArgumentException(sprintf('You cannot dump a container with parameters that contain expressions. Expression "%s" found in "%s".', $value, $path.'/'.$key)); + } else { + $value = $this->export($value); + } + + $php[] = sprintf('%s%s => %s,', str_repeat(' ', $indent), $this->export($key), $value); + } + + return sprintf("[\n%s\n%s]", implode("\n", $php), str_repeat(' ', $indent - 4)); + } + + private function endClass(): string + { + if ($this->addThrow) { + return <<<'EOF' + + protected function throw($message) + { + throw new RuntimeException($message); + } +} + +EOF; + } + + return <<<'EOF' +} + +EOF; + } + + private function wrapServiceConditionals($value, string $code): string + { + if (!$condition = $this->getServiceConditionals($value)) { + return $code; + } + + // re-indent the wrapped code + $code = implode("\n", array_map(function ($line) { return $line ? ' '.$line : $line; }, explode("\n", $code))); + + return sprintf(" if (%s) {\n%s }\n", $condition, $code); + } + + private function getServiceConditionals($value): string + { + $conditions = []; + foreach (ContainerBuilder::getInitializedConditionals($value) as $service) { + if (!$this->container->hasDefinition($service)) { + return 'false'; + } + $conditions[] = sprintf('isset($this->%s[%s])', $this->container->getDefinition($service)->isPublic() ? 'services' : 'privates', $this->doExport($service)); + } + foreach (ContainerBuilder::getServiceConditionals($value) as $service) { + if ($this->container->hasDefinition($service) && !$this->container->getDefinition($service)->isPublic()) { + continue; + } + + $conditions[] = sprintf('$this->has(%s)', $this->doExport($service)); + } + + if (!$conditions) { + return ''; + } + + return implode(' && ', $conditions); + } + + private function getDefinitionsFromArguments(array $arguments, \SplObjectStorage $definitions = null, array &$calls = [], bool $byConstructor = null): \SplObjectStorage + { + if (null === $definitions) { + $definitions = new \SplObjectStorage(); + } + + foreach ($arguments as $argument) { + if (\is_array($argument)) { + $this->getDefinitionsFromArguments($argument, $definitions, $calls, $byConstructor); + } elseif ($argument instanceof Reference) { + $id = (string) $argument; + + while ($this->container->hasAlias($id)) { + $id = (string) $this->container->getAlias($id); + } + + if (!isset($calls[$id])) { + $calls[$id] = [0, $argument->getInvalidBehavior(), $byConstructor]; + } else { + $calls[$id][1] = min($calls[$id][1], $argument->getInvalidBehavior()); + } + + ++$calls[$id][0]; + } elseif (!$argument instanceof Definition) { + // no-op + } elseif (isset($definitions[$argument])) { + $definitions[$argument] = 1 + $definitions[$argument]; + } else { + $definitions[$argument] = 1; + $arguments = [$argument->getArguments(), $argument->getFactory()]; + $this->getDefinitionsFromArguments($arguments, $definitions, $calls, null === $byConstructor || $byConstructor); + $arguments = [$argument->getProperties(), $argument->getMethodCalls(), $argument->getConfigurator()]; + $this->getDefinitionsFromArguments($arguments, $definitions, $calls, null !== $byConstructor && $byConstructor); + } + } + + return $definitions; + } + + /** + * @throws RuntimeException + */ + private function dumpValue($value, bool $interpolate = true): string + { + if (\is_array($value)) { + if ($value && $interpolate && false !== $param = array_search($value, $this->container->getParameterBag()->all(), true)) { + return $this->dumpValue("%$param%"); + } + $code = []; + foreach ($value as $k => $v) { + $code[] = sprintf('%s => %s', $this->dumpValue($k, $interpolate), $this->dumpValue($v, $interpolate)); + } + + return sprintf('[%s]', implode(', ', $code)); + } elseif ($value instanceof ArgumentInterface) { + $scope = [$this->definitionVariables, $this->referenceVariables]; + $this->definitionVariables = $this->referenceVariables = null; + + try { + if ($value instanceof ServiceClosureArgument) { + $value = $value->getValues()[0]; + $code = $this->dumpValue($value, $interpolate); + + $returnedType = ''; + if ($value instanceof TypedReference) { + $returnedType = sprintf(': %s\%s', ContainerInterface::EXCEPTION_ON_INVALID_REFERENCE >= $value->getInvalidBehavior() ? '' : '?', $value->getType()); + } + + $code = sprintf('return %s;', $code); + + return sprintf("function ()%s {\n %s\n }", $returnedType, $code); + } + + if ($value instanceof IteratorArgument) { + $operands = [0]; + $code = []; + $code[] = 'new RewindableGenerator(function () {'; + + if (!$values = $value->getValues()) { + $code[] = ' return new \EmptyIterator();'; + } else { + $countCode = []; + $countCode[] = 'function () {'; + + foreach ($values as $k => $v) { + ($c = $this->getServiceConditionals($v)) ? $operands[] = "(int) ($c)" : ++$operands[0]; + $v = $this->wrapServiceConditionals($v, sprintf(" yield %s => %s;\n", $this->dumpValue($k, $interpolate), $this->dumpValue($v, $interpolate))); + foreach (explode("\n", $v) as $v) { + if ($v) { + $code[] = ' '.$v; + } + } + } + + $countCode[] = sprintf(' return %s;', implode(' + ', $operands)); + $countCode[] = ' }'; + } + + $code[] = sprintf(' }, %s)', \count($operands) > 1 ? implode("\n", $countCode) : $operands[0]); + + return implode("\n", $code); + } + + if ($value instanceof ServiceLocatorArgument) { + $serviceMap = ''; + $serviceTypes = ''; + foreach ($value->getValues() as $k => $v) { + if (!$v) { + continue; + } + $definition = $this->container->findDefinition($id = (string) $v); + $load = !($definition->hasErrors() && $e = $definition->getErrors()) ? $this->asFiles && !$this->inlineFactories && !$this->isHotPath($definition) : reset($e); + $serviceMap .= sprintf("\n %s => [%s, %s, %s, %s],", + $this->export($k), + $this->export($definition->isShared() ? ($definition->isPublic() ? 'services' : 'privates') : false), + $this->doExport($id), + $this->export(ContainerInterface::IGNORE_ON_UNINITIALIZED_REFERENCE !== $v->getInvalidBehavior() && !\is_string($load) ? $this->generateMethodName($id).($load ? '.php' : '') : null), + $this->export($load) + ); + $serviceTypes .= sprintf("\n %s => %s,", $this->export($k), $this->export($v instanceof TypedReference ? $v->getType() : '?')); + $this->locatedIds[$id] = true; + } + $this->addGetService = true; + + return sprintf('new \%s($this->getService, [%s%s], [%s%s])', ServiceLocator::class, $serviceMap, $serviceMap ? "\n " : '', $serviceTypes, $serviceTypes ? "\n " : ''); + } + } finally { + list($this->definitionVariables, $this->referenceVariables) = $scope; + } + } elseif ($value instanceof Definition) { + if ($value->hasErrors() && $e = $value->getErrors()) { + $this->addThrow = true; + + return sprintf('$this->throw(%s)', $this->export(reset($e))); + } + if (null !== $this->definitionVariables && $this->definitionVariables->contains($value)) { + return $this->dumpValue($this->definitionVariables[$value], $interpolate); + } + if ($value->getMethodCalls()) { + throw new RuntimeException('Cannot dump definitions which have method calls.'); + } + if ($value->getProperties()) { + throw new RuntimeException('Cannot dump definitions which have properties.'); + } + if (null !== $value->getConfigurator()) { + throw new RuntimeException('Cannot dump definitions which have a configurator.'); + } + + return $this->addNewInstance($value); + } elseif ($value instanceof Variable) { + return '$'.$value; + } elseif ($value instanceof Reference) { + $id = (string) $value; + + while ($this->container->hasAlias($id)) { + $id = (string) $this->container->getAlias($id); + } + + if (null !== $this->referenceVariables && isset($this->referenceVariables[$id])) { + return $this->dumpValue($this->referenceVariables[$id], $interpolate); + } + + return $this->getServiceCall($id, $value); + } elseif ($value instanceof Expression) { + return $this->getExpressionLanguage()->compile((string) $value, ['this' => 'container']); + } elseif ($value instanceof Parameter) { + return $this->dumpParameter($value); + } elseif (true === $interpolate && \is_string($value)) { + if (preg_match('/^%([^%]+)%$/', $value, $match)) { + // we do this to deal with non string values (Boolean, integer, ...) + // the preg_replace_callback converts them to strings + return $this->dumpParameter($match[1]); + } else { + $replaceParameters = function ($match) { + return "'.".$this->dumpParameter($match[2]).".'"; + }; + + $code = str_replace('%%', '%', preg_replace_callback('/(?<!%)(%)([^%]+)\1/', $replaceParameters, $this->export($value))); + + return $code; + } + } elseif (\is_object($value) || \is_resource($value)) { + throw new RuntimeException('Unable to dump a service container if a parameter is an object or a resource.'); + } + + return $this->export($value); + } + + /** + * Dumps a string to a literal (aka PHP Code) class value. + * + * @throws RuntimeException + */ + private function dumpLiteralClass(string $class): string + { + if (false !== strpos($class, '$')) { + return sprintf('${($_ = %s) && false ?: "_"}', $class); + } + if (0 !== strpos($class, "'") || !preg_match('/^\'(?:\\\{2})?[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*(?:\\\{2}[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*)*\'$/', $class)) { + throw new RuntimeException(sprintf('Cannot dump definition because of invalid class name (%s)', $class ?: 'n/a')); + } + + $class = substr(str_replace('\\\\', '\\', $class), 1, -1); + + return 0 === strpos($class, '\\') ? $class : '\\'.$class; + } + + private function dumpParameter(string $name): string + { + if ($this->container->hasParameter($name)) { + $value = $this->container->getParameter($name); + $dumpedValue = $this->dumpValue($value, false); + + if (!$value || !\is_array($value)) { + return $dumpedValue; + } + + if (!preg_match("/\\\$this->(?:getEnv\('(?:\w++:)*+\w++'\)|targetDir\.'')/", $dumpedValue)) { + return sprintf('$this->parameters[%s]', $this->doExport($name)); + } + } + + return sprintf('$this->getParameter(%s)', $this->doExport($name)); + } + + private function getServiceCall(string $id, Reference $reference = null): string + { + while ($this->container->hasAlias($id)) { + $id = (string) $this->container->getAlias($id); + } + + if ('service_container' === $id) { + return '$this'; + } + + if ($this->container->hasDefinition($id) && $definition = $this->container->getDefinition($id)) { + if ($definition->isSynthetic()) { + $code = sprintf('$this->get(%s%s)', $this->doExport($id), null !== $reference ? ', '.$reference->getInvalidBehavior() : ''); + } elseif (null !== $reference && ContainerInterface::IGNORE_ON_UNINITIALIZED_REFERENCE === $reference->getInvalidBehavior()) { + $code = 'null'; + if (!$definition->isShared()) { + return $code; + } + } elseif ($this->isTrivialInstance($definition)) { + if ($definition->hasErrors() && $e = $definition->getErrors()) { + $this->addThrow = true; + + return sprintf('$this->throw(%s)', $this->export(reset($e))); + } + $code = $this->addNewInstance($definition, '', $id); + if ($definition->isShared() && !isset($this->singleUsePrivateIds[$id])) { + $code = sprintf('$this->%s[%s] = %s', $definition->isPublic() ? 'services' : 'privates', $this->doExport($id), $code); + } + $code = "($code)"; + } elseif ($this->asFiles && !$this->inlineFactories && !$this->isHotPath($definition)) { + $code = sprintf("\$this->load('%s.php')", $this->generateMethodName($id)); + if (!$definition->isShared()) { + $factory = sprintf('$this->factories%s[%s]', $definition->isPublic() ? '' : "['service_container']", $this->doExport($id)); + $code = sprintf('(isset(%s) ? %1$s() : %s)', $factory, $code); + } + } else { + $code = sprintf('$this->%s()', $this->generateMethodName($id)); + } + if ($definition->isShared() && !isset($this->singleUsePrivateIds[$id])) { + $code = sprintf('($this->%s[%s] ?? %s)', $definition->isPublic() ? 'services' : 'privates', $this->doExport($id), $code); + } + + return $code; + } + if (null !== $reference && ContainerInterface::IGNORE_ON_UNINITIALIZED_REFERENCE === $reference->getInvalidBehavior()) { + return 'null'; + } + if (null !== $reference && ContainerInterface::EXCEPTION_ON_INVALID_REFERENCE < $reference->getInvalidBehavior()) { + $code = sprintf('$this->get(%s, /* ContainerInterface::NULL_ON_INVALID_REFERENCE */ %d)', $this->doExport($id), ContainerInterface::NULL_ON_INVALID_REFERENCE); + } else { + $code = sprintf('$this->get(%s)', $this->doExport($id)); + } + + return sprintf('($this->services[%s] ?? %s)', $this->doExport($id), $code); + } + + /** + * Initializes the method names map to avoid conflicts with the Container methods. + */ + private function initializeMethodNamesMap(string $class) + { + $this->serviceIdToMethodNameMap = []; + $this->usedMethodNames = []; + + if ($reflectionClass = $this->container->getReflectionClass($class)) { + foreach ($reflectionClass->getMethods() as $method) { + $this->usedMethodNames[strtolower($method->getName())] = true; + } + } + } + + /** + * @throws InvalidArgumentException + */ + private function generateMethodName(string $id): string + { + if (isset($this->serviceIdToMethodNameMap[$id])) { + return $this->serviceIdToMethodNameMap[$id]; + } + + $i = strrpos($id, '\\'); + $name = Container::camelize(false !== $i && isset($id[1 + $i]) ? substr($id, 1 + $i) : $id); + $name = preg_replace('/[^a-zA-Z0-9_\x7f-\xff]/', '', $name); + $methodName = 'get'.$name.'Service'; + $suffix = 1; + + while (isset($this->usedMethodNames[strtolower($methodName)])) { + ++$suffix; + $methodName = 'get'.$name.$suffix.'Service'; + } + + $this->serviceIdToMethodNameMap[$id] = $methodName; + $this->usedMethodNames[strtolower($methodName)] = true; + + return $methodName; + } + + private function getNextVariableName(): string + { + $firstChars = self::FIRST_CHARS; + $firstCharsLength = \strlen($firstChars); + $nonFirstChars = self::NON_FIRST_CHARS; + $nonFirstCharsLength = \strlen($nonFirstChars); + + while (true) { + $name = ''; + $i = $this->variableCount; + + if ('' === $name) { + $name .= $firstChars[$i % $firstCharsLength]; + $i = (int) ($i / $firstCharsLength); + } + + while ($i > 0) { + --$i; + $name .= $nonFirstChars[$i % $nonFirstCharsLength]; + $i = (int) ($i / $nonFirstCharsLength); + } + + ++$this->variableCount; + + // check that the name is not reserved + if (\in_array($name, $this->reservedVariables, true)) { + continue; + } + + return $name; + } + } + + private function getExpressionLanguage(): ExpressionLanguage + { + if (null === $this->expressionLanguage) { + if (!class_exists('Symfony\Component\ExpressionLanguage\ExpressionLanguage')) { + throw new LogicException('Unable to use expressions as the Symfony ExpressionLanguage component is not installed.'); + } + $providers = $this->container->getExpressionLanguageProviders(); + $this->expressionLanguage = new ExpressionLanguage(null, $providers, function ($arg) { + $id = '""' === substr_replace($arg, '', 1, -1) ? stripcslashes(substr($arg, 1, -1)) : null; + + if (null !== $id && ($this->container->hasAlias($id) || $this->container->hasDefinition($id))) { + return $this->getServiceCall($id); + } + + return sprintf('$this->get(%s)', $arg); + }); + + if ($this->container->isTrackingResources()) { + foreach ($providers as $provider) { + $this->container->addObjectResource($provider); + } + } + } + + return $this->expressionLanguage; + } + + private function isHotPath(Definition $definition): bool + { + return $this->hotPathTag && $definition->hasTag($this->hotPathTag) && !$definition->isDeprecated(); + } + + private function isSingleUsePrivateNode(ServiceReferenceGraphNode $node): bool + { + if ($node->getValue()->isPublic()) { + return false; + } + $ids = []; + foreach ($node->getInEdges() as $edge) { + if (!$value = $edge->getSourceNode()->getValue()) { + continue; + } + if ($edge->isLazy() || !$value instanceof Definition || !$value->isShared()) { + return false; + } + $ids[$edge->getSourceNode()->getId()] = true; + } + + return 1 === \count($ids); + } + + /** + * @return mixed + */ + private function export($value) + { + if (null !== $this->targetDirRegex && \is_string($value) && preg_match($this->targetDirRegex, $value, $matches, PREG_OFFSET_CAPTURE)) { + $prefix = $matches[0][1] ? $this->doExport(substr($value, 0, $matches[0][1]), true).'.' : ''; + $suffix = $matches[0][1] + \strlen($matches[0][0]); + $suffix = isset($value[$suffix]) ? '.'.$this->doExport(substr($value, $suffix), true) : ''; + $dirname = $this->asFiles ? '$this->containerDir' : '__DIR__'; + $offset = 1 + $this->targetDirMaxMatches - \count($matches); + + if (0 < $offset) { + $dirname = sprintf('\dirname(__DIR__, %d)', $offset + (int) $this->asFiles); + } elseif ($this->asFiles) { + $dirname = "\$this->targetDir.''"; // empty string concatenation on purpose + } + + if ($prefix || $suffix) { + return sprintf('(%s%s%s)', $prefix, $dirname, $suffix); + } + + return $dirname; + } + + return $this->doExport($value, true); + } + + /** + * @return mixed + */ + private function doExport($value, bool $resolveEnv = false) + { + $shouldCacheValue = $resolveEnv && \is_string($value); + if ($shouldCacheValue && isset($this->exportedVariables[$value])) { + return $this->exportedVariables[$value]; + } + if (\is_string($value) && false !== strpos($value, "\n")) { + $cleanParts = explode("\n", $value); + $cleanParts = array_map(function ($part) { return var_export($part, true); }, $cleanParts); + $export = implode('."\n".', $cleanParts); + } else { + $export = var_export($value, true); + } + + if ($resolveEnv && "'" === $export[0] && $export !== $resolvedExport = $this->container->resolveEnvPlaceholders($export, "'.\$this->getEnv('string:%s').'")) { + $export = $resolvedExport; + if (".''" === substr($export, -3)) { + $export = substr($export, 0, -3); + if ("'" === $export[1]) { + $export = substr_replace($export, '', 18, 7); + } + } + if ("'" === $export[1]) { + $export = substr($export, 3); + } + } + + if ($shouldCacheValue) { + $this->exportedVariables[$value] = $export; + } + + return $export; + } + + private function getAutoloadFile(): ?string + { + if (null === $this->targetDirRegex) { + return null; + } + + foreach (spl_autoload_functions() as $autoloader) { + if (!\is_array($autoloader)) { + continue; + } + + if ($autoloader[0] instanceof DebugClassLoader || $autoloader[0] instanceof LegacyDebugClassLoader) { + $autoloader = $autoloader[0]->getClassLoader(); + } + + if (!\is_array($autoloader) || !$autoloader[0] instanceof ClassLoader || !$autoloader[0]->findFile(__CLASS__)) { + continue; + } + + foreach (get_declared_classes() as $class) { + if (0 === strpos($class, 'ComposerAutoloaderInit') && $class::getLoader() === $autoloader[0]) { + $file = \dirname((new \ReflectionClass($class))->getFileName(), 2).'/autoload.php'; + + if (preg_match($this->targetDirRegex.'A', $file)) { + return $file; + } + } + } + } + + return null; + } +} diff --git a/srcs/phpmyadmin/vendor/symfony/dependency-injection/Dumper/Preloader.php b/srcs/phpmyadmin/vendor/symfony/dependency-injection/Dumper/Preloader.php new file mode 100644 index 0000000..abb7d90 --- /dev/null +++ b/srcs/phpmyadmin/vendor/symfony/dependency-injection/Dumper/Preloader.php @@ -0,0 +1,100 @@ +<?php + +/* + * This file is part of the Symfony package. + * + * (c) Fabien Potencier <fabien@symfony.com> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection\Dumper; + +/** + * @author Nicolas Grekas <p@tchwork.com> + * + * @internal + */ +class Preloader +{ + public static function preload(array $classes) + { + set_error_handler(function ($t, $m, $f, $l) { + if (error_reporting() & $t) { + if (__FILE__ !== $f) { + throw new \ErrorException($m, 0, $t, $f, $l); + } + + throw new \ReflectionException($m); + } + }); + + $prev = []; + $preloaded = []; + + try { + while ($prev !== $classes) { + $prev = $classes; + foreach ($classes as $c) { + if (!isset($preloaded[$c])) { + self::doPreload($c, $preloaded); + } + } + $classes = array_merge(get_declared_classes(), get_declared_interfaces(), get_declared_traits()); + } + } finally { + restore_error_handler(); + } + } + + private static function doPreload(string $class, array &$preloaded) + { + if (isset($preloaded[$class]) || \in_array($class, ['self', 'static', 'parent'], true)) { + return; + } + + $preloaded[$class] = true; + + try { + $r = new \ReflectionClass($class); + + if ($r->isInternal()) { + return; + } + + $r->getConstants(); + $r->getDefaultProperties(); + + if (\PHP_VERSION_ID >= 70400) { + foreach ($r->getProperties(\ReflectionProperty::IS_PUBLIC) as $p) { + if (($t = $p->getType()) && !$t->isBuiltin()) { + self::doPreload($t->getName(), $preloaded); + } + } + } + + foreach ($r->getMethods(\ReflectionMethod::IS_PUBLIC) as $m) { + foreach ($m->getParameters() as $p) { + if ($p->isDefaultValueAvailable() && $p->isDefaultValueConstant()) { + $c = $p->getDefaultValueConstantName(); + + if ($i = strpos($c, '::')) { + self::doPreload(substr($c, 0, $i), $preloaded); + } + } + + if (($t = $p->getType()) && !$t->isBuiltin()) { + self::doPreload($t->getName(), $preloaded); + } + } + + if (($t = $m->getReturnType()) && !$t->isBuiltin()) { + self::doPreload($t->getName(), $preloaded); + } + } + } catch (\ReflectionException $e) { + // ignore missing classes + } + } +} diff --git a/srcs/phpmyadmin/vendor/symfony/dependency-injection/Dumper/XmlDumper.php b/srcs/phpmyadmin/vendor/symfony/dependency-injection/Dumper/XmlDumper.php new file mode 100644 index 0000000..fb5d827 --- /dev/null +++ b/srcs/phpmyadmin/vendor/symfony/dependency-injection/Dumper/XmlDumper.php @@ -0,0 +1,374 @@ +<?php + +/* + * This file is part of the Symfony package. + * + * (c) Fabien Potencier <fabien@symfony.com> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection\Dumper; + +use Symfony\Component\DependencyInjection\Alias; +use Symfony\Component\DependencyInjection\Argument\IteratorArgument; +use Symfony\Component\DependencyInjection\Argument\ServiceClosureArgument; +use Symfony\Component\DependencyInjection\Argument\ServiceLocatorArgument; +use Symfony\Component\DependencyInjection\Argument\TaggedIteratorArgument; +use Symfony\Component\DependencyInjection\ContainerInterface; +use Symfony\Component\DependencyInjection\Definition; +use Symfony\Component\DependencyInjection\Exception\RuntimeException; +use Symfony\Component\DependencyInjection\Parameter; +use Symfony\Component\DependencyInjection\Reference; +use Symfony\Component\ExpressionLanguage\Expression; + +/** + * XmlDumper dumps a service container as an XML string. + * + * @author Fabien Potencier <fabien@symfony.com> + * @author Martin Hasoň <martin.hason@gmail.com> + */ +class XmlDumper extends Dumper +{ + /** + * @var \DOMDocument + */ + private $document; + + /** + * Dumps the service container as an XML string. + * + * @return string An xml string representing of the service container + */ + public function dump(array $options = []) + { + $this->document = new \DOMDocument('1.0', 'utf-8'); + $this->document->formatOutput = true; + + $container = $this->document->createElementNS('http://symfony.com/schema/dic/services', 'container'); + $container->setAttribute('xmlns:xsi', 'http://www.w3.org/2001/XMLSchema-instance'); + $container->setAttribute('xsi:schemaLocation', 'http://symfony.com/schema/dic/services https://symfony.com/schema/dic/services/services-1.0.xsd'); + + $this->addParameters($container); + $this->addServices($container); + + $this->document->appendChild($container); + $xml = $this->document->saveXML(); + $this->document = null; + + return $this->container->resolveEnvPlaceholders($xml); + } + + private function addParameters(\DOMElement $parent) + { + $data = $this->container->getParameterBag()->all(); + if (!$data) { + return; + } + + if ($this->container->isCompiled()) { + $data = $this->escape($data); + } + + $parameters = $this->document->createElement('parameters'); + $parent->appendChild($parameters); + $this->convertParameters($data, 'parameter', $parameters); + } + + private function addMethodCalls(array $methodcalls, \DOMElement $parent) + { + foreach ($methodcalls as $methodcall) { + $call = $this->document->createElement('call'); + $call->setAttribute('method', $methodcall[0]); + if (\count($methodcall[1])) { + $this->convertParameters($methodcall[1], 'argument', $call); + } + if ($methodcall[2] ?? false) { + $call->setAttribute('returns-clone', 'true'); + } + $parent->appendChild($call); + } + } + + private function addService(Definition $definition, ?string $id, \DOMElement $parent) + { + $service = $this->document->createElement('service'); + if (null !== $id) { + $service->setAttribute('id', $id); + } + if ($class = $definition->getClass()) { + if ('\\' === substr($class, 0, 1)) { + $class = substr($class, 1); + } + + $service->setAttribute('class', $class); + } + if (!$definition->isShared()) { + $service->setAttribute('shared', 'false'); + } + if (!$definition->isPrivate()) { + $service->setAttribute('public', $definition->isPublic() ? 'true' : 'false'); + } + if ($definition->isSynthetic()) { + $service->setAttribute('synthetic', 'true'); + } + if ($definition->isLazy()) { + $service->setAttribute('lazy', 'true'); + } + if (null !== $decoratedService = $definition->getDecoratedService()) { + list($decorated, $renamedId, $priority) = $decoratedService; + $service->setAttribute('decorates', $decorated); + + $decorationOnInvalid = $decoratedService[3] ?? ContainerInterface::EXCEPTION_ON_INVALID_REFERENCE; + if (\in_array($decorationOnInvalid, [ContainerInterface::IGNORE_ON_INVALID_REFERENCE, ContainerInterface::NULL_ON_INVALID_REFERENCE], true)) { + $invalidBehavior = ContainerInterface::NULL_ON_INVALID_REFERENCE === $decorationOnInvalid ? 'null' : 'ignore'; + $service->setAttribute('decoration-on-invalid', $invalidBehavior); + } + if (null !== $renamedId) { + $service->setAttribute('decoration-inner-name', $renamedId); + } + if (0 !== $priority) { + $service->setAttribute('decoration-priority', $priority); + } + } + + foreach ($definition->getTags() as $name => $tags) { + foreach ($tags as $attributes) { + $tag = $this->document->createElement('tag'); + $tag->setAttribute('name', $name); + foreach ($attributes as $key => $value) { + $tag->setAttribute($key, $value); + } + $service->appendChild($tag); + } + } + + if ($definition->getFile()) { + $file = $this->document->createElement('file'); + $file->appendChild($this->document->createTextNode($definition->getFile())); + $service->appendChild($file); + } + + if ($parameters = $definition->getArguments()) { + $this->convertParameters($parameters, 'argument', $service); + } + + if ($parameters = $definition->getProperties()) { + $this->convertParameters($parameters, 'property', $service, 'name'); + } + + $this->addMethodCalls($definition->getMethodCalls(), $service); + + if ($callable = $definition->getFactory()) { + $factory = $this->document->createElement('factory'); + + if (\is_array($callable) && $callable[0] instanceof Definition) { + $this->addService($callable[0], null, $factory); + $factory->setAttribute('method', $callable[1]); + } elseif (\is_array($callable)) { + if (null !== $callable[0]) { + $factory->setAttribute($callable[0] instanceof Reference ? 'service' : 'class', $callable[0]); + } + $factory->setAttribute('method', $callable[1]); + } else { + $factory->setAttribute('function', $callable); + } + $service->appendChild($factory); + } + + if ($definition->isDeprecated()) { + $deprecated = $this->document->createElement('deprecated'); + $deprecated->appendChild($this->document->createTextNode($definition->getDeprecationMessage('%service_id%'))); + + $service->appendChild($deprecated); + } + + if ($definition->isAutowired()) { + $service->setAttribute('autowire', 'true'); + } + + if ($definition->isAutoconfigured()) { + $service->setAttribute('autoconfigure', 'true'); + } + + if ($definition->isAbstract()) { + $service->setAttribute('abstract', 'true'); + } + + if ($callable = $definition->getConfigurator()) { + $configurator = $this->document->createElement('configurator'); + + if (\is_array($callable) && $callable[0] instanceof Definition) { + $this->addService($callable[0], null, $configurator); + $configurator->setAttribute('method', $callable[1]); + } elseif (\is_array($callable)) { + $configurator->setAttribute($callable[0] instanceof Reference ? 'service' : 'class', $callable[0]); + $configurator->setAttribute('method', $callable[1]); + } else { + $configurator->setAttribute('function', $callable); + } + $service->appendChild($configurator); + } + + $parent->appendChild($service); + } + + private function addServiceAlias(string $alias, Alias $id, \DOMElement $parent) + { + $service = $this->document->createElement('service'); + $service->setAttribute('id', $alias); + $service->setAttribute('alias', $id); + if (!$id->isPrivate()) { + $service->setAttribute('public', $id->isPublic() ? 'true' : 'false'); + } + + if ($id->isDeprecated()) { + $deprecated = $this->document->createElement('deprecated'); + $deprecated->appendChild($this->document->createTextNode($id->getDeprecationMessage('%alias_id%'))); + + $service->appendChild($deprecated); + } + + $parent->appendChild($service); + } + + private function addServices(\DOMElement $parent) + { + $definitions = $this->container->getDefinitions(); + if (!$definitions) { + return; + } + + $services = $this->document->createElement('services'); + foreach ($definitions as $id => $definition) { + $this->addService($definition, $id, $services); + } + + $aliases = $this->container->getAliases(); + foreach ($aliases as $alias => $id) { + while (isset($aliases[(string) $id])) { + $id = $aliases[(string) $id]; + } + $this->addServiceAlias($alias, $id, $services); + } + $parent->appendChild($services); + } + + private function convertParameters(array $parameters, string $type, \DOMElement $parent, string $keyAttribute = 'key') + { + $withKeys = array_keys($parameters) !== range(0, \count($parameters) - 1); + foreach ($parameters as $key => $value) { + $element = $this->document->createElement($type); + if ($withKeys) { + $element->setAttribute($keyAttribute, $key); + } + + if ($value instanceof ServiceClosureArgument) { + $value = $value->getValues()[0]; + } + if (\is_array($tag = $value)) { + $element->setAttribute('type', 'collection'); + $this->convertParameters($value, $type, $element, 'key'); + } elseif ($value instanceof TaggedIteratorArgument || ($value instanceof ServiceLocatorArgument && $tag = $value->getTaggedIteratorArgument())) { + $element->setAttribute('type', $value instanceof TaggedIteratorArgument ? 'tagged_iterator' : 'tagged_locator'); + $element->setAttribute('tag', $tag->getTag()); + + if (null !== $tag->getIndexAttribute()) { + $element->setAttribute('index-by', $tag->getIndexAttribute()); + + if (null !== $tag->getDefaultIndexMethod()) { + $element->setAttribute('default-index-method', $tag->getDefaultIndexMethod()); + } + if (null !== $tag->getDefaultPriorityMethod()) { + $element->setAttribute('default-priority-method', $tag->getDefaultPriorityMethod()); + } + } + } elseif ($value instanceof IteratorArgument) { + $element->setAttribute('type', 'iterator'); + $this->convertParameters($value->getValues(), $type, $element, 'key'); + } elseif ($value instanceof ServiceLocatorArgument) { + $element->setAttribute('type', 'service_locator'); + $this->convertParameters($value->getValues(), $type, $element, 'key'); + } elseif ($value instanceof Reference) { + $element->setAttribute('type', 'service'); + $element->setAttribute('id', (string) $value); + $behavior = $value->getInvalidBehavior(); + if (ContainerInterface::NULL_ON_INVALID_REFERENCE == $behavior) { + $element->setAttribute('on-invalid', 'null'); + } elseif (ContainerInterface::IGNORE_ON_INVALID_REFERENCE == $behavior) { + $element->setAttribute('on-invalid', 'ignore'); + } elseif (ContainerInterface::IGNORE_ON_UNINITIALIZED_REFERENCE == $behavior) { + $element->setAttribute('on-invalid', 'ignore_uninitialized'); + } + } elseif ($value instanceof Definition) { + $element->setAttribute('type', 'service'); + $this->addService($value, null, $element); + } elseif ($value instanceof Expression) { + $element->setAttribute('type', 'expression'); + $text = $this->document->createTextNode(self::phpToXml((string) $value)); + $element->appendChild($text); + } elseif (\is_string($value) && !preg_match('/^[^\x00-\x08\x0B\x0E-\x1A\x1C-\x1F\x7F]*+$/u', $value)) { + $element->setAttribute('type', 'binary'); + $text = $this->document->createTextNode(self::phpToXml(base64_encode($value))); + $element->appendChild($text); + } else { + if (\in_array($value, ['null', 'true', 'false'], true)) { + $element->setAttribute('type', 'string'); + } + + if (\is_string($value) && (is_numeric($value) || preg_match('/^0b[01]*$/', $value) || preg_match('/^0x[0-9a-f]++$/i', $value))) { + $element->setAttribute('type', 'string'); + } + + $text = $this->document->createTextNode(self::phpToXml($value)); + $element->appendChild($text); + } + $parent->appendChild($element); + } + } + + /** + * Escapes arguments. + */ + private function escape(array $arguments): array + { + $args = []; + foreach ($arguments as $k => $v) { + if (\is_array($v)) { + $args[$k] = $this->escape($v); + } elseif (\is_string($v)) { + $args[$k] = str_replace('%', '%%', $v); + } else { + $args[$k] = $v; + } + } + + return $args; + } + + /** + * Converts php types to xml types. + * + * @param mixed $value Value to convert + * + * @throws RuntimeException When trying to dump object or resource + */ + public static function phpToXml($value): string + { + switch (true) { + case null === $value: + return 'null'; + case true === $value: + return 'true'; + case false === $value: + return 'false'; + case $value instanceof Parameter: + return '%'.$value.'%'; + case \is_object($value) || \is_resource($value): + throw new RuntimeException('Unable to dump a service container if a parameter is an object or a resource.'); + default: + return (string) $value; + } + } +} diff --git a/srcs/phpmyadmin/vendor/symfony/dependency-injection/Dumper/YamlDumper.php b/srcs/phpmyadmin/vendor/symfony/dependency-injection/Dumper/YamlDumper.php new file mode 100644 index 0000000..ccb68ee --- /dev/null +++ b/srcs/phpmyadmin/vendor/symfony/dependency-injection/Dumper/YamlDumper.php @@ -0,0 +1,349 @@ +<?php + +/* + * This file is part of the Symfony package. + * + * (c) Fabien Potencier <fabien@symfony.com> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection\Dumper; + +use Symfony\Component\DependencyInjection\Alias; +use Symfony\Component\DependencyInjection\Argument\ArgumentInterface; +use Symfony\Component\DependencyInjection\Argument\IteratorArgument; +use Symfony\Component\DependencyInjection\Argument\ServiceClosureArgument; +use Symfony\Component\DependencyInjection\Argument\ServiceLocatorArgument; +use Symfony\Component\DependencyInjection\Argument\TaggedIteratorArgument; +use Symfony\Component\DependencyInjection\ContainerInterface; +use Symfony\Component\DependencyInjection\Definition; +use Symfony\Component\DependencyInjection\Exception\LogicException; +use Symfony\Component\DependencyInjection\Exception\RuntimeException; +use Symfony\Component\DependencyInjection\Parameter; +use Symfony\Component\DependencyInjection\Reference; +use Symfony\Component\ExpressionLanguage\Expression; +use Symfony\Component\Yaml\Dumper as YmlDumper; +use Symfony\Component\Yaml\Parser; +use Symfony\Component\Yaml\Tag\TaggedValue; +use Symfony\Component\Yaml\Yaml; + +/** + * YamlDumper dumps a service container as a YAML string. + * + * @author Fabien Potencier <fabien@symfony.com> + */ +class YamlDumper extends Dumper +{ + private $dumper; + + /** + * Dumps the service container as an YAML string. + * + * @return string A YAML string representing of the service container + */ + public function dump(array $options = []) + { + if (!class_exists('Symfony\Component\Yaml\Dumper')) { + throw new LogicException('Unable to dump the container as the Symfony Yaml Component is not installed.'); + } + + if (null === $this->dumper) { + $this->dumper = new YmlDumper(); + } + + return $this->container->resolveEnvPlaceholders($this->addParameters()."\n".$this->addServices()); + } + + private function addService(string $id, Definition $definition): string + { + $code = " $id:\n"; + if ($class = $definition->getClass()) { + if ('\\' === substr($class, 0, 1)) { + $class = substr($class, 1); + } + + $code .= sprintf(" class: %s\n", $this->dumper->dump($class)); + } + + if (!$definition->isPrivate()) { + $code .= sprintf(" public: %s\n", $definition->isPublic() ? 'true' : 'false'); + } + + $tagsCode = ''; + foreach ($definition->getTags() as $name => $tags) { + foreach ($tags as $attributes) { + $att = []; + foreach ($attributes as $key => $value) { + $att[] = sprintf('%s: %s', $this->dumper->dump($key), $this->dumper->dump($value)); + } + $att = $att ? ', '.implode(', ', $att) : ''; + + $tagsCode .= sprintf(" - { name: %s%s }\n", $this->dumper->dump($name), $att); + } + } + if ($tagsCode) { + $code .= " tags:\n".$tagsCode; + } + + if ($definition->getFile()) { + $code .= sprintf(" file: %s\n", $this->dumper->dump($definition->getFile())); + } + + if ($definition->isSynthetic()) { + $code .= " synthetic: true\n"; + } + + if ($definition->isDeprecated()) { + $code .= sprintf(" deprecated: %s\n", $this->dumper->dump($definition->getDeprecationMessage('%service_id%'))); + } + + if ($definition->isAutowired()) { + $code .= " autowire: true\n"; + } + + if ($definition->isAutoconfigured()) { + $code .= " autoconfigure: true\n"; + } + + if ($definition->isAbstract()) { + $code .= " abstract: true\n"; + } + + if ($definition->isLazy()) { + $code .= " lazy: true\n"; + } + + if ($definition->getArguments()) { + $code .= sprintf(" arguments: %s\n", $this->dumper->dump($this->dumpValue($definition->getArguments()), 0)); + } + + if ($definition->getProperties()) { + $code .= sprintf(" properties: %s\n", $this->dumper->dump($this->dumpValue($definition->getProperties()), 0)); + } + + if ($definition->getMethodCalls()) { + $code .= sprintf(" calls:\n%s\n", $this->dumper->dump($this->dumpValue($definition->getMethodCalls()), 1, 12)); + } + + if (!$definition->isShared()) { + $code .= " shared: false\n"; + } + + if (null !== $decoratedService = $definition->getDecoratedService()) { + list($decorated, $renamedId, $priority) = $decoratedService; + $code .= sprintf(" decorates: %s\n", $decorated); + if (null !== $renamedId) { + $code .= sprintf(" decoration_inner_name: %s\n", $renamedId); + } + if (0 !== $priority) { + $code .= sprintf(" decoration_priority: %s\n", $priority); + } + + $decorationOnInvalid = $decoratedService[3] ?? ContainerInterface::EXCEPTION_ON_INVALID_REFERENCE; + if (\in_array($decorationOnInvalid, [ContainerInterface::IGNORE_ON_INVALID_REFERENCE, ContainerInterface::NULL_ON_INVALID_REFERENCE])) { + $invalidBehavior = ContainerInterface::NULL_ON_INVALID_REFERENCE === $decorationOnInvalid ? 'null' : 'ignore'; + $code .= sprintf(" decoration_on_invalid: %s\n", $invalidBehavior); + } + } + + if ($callable = $definition->getFactory()) { + $code .= sprintf(" factory: %s\n", $this->dumper->dump($this->dumpCallable($callable), 0)); + } + + if ($callable = $definition->getConfigurator()) { + $code .= sprintf(" configurator: %s\n", $this->dumper->dump($this->dumpCallable($callable), 0)); + } + + return $code; + } + + private function addServiceAlias(string $alias, Alias $id): string + { + $deprecated = $id->isDeprecated() ? sprintf(" deprecated: %s\n", $id->getDeprecationMessage('%alias_id%')) : ''; + + if ($id->isPrivate()) { + return sprintf(" %s: '@%s'\n%s", $alias, $id, $deprecated); + } + + return sprintf(" %s:\n alias: %s\n public: %s\n%s", $alias, $id, $id->isPublic() ? 'true' : 'false', $deprecated); + } + + private function addServices(): string + { + if (!$this->container->getDefinitions()) { + return ''; + } + + $code = "services:\n"; + foreach ($this->container->getDefinitions() as $id => $definition) { + $code .= $this->addService($id, $definition); + } + + $aliases = $this->container->getAliases(); + foreach ($aliases as $alias => $id) { + while (isset($aliases[(string) $id])) { + $id = $aliases[(string) $id]; + } + $code .= $this->addServiceAlias($alias, $id); + } + + return $code; + } + + private function addParameters(): string + { + if (!$this->container->getParameterBag()->all()) { + return ''; + } + + $parameters = $this->prepareParameters($this->container->getParameterBag()->all(), $this->container->isCompiled()); + + return $this->dumper->dump(['parameters' => $parameters], 2); + } + + /** + * Dumps callable to YAML format. + * + * @param mixed $callable + * + * @return mixed + */ + private function dumpCallable($callable) + { + if (\is_array($callable)) { + if ($callable[0] instanceof Reference) { + $callable = [$this->getServiceCall((string) $callable[0], $callable[0]), $callable[1]]; + } else { + $callable = [$callable[0], $callable[1]]; + } + } + + return $callable; + } + + /** + * Dumps the value to YAML format. + * + * @return mixed + * + * @throws RuntimeException When trying to dump object or resource + */ + private function dumpValue($value) + { + if ($value instanceof ServiceClosureArgument) { + $value = $value->getValues()[0]; + } + if ($value instanceof ArgumentInterface) { + $tag = $value; + + if ($value instanceof TaggedIteratorArgument || ($value instanceof ServiceLocatorArgument && $tag = $value->getTaggedIteratorArgument())) { + if (null === $tag->getIndexAttribute()) { + $content = $tag->getTag(); + } else { + $content = [ + 'tag' => $tag->getTag(), + 'index_by' => $tag->getIndexAttribute(), + ]; + + if (null !== $tag->getDefaultIndexMethod()) { + $content['default_index_method'] = $tag->getDefaultIndexMethod(); + } + if (null !== $tag->getDefaultPriorityMethod()) { + $content['default_priority_method'] = $tag->getDefaultPriorityMethod(); + } + } + + return new TaggedValue($value instanceof TaggedIteratorArgument ? 'tagged_iterator' : 'tagged_locator', $content); + } + + if ($value instanceof IteratorArgument) { + $tag = 'iterator'; + } elseif ($value instanceof ServiceLocatorArgument) { + $tag = 'service_locator'; + } else { + throw new RuntimeException(sprintf('Unspecified Yaml tag for type "%s".', \get_class($value))); + } + + return new TaggedValue($tag, $this->dumpValue($value->getValues())); + } + + if (\is_array($value)) { + $code = []; + foreach ($value as $k => $v) { + $code[$k] = $this->dumpValue($v); + } + + return $code; + } elseif ($value instanceof Reference) { + return $this->getServiceCall((string) $value, $value); + } elseif ($value instanceof Parameter) { + return $this->getParameterCall((string) $value); + } elseif ($value instanceof Expression) { + return $this->getExpressionCall((string) $value); + } elseif ($value instanceof Definition) { + return new TaggedValue('service', (new Parser())->parse("_:\n".$this->addService('_', $value), Yaml::PARSE_CUSTOM_TAGS)['_']['_']); + } elseif (\is_object($value) || \is_resource($value)) { + throw new RuntimeException('Unable to dump a service container if a parameter is an object or a resource.'); + } + + return $value; + } + + private function getServiceCall(string $id, Reference $reference = null): string + { + if (null !== $reference) { + switch ($reference->getInvalidBehavior()) { + case ContainerInterface::RUNTIME_EXCEPTION_ON_INVALID_REFERENCE: break; + case ContainerInterface::EXCEPTION_ON_INVALID_REFERENCE: break; + case ContainerInterface::IGNORE_ON_UNINITIALIZED_REFERENCE: return sprintf('@!%s', $id); + default: return sprintf('@?%s', $id); + } + } + + return sprintf('@%s', $id); + } + + private function getParameterCall(string $id): string + { + return sprintf('%%%s%%', $id); + } + + private function getExpressionCall(string $expression): string + { + return sprintf('@=%s', $expression); + } + + private function prepareParameters(array $parameters, bool $escape = true): array + { + $filtered = []; + foreach ($parameters as $key => $value) { + if (\is_array($value)) { + $value = $this->prepareParameters($value, $escape); + } elseif ($value instanceof Reference || \is_string($value) && 0 === strpos($value, '@')) { + $value = '@'.$value; + } + + $filtered[$key] = $value; + } + + return $escape ? $this->escape($filtered) : $filtered; + } + + private function escape(array $arguments): array + { + $args = []; + foreach ($arguments as $k => $v) { + if (\is_array($v)) { + $args[$k] = $this->escape($v); + } elseif (\is_string($v)) { + $args[$k] = str_replace('%', '%%', $v); + } else { + $args[$k] = $v; + } + } + + return $args; + } +} diff --git a/srcs/phpmyadmin/vendor/symfony/dependency-injection/EnvVarLoaderInterface.php b/srcs/phpmyadmin/vendor/symfony/dependency-injection/EnvVarLoaderInterface.php new file mode 100644 index 0000000..0c547f8 --- /dev/null +++ b/srcs/phpmyadmin/vendor/symfony/dependency-injection/EnvVarLoaderInterface.php @@ -0,0 +1,25 @@ +<?php + +/* + * This file is part of the Symfony package. + * + * (c) Fabien Potencier <fabien@symfony.com> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection; + +/** + * EnvVarLoaderInterface objects return key/value pairs that are added to the list of available env vars. + * + * @author Nicolas Grekas <p@tchwork.com> + */ +interface EnvVarLoaderInterface +{ + /** + * @return string[] Key/value pairs that can be accessed using the regular "%env()%" syntax + */ + public function loadEnvVars(): array; +} diff --git a/srcs/phpmyadmin/vendor/symfony/dependency-injection/EnvVarProcessor.php b/srcs/phpmyadmin/vendor/symfony/dependency-injection/EnvVarProcessor.php new file mode 100644 index 0000000..724187b --- /dev/null +++ b/srcs/phpmyadmin/vendor/symfony/dependency-injection/EnvVarProcessor.php @@ -0,0 +1,280 @@ +<?php + +/* + * This file is part of the Symfony package. + * + * (c) Fabien Potencier <fabien@symfony.com> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection; + +use Symfony\Component\DependencyInjection\Exception\EnvNotFoundException; +use Symfony\Component\DependencyInjection\Exception\ParameterCircularReferenceException; +use Symfony\Component\DependencyInjection\Exception\RuntimeException; + +/** + * @author Nicolas Grekas <p@tchwork.com> + */ +class EnvVarProcessor implements EnvVarProcessorInterface +{ + private $container; + private $loaders; + private $loadedVars = []; + + /** + * @param EnvVarLoaderInterface[] $loaders + */ + public function __construct(ContainerInterface $container, \Traversable $loaders = null) + { + $this->container = $container; + $this->loaders = new \IteratorIterator($loaders ?? new \ArrayIterator()); + $this->loaders = $this->loaders->getInnerIterator(); + } + + /** + * {@inheritdoc} + */ + public static function getProvidedTypes() + { + return [ + 'base64' => 'string', + 'bool' => 'bool', + 'const' => 'bool|int|float|string|array', + 'csv' => 'array', + 'file' => 'string', + 'float' => 'float', + 'int' => 'int', + 'json' => 'array', + 'key' => 'bool|int|float|string|array', + 'url' => 'array', + 'query_string' => 'array', + 'resolve' => 'string', + 'default' => 'bool|int|float|string|array', + 'string' => 'string', + 'trim' => 'string', + 'require' => 'bool|int|float|string|array', + ]; + } + + /** + * {@inheritdoc} + */ + public function getEnv($prefix, $name, \Closure $getEnv) + { + $i = strpos($name, ':'); + + if ('key' === $prefix) { + if (false === $i) { + throw new RuntimeException(sprintf('Invalid env "key:%s": a key specifier should be provided.', $name)); + } + + $next = substr($name, $i + 1); + $key = substr($name, 0, $i); + $array = $getEnv($next); + + if (!\is_array($array)) { + throw new RuntimeException(sprintf('Resolved value of "%s" did not result in an array value.', $next)); + } + + if (!isset($array[$key]) && !\array_key_exists($key, $array)) { + throw new EnvNotFoundException(sprintf('Key "%s" not found in "%s" (resolved from "%s").', $key, json_encode($array), $next)); + } + + return $array[$key]; + } + + if ('default' === $prefix) { + if (false === $i) { + throw new RuntimeException(sprintf('Invalid env "default:%s": a fallback parameter should be provided.', $name)); + } + + $next = substr($name, $i + 1); + $default = substr($name, 0, $i); + + if ('' !== $default && !$this->container->hasParameter($default)) { + throw new RuntimeException(sprintf('Invalid env fallback in "default:%s": parameter "%s" not found.', $name, $default)); + } + + try { + $env = $getEnv($next); + + if ('' !== $env && null !== $env) { + return $env; + } + } catch (EnvNotFoundException $e) { + // no-op + } + + return '' === $default ? null : $this->container->getParameter($default); + } + + if ('file' === $prefix || 'require' === $prefix) { + if (!is_scalar($file = $getEnv($name))) { + throw new RuntimeException(sprintf('Invalid file name: env var "%s" is non-scalar.', $name)); + } + if (!file_exists($file)) { + throw new EnvNotFoundException(sprintf('File "%s" not found (resolved from "%s").', $file, $name)); + } + + if ('file' === $prefix) { + return file_get_contents($file); + } else { + return require $file; + } + } + + if (false !== $i || 'string' !== $prefix) { + if (null === $env = $getEnv($name)) { + return null; + } + } elseif (isset($_ENV[$name])) { + $env = $_ENV[$name]; + } elseif (isset($_SERVER[$name]) && 0 !== strpos($name, 'HTTP_')) { + $env = $_SERVER[$name]; + } elseif (false === ($env = getenv($name)) || null === $env) { // null is a possible value because of thread safety issues + foreach ($this->loadedVars as $vars) { + if (false !== $env = ($vars[$name] ?? false)) { + break; + } + } + + $loaders = $this->loaders; + $this->loaders = new \ArrayIterator(); + + try { + while ((false === $env || null === $env) && $loaders->valid()) { + $loader = $loaders->current(); + $loaders->next(); + $this->loadedVars[] = $vars = $loader->loadEnvVars(); + $env = $vars[$name] ?? false; + } + } catch (ParameterCircularReferenceException $e) { + // skip loaders that need an env var that is not defined + } finally { + $this->loaders = $loaders; + } + + if (false === $env || null === $env) { + if (!$this->container->hasParameter("env($name)")) { + throw new EnvNotFoundException(sprintf('Environment variable not found: "%s".', $name)); + } + + if (null === $env = $this->container->getParameter("env($name)")) { + return null; + } + } + } + + if (!is_scalar($env)) { + throw new RuntimeException(sprintf('Non-scalar env var "%s" cannot be cast to %s.', $name, $prefix)); + } + + if ('string' === $prefix) { + return (string) $env; + } + + if ('bool' === $prefix) { + return (bool) (filter_var($env, FILTER_VALIDATE_BOOLEAN) ?: filter_var($env, FILTER_VALIDATE_INT) ?: filter_var($env, FILTER_VALIDATE_FLOAT)); + } + + if ('int' === $prefix) { + if (false === $env = filter_var($env, FILTER_VALIDATE_INT) ?: filter_var($env, FILTER_VALIDATE_FLOAT)) { + throw new RuntimeException(sprintf('Non-numeric env var "%s" cannot be cast to int.', $name)); + } + + return (int) $env; + } + + if ('float' === $prefix) { + if (false === $env = filter_var($env, FILTER_VALIDATE_FLOAT)) { + throw new RuntimeException(sprintf('Non-numeric env var "%s" cannot be cast to float.', $name)); + } + + return (float) $env; + } + + if ('const' === $prefix) { + if (!\defined($env)) { + throw new RuntimeException(sprintf('Env var "%s" maps to undefined constant "%s".', $name, $env)); + } + + return \constant($env); + } + + if ('base64' === $prefix) { + return base64_decode(strtr($env, '-_', '+/')); + } + + if ('json' === $prefix) { + $env = json_decode($env, true); + + if (JSON_ERROR_NONE !== json_last_error()) { + throw new RuntimeException(sprintf('Invalid JSON in env var "%s": '.json_last_error_msg(), $name)); + } + + if (null !== $env && !\is_array($env)) { + throw new RuntimeException(sprintf('Invalid JSON env var "%s": array or null expected, %s given.', $name, \gettype($env))); + } + + return $env; + } + + if ('url' === $prefix) { + $parsedEnv = parse_url($env); + + if (false === $parsedEnv) { + throw new RuntimeException(sprintf('Invalid URL in env var "%s"', $name)); + } + if (!isset($parsedEnv['scheme'], $parsedEnv['host'])) { + throw new RuntimeException(sprintf('Invalid URL env var "%s": schema and host expected, %s given.', $name, $env)); + } + $parsedEnv += [ + 'port' => null, + 'user' => null, + 'pass' => null, + 'path' => null, + 'query' => null, + 'fragment' => null, + ]; + + // remove the '/' separator + $parsedEnv['path'] = '/' === $parsedEnv['path'] ? null : substr($parsedEnv['path'], 1); + + return $parsedEnv; + } + + if ('query_string' === $prefix) { + $queryString = parse_url($env, PHP_URL_QUERY) ?: $env; + parse_str($queryString, $result); + + return $result; + } + + if ('resolve' === $prefix) { + return preg_replace_callback('/%%|%([^%\s]+)%/', function ($match) use ($name) { + if (!isset($match[1])) { + return '%'; + } + $value = $this->container->getParameter($match[1]); + if (!is_scalar($value)) { + throw new RuntimeException(sprintf('Parameter "%s" found when resolving env var "%s" must be scalar, "%s" given.', $match[1], $name, \gettype($value))); + } + + return $value; + }, $env); + } + + if ('csv' === $prefix) { + return str_getcsv($env, ',', '"', \PHP_VERSION_ID >= 70400 ? '' : '\\'); + } + + if ('trim' === $prefix) { + return trim($env); + } + + throw new RuntimeException(sprintf('Unsupported env var prefix "%s".', $prefix)); + } +} diff --git a/srcs/phpmyadmin/vendor/symfony/dependency-injection/EnvVarProcessorInterface.php b/srcs/phpmyadmin/vendor/symfony/dependency-injection/EnvVarProcessorInterface.php new file mode 100644 index 0000000..654fe55 --- /dev/null +++ b/srcs/phpmyadmin/vendor/symfony/dependency-injection/EnvVarProcessorInterface.php @@ -0,0 +1,40 @@ +<?php + +/* + * This file is part of the Symfony package. + * + * (c) Fabien Potencier <fabien@symfony.com> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection; + +use Symfony\Component\DependencyInjection\Exception\RuntimeException; + +/** + * The EnvVarProcessorInterface is implemented by objects that manage environment-like variables. + * + * @author Nicolas Grekas <p@tchwork.com> + */ +interface EnvVarProcessorInterface +{ + /** + * Returns the value of the given variable as managed by the current instance. + * + * @param string $prefix The namespace of the variable + * @param string $name The name of the variable within the namespace + * @param \Closure $getEnv A closure that allows fetching more env vars + * + * @return mixed + * + * @throws RuntimeException on error + */ + public function getEnv($prefix, $name, \Closure $getEnv); + + /** + * @return string[] The PHP-types managed by getEnv(), keyed by prefixes + */ + public static function getProvidedTypes(); +} diff --git a/srcs/phpmyadmin/vendor/symfony/dependency-injection/Exception/AutowiringFailedException.php b/srcs/phpmyadmin/vendor/symfony/dependency-injection/Exception/AutowiringFailedException.php new file mode 100644 index 0000000..c203b85 --- /dev/null +++ b/srcs/phpmyadmin/vendor/symfony/dependency-injection/Exception/AutowiringFailedException.php @@ -0,0 +1,72 @@ +<?php + +/* + * This file is part of the Symfony package. + * + * (c) Fabien Potencier <fabien@symfony.com> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection\Exception; + +/** + * Thrown when a definition cannot be autowired. + */ +class AutowiringFailedException extends RuntimeException +{ + private $serviceId; + private $messageCallback; + + public function __construct(string $serviceId, $message = '', int $code = 0, \Throwable $previous = null) + { + $this->serviceId = $serviceId; + + if ($message instanceof \Closure && \function_exists('xdebug_is_enabled') && xdebug_is_enabled()) { + $message = $message(); + } + + if (!$message instanceof \Closure) { + parent::__construct($message, $code, $previous); + + return; + } + + $this->messageCallback = $message; + parent::__construct('', $code, $previous); + + $this->message = new class($this->message, $this->messageCallback) { + private $message; + private $messageCallback; + + public function __construct(&$message, &$messageCallback) + { + $this->message = &$message; + $this->messageCallback = &$messageCallback; + } + + public function __toString(): string + { + $messageCallback = $this->messageCallback; + $this->messageCallback = null; + + try { + return $this->message = $messageCallback(); + } catch (\Throwable $e) { + return $this->message = $e->getMessage(); + } + } + }; + } + + public function getMessageCallback(): ?\Closure + { + return $this->messageCallback; + } + + public function getServiceId() + { + return $this->serviceId; + } +} diff --git a/srcs/phpmyadmin/vendor/symfony/dependency-injection/Exception/BadMethodCallException.php b/srcs/phpmyadmin/vendor/symfony/dependency-injection/Exception/BadMethodCallException.php new file mode 100644 index 0000000..959238e --- /dev/null +++ b/srcs/phpmyadmin/vendor/symfony/dependency-injection/Exception/BadMethodCallException.php @@ -0,0 +1,19 @@ +<?php + +/* + * This file is part of the Symfony package. + * + * (c) Fabien Potencier <fabien@symfony.com> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection\Exception; + +/** + * Base BadMethodCallException for Dependency Injection component. + */ +class BadMethodCallException extends \BadMethodCallException implements ExceptionInterface +{ +} diff --git a/srcs/phpmyadmin/vendor/symfony/dependency-injection/Exception/EnvNotFoundException.php b/srcs/phpmyadmin/vendor/symfony/dependency-injection/Exception/EnvNotFoundException.php new file mode 100644 index 0000000..04ac848 --- /dev/null +++ b/srcs/phpmyadmin/vendor/symfony/dependency-injection/Exception/EnvNotFoundException.php @@ -0,0 +1,21 @@ +<?php + +/* + * This file is part of the Symfony package. + * + * (c) Fabien Potencier <fabien@symfony.com> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection\Exception; + +/** + * This exception is thrown when an environment variable is not found. + * + * @author Nicolas Grekas <p@tchwork.com> + */ +class EnvNotFoundException extends InvalidArgumentException +{ +} diff --git a/srcs/phpmyadmin/vendor/symfony/dependency-injection/Exception/EnvParameterException.php b/srcs/phpmyadmin/vendor/symfony/dependency-injection/Exception/EnvParameterException.php new file mode 100644 index 0000000..48b5e48 --- /dev/null +++ b/srcs/phpmyadmin/vendor/symfony/dependency-injection/Exception/EnvParameterException.php @@ -0,0 +1,25 @@ +<?php + +/* + * This file is part of the Symfony package. + * + * (c) Fabien Potencier <fabien@symfony.com> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection\Exception; + +/** + * This exception wraps exceptions whose messages contain a reference to an env parameter. + * + * @author Nicolas Grekas <p@tchwork.com> + */ +class EnvParameterException extends InvalidArgumentException +{ + public function __construct(array $envs, \Throwable $previous = null, string $message = 'Incompatible use of dynamic environment variables "%s" found in parameters.') + { + parent::__construct(sprintf($message, implode('", "', $envs)), 0, $previous); + } +} diff --git a/srcs/phpmyadmin/vendor/symfony/dependency-injection/Exception/ExceptionInterface.php b/srcs/phpmyadmin/vendor/symfony/dependency-injection/Exception/ExceptionInterface.php new file mode 100644 index 0000000..6202df7 --- /dev/null +++ b/srcs/phpmyadmin/vendor/symfony/dependency-injection/Exception/ExceptionInterface.php @@ -0,0 +1,24 @@ +<?php + +/* + * This file is part of the Symfony package. + * + * (c) Fabien Potencier <fabien@symfony.com> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection\Exception; + +use Psr\Container\ContainerExceptionInterface; + +/** + * Base ExceptionInterface for Dependency Injection component. + * + * @author Fabien Potencier <fabien@symfony.com> + * @author Bulat Shakirzyanov <bulat@theopenskyproject.com> + */ +interface ExceptionInterface extends ContainerExceptionInterface, \Throwable +{ +} diff --git a/srcs/phpmyadmin/vendor/symfony/dependency-injection/Exception/InvalidArgumentException.php b/srcs/phpmyadmin/vendor/symfony/dependency-injection/Exception/InvalidArgumentException.php new file mode 100644 index 0000000..119bb7d --- /dev/null +++ b/srcs/phpmyadmin/vendor/symfony/dependency-injection/Exception/InvalidArgumentException.php @@ -0,0 +1,21 @@ +<?php + +/* + * This file is part of the Symfony package. + * + * (c) Fabien Potencier <fabien@symfony.com> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection\Exception; + +/** + * Base InvalidArgumentException for Dependency Injection component. + * + * @author Bulat Shakirzyanov <bulat@theopenskyproject.com> + */ +class InvalidArgumentException extends \InvalidArgumentException implements ExceptionInterface +{ +} diff --git a/srcs/phpmyadmin/vendor/symfony/dependency-injection/Exception/InvalidParameterTypeException.php b/srcs/phpmyadmin/vendor/symfony/dependency-injection/Exception/InvalidParameterTypeException.php new file mode 100644 index 0000000..206561f --- /dev/null +++ b/srcs/phpmyadmin/vendor/symfony/dependency-injection/Exception/InvalidParameterTypeException.php @@ -0,0 +1,26 @@ +<?php + +/* + * This file is part of the Symfony package. + * + * (c) Fabien Potencier <fabien@symfony.com> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection\Exception; + +/** + * Thrown when trying to inject a parameter into a constructor/method with an incompatible type. + * + * @author Nicolas Grekas <p@tchwork.com> + * @author Julien Maulny <jmaulny@darkmira.fr> + */ +class InvalidParameterTypeException extends InvalidArgumentException +{ + public function __construct(string $serviceId, string $type, \ReflectionParameter $parameter) + { + parent::__construct(sprintf('Invalid definition for service "%s": argument %d of "%s::%s" accepts "%s", "%s" passed.', $serviceId, 1 + $parameter->getPosition(), $parameter->getDeclaringClass()->getName(), $parameter->getDeclaringFunction()->getName(), $parameter->getType()->getName(), $type)); + } +} diff --git a/srcs/phpmyadmin/vendor/symfony/dependency-injection/Exception/LogicException.php b/srcs/phpmyadmin/vendor/symfony/dependency-injection/Exception/LogicException.php new file mode 100644 index 0000000..17a070c --- /dev/null +++ b/srcs/phpmyadmin/vendor/symfony/dependency-injection/Exception/LogicException.php @@ -0,0 +1,19 @@ +<?php + +/* + * This file is part of the Symfony package. + * + * (c) Fabien Potencier <fabien@symfony.com> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection\Exception; + +/** + * Base LogicException for Dependency Injection component. + */ +class LogicException extends \LogicException implements ExceptionInterface +{ +} diff --git a/srcs/phpmyadmin/vendor/symfony/dependency-injection/Exception/OutOfBoundsException.php b/srcs/phpmyadmin/vendor/symfony/dependency-injection/Exception/OutOfBoundsException.php new file mode 100644 index 0000000..a61f143 --- /dev/null +++ b/srcs/phpmyadmin/vendor/symfony/dependency-injection/Exception/OutOfBoundsException.php @@ -0,0 +1,19 @@ +<?php + +/* + * This file is part of the Symfony package. + * + * (c) Fabien Potencier <fabien@symfony.com> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection\Exception; + +/** + * Base OutOfBoundsException for Dependency Injection component. + */ +class OutOfBoundsException extends \OutOfBoundsException implements ExceptionInterface +{ +} diff --git a/srcs/phpmyadmin/vendor/symfony/dependency-injection/Exception/ParameterCircularReferenceException.php b/srcs/phpmyadmin/vendor/symfony/dependency-injection/Exception/ParameterCircularReferenceException.php new file mode 100644 index 0000000..2450ccb --- /dev/null +++ b/srcs/phpmyadmin/vendor/symfony/dependency-injection/Exception/ParameterCircularReferenceException.php @@ -0,0 +1,34 @@ +<?php + +/* + * This file is part of the Symfony package. + * + * (c) Fabien Potencier <fabien@symfony.com> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection\Exception; + +/** + * This exception is thrown when a circular reference in a parameter is detected. + * + * @author Fabien Potencier <fabien@symfony.com> + */ +class ParameterCircularReferenceException extends RuntimeException +{ + private $parameters; + + public function __construct(array $parameters, \Throwable $previous = null) + { + parent::__construct(sprintf('Circular reference detected for parameter "%s" ("%s" > "%s").', $parameters[0], implode('" > "', $parameters), $parameters[0]), 0, $previous); + + $this->parameters = $parameters; + } + + public function getParameters() + { + return $this->parameters; + } +} diff --git a/srcs/phpmyadmin/vendor/symfony/dependency-injection/Exception/ParameterNotFoundException.php b/srcs/phpmyadmin/vendor/symfony/dependency-injection/Exception/ParameterNotFoundException.php new file mode 100644 index 0000000..7c0c5e3 --- /dev/null +++ b/srcs/phpmyadmin/vendor/symfony/dependency-injection/Exception/ParameterNotFoundException.php @@ -0,0 +1,100 @@ +<?php + +/* + * This file is part of the Symfony package. + * + * (c) Fabien Potencier <fabien@symfony.com> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection\Exception; + +use Psr\Container\NotFoundExceptionInterface; + +/** + * This exception is thrown when a non-existent parameter is used. + * + * @author Fabien Potencier <fabien@symfony.com> + */ +class ParameterNotFoundException extends InvalidArgumentException implements NotFoundExceptionInterface +{ + private $key; + private $sourceId; + private $sourceKey; + private $alternatives; + private $nonNestedAlternative; + + /** + * @param string $key The requested parameter key + * @param string $sourceId The service id that references the non-existent parameter + * @param string $sourceKey The parameter key that references the non-existent parameter + * @param \Throwable $previous The previous exception + * @param string[] $alternatives Some parameter name alternatives + * @param string|null $nonNestedAlternative The alternative parameter name when the user expected dot notation for nested parameters + */ + public function __construct(string $key, string $sourceId = null, string $sourceKey = null, \Throwable $previous = null, array $alternatives = [], string $nonNestedAlternative = null) + { + $this->key = $key; + $this->sourceId = $sourceId; + $this->sourceKey = $sourceKey; + $this->alternatives = $alternatives; + $this->nonNestedAlternative = $nonNestedAlternative; + + parent::__construct('', 0, $previous); + + $this->updateRepr(); + } + + public function updateRepr() + { + if (null !== $this->sourceId) { + $this->message = sprintf('The service "%s" has a dependency on a non-existent parameter "%s".', $this->sourceId, $this->key); + } elseif (null !== $this->sourceKey) { + $this->message = sprintf('The parameter "%s" has a dependency on a non-existent parameter "%s".', $this->sourceKey, $this->key); + } else { + $this->message = sprintf('You have requested a non-existent parameter "%s".', $this->key); + } + + if ($this->alternatives) { + if (1 == \count($this->alternatives)) { + $this->message .= ' Did you mean this: "'; + } else { + $this->message .= ' Did you mean one of these: "'; + } + $this->message .= implode('", "', $this->alternatives).'"?'; + } elseif (null !== $this->nonNestedAlternative) { + $this->message .= ' You cannot access nested array items, do you want to inject "'.$this->nonNestedAlternative.'" instead?'; + } + } + + public function getKey() + { + return $this->key; + } + + public function getSourceId() + { + return $this->sourceId; + } + + public function getSourceKey() + { + return $this->sourceKey; + } + + public function setSourceId($sourceId) + { + $this->sourceId = $sourceId; + + $this->updateRepr(); + } + + public function setSourceKey($sourceKey) + { + $this->sourceKey = $sourceKey; + + $this->updateRepr(); + } +} diff --git a/srcs/phpmyadmin/vendor/symfony/dependency-injection/Exception/RuntimeException.php b/srcs/phpmyadmin/vendor/symfony/dependency-injection/Exception/RuntimeException.php new file mode 100644 index 0000000..5c24541 --- /dev/null +++ b/srcs/phpmyadmin/vendor/symfony/dependency-injection/Exception/RuntimeException.php @@ -0,0 +1,21 @@ +<?php + +/* + * This file is part of the Symfony package. + * + * (c) Fabien Potencier <fabien@symfony.com> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection\Exception; + +/** + * Base RuntimeException for Dependency Injection component. + * + * @author Johannes M. Schmitt <schmittjoh@gmail.com> + */ +class RuntimeException extends \RuntimeException implements ExceptionInterface +{ +} diff --git a/srcs/phpmyadmin/vendor/symfony/dependency-injection/Exception/ServiceCircularReferenceException.php b/srcs/phpmyadmin/vendor/symfony/dependency-injection/Exception/ServiceCircularReferenceException.php new file mode 100644 index 0000000..a38671b --- /dev/null +++ b/srcs/phpmyadmin/vendor/symfony/dependency-injection/Exception/ServiceCircularReferenceException.php @@ -0,0 +1,41 @@ +<?php + +/* + * This file is part of the Symfony package. + * + * (c) Fabien Potencier <fabien@symfony.com> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection\Exception; + +/** + * This exception is thrown when a circular reference is detected. + * + * @author Johannes M. Schmitt <schmittjoh@gmail.com> + */ +class ServiceCircularReferenceException extends RuntimeException +{ + private $serviceId; + private $path; + + public function __construct(string $serviceId, array $path, \Throwable $previous = null) + { + parent::__construct(sprintf('Circular reference detected for service "%s", path: "%s".', $serviceId, implode(' -> ', $path)), 0, $previous); + + $this->serviceId = $serviceId; + $this->path = $path; + } + + public function getServiceId() + { + return $this->serviceId; + } + + public function getPath() + { + return $this->path; + } +} diff --git a/srcs/phpmyadmin/vendor/symfony/dependency-injection/Exception/ServiceNotFoundException.php b/srcs/phpmyadmin/vendor/symfony/dependency-injection/Exception/ServiceNotFoundException.php new file mode 100644 index 0000000..f91afae --- /dev/null +++ b/srcs/phpmyadmin/vendor/symfony/dependency-injection/Exception/ServiceNotFoundException.php @@ -0,0 +1,67 @@ +<?php + +/* + * This file is part of the Symfony package. + * + * (c) Fabien Potencier <fabien@symfony.com> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection\Exception; + +use Psr\Container\NotFoundExceptionInterface; + +/** + * This exception is thrown when a non-existent service is requested. + * + * @author Johannes M. Schmitt <schmittjoh@gmail.com> + */ +class ServiceNotFoundException extends InvalidArgumentException implements NotFoundExceptionInterface +{ + private $id; + private $sourceId; + private $alternatives; + + public function __construct(string $id, string $sourceId = null, \Throwable $previous = null, array $alternatives = [], string $msg = null) + { + if (null !== $msg) { + // no-op + } elseif (null === $sourceId) { + $msg = sprintf('You have requested a non-existent service "%s".', $id); + } else { + $msg = sprintf('The service "%s" has a dependency on a non-existent service "%s".', $sourceId, $id); + } + + if ($alternatives) { + if (1 == \count($alternatives)) { + $msg .= ' Did you mean this: "'; + } else { + $msg .= ' Did you mean one of these: "'; + } + $msg .= implode('", "', $alternatives).'"?'; + } + + parent::__construct($msg, 0, $previous); + + $this->id = $id; + $this->sourceId = $sourceId; + $this->alternatives = $alternatives; + } + + public function getId() + { + return $this->id; + } + + public function getSourceId() + { + return $this->sourceId; + } + + public function getAlternatives() + { + return $this->alternatives; + } +} diff --git a/srcs/phpmyadmin/vendor/symfony/dependency-injection/ExpressionLanguage.php b/srcs/phpmyadmin/vendor/symfony/dependency-injection/ExpressionLanguage.php new file mode 100644 index 0000000..961c737 --- /dev/null +++ b/srcs/phpmyadmin/vendor/symfony/dependency-injection/ExpressionLanguage.php @@ -0,0 +1,40 @@ +<?php + +/* + * This file is part of the Symfony package. + * + * (c) Fabien Potencier <fabien@symfony.com> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection; + +use Psr\Cache\CacheItemPoolInterface; +use Symfony\Component\ExpressionLanguage\ExpressionLanguage as BaseExpressionLanguage; + +if (!class_exists(BaseExpressionLanguage::class)) { + return; +} + +/** + * Adds some function to the default ExpressionLanguage. + * + * @author Fabien Potencier <fabien@symfony.com> + * + * @see ExpressionLanguageProvider + */ +class ExpressionLanguage extends BaseExpressionLanguage +{ + /** + * {@inheritdoc} + */ + public function __construct(CacheItemPoolInterface $cache = null, array $providers = [], callable $serviceCompiler = null) + { + // prepend the default provider to let users override it easily + array_unshift($providers, new ExpressionLanguageProvider($serviceCompiler)); + + parent::__construct($cache, $providers); + } +} diff --git a/srcs/phpmyadmin/vendor/symfony/dependency-injection/ExpressionLanguageProvider.php b/srcs/phpmyadmin/vendor/symfony/dependency-injection/ExpressionLanguageProvider.php new file mode 100644 index 0000000..9198ca0 --- /dev/null +++ b/srcs/phpmyadmin/vendor/symfony/dependency-injection/ExpressionLanguageProvider.php @@ -0,0 +1,50 @@ +<?php + +/* + * This file is part of the Symfony package. + * + * (c) Fabien Potencier <fabien@symfony.com> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection; + +use Symfony\Component\ExpressionLanguage\ExpressionFunction; +use Symfony\Component\ExpressionLanguage\ExpressionFunctionProviderInterface; + +/** + * Define some ExpressionLanguage functions. + * + * To get a service, use service('request'). + * To get a parameter, use parameter('kernel.debug'). + * + * @author Fabien Potencier <fabien@symfony.com> + */ +class ExpressionLanguageProvider implements ExpressionFunctionProviderInterface +{ + private $serviceCompiler; + + public function __construct(callable $serviceCompiler = null) + { + $this->serviceCompiler = $serviceCompiler; + } + + public function getFunctions() + { + return [ + new ExpressionFunction('service', $this->serviceCompiler ?: function ($arg) { + return sprintf('$this->get(%s)', $arg); + }, function (array $variables, $value) { + return $variables['container']->get($value); + }), + + new ExpressionFunction('parameter', function ($arg) { + return sprintf('$this->getParameter(%s)', $arg); + }, function (array $variables, $value) { + return $variables['container']->getParameter($value); + }), + ]; + } +} diff --git a/srcs/phpmyadmin/vendor/symfony/dependency-injection/Extension/ConfigurationExtensionInterface.php b/srcs/phpmyadmin/vendor/symfony/dependency-injection/Extension/ConfigurationExtensionInterface.php new file mode 100644 index 0000000..c3bd842 --- /dev/null +++ b/srcs/phpmyadmin/vendor/symfony/dependency-injection/Extension/ConfigurationExtensionInterface.php @@ -0,0 +1,30 @@ +<?php + +/* + * This file is part of the Symfony package. + * + * (c) Fabien Potencier <fabien@symfony.com> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection\Extension; + +use Symfony\Component\Config\Definition\ConfigurationInterface; +use Symfony\Component\DependencyInjection\ContainerBuilder; + +/** + * ConfigurationExtensionInterface is the interface implemented by container extension classes. + * + * @author Kevin Bond <kevinbond@gmail.com> + */ +interface ConfigurationExtensionInterface +{ + /** + * Returns extension configuration. + * + * @return ConfigurationInterface|null The configuration or null + */ + public function getConfiguration(array $config, ContainerBuilder $container); +} diff --git a/srcs/phpmyadmin/vendor/symfony/dependency-injection/Extension/Extension.php b/srcs/phpmyadmin/vendor/symfony/dependency-injection/Extension/Extension.php new file mode 100644 index 0000000..21580f6 --- /dev/null +++ b/srcs/phpmyadmin/vendor/symfony/dependency-injection/Extension/Extension.php @@ -0,0 +1,141 @@ +<?php + +/* + * This file is part of the Symfony package. + * + * (c) Fabien Potencier <fabien@symfony.com> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection\Extension; + +use Symfony\Component\Config\Definition\ConfigurationInterface; +use Symfony\Component\Config\Definition\Processor; +use Symfony\Component\DependencyInjection\Container; +use Symfony\Component\DependencyInjection\ContainerBuilder; +use Symfony\Component\DependencyInjection\Exception\BadMethodCallException; +use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException; + +/** + * Provides useful features shared by many extensions. + * + * @author Fabien Potencier <fabien@symfony.com> + */ +abstract class Extension implements ExtensionInterface, ConfigurationExtensionInterface +{ + private $processedConfigs = []; + + /** + * {@inheritdoc} + */ + public function getXsdValidationBasePath() + { + return false; + } + + /** + * {@inheritdoc} + */ + public function getNamespace() + { + return 'http://example.org/schema/dic/'.$this->getAlias(); + } + + /** + * Returns the recommended alias to use in XML. + * + * This alias is also the mandatory prefix to use when using YAML. + * + * This convention is to remove the "Extension" postfix from the class + * name and then lowercase and underscore the result. So: + * + * AcmeHelloExtension + * + * becomes + * + * acme_hello + * + * This can be overridden in a sub-class to specify the alias manually. + * + * @return string The alias + * + * @throws BadMethodCallException When the extension name does not follow conventions + */ + public function getAlias() + { + $className = \get_class($this); + if ('Extension' != substr($className, -9)) { + throw new BadMethodCallException('This extension does not follow the naming convention; you must overwrite the getAlias() method.'); + } + $classBaseName = substr(strrchr($className, '\\'), 1, -9); + + return Container::underscore($classBaseName); + } + + /** + * {@inheritdoc} + */ + public function getConfiguration(array $config, ContainerBuilder $container) + { + $class = \get_class($this); + + if (false !== strpos($class, "\0")) { + return null; // ignore anonymous classes + } + + $class = substr_replace($class, '\Configuration', strrpos($class, '\\')); + $class = $container->getReflectionClass($class); + + if (!$class) { + return null; + } + + if (!$class->implementsInterface(ConfigurationInterface::class)) { + @trigger_error(sprintf('Not implementing "%s" in the extension configuration class "%s" is deprecated since Symfony 4.1.', ConfigurationInterface::class, $class->getName()), E_USER_DEPRECATED); + //throw new LogicException(sprintf('The extension configuration class "%s" must implement "%s".', $class->getName(), ConfigurationInterface::class)); + + return null; + } + + if (!($constructor = $class->getConstructor()) || !$constructor->getNumberOfRequiredParameters()) { + return $class->newInstance(); + } + + return null; + } + + final protected function processConfiguration(ConfigurationInterface $configuration, array $configs): array + { + $processor = new Processor(); + + return $this->processedConfigs[] = $processor->processConfiguration($configuration, $configs); + } + + /** + * @internal + */ + final public function getProcessedConfigs(): array + { + try { + return $this->processedConfigs; + } finally { + $this->processedConfigs = []; + } + } + + /** + * @return bool Whether the configuration is enabled + * + * @throws InvalidArgumentException When the config is not enableable + */ + protected function isConfigEnabled(ContainerBuilder $container, array $config) + { + if (!\array_key_exists('enabled', $config)) { + throw new InvalidArgumentException("The config array has no 'enabled' key."); + } + + return (bool) $container->getParameterBag()->resolveValue($config['enabled']); + } +} diff --git a/srcs/phpmyadmin/vendor/symfony/dependency-injection/Extension/ExtensionInterface.php b/srcs/phpmyadmin/vendor/symfony/dependency-injection/Extension/ExtensionInterface.php new file mode 100644 index 0000000..6a7a2cf --- /dev/null +++ b/srcs/phpmyadmin/vendor/symfony/dependency-injection/Extension/ExtensionInterface.php @@ -0,0 +1,52 @@ +<?php + +/* + * This file is part of the Symfony package. + * + * (c) Fabien Potencier <fabien@symfony.com> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection\Extension; + +use Symfony\Component\DependencyInjection\ContainerBuilder; + +/** + * ExtensionInterface is the interface implemented by container extension classes. + * + * @author Fabien Potencier <fabien@symfony.com> + */ +interface ExtensionInterface +{ + /** + * Loads a specific configuration. + * + * @throws \InvalidArgumentException When provided tag is not defined in this extension + */ + public function load(array $configs, ContainerBuilder $container); + + /** + * Returns the namespace to be used for this extension (XML namespace). + * + * @return string The XML namespace + */ + public function getNamespace(); + + /** + * Returns the base path for the XSD files. + * + * @return string|false + */ + public function getXsdValidationBasePath(); + + /** + * Returns the recommended alias to use in XML. + * + * This alias is also the mandatory prefix to use when using YAML. + * + * @return string The alias + */ + public function getAlias(); +} diff --git a/srcs/phpmyadmin/vendor/symfony/dependency-injection/Extension/PrependExtensionInterface.php b/srcs/phpmyadmin/vendor/symfony/dependency-injection/Extension/PrependExtensionInterface.php new file mode 100644 index 0000000..5bd18d7 --- /dev/null +++ b/srcs/phpmyadmin/vendor/symfony/dependency-injection/Extension/PrependExtensionInterface.php @@ -0,0 +1,22 @@ +<?php + +/* + * This file is part of the Symfony package. + * + * (c) Fabien Potencier <fabien@symfony.com> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection\Extension; + +use Symfony\Component\DependencyInjection\ContainerBuilder; + +interface PrependExtensionInterface +{ + /** + * Allow an extension to prepend the extension configurations. + */ + public function prepend(ContainerBuilder $container); +} diff --git a/srcs/phpmyadmin/vendor/symfony/dependency-injection/LICENSE b/srcs/phpmyadmin/vendor/symfony/dependency-injection/LICENSE new file mode 100644 index 0000000..a677f43 --- /dev/null +++ b/srcs/phpmyadmin/vendor/symfony/dependency-injection/LICENSE @@ -0,0 +1,19 @@ +Copyright (c) 2004-2019 Fabien Potencier + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is furnished +to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/srcs/phpmyadmin/vendor/symfony/dependency-injection/LazyProxy/Instantiator/InstantiatorInterface.php b/srcs/phpmyadmin/vendor/symfony/dependency-injection/LazyProxy/Instantiator/InstantiatorInterface.php new file mode 100644 index 0000000..96104e4 --- /dev/null +++ b/srcs/phpmyadmin/vendor/symfony/dependency-injection/LazyProxy/Instantiator/InstantiatorInterface.php @@ -0,0 +1,34 @@ +<?php + +/* + * This file is part of the Symfony package. + * + * (c) Fabien Potencier <fabien@symfony.com> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection\LazyProxy\Instantiator; + +use Symfony\Component\DependencyInjection\ContainerInterface; +use Symfony\Component\DependencyInjection\Definition; + +/** + * Lazy proxy instantiator, capable of instantiating a proxy given a container, the + * service definitions and a callback that produces the real service instance. + * + * @author Marco Pivetta <ocramius@gmail.com> + */ +interface InstantiatorInterface +{ + /** + * Instantiates a proxy object. + * + * @param string $id Identifier of the requested service + * @param callable $realInstantiator Zero-argument callback that is capable of producing the real service instance + * + * @return object + */ + public function instantiateProxy(ContainerInterface $container, Definition $definition, $id, $realInstantiator); +} diff --git a/srcs/phpmyadmin/vendor/symfony/dependency-injection/LazyProxy/Instantiator/RealServiceInstantiator.php b/srcs/phpmyadmin/vendor/symfony/dependency-injection/LazyProxy/Instantiator/RealServiceInstantiator.php new file mode 100644 index 0000000..2e36704 --- /dev/null +++ b/srcs/phpmyadmin/vendor/symfony/dependency-injection/LazyProxy/Instantiator/RealServiceInstantiator.php @@ -0,0 +1,33 @@ +<?php + +/* + * This file is part of the Symfony package. + * + * (c) Fabien Potencier <fabien@symfony.com> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection\LazyProxy\Instantiator; + +use Symfony\Component\DependencyInjection\ContainerInterface; +use Symfony\Component\DependencyInjection\Definition; + +/** + * {@inheritdoc} + * + * Noop proxy instantiator - produces the real service instead of a proxy instance. + * + * @author Marco Pivetta <ocramius@gmail.com> + */ +class RealServiceInstantiator implements InstantiatorInterface +{ + /** + * {@inheritdoc} + */ + public function instantiateProxy(ContainerInterface $container, Definition $definition, $id, $realInstantiator) + { + return $realInstantiator(); + } +} diff --git a/srcs/phpmyadmin/vendor/symfony/dependency-injection/LazyProxy/PhpDumper/DumperInterface.php b/srcs/phpmyadmin/vendor/symfony/dependency-injection/LazyProxy/PhpDumper/DumperInterface.php new file mode 100644 index 0000000..f592e6c --- /dev/null +++ b/srcs/phpmyadmin/vendor/symfony/dependency-injection/LazyProxy/PhpDumper/DumperInterface.php @@ -0,0 +1,46 @@ +<?php + +/* + * This file is part of the Symfony package. + * + * (c) Fabien Potencier <fabien@symfony.com> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection\LazyProxy\PhpDumper; + +use Symfony\Component\DependencyInjection\Definition; + +/** + * Lazy proxy dumper capable of generating the instantiation logic PHP code for proxied services. + * + * @author Marco Pivetta <ocramius@gmail.com> + */ +interface DumperInterface +{ + /** + * Inspects whether the given definitions should produce proxy instantiation logic in the dumped container. + * + * @return bool + */ + public function isProxyCandidate(Definition $definition); + + /** + * Generates the code to be used to instantiate a proxy in the dumped factory code. + * + * @param string $id Service identifier + * @param string $factoryCode The code to execute to create the service + * + * @return string + */ + public function getProxyFactoryCode(Definition $definition, $id, $factoryCode); + + /** + * Generates the code for the lazy proxy. + * + * @return string + */ + public function getProxyCode(Definition $definition); +} diff --git a/srcs/phpmyadmin/vendor/symfony/dependency-injection/LazyProxy/PhpDumper/NullDumper.php b/srcs/phpmyadmin/vendor/symfony/dependency-injection/LazyProxy/PhpDumper/NullDumper.php new file mode 100644 index 0000000..ebc6a5d --- /dev/null +++ b/srcs/phpmyadmin/vendor/symfony/dependency-injection/LazyProxy/PhpDumper/NullDumper.php @@ -0,0 +1,48 @@ +<?php + +/* + * This file is part of the Symfony package. + * + * (c) Fabien Potencier <fabien@symfony.com> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection\LazyProxy\PhpDumper; + +use Symfony\Component\DependencyInjection\Definition; + +/** + * Null dumper, negates any proxy code generation for any given service definition. + * + * @author Marco Pivetta <ocramius@gmail.com> + * + * @final + */ +class NullDumper implements DumperInterface +{ + /** + * {@inheritdoc} + */ + public function isProxyCandidate(Definition $definition): bool + { + return false; + } + + /** + * {@inheritdoc} + */ + public function getProxyFactoryCode(Definition $definition, $id, $factoryCode = null): string + { + return ''; + } + + /** + * {@inheritdoc} + */ + public function getProxyCode(Definition $definition): string + { + return ''; + } +} diff --git a/srcs/phpmyadmin/vendor/symfony/dependency-injection/LazyProxy/ProxyHelper.php b/srcs/phpmyadmin/vendor/symfony/dependency-injection/LazyProxy/ProxyHelper.php new file mode 100644 index 0000000..e5611bc --- /dev/null +++ b/srcs/phpmyadmin/vendor/symfony/dependency-injection/LazyProxy/ProxyHelper.php @@ -0,0 +1,56 @@ +<?php + +/* + * This file is part of the Symfony package. + * + * (c) Fabien Potencier <fabien@symfony.com> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection\LazyProxy; + +/** + * @author Nicolas Grekas <p@tchwork.com> + * + * @internal + */ +class ProxyHelper +{ + /** + * @return string|null The FQCN or builtin name of the type hint, or null when the type hint references an invalid self|parent context + */ + public static function getTypeHint(\ReflectionFunctionAbstract $r, \ReflectionParameter $p = null, bool $noBuiltin = false): ?string + { + if ($p instanceof \ReflectionParameter) { + $type = $p->getType(); + } else { + $type = $r->getReturnType(); + } + if (!$type) { + return null; + } + if (!\is_string($type)) { + $name = $type->getName(); + + if ($type->isBuiltin()) { + return $noBuiltin ? null : $name; + } + } + $lcName = strtolower($name); + $prefix = $noBuiltin ? '' : '\\'; + + if ('self' !== $lcName && 'parent' !== $lcName) { + return $prefix.$name; + } + if (!$r instanceof \ReflectionMethod) { + return null; + } + if ('self' === $lcName) { + return $prefix.$r->getDeclaringClass()->name; + } + + return ($parent = $r->getDeclaringClass()->getParentClass()) ? $prefix.$parent->name : null; + } +} diff --git a/srcs/phpmyadmin/vendor/symfony/dependency-injection/Loader/ClosureLoader.php b/srcs/phpmyadmin/vendor/symfony/dependency-injection/Loader/ClosureLoader.php new file mode 100644 index 0000000..939dd7c --- /dev/null +++ b/srcs/phpmyadmin/vendor/symfony/dependency-injection/Loader/ClosureLoader.php @@ -0,0 +1,48 @@ +<?php + +/* + * This file is part of the Symfony package. + * + * (c) Fabien Potencier <fabien@symfony.com> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection\Loader; + +use Symfony\Component\Config\Loader\Loader; +use Symfony\Component\DependencyInjection\ContainerBuilder; + +/** + * ClosureLoader loads service definitions from a PHP closure. + * + * The Closure has access to the container as its first argument. + * + * @author Fabien Potencier <fabien@symfony.com> + */ +class ClosureLoader extends Loader +{ + private $container; + + public function __construct(ContainerBuilder $container) + { + $this->container = $container; + } + + /** + * {@inheritdoc} + */ + public function load($resource, $type = null) + { + $resource($this->container); + } + + /** + * {@inheritdoc} + */ + public function supports($resource, $type = null) + { + return $resource instanceof \Closure; + } +} diff --git a/srcs/phpmyadmin/vendor/symfony/dependency-injection/Loader/Configurator/AbstractConfigurator.php b/srcs/phpmyadmin/vendor/symfony/dependency-injection/Loader/Configurator/AbstractConfigurator.php new file mode 100644 index 0000000..c29ca7f --- /dev/null +++ b/srcs/phpmyadmin/vendor/symfony/dependency-injection/Loader/Configurator/AbstractConfigurator.php @@ -0,0 +1,87 @@ +<?php + +/* + * This file is part of the Symfony package. + * + * (c) Fabien Potencier <fabien@symfony.com> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection\Loader\Configurator; + +use Symfony\Component\DependencyInjection\Argument\ArgumentInterface; +use Symfony\Component\DependencyInjection\Definition; +use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException; +use Symfony\Component\DependencyInjection\Parameter; +use Symfony\Component\DependencyInjection\Reference; +use Symfony\Component\ExpressionLanguage\Expression; + +abstract class AbstractConfigurator +{ + const FACTORY = 'unknown'; + + /** @internal */ + protected $definition; + + public function __call($method, $args) + { + if (method_exists($this, 'set'.$method)) { + return $this->{'set'.$method}(...$args); + } + + throw new \BadMethodCallException(sprintf('Call to undefined method %s::%s()', \get_class($this), $method)); + } + + /** + * Checks that a value is valid, optionally replacing Definition and Reference configurators by their configure value. + * + * @param mixed $value + * @param bool $allowServices whether Definition and Reference are allowed; by default, only scalars and arrays are + * + * @return mixed the value, optionally cast to a Definition/Reference + */ + public static function processValue($value, $allowServices = false) + { + if (\is_array($value)) { + foreach ($value as $k => $v) { + $value[$k] = static::processValue($v, $allowServices); + } + + return $value; + } + + if ($value instanceof ReferenceConfigurator) { + return new Reference($value->id, $value->invalidBehavior); + } + + if ($value instanceof InlineServiceConfigurator) { + $def = $value->definition; + $value->definition = null; + + return $def; + } + + if ($value instanceof self) { + throw new InvalidArgumentException(sprintf('"%s()" can be used only at the root of service configuration files.', $value::FACTORY)); + } + + switch (true) { + case null === $value: + case is_scalar($value): + return $value; + + case $value instanceof ArgumentInterface: + case $value instanceof Definition: + case $value instanceof Expression: + case $value instanceof Parameter: + case $value instanceof Reference: + if ($allowServices) { + return $value; + } + } + + throw new InvalidArgumentException(sprintf('Cannot use values of type "%s" in service configuration files.', \is_object($value) ? \get_class($value) : \gettype($value))); + } +} diff --git a/srcs/phpmyadmin/vendor/symfony/dependency-injection/Loader/Configurator/AbstractServiceConfigurator.php b/srcs/phpmyadmin/vendor/symfony/dependency-injection/Loader/Configurator/AbstractServiceConfigurator.php new file mode 100644 index 0000000..9d3305e --- /dev/null +++ b/srcs/phpmyadmin/vendor/symfony/dependency-injection/Loader/Configurator/AbstractServiceConfigurator.php @@ -0,0 +1,93 @@ +<?php + +/* + * This file is part of the Symfony package. + * + * (c) Fabien Potencier <fabien@symfony.com> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection\Loader\Configurator; + +use Symfony\Component\DependencyInjection\Definition; +use Symfony\Component\DependencyInjection\Exception\ServiceNotFoundException; + +abstract class AbstractServiceConfigurator extends AbstractConfigurator +{ + protected $parent; + protected $id; + private $defaultTags = []; + + public function __construct(ServicesConfigurator $parent, Definition $definition, string $id = null, array $defaultTags = []) + { + $this->parent = $parent; + $this->definition = $definition; + $this->id = $id; + $this->defaultTags = $defaultTags; + } + + public function __destruct() + { + // default tags should be added last + foreach ($this->defaultTags as $name => $attributes) { + foreach ($attributes as $attributes) { + $this->definition->addTag($name, $attributes); + } + } + $this->defaultTags = []; + } + + /** + * Registers a service. + */ + final public function set(string $id, string $class = null): ServiceConfigurator + { + $this->__destruct(); + + return $this->parent->set($id, $class); + } + + /** + * Creates an alias. + */ + final public function alias(string $id, string $referencedId): AliasConfigurator + { + $this->__destruct(); + + return $this->parent->alias($id, $referencedId); + } + + /** + * Registers a PSR-4 namespace using a glob pattern. + */ + final public function load(string $namespace, string $resource): PrototypeConfigurator + { + $this->__destruct(); + + return $this->parent->load($namespace, $resource); + } + + /** + * Gets an already defined service definition. + * + * @throws ServiceNotFoundException if the service definition does not exist + */ + final public function get(string $id): ServiceConfigurator + { + $this->__destruct(); + + return $this->parent->get($id); + } + + /** + * Registers a service. + */ + final public function __invoke(string $id, string $class = null): ServiceConfigurator + { + $this->__destruct(); + + return $this->parent->set($id, $class); + } +} diff --git a/srcs/phpmyadmin/vendor/symfony/dependency-injection/Loader/Configurator/AliasConfigurator.php b/srcs/phpmyadmin/vendor/symfony/dependency-injection/Loader/Configurator/AliasConfigurator.php new file mode 100644 index 0000000..cb00f58 --- /dev/null +++ b/srcs/phpmyadmin/vendor/symfony/dependency-injection/Loader/Configurator/AliasConfigurator.php @@ -0,0 +1,30 @@ +<?php + +/* + * This file is part of the Symfony package. + * + * (c) Fabien Potencier <fabien@symfony.com> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection\Loader\Configurator; + +use Symfony\Component\DependencyInjection\Alias; + +/** + * @author Nicolas Grekas <p@tchwork.com> + */ +class AliasConfigurator extends AbstractServiceConfigurator +{ + const FACTORY = 'alias'; + + use Traits\PublicTrait; + + public function __construct(ServicesConfigurator $parent, Alias $alias) + { + $this->parent = $parent; + $this->definition = $alias; + } +} diff --git a/srcs/phpmyadmin/vendor/symfony/dependency-injection/Loader/Configurator/ContainerConfigurator.php b/srcs/phpmyadmin/vendor/symfony/dependency-injection/Loader/Configurator/ContainerConfigurator.php new file mode 100644 index 0000000..712d8c9 --- /dev/null +++ b/srcs/phpmyadmin/vendor/symfony/dependency-injection/Loader/Configurator/ContainerConfigurator.php @@ -0,0 +1,144 @@ +<?php + +/* + * This file is part of the Symfony package. + * + * (c) Fabien Potencier <fabien@symfony.com> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection\Loader\Configurator; + +use Symfony\Component\DependencyInjection\Argument\IteratorArgument; +use Symfony\Component\DependencyInjection\Argument\ServiceLocatorArgument; +use Symfony\Component\DependencyInjection\Argument\TaggedIteratorArgument; +use Symfony\Component\DependencyInjection\ContainerBuilder; +use Symfony\Component\DependencyInjection\Definition; +use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException; +use Symfony\Component\DependencyInjection\Extension\ExtensionInterface; +use Symfony\Component\DependencyInjection\Loader\PhpFileLoader; +use Symfony\Component\ExpressionLanguage\Expression; + +/** + * @author Nicolas Grekas <p@tchwork.com> + */ +class ContainerConfigurator extends AbstractConfigurator +{ + const FACTORY = 'container'; + + private $container; + private $loader; + private $instanceof; + private $path; + private $file; + private $anonymousCount = 0; + + public function __construct(ContainerBuilder $container, PhpFileLoader $loader, array &$instanceof, string $path, string $file) + { + $this->container = $container; + $this->loader = $loader; + $this->instanceof = &$instanceof; + $this->path = $path; + $this->file = $file; + } + + final public function extension(string $namespace, array $config) + { + if (!$this->container->hasExtension($namespace)) { + $extensions = array_filter(array_map(function (ExtensionInterface $ext) { return $ext->getAlias(); }, $this->container->getExtensions())); + throw new InvalidArgumentException(sprintf('There is no extension able to load the configuration for "%s" (in %s). Looked for namespace "%s", found %s', $namespace, $this->file, $namespace, $extensions ? sprintf('"%s"', implode('", "', $extensions)) : 'none')); + } + + $this->container->loadFromExtension($namespace, static::processValue($config)); + } + + final public function import(string $resource, string $type = null, $ignoreErrors = false) + { + $this->loader->setCurrentDir(\dirname($this->path)); + $this->loader->import($resource, $type, $ignoreErrors, $this->file); + } + + final public function parameters(): ParametersConfigurator + { + return new ParametersConfigurator($this->container); + } + + final public function services(): ServicesConfigurator + { + return new ServicesConfigurator($this->container, $this->loader, $this->instanceof, $this->path, $this->anonymousCount); + } +} + +/** + * Creates a service reference. + */ +function ref(string $id): ReferenceConfigurator +{ + return new ReferenceConfigurator($id); +} + +/** + * Creates an inline service. + */ +function inline(string $class = null): InlineServiceConfigurator +{ + return new InlineServiceConfigurator(new Definition($class)); +} + +/** + * Creates a service locator. + * + * @param ReferenceConfigurator[] $values + */ +function service_locator(array $values): ServiceLocatorArgument +{ + return new ServiceLocatorArgument(AbstractConfigurator::processValue($values, true)); +} + +/** + * Creates a lazy iterator. + * + * @param ReferenceConfigurator[] $values + */ +function iterator(array $values): IteratorArgument +{ + return new IteratorArgument(AbstractConfigurator::processValue($values, true)); +} + +/** + * Creates a lazy iterator by tag name. + * + * @deprecated since Symfony 4.4, to be removed in 5.0, use "tagged_iterator" instead. + */ +function tagged(string $tag, string $indexAttribute = null, string $defaultIndexMethod = null): TaggedIteratorArgument +{ + @trigger_error(__NAMESPACE__.'\tagged() is deprecated since Symfony 4.4 and will be removed in 5.0, use '.__NAMESPACE__.'\tagged_iterator() instead.', E_USER_DEPRECATED); + + return new TaggedIteratorArgument($tag, $indexAttribute, $defaultIndexMethod); +} + +/** + * Creates a lazy iterator by tag name. + */ +function tagged_iterator(string $tag, string $indexAttribute = null, string $defaultIndexMethod = null, string $defaultPriorityMethod = null): TaggedIteratorArgument +{ + return new TaggedIteratorArgument($tag, $indexAttribute, $defaultIndexMethod, false, $defaultPriorityMethod); +} + +/** + * Creates a service locator by tag name. + */ +function tagged_locator(string $tag, string $indexAttribute = null, string $defaultIndexMethod = null): ServiceLocatorArgument +{ + return new ServiceLocatorArgument(new TaggedIteratorArgument($tag, $indexAttribute, $defaultIndexMethod, true)); +} + +/** + * Creates an expression. + */ +function expr(string $expression): Expression +{ + return new Expression($expression); +} diff --git a/srcs/phpmyadmin/vendor/symfony/dependency-injection/Loader/Configurator/DefaultsConfigurator.php b/srcs/phpmyadmin/vendor/symfony/dependency-injection/Loader/Configurator/DefaultsConfigurator.php new file mode 100644 index 0000000..cd9088f --- /dev/null +++ b/srcs/phpmyadmin/vendor/symfony/dependency-injection/Loader/Configurator/DefaultsConfigurator.php @@ -0,0 +1,69 @@ +<?php + +/* + * This file is part of the Symfony package. + * + * (c) Fabien Potencier <fabien@symfony.com> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection\Loader\Configurator; + +use Symfony\Component\DependencyInjection\Definition; +use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException; + +/** + * @author Nicolas Grekas <p@tchwork.com> + */ +class DefaultsConfigurator extends AbstractServiceConfigurator +{ + const FACTORY = 'defaults'; + + use Traits\AutoconfigureTrait; + use Traits\AutowireTrait; + use Traits\BindTrait; + use Traits\PublicTrait; + + private $path; + + public function __construct(ServicesConfigurator $parent, Definition $definition, string $path = null) + { + parent::__construct($parent, $definition, null, []); + + $this->path = $path; + } + + /** + * Adds a tag for this definition. + * + * @return $this + * + * @throws InvalidArgumentException when an invalid tag name or attribute is provided + */ + final public function tag(string $name, array $attributes = []): self + { + if ('' === $name) { + throw new InvalidArgumentException('The tag name in "_defaults" must be a non-empty string.'); + } + + foreach ($attributes as $attribute => $value) { + if (null !== $value && !is_scalar($value)) { + throw new InvalidArgumentException(sprintf('Tag "%s", attribute "%s" in "_defaults" must be of a scalar-type.', $name, $attribute)); + } + } + + $this->definition->addTag($name, $attributes); + + return $this; + } + + /** + * Defines an instanceof-conditional to be applied to following service definitions. + */ + final public function instanceof(string $fqcn): InstanceofConfigurator + { + return $this->parent->instanceof($fqcn); + } +} diff --git a/srcs/phpmyadmin/vendor/symfony/dependency-injection/Loader/Configurator/InlineServiceConfigurator.php b/srcs/phpmyadmin/vendor/symfony/dependency-injection/Loader/Configurator/InlineServiceConfigurator.php new file mode 100644 index 0000000..362b374 --- /dev/null +++ b/srcs/phpmyadmin/vendor/symfony/dependency-injection/Loader/Configurator/InlineServiceConfigurator.php @@ -0,0 +1,36 @@ +<?php + +/* + * This file is part of the Symfony package. + * + * (c) Fabien Potencier <fabien@symfony.com> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection\Loader\Configurator; + +use Symfony\Component\DependencyInjection\Definition; + +/** + * @author Nicolas Grekas <p@tchwork.com> + */ +class InlineServiceConfigurator extends AbstractConfigurator +{ + const FACTORY = 'inline'; + + use Traits\ArgumentTrait; + use Traits\AutowireTrait; + use Traits\BindTrait; + use Traits\FactoryTrait; + use Traits\FileTrait; + use Traits\LazyTrait; + use Traits\ParentTrait; + use Traits\TagTrait; + + public function __construct(Definition $definition) + { + $this->definition = $definition; + } +} diff --git a/srcs/phpmyadmin/vendor/symfony/dependency-injection/Loader/Configurator/InstanceofConfigurator.php b/srcs/phpmyadmin/vendor/symfony/dependency-injection/Loader/Configurator/InstanceofConfigurator.php new file mode 100644 index 0000000..f75e176 --- /dev/null +++ b/srcs/phpmyadmin/vendor/symfony/dependency-injection/Loader/Configurator/InstanceofConfigurator.php @@ -0,0 +1,49 @@ +<?php + +/* + * This file is part of the Symfony package. + * + * (c) Fabien Potencier <fabien@symfony.com> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection\Loader\Configurator; + +use Symfony\Component\DependencyInjection\Definition; + +/** + * @author Nicolas Grekas <p@tchwork.com> + */ +class InstanceofConfigurator extends AbstractServiceConfigurator +{ + const FACTORY = 'instanceof'; + + use Traits\AutowireTrait; + use Traits\CallTrait; + use Traits\ConfiguratorTrait; + use Traits\LazyTrait; + use Traits\PropertyTrait; + use Traits\PublicTrait; + use Traits\ShareTrait; + use Traits\TagTrait; + use Traits\BindTrait; + + private $path; + + public function __construct(ServicesConfigurator $parent, Definition $definition, string $id, string $path = null) + { + parent::__construct($parent, $definition, $id, []); + + $this->path = $path; + } + + /** + * Defines an instanceof-conditional to be applied to following service definitions. + */ + final public function instanceof(string $fqcn): self + { + return $this->parent->instanceof($fqcn); + } +} diff --git a/srcs/phpmyadmin/vendor/symfony/dependency-injection/Loader/Configurator/ParametersConfigurator.php b/srcs/phpmyadmin/vendor/symfony/dependency-injection/Loader/Configurator/ParametersConfigurator.php new file mode 100644 index 0000000..a88d28e --- /dev/null +++ b/srcs/phpmyadmin/vendor/symfony/dependency-injection/Loader/Configurator/ParametersConfigurator.php @@ -0,0 +1,51 @@ +<?php + +/* + * This file is part of the Symfony package. + * + * (c) Fabien Potencier <fabien@symfony.com> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection\Loader\Configurator; + +use Symfony\Component\DependencyInjection\ContainerBuilder; + +/** + * @author Nicolas Grekas <p@tchwork.com> + */ +class ParametersConfigurator extends AbstractConfigurator +{ + const FACTORY = 'parameters'; + + private $container; + + public function __construct(ContainerBuilder $container) + { + $this->container = $container; + } + + /** + * Creates a parameter. + * + * @return $this + */ + final public function set(string $name, $value): self + { + $this->container->setParameter($name, static::processValue($value, true)); + + return $this; + } + + /** + * Creates a parameter. + * + * @return $this + */ + final public function __invoke(string $name, $value): self + { + return $this->set($name, $value); + } +} diff --git a/srcs/phpmyadmin/vendor/symfony/dependency-injection/Loader/Configurator/PrototypeConfigurator.php b/srcs/phpmyadmin/vendor/symfony/dependency-injection/Loader/Configurator/PrototypeConfigurator.php new file mode 100644 index 0000000..3cd56e0 --- /dev/null +++ b/srcs/phpmyadmin/vendor/symfony/dependency-injection/Loader/Configurator/PrototypeConfigurator.php @@ -0,0 +1,84 @@ +<?php + +/* + * This file is part of the Symfony package. + * + * (c) Fabien Potencier <fabien@symfony.com> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection\Loader\Configurator; + +use Symfony\Component\DependencyInjection\Definition; +use Symfony\Component\DependencyInjection\Loader\PhpFileLoader; + +/** + * @author Nicolas Grekas <p@tchwork.com> + */ +class PrototypeConfigurator extends AbstractServiceConfigurator +{ + const FACTORY = 'load'; + + use Traits\AbstractTrait; + use Traits\ArgumentTrait; + use Traits\AutoconfigureTrait; + use Traits\AutowireTrait; + use Traits\BindTrait; + use Traits\CallTrait; + use Traits\ConfiguratorTrait; + use Traits\DeprecateTrait; + use Traits\FactoryTrait; + use Traits\LazyTrait; + use Traits\ParentTrait; + use Traits\PropertyTrait; + use Traits\PublicTrait; + use Traits\ShareTrait; + use Traits\TagTrait; + + private $loader; + private $resource; + private $excludes; + private $allowParent; + + public function __construct(ServicesConfigurator $parent, PhpFileLoader $loader, Definition $defaults, string $namespace, string $resource, bool $allowParent) + { + $definition = new Definition(); + $definition->setPublic($defaults->isPublic()); + $definition->setAutowired($defaults->isAutowired()); + $definition->setAutoconfigured($defaults->isAutoconfigured()); + $definition->setBindings($defaults->getBindings()); + $definition->setChanges([]); + + $this->loader = $loader; + $this->resource = $resource; + $this->allowParent = $allowParent; + + parent::__construct($parent, $definition, $namespace, $defaults->getTags()); + } + + public function __destruct() + { + parent::__destruct(); + + if ($this->loader) { + $this->loader->registerClasses($this->definition, $this->id, $this->resource, $this->excludes); + } + $this->loader = null; + } + + /** + * Excludes files from registration using glob patterns. + * + * @param string[]|string $excludes + * + * @return $this + */ + final public function exclude($excludes): self + { + $this->excludes = (array) $excludes; + + return $this; + } +} diff --git a/srcs/phpmyadmin/vendor/symfony/dependency-injection/Loader/Configurator/ReferenceConfigurator.php b/srcs/phpmyadmin/vendor/symfony/dependency-injection/Loader/Configurator/ReferenceConfigurator.php new file mode 100644 index 0000000..fa04253 --- /dev/null +++ b/srcs/phpmyadmin/vendor/symfony/dependency-injection/Loader/Configurator/ReferenceConfigurator.php @@ -0,0 +1,69 @@ +<?php + +/* + * This file is part of the Symfony package. + * + * (c) Fabien Potencier <fabien@symfony.com> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection\Loader\Configurator; + +use Symfony\Component\DependencyInjection\ContainerInterface; + +/** + * @author Nicolas Grekas <p@tchwork.com> + */ +class ReferenceConfigurator extends AbstractConfigurator +{ + /** @internal */ + protected $id; + + /** @internal */ + protected $invalidBehavior = ContainerInterface::EXCEPTION_ON_INVALID_REFERENCE; + + public function __construct(string $id) + { + $this->id = $id; + } + + /** + * @return $this + */ + final public function ignoreOnInvalid(): self + { + $this->invalidBehavior = ContainerInterface::IGNORE_ON_INVALID_REFERENCE; + + return $this; + } + + /** + * @return $this + */ + final public function nullOnInvalid(): self + { + $this->invalidBehavior = ContainerInterface::NULL_ON_INVALID_REFERENCE; + + return $this; + } + + /** + * @return $this + */ + final public function ignoreOnUninitialized(): self + { + $this->invalidBehavior = ContainerInterface::IGNORE_ON_UNINITIALIZED_REFERENCE; + + return $this; + } + + /** + * @return string + */ + public function __toString() + { + return $this->id; + } +} diff --git a/srcs/phpmyadmin/vendor/symfony/dependency-injection/Loader/Configurator/ServiceConfigurator.php b/srcs/phpmyadmin/vendor/symfony/dependency-injection/Loader/Configurator/ServiceConfigurator.php new file mode 100644 index 0000000..f1a6af7 --- /dev/null +++ b/srcs/phpmyadmin/vendor/symfony/dependency-injection/Loader/Configurator/ServiceConfigurator.php @@ -0,0 +1,72 @@ +<?php + +/* + * This file is part of the Symfony package. + * + * (c) Fabien Potencier <fabien@symfony.com> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection\Loader\Configurator; + +use Symfony\Component\DependencyInjection\ChildDefinition; +use Symfony\Component\DependencyInjection\ContainerBuilder; +use Symfony\Component\DependencyInjection\Definition; + +/** + * @author Nicolas Grekas <p@tchwork.com> + */ +class ServiceConfigurator extends AbstractServiceConfigurator +{ + const FACTORY = 'services'; + + use Traits\AbstractTrait; + use Traits\ArgumentTrait; + use Traits\AutoconfigureTrait; + use Traits\AutowireTrait; + use Traits\BindTrait; + use Traits\CallTrait; + use Traits\ClassTrait; + use Traits\ConfiguratorTrait; + use Traits\DecorateTrait; + use Traits\DeprecateTrait; + use Traits\FactoryTrait; + use Traits\FileTrait; + use Traits\LazyTrait; + use Traits\ParentTrait; + use Traits\PropertyTrait; + use Traits\PublicTrait; + use Traits\ShareTrait; + use Traits\SyntheticTrait; + use Traits\TagTrait; + + private $container; + private $instanceof; + private $allowParent; + private $path; + + public function __construct(ContainerBuilder $container, array $instanceof, bool $allowParent, ServicesConfigurator $parent, Definition $definition, $id, array $defaultTags, string $path = null) + { + $this->container = $container; + $this->instanceof = $instanceof; + $this->allowParent = $allowParent; + $this->path = $path; + + parent::__construct($parent, $definition, $id, $defaultTags); + } + + public function __destruct() + { + parent::__destruct(); + + $this->container->removeBindings($this->id); + + if (!$this->definition instanceof ChildDefinition) { + $this->container->setDefinition($this->id, $this->definition->setInstanceofConditionals($this->instanceof)); + } else { + $this->container->setDefinition($this->id, $this->definition); + } + } +} diff --git a/srcs/phpmyadmin/vendor/symfony/dependency-injection/Loader/Configurator/ServicesConfigurator.php b/srcs/phpmyadmin/vendor/symfony/dependency-injection/Loader/Configurator/ServicesConfigurator.php new file mode 100644 index 0000000..f0fdde8 --- /dev/null +++ b/srcs/phpmyadmin/vendor/symfony/dependency-injection/Loader/Configurator/ServicesConfigurator.php @@ -0,0 +1,147 @@ +<?php + +/* + * This file is part of the Symfony package. + * + * (c) Fabien Potencier <fabien@symfony.com> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection\Loader\Configurator; + +use Symfony\Component\DependencyInjection\Alias; +use Symfony\Component\DependencyInjection\ChildDefinition; +use Symfony\Component\DependencyInjection\ContainerBuilder; +use Symfony\Component\DependencyInjection\Definition; +use Symfony\Component\DependencyInjection\Exception\ServiceNotFoundException; +use Symfony\Component\DependencyInjection\Loader\PhpFileLoader; + +/** + * @author Nicolas Grekas <p@tchwork.com> + */ +class ServicesConfigurator extends AbstractConfigurator +{ + const FACTORY = 'services'; + + private $defaults; + private $container; + private $loader; + private $instanceof; + private $path; + private $anonymousHash; + private $anonymousCount; + + public function __construct(ContainerBuilder $container, PhpFileLoader $loader, array &$instanceof, string $path = null, int &$anonymousCount = 0) + { + $this->defaults = new Definition(); + $this->container = $container; + $this->loader = $loader; + $this->instanceof = &$instanceof; + $this->path = $path; + $this->anonymousHash = ContainerBuilder::hash($path ?: mt_rand()); + $this->anonymousCount = &$anonymousCount; + $instanceof = []; + } + + /** + * Defines a set of defaults for following service definitions. + */ + final public function defaults(): DefaultsConfigurator + { + return new DefaultsConfigurator($this, $this->defaults = new Definition(), $this->path); + } + + /** + * Defines an instanceof-conditional to be applied to following service definitions. + */ + final public function instanceof(string $fqcn): InstanceofConfigurator + { + $this->instanceof[$fqcn] = $definition = new ChildDefinition(''); + + return new InstanceofConfigurator($this, $definition, $fqcn, $this->path); + } + + /** + * Registers a service. + * + * @param string|null $id The service id, or null to create an anonymous service + * @param string|null $class The class of the service, or null when $id is also the class name + */ + final public function set(?string $id, string $class = null): ServiceConfigurator + { + $defaults = $this->defaults; + $allowParent = !$defaults->getChanges() && empty($this->instanceof); + + $definition = new Definition(); + + if (null === $id) { + if (!$class) { + throw new \LogicException('Anonymous services must have a class name.'); + } + + $id = sprintf('.%d_%s', ++$this->anonymousCount, preg_replace('/^.*\\\\/', '', $class).'~'.$this->anonymousHash); + $definition->setPublic(false); + } else { + $definition->setPublic($defaults->isPublic()); + } + + $definition->setAutowired($defaults->isAutowired()); + $definition->setAutoconfigured($defaults->isAutoconfigured()); + $definition->setBindings($defaults->getBindings()); + $definition->setChanges([]); + + $configurator = new ServiceConfigurator($this->container, $this->instanceof, $allowParent, $this, $definition, $id, $defaults->getTags(), $this->path); + + return null !== $class ? $configurator->class($class) : $configurator; + } + + /** + * Creates an alias. + */ + final public function alias(string $id, string $referencedId): AliasConfigurator + { + $ref = static::processValue($referencedId, true); + $alias = new Alias((string) $ref, $this->defaults->isPublic()); + $this->container->setAlias($id, $alias); + + return new AliasConfigurator($this, $alias); + } + + /** + * Registers a PSR-4 namespace using a glob pattern. + */ + final public function load(string $namespace, string $resource): PrototypeConfigurator + { + $allowParent = !$this->defaults->getChanges() && empty($this->instanceof); + + return new PrototypeConfigurator($this, $this->loader, $this->defaults, $namespace, $resource, $allowParent); + } + + /** + * Gets an already defined service definition. + * + * @throws ServiceNotFoundException if the service definition does not exist + */ + final public function get(string $id): ServiceConfigurator + { + $allowParent = !$this->defaults->getChanges() && empty($this->instanceof); + $definition = $this->container->getDefinition($id); + + return new ServiceConfigurator($this->container, $definition->getInstanceofConditionals(), $allowParent, $this, $definition, $id, []); + } + + /** + * Registers a service. + */ + final public function __invoke(string $id, string $class = null): ServiceConfigurator + { + return $this->set($id, $class); + } + + public function __destruct() + { + $this->loader->registerAliasesForSinglyImplementedInterfaces(); + } +} diff --git a/srcs/phpmyadmin/vendor/symfony/dependency-injection/Loader/Configurator/Traits/AbstractTrait.php b/srcs/phpmyadmin/vendor/symfony/dependency-injection/Loader/Configurator/Traits/AbstractTrait.php new file mode 100644 index 0000000..82ba21d --- /dev/null +++ b/srcs/phpmyadmin/vendor/symfony/dependency-injection/Loader/Configurator/Traits/AbstractTrait.php @@ -0,0 +1,28 @@ +<?php + +/* + * This file is part of the Symfony package. + * + * (c) Fabien Potencier <fabien@symfony.com> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection\Loader\Configurator\Traits; + +trait AbstractTrait +{ + /** + * Whether this definition is abstract, that means it merely serves as a + * template for other definitions. + * + * @return $this + */ + final public function abstract(bool $abstract = true): self + { + $this->definition->setAbstract($abstract); + + return $this; + } +} diff --git a/srcs/phpmyadmin/vendor/symfony/dependency-injection/Loader/Configurator/Traits/ArgumentTrait.php b/srcs/phpmyadmin/vendor/symfony/dependency-injection/Loader/Configurator/Traits/ArgumentTrait.php new file mode 100644 index 0000000..5c9a475 --- /dev/null +++ b/srcs/phpmyadmin/vendor/symfony/dependency-injection/Loader/Configurator/Traits/ArgumentTrait.php @@ -0,0 +1,42 @@ +<?php + +/* + * This file is part of the Symfony package. + * + * (c) Fabien Potencier <fabien@symfony.com> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection\Loader\Configurator\Traits; + +trait ArgumentTrait +{ + /** + * Sets the arguments to pass to the service constructor/factory method. + * + * @return $this + */ + final public function args(array $arguments): self + { + $this->definition->setArguments(static::processValue($arguments, true)); + + return $this; + } + + /** + * Sets one argument to pass to the service constructor/factory method. + * + * @param string|int $key + * @param mixed $value + * + * @return $this + */ + final public function arg($key, $value): self + { + $this->definition->setArgument($key, static::processValue($value, true)); + + return $this; + } +} diff --git a/srcs/phpmyadmin/vendor/symfony/dependency-injection/Loader/Configurator/Traits/AutoconfigureTrait.php b/srcs/phpmyadmin/vendor/symfony/dependency-injection/Loader/Configurator/Traits/AutoconfigureTrait.php new file mode 100644 index 0000000..836f458 --- /dev/null +++ b/srcs/phpmyadmin/vendor/symfony/dependency-injection/Loader/Configurator/Traits/AutoconfigureTrait.php @@ -0,0 +1,35 @@ +<?php + +/* + * This file is part of the Symfony package. + * + * (c) Fabien Potencier <fabien@symfony.com> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection\Loader\Configurator\Traits; + +use Symfony\Component\DependencyInjection\ChildDefinition; +use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException; + +trait AutoconfigureTrait +{ + /** + * Sets whether or not instanceof conditionals should be prepended with a global set. + * + * @return $this + * + * @throws InvalidArgumentException when a parent is already set + */ + final public function autoconfigure(bool $autoconfigured = true): self + { + if ($autoconfigured && $this->definition instanceof ChildDefinition) { + throw new InvalidArgumentException(sprintf('The service "%s" cannot have a "parent" and also have "autoconfigure". Try disabling autoconfiguration for the service.', $this->id)); + } + $this->definition->setAutoconfigured($autoconfigured); + + return $this; + } +} diff --git a/srcs/phpmyadmin/vendor/symfony/dependency-injection/Loader/Configurator/Traits/AutowireTrait.php b/srcs/phpmyadmin/vendor/symfony/dependency-injection/Loader/Configurator/Traits/AutowireTrait.php new file mode 100644 index 0000000..2837a02 --- /dev/null +++ b/srcs/phpmyadmin/vendor/symfony/dependency-injection/Loader/Configurator/Traits/AutowireTrait.php @@ -0,0 +1,27 @@ +<?php + +/* + * This file is part of the Symfony package. + * + * (c) Fabien Potencier <fabien@symfony.com> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection\Loader\Configurator\Traits; + +trait AutowireTrait +{ + /** + * Enables/disables autowiring. + * + * @return $this + */ + final public function autowire(bool $autowired = true): self + { + $this->definition->setAutowired($autowired); + + return $this; + } +} diff --git a/srcs/phpmyadmin/vendor/symfony/dependency-injection/Loader/Configurator/Traits/BindTrait.php b/srcs/phpmyadmin/vendor/symfony/dependency-injection/Loader/Configurator/Traits/BindTrait.php new file mode 100644 index 0000000..1328494 --- /dev/null +++ b/srcs/phpmyadmin/vendor/symfony/dependency-injection/Loader/Configurator/Traits/BindTrait.php @@ -0,0 +1,47 @@ +<?php + +/* + * This file is part of the Symfony package. + * + * (c) Fabien Potencier <fabien@symfony.com> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection\Loader\Configurator\Traits; + +use Symfony\Component\DependencyInjection\Argument\BoundArgument; +use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException; +use Symfony\Component\DependencyInjection\Loader\Configurator\DefaultsConfigurator; +use Symfony\Component\DependencyInjection\Loader\Configurator\InstanceofConfigurator; +use Symfony\Component\DependencyInjection\Reference; + +trait BindTrait +{ + /** + * Sets bindings. + * + * Bindings map $named or FQCN arguments to values that should be + * injected in the matching parameters (of the constructor, of methods + * called and of controller actions). + * + * @param string $nameOrFqcn A parameter name with its "$" prefix, or a FQCN + * @param mixed $valueOrRef The value or reference to bind + * + * @return $this + */ + final public function bind(string $nameOrFqcn, $valueOrRef): self + { + $valueOrRef = static::processValue($valueOrRef, true); + if (!preg_match('/^(?:(?:array|bool|float|int|string)[ \t]*+)?\$/', $nameOrFqcn) && !$valueOrRef instanceof Reference) { + throw new InvalidArgumentException(sprintf('Invalid binding for service "%s": named arguments must start with a "$", and FQCN must map to references. Neither applies to binding "%s".', $this->id, $nameOrFqcn)); + } + $bindings = $this->definition->getBindings(); + $type = $this instanceof DefaultsConfigurator ? BoundArgument::DEFAULTS_BINDING : ($this instanceof InstanceofConfigurator ? BoundArgument::INSTANCEOF_BINDING : BoundArgument::SERVICE_BINDING); + $bindings[$nameOrFqcn] = new BoundArgument($valueOrRef, true, $type, $this->path ?? null); + $this->definition->setBindings($bindings); + + return $this; + } +} diff --git a/srcs/phpmyadmin/vendor/symfony/dependency-injection/Loader/Configurator/Traits/CallTrait.php b/srcs/phpmyadmin/vendor/symfony/dependency-injection/Loader/Configurator/Traits/CallTrait.php new file mode 100644 index 0000000..28f92d2 --- /dev/null +++ b/srcs/phpmyadmin/vendor/symfony/dependency-injection/Loader/Configurator/Traits/CallTrait.php @@ -0,0 +1,35 @@ +<?php + +/* + * This file is part of the Symfony package. + * + * (c) Fabien Potencier <fabien@symfony.com> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection\Loader\Configurator\Traits; + +use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException; + +trait CallTrait +{ + /** + * Adds a method to call after service initialization. + * + * @param string $method The method name to call + * @param array $arguments An array of arguments to pass to the method call + * @param bool $returnsClone Whether the call returns the service instance or not + * + * @return $this + * + * @throws InvalidArgumentException on empty $method param + */ + final public function call(string $method, array $arguments = [], bool $returnsClone = false): self + { + $this->definition->addMethodCall($method, static::processValue($arguments, true), $returnsClone); + + return $this; + } +} diff --git a/srcs/phpmyadmin/vendor/symfony/dependency-injection/Loader/Configurator/Traits/ClassTrait.php b/srcs/phpmyadmin/vendor/symfony/dependency-injection/Loader/Configurator/Traits/ClassTrait.php new file mode 100644 index 0000000..20da791 --- /dev/null +++ b/srcs/phpmyadmin/vendor/symfony/dependency-injection/Loader/Configurator/Traits/ClassTrait.php @@ -0,0 +1,27 @@ +<?php + +/* + * This file is part of the Symfony package. + * + * (c) Fabien Potencier <fabien@symfony.com> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection\Loader\Configurator\Traits; + +trait ClassTrait +{ + /** + * Sets the service class. + * + * @return $this + */ + final public function class(?string $class): self + { + $this->definition->setClass($class); + + return $this; + } +} diff --git a/srcs/phpmyadmin/vendor/symfony/dependency-injection/Loader/Configurator/Traits/ConfiguratorTrait.php b/srcs/phpmyadmin/vendor/symfony/dependency-injection/Loader/Configurator/Traits/ConfiguratorTrait.php new file mode 100644 index 0000000..25d363c --- /dev/null +++ b/srcs/phpmyadmin/vendor/symfony/dependency-injection/Loader/Configurator/Traits/ConfiguratorTrait.php @@ -0,0 +1,29 @@ +<?php + +/* + * This file is part of the Symfony package. + * + * (c) Fabien Potencier <fabien@symfony.com> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection\Loader\Configurator\Traits; + +trait ConfiguratorTrait +{ + /** + * Sets a configurator to call after the service is fully initialized. + * + * @param string|array $configurator A PHP callable reference + * + * @return $this + */ + final public function configurator($configurator): self + { + $this->definition->setConfigurator(static::processValue($configurator, true)); + + return $this; + } +} diff --git a/srcs/phpmyadmin/vendor/symfony/dependency-injection/Loader/Configurator/Traits/DecorateTrait.php b/srcs/phpmyadmin/vendor/symfony/dependency-injection/Loader/Configurator/Traits/DecorateTrait.php new file mode 100644 index 0000000..222cf75 --- /dev/null +++ b/srcs/phpmyadmin/vendor/symfony/dependency-injection/Loader/Configurator/Traits/DecorateTrait.php @@ -0,0 +1,37 @@ +<?php + +/* + * This file is part of the Symfony package. + * + * (c) Fabien Potencier <fabien@symfony.com> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection\Loader\Configurator\Traits; + +use Symfony\Component\DependencyInjection\ContainerInterface; +use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException; + +trait DecorateTrait +{ + /** + * Sets the service that this service is decorating. + * + * @param string|null $id The decorated service id, use null to remove decoration + * @param string|null $renamedId The new decorated service id + * @param int $priority The priority of decoration + * @param int $invalidBehavior The behavior to adopt when decorated is invalid + * + * @return $this + * + * @throws InvalidArgumentException in case the decorated service id and the new decorated service id are equals + */ + final public function decorate(?string $id, string $renamedId = null, int $priority = 0, int $invalidBehavior = ContainerInterface::EXCEPTION_ON_INVALID_REFERENCE): self + { + $this->definition->setDecoratedService($id, $renamedId, $priority, $invalidBehavior); + + return $this; + } +} diff --git a/srcs/phpmyadmin/vendor/symfony/dependency-injection/Loader/Configurator/Traits/DeprecateTrait.php b/srcs/phpmyadmin/vendor/symfony/dependency-injection/Loader/Configurator/Traits/DeprecateTrait.php new file mode 100644 index 0000000..b2d5b0e --- /dev/null +++ b/srcs/phpmyadmin/vendor/symfony/dependency-injection/Loader/Configurator/Traits/DeprecateTrait.php @@ -0,0 +1,33 @@ +<?php + +/* + * This file is part of the Symfony package. + * + * (c) Fabien Potencier <fabien@symfony.com> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection\Loader\Configurator\Traits; + +use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException; + +trait DeprecateTrait +{ + /** + * Whether this definition is deprecated, that means it should not be called anymore. + * + * @param string $template Template message to use if the definition is deprecated + * + * @return $this + * + * @throws InvalidArgumentException when the message template is invalid + */ + final public function deprecate(string $template = null): self + { + $this->definition->setDeprecated(true, $template); + + return $this; + } +} diff --git a/srcs/phpmyadmin/vendor/symfony/dependency-injection/Loader/Configurator/Traits/FactoryTrait.php b/srcs/phpmyadmin/vendor/symfony/dependency-injection/Loader/Configurator/Traits/FactoryTrait.php new file mode 100644 index 0000000..3834d72 --- /dev/null +++ b/srcs/phpmyadmin/vendor/symfony/dependency-injection/Loader/Configurator/Traits/FactoryTrait.php @@ -0,0 +1,37 @@ +<?php + +/* + * This file is part of the Symfony package. + * + * (c) Fabien Potencier <fabien@symfony.com> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection\Loader\Configurator\Traits; + +use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException; + +trait FactoryTrait +{ + /** + * Sets a factory. + * + * @param string|array $factory A PHP callable reference + * + * @return $this + */ + final public function factory($factory): self + { + if (\is_string($factory) && 1 === substr_count($factory, ':')) { + $factoryParts = explode(':', $factory); + + throw new InvalidArgumentException(sprintf('Invalid factory "%s": the "service:method" notation is not available when using PHP-based DI configuration. Use "[ref(\'%s\'), \'%s\']" instead.', $factory, $factoryParts[0], $factoryParts[1])); + } + + $this->definition->setFactory(static::processValue($factory, true)); + + return $this; + } +} diff --git a/srcs/phpmyadmin/vendor/symfony/dependency-injection/Loader/Configurator/Traits/FileTrait.php b/srcs/phpmyadmin/vendor/symfony/dependency-injection/Loader/Configurator/Traits/FileTrait.php new file mode 100644 index 0000000..5f42aef --- /dev/null +++ b/srcs/phpmyadmin/vendor/symfony/dependency-injection/Loader/Configurator/Traits/FileTrait.php @@ -0,0 +1,27 @@ +<?php + +/* + * This file is part of the Symfony package. + * + * (c) Fabien Potencier <fabien@symfony.com> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection\Loader\Configurator\Traits; + +trait FileTrait +{ + /** + * Sets a file to require before creating the service. + * + * @return $this + */ + final public function file(string $file): self + { + $this->definition->setFile($file); + + return $this; + } +} diff --git a/srcs/phpmyadmin/vendor/symfony/dependency-injection/Loader/Configurator/Traits/LazyTrait.php b/srcs/phpmyadmin/vendor/symfony/dependency-injection/Loader/Configurator/Traits/LazyTrait.php new file mode 100644 index 0000000..2829def --- /dev/null +++ b/srcs/phpmyadmin/vendor/symfony/dependency-injection/Loader/Configurator/Traits/LazyTrait.php @@ -0,0 +1,32 @@ +<?php + +/* + * This file is part of the Symfony package. + * + * (c) Fabien Potencier <fabien@symfony.com> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection\Loader\Configurator\Traits; + +trait LazyTrait +{ + /** + * Sets the lazy flag of this service. + * + * @param bool|string $lazy A FQCN to derivate the lazy proxy from or `true` to make it extend from the definition's class + * + * @return $this + */ + final public function lazy($lazy = true): self + { + $this->definition->setLazy((bool) $lazy); + if (\is_string($lazy)) { + $this->definition->addTag('proxy', ['interface' => $lazy]); + } + + return $this; + } +} diff --git a/srcs/phpmyadmin/vendor/symfony/dependency-injection/Loader/Configurator/Traits/ParentTrait.php b/srcs/phpmyadmin/vendor/symfony/dependency-injection/Loader/Configurator/Traits/ParentTrait.php new file mode 100644 index 0000000..7488a38 --- /dev/null +++ b/srcs/phpmyadmin/vendor/symfony/dependency-injection/Loader/Configurator/Traits/ParentTrait.php @@ -0,0 +1,50 @@ +<?php + +/* + * This file is part of the Symfony package. + * + * (c) Fabien Potencier <fabien@symfony.com> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection\Loader\Configurator\Traits; + +use Symfony\Component\DependencyInjection\ChildDefinition; +use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException; + +trait ParentTrait +{ + /** + * Sets the Definition to inherit from. + * + * @return $this + * + * @throws InvalidArgumentException when parent cannot be set + */ + final public function parent(string $parent): self + { + if (!$this->allowParent) { + throw new InvalidArgumentException(sprintf('A parent cannot be defined when either "_instanceof" or "_defaults" are also defined for service prototype "%s".', $this->id)); + } + + if ($this->definition instanceof ChildDefinition) { + $this->definition->setParent($parent); + } elseif ($this->definition->isAutoconfigured()) { + throw new InvalidArgumentException(sprintf('The service "%s" cannot have a "parent" and also have "autoconfigure". Try disabling autoconfiguration for the service.', $this->id)); + } elseif ($this->definition->getBindings()) { + throw new InvalidArgumentException(sprintf('The service "%s" cannot have a "parent" and also "bind" arguments.', $this->id)); + } else { + // cast Definition to ChildDefinition + $definition = serialize($this->definition); + $definition = substr_replace($definition, '53', 2, 2); + $definition = substr_replace($definition, 'Child', 44, 0); + $definition = unserialize($definition); + + $this->definition = $definition->setParent($parent); + } + + return $this; + } +} diff --git a/srcs/phpmyadmin/vendor/symfony/dependency-injection/Loader/Configurator/Traits/PropertyTrait.php b/srcs/phpmyadmin/vendor/symfony/dependency-injection/Loader/Configurator/Traits/PropertyTrait.php new file mode 100644 index 0000000..10fdcfb --- /dev/null +++ b/srcs/phpmyadmin/vendor/symfony/dependency-injection/Loader/Configurator/Traits/PropertyTrait.php @@ -0,0 +1,27 @@ +<?php + +/* + * This file is part of the Symfony package. + * + * (c) Fabien Potencier <fabien@symfony.com> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection\Loader\Configurator\Traits; + +trait PropertyTrait +{ + /** + * Sets a specific property. + * + * @return $this + */ + final public function property(string $name, $value): self + { + $this->definition->setProperty($name, static::processValue($value, true)); + + return $this; + } +} diff --git a/srcs/phpmyadmin/vendor/symfony/dependency-injection/Loader/Configurator/Traits/PublicTrait.php b/srcs/phpmyadmin/vendor/symfony/dependency-injection/Loader/Configurator/Traits/PublicTrait.php new file mode 100644 index 0000000..f15756c --- /dev/null +++ b/srcs/phpmyadmin/vendor/symfony/dependency-injection/Loader/Configurator/Traits/PublicTrait.php @@ -0,0 +1,35 @@ +<?php + +/* + * This file is part of the Symfony package. + * + * (c) Fabien Potencier <fabien@symfony.com> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection\Loader\Configurator\Traits; + +trait PublicTrait +{ + /** + * @return $this + */ + final public function public(): self + { + $this->definition->setPublic(true); + + return $this; + } + + /** + * @return $this + */ + final public function private(): self + { + $this->definition->setPublic(false); + + return $this; + } +} diff --git a/srcs/phpmyadmin/vendor/symfony/dependency-injection/Loader/Configurator/Traits/ShareTrait.php b/srcs/phpmyadmin/vendor/symfony/dependency-injection/Loader/Configurator/Traits/ShareTrait.php new file mode 100644 index 0000000..16fde0f --- /dev/null +++ b/srcs/phpmyadmin/vendor/symfony/dependency-injection/Loader/Configurator/Traits/ShareTrait.php @@ -0,0 +1,27 @@ +<?php + +/* + * This file is part of the Symfony package. + * + * (c) Fabien Potencier <fabien@symfony.com> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection\Loader\Configurator\Traits; + +trait ShareTrait +{ + /** + * Sets if the service must be shared or not. + * + * @return $this + */ + final public function share(bool $shared = true): self + { + $this->definition->setShared($shared); + + return $this; + } +} diff --git a/srcs/phpmyadmin/vendor/symfony/dependency-injection/Loader/Configurator/Traits/SyntheticTrait.php b/srcs/phpmyadmin/vendor/symfony/dependency-injection/Loader/Configurator/Traits/SyntheticTrait.php new file mode 100644 index 0000000..cb08b11 --- /dev/null +++ b/srcs/phpmyadmin/vendor/symfony/dependency-injection/Loader/Configurator/Traits/SyntheticTrait.php @@ -0,0 +1,28 @@ +<?php + +/* + * This file is part of the Symfony package. + * + * (c) Fabien Potencier <fabien@symfony.com> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection\Loader\Configurator\Traits; + +trait SyntheticTrait +{ + /** + * Sets whether this definition is synthetic, that is not constructed by the + * container, but dynamically injected. + * + * @return $this + */ + final public function synthetic(bool $synthetic = true): self + { + $this->definition->setSynthetic($synthetic); + + return $this; + } +} diff --git a/srcs/phpmyadmin/vendor/symfony/dependency-injection/Loader/Configurator/Traits/TagTrait.php b/srcs/phpmyadmin/vendor/symfony/dependency-injection/Loader/Configurator/Traits/TagTrait.php new file mode 100644 index 0000000..f4d5f00 --- /dev/null +++ b/srcs/phpmyadmin/vendor/symfony/dependency-injection/Loader/Configurator/Traits/TagTrait.php @@ -0,0 +1,39 @@ +<?php + +/* + * This file is part of the Symfony package. + * + * (c) Fabien Potencier <fabien@symfony.com> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection\Loader\Configurator\Traits; + +use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException; + +trait TagTrait +{ + /** + * Adds a tag for this definition. + * + * @return $this + */ + final public function tag(string $name, array $attributes = []): self + { + if ('' === $name) { + throw new InvalidArgumentException(sprintf('The tag name for service "%s" must be a non-empty string.', $this->id)); + } + + foreach ($attributes as $attribute => $value) { + if (!is_scalar($value) && null !== $value) { + throw new InvalidArgumentException(sprintf('A tag attribute must be of a scalar-type for service "%s", tag "%s", attribute "%s".', $this->id, $name, $attribute)); + } + } + + $this->definition->addTag($name, $attributes); + + return $this; + } +} diff --git a/srcs/phpmyadmin/vendor/symfony/dependency-injection/Loader/DirectoryLoader.php b/srcs/phpmyadmin/vendor/symfony/dependency-injection/Loader/DirectoryLoader.php new file mode 100644 index 0000000..a57cac3 --- /dev/null +++ b/srcs/phpmyadmin/vendor/symfony/dependency-injection/Loader/DirectoryLoader.php @@ -0,0 +1,54 @@ +<?php + +/* + * This file is part of the Symfony package. + * + * (c) Fabien Potencier <fabien@symfony.com> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection\Loader; + +/** + * DirectoryLoader is a recursive loader to go through directories. + * + * @author Sebastien Lavoie <seb@wemakecustom.com> + */ +class DirectoryLoader extends FileLoader +{ + /** + * {@inheritdoc} + */ + public function load($file, $type = null) + { + $file = rtrim($file, '/'); + $path = $this->locator->locate($file); + $this->container->fileExists($path, false); + + foreach (scandir($path) as $dir) { + if ('.' !== $dir[0]) { + if (is_dir($path.'/'.$dir)) { + $dir .= '/'; // append / to allow recursion + } + + $this->setCurrentDir($path); + + $this->import($dir, null, false, $path); + } + } + } + + /** + * {@inheritdoc} + */ + public function supports($resource, $type = null) + { + if ('directory' === $type) { + return true; + } + + return null === $type && \is_string($resource) && '/' === substr($resource, -1); + } +} diff --git a/srcs/phpmyadmin/vendor/symfony/dependency-injection/Loader/FileLoader.php b/srcs/phpmyadmin/vendor/symfony/dependency-injection/Loader/FileLoader.php new file mode 100644 index 0000000..d6f6fae --- /dev/null +++ b/srcs/phpmyadmin/vendor/symfony/dependency-injection/Loader/FileLoader.php @@ -0,0 +1,227 @@ +<?php + +/* + * This file is part of the Symfony package. + * + * (c) Fabien Potencier <fabien@symfony.com> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection\Loader; + +use Symfony\Component\Config\Exception\FileLocatorFileNotFoundException; +use Symfony\Component\Config\Exception\LoaderLoadException; +use Symfony\Component\Config\FileLocatorInterface; +use Symfony\Component\Config\Loader\FileLoader as BaseFileLoader; +use Symfony\Component\Config\Loader\Loader; +use Symfony\Component\Config\Resource\GlobResource; +use Symfony\Component\DependencyInjection\ChildDefinition; +use Symfony\Component\DependencyInjection\ContainerBuilder; +use Symfony\Component\DependencyInjection\Definition; +use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException; + +/** + * FileLoader is the abstract class used by all built-in loaders that are file based. + * + * @author Fabien Potencier <fabien@symfony.com> + */ +abstract class FileLoader extends BaseFileLoader +{ + public const ANONYMOUS_ID_REGEXP = '/^\.\d+_[^~]*+~[._a-zA-Z\d]{7}$/'; + + protected $container; + protected $isLoadingInstanceof = false; + protected $instanceof = []; + protected $interfaces = []; + protected $singlyImplemented = []; + protected $autoRegisterAliasesForSinglyImplementedInterfaces = true; + + public function __construct(ContainerBuilder $container, FileLocatorInterface $locator) + { + $this->container = $container; + + parent::__construct($locator); + } + + /** + * {@inheritdoc} + * + * @param bool|string $ignoreErrors Whether errors should be ignored; pass "not_found" to ignore only when the loaded resource is not found + * @param string|string[]|null $exclude Glob patterns to exclude from the import + */ + public function import($resource, $type = null, $ignoreErrors = false, $sourceResource = null/*, $exclude = null*/) + { + $args = \func_get_args(); + + if ($ignoreNotFound = 'not_found' === $ignoreErrors) { + $args[2] = false; + } elseif (!\is_bool($ignoreErrors)) { + @trigger_error(sprintf('Invalid argument $ignoreErrors provided to %s::import(): boolean or "not_found" expected, %s given.', \get_class($this), \gettype($ignoreErrors)), E_USER_DEPRECATED); + $args[2] = (bool) $ignoreErrors; + } + + try { + parent::import(...$args); + } catch (LoaderLoadException $e) { + if (!$ignoreNotFound || !($prev = $e->getPrevious()) instanceof FileLocatorFileNotFoundException) { + throw $e; + } + + foreach ($prev->getTrace() as $frame) { + if ('import' === ($frame['function'] ?? null) && is_a($frame['class'] ?? '', Loader::class, true)) { + break; + } + } + + if (__FILE__ !== $frame['file']) { + throw $e; + } + } + } + + /** + * Registers a set of classes as services using PSR-4 for discovery. + * + * @param Definition $prototype A definition to use as template + * @param string $namespace The namespace prefix of classes in the scanned directory + * @param string $resource The directory to look for classes, glob-patterns allowed + * @param string|string[]|null $exclude A globbed path of files to exclude or an array of globbed paths of files to exclude + */ + public function registerClasses(Definition $prototype, $namespace, $resource, $exclude = null) + { + if ('\\' !== substr($namespace, -1)) { + throw new InvalidArgumentException(sprintf('Namespace prefix must end with a "\\": %s.', $namespace)); + } + if (!preg_match('/^(?:[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*+\\\\)++$/', $namespace)) { + throw new InvalidArgumentException(sprintf('Namespace is not a valid PSR-4 prefix: %s.', $namespace)); + } + + $classes = $this->findClasses($namespace, $resource, (array) $exclude); + // prepare for deep cloning + $serializedPrototype = serialize($prototype); + + foreach ($classes as $class => $errorMessage) { + if (interface_exists($class, false)) { + $this->interfaces[] = $class; + } else { + $this->setDefinition($class, $definition = unserialize($serializedPrototype)); + if (null !== $errorMessage) { + $definition->addError($errorMessage); + + continue; + } + foreach (class_implements($class, false) as $interface) { + $this->singlyImplemented[$interface] = ($this->singlyImplemented[$interface] ?? $class) !== $class ? false : $class; + } + } + } + + if ($this->autoRegisterAliasesForSinglyImplementedInterfaces) { + $this->registerAliasesForSinglyImplementedInterfaces(); + } + } + + public function registerAliasesForSinglyImplementedInterfaces() + { + foreach ($this->interfaces as $interface) { + if (!empty($this->singlyImplemented[$interface]) && !$this->container->has($interface)) { + $this->container->setAlias($interface, $this->singlyImplemented[$interface])->setPublic(false); + } + } + + $this->interfaces = $this->singlyImplemented = []; + } + + /** + * Registers a definition in the container with its instanceof-conditionals. + * + * @param string $id + */ + protected function setDefinition($id, Definition $definition) + { + $this->container->removeBindings($id); + + if ($this->isLoadingInstanceof) { + if (!$definition instanceof ChildDefinition) { + throw new InvalidArgumentException(sprintf('Invalid type definition "%s": ChildDefinition expected, "%s" given.', $id, \get_class($definition))); + } + $this->instanceof[$id] = $definition; + } else { + $this->container->setDefinition($id, $definition instanceof ChildDefinition ? $definition : $definition->setInstanceofConditionals($this->instanceof)); + } + } + + private function findClasses(string $namespace, string $pattern, array $excludePatterns): array + { + $parameterBag = $this->container->getParameterBag(); + + $excludePaths = []; + $excludePrefix = null; + $excludePatterns = $parameterBag->unescapeValue($parameterBag->resolveValue($excludePatterns)); + foreach ($excludePatterns as $excludePattern) { + foreach ($this->glob($excludePattern, true, $resource, false, true) as $path => $info) { + if (null === $excludePrefix) { + $excludePrefix = $resource->getPrefix(); + } + + // normalize Windows slashes + $excludePaths[str_replace('\\', '/', $path)] = true; + } + } + + $pattern = $parameterBag->unescapeValue($parameterBag->resolveValue($pattern)); + $classes = []; + $extRegexp = '/\\.php$/'; + $prefixLen = null; + foreach ($this->glob($pattern, true, $resource, false, false, $excludePaths) as $path => $info) { + if (null === $prefixLen) { + $prefixLen = \strlen($resource->getPrefix()); + + if ($excludePrefix && 0 !== strpos($excludePrefix, $resource->getPrefix())) { + throw new InvalidArgumentException(sprintf('Invalid "exclude" pattern when importing classes for "%s": make sure your "exclude" pattern (%s) is a subset of the "resource" pattern (%s)', $namespace, $excludePattern, $pattern)); + } + } + + if (isset($excludePaths[str_replace('\\', '/', $path)])) { + continue; + } + + if (!preg_match($extRegexp, $path, $m) || !$info->isReadable()) { + continue; + } + $class = $namespace.ltrim(str_replace('/', '\\', substr($path, $prefixLen, -\strlen($m[0]))), '\\'); + + if (!preg_match('/^[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*+(?:\\\\[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*+)*+$/', $class)) { + continue; + } + + try { + $r = $this->container->getReflectionClass($class); + } catch (\ReflectionException $e) { + $classes[$class] = $e->getMessage(); + continue; + } + // check to make sure the expected class exists + if (!$r) { + throw new InvalidArgumentException(sprintf('Expected to find class "%s" in file "%s" while importing services from resource "%s", but it was not found! Check the namespace prefix used with the resource.', $class, $path, $pattern)); + } + + if ($r->isInstantiable() || $r->isInterface()) { + $classes[$class] = null; + } + } + + // track only for new & removed files + if ($resource instanceof GlobResource) { + $this->container->addResource($resource); + } else { + foreach ($resource as $path) { + $this->container->fileExists($path, false); + } + } + + return $classes; + } +} diff --git a/srcs/phpmyadmin/vendor/symfony/dependency-injection/Loader/GlobFileLoader.php b/srcs/phpmyadmin/vendor/symfony/dependency-injection/Loader/GlobFileLoader.php new file mode 100644 index 0000000..4b25610 --- /dev/null +++ b/srcs/phpmyadmin/vendor/symfony/dependency-injection/Loader/GlobFileLoader.php @@ -0,0 +1,40 @@ +<?php + +/* + * This file is part of the Symfony package. + * + * (c) Fabien Potencier <fabien@symfony.com> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection\Loader; + +/** + * GlobFileLoader loads files from a glob pattern. + * + * @author Nicolas Grekas <p@tchwork.com> + */ +class GlobFileLoader extends FileLoader +{ + /** + * {@inheritdoc} + */ + public function load($resource, $type = null) + { + foreach ($this->glob($resource, false, $globResource) as $path => $info) { + $this->import($path); + } + + $this->container->addResource($globResource); + } + + /** + * {@inheritdoc} + */ + public function supports($resource, $type = null) + { + return 'glob' === $type; + } +} diff --git a/srcs/phpmyadmin/vendor/symfony/dependency-injection/Loader/IniFileLoader.php b/srcs/phpmyadmin/vendor/symfony/dependency-injection/Loader/IniFileLoader.php new file mode 100644 index 0000000..40137b1 --- /dev/null +++ b/srcs/phpmyadmin/vendor/symfony/dependency-injection/Loader/IniFileLoader.php @@ -0,0 +1,97 @@ +<?php + +/* + * This file is part of the Symfony package. + * + * (c) Fabien Potencier <fabien@symfony.com> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection\Loader; + +use Symfony\Component\Config\Util\XmlUtils; +use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException; + +/** + * IniFileLoader loads parameters from INI files. + * + * @author Fabien Potencier <fabien@symfony.com> + */ +class IniFileLoader extends FileLoader +{ + /** + * {@inheritdoc} + */ + public function load($resource, $type = null) + { + $path = $this->locator->locate($resource); + + $this->container->fileExists($path); + + // first pass to catch parsing errors + $result = parse_ini_file($path, true); + if (false === $result || [] === $result) { + throw new InvalidArgumentException(sprintf('The "%s" file is not valid.', $resource)); + } + + // real raw parsing + $result = parse_ini_file($path, true, INI_SCANNER_RAW); + + if (isset($result['parameters']) && \is_array($result['parameters'])) { + foreach ($result['parameters'] as $key => $value) { + $this->container->setParameter($key, $this->phpize($value)); + } + } + } + + /** + * {@inheritdoc} + */ + public function supports($resource, $type = null) + { + if (!\is_string($resource)) { + return false; + } + + if (null === $type && 'ini' === pathinfo($resource, PATHINFO_EXTENSION)) { + return true; + } + + return 'ini' === $type; + } + + /** + * Note that the following features are not supported: + * * strings with escaped quotes are not supported "foo\"bar"; + * * string concatenation ("foo" "bar"). + * + * @return mixed + */ + private function phpize(string $value) + { + // trim on the right as comments removal keep whitespaces + if ($value !== $v = rtrim($value)) { + $value = '""' === substr_replace($v, '', 1, -1) ? substr($v, 1, -1) : $v; + } + $lowercaseValue = strtolower($value); + + switch (true) { + case \defined($value): + return \constant($value); + case 'yes' === $lowercaseValue || 'on' === $lowercaseValue: + return true; + case 'no' === $lowercaseValue || 'off' === $lowercaseValue || 'none' === $lowercaseValue: + return false; + case isset($value[1]) && ( + ("'" === $value[0] && "'" === $value[\strlen($value) - 1]) || + ('"' === $value[0] && '"' === $value[\strlen($value) - 1]) + ): + // quoted string + return substr($value, 1, -1); + default: + return XmlUtils::phpize($value); + } + } +} diff --git a/srcs/phpmyadmin/vendor/symfony/dependency-injection/Loader/PhpFileLoader.php b/srcs/phpmyadmin/vendor/symfony/dependency-injection/Loader/PhpFileLoader.php new file mode 100644 index 0000000..f1477ec --- /dev/null +++ b/srcs/phpmyadmin/vendor/symfony/dependency-injection/Loader/PhpFileLoader.php @@ -0,0 +1,80 @@ +<?php + +/* + * This file is part of the Symfony package. + * + * (c) Fabien Potencier <fabien@symfony.com> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection\Loader; + +use Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigurator; + +/** + * PhpFileLoader loads service definitions from a PHP file. + * + * The PHP file is required and the $container variable can be + * used within the file to change the container. + * + * @author Fabien Potencier <fabien@symfony.com> + */ +class PhpFileLoader extends FileLoader +{ + protected $autoRegisterAliasesForSinglyImplementedInterfaces = false; + + /** + * {@inheritdoc} + */ + public function load($resource, $type = null) + { + // the container and loader variables are exposed to the included file below + $container = $this->container; + $loader = $this; + + $path = $this->locator->locate($resource); + $this->setCurrentDir(\dirname($path)); + $this->container->fileExists($path); + + // the closure forbids access to the private scope in the included file + $load = \Closure::bind(function ($path) use ($container, $loader, $resource, $type) { + return include $path; + }, $this, ProtectedPhpFileLoader::class); + + try { + $callback = $load($path); + + if (\is_object($callback) && \is_callable($callback)) { + $callback(new ContainerConfigurator($this->container, $this, $this->instanceof, $path, $resource), $this->container, $this); + } + } finally { + $this->instanceof = []; + $this->registerAliasesForSinglyImplementedInterfaces(); + } + } + + /** + * {@inheritdoc} + */ + public function supports($resource, $type = null) + { + if (!\is_string($resource)) { + return false; + } + + if (null === $type && 'php' === pathinfo($resource, PATHINFO_EXTENSION)) { + return true; + } + + return 'php' === $type; + } +} + +/** + * @internal + */ +final class ProtectedPhpFileLoader extends PhpFileLoader +{ +} diff --git a/srcs/phpmyadmin/vendor/symfony/dependency-injection/Loader/XmlFileLoader.php b/srcs/phpmyadmin/vendor/symfony/dependency-injection/Loader/XmlFileLoader.php new file mode 100644 index 0000000..41a9f0a --- /dev/null +++ b/srcs/phpmyadmin/vendor/symfony/dependency-injection/Loader/XmlFileLoader.php @@ -0,0 +1,728 @@ +<?php + +/* + * This file is part of the Symfony package. + * + * (c) Fabien Potencier <fabien@symfony.com> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection\Loader; + +use Symfony\Component\Config\Util\XmlUtils; +use Symfony\Component\DependencyInjection\Alias; +use Symfony\Component\DependencyInjection\Argument\BoundArgument; +use Symfony\Component\DependencyInjection\Argument\IteratorArgument; +use Symfony\Component\DependencyInjection\Argument\ServiceLocatorArgument; +use Symfony\Component\DependencyInjection\Argument\TaggedIteratorArgument; +use Symfony\Component\DependencyInjection\ChildDefinition; +use Symfony\Component\DependencyInjection\ContainerBuilder; +use Symfony\Component\DependencyInjection\ContainerInterface; +use Symfony\Component\DependencyInjection\Definition; +use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException; +use Symfony\Component\DependencyInjection\Exception\RuntimeException; +use Symfony\Component\DependencyInjection\Extension\ExtensionInterface; +use Symfony\Component\DependencyInjection\Reference; +use Symfony\Component\ExpressionLanguage\Expression; + +/** + * XmlFileLoader loads XML files service definitions. + * + * @author Fabien Potencier <fabien@symfony.com> + */ +class XmlFileLoader extends FileLoader +{ + const NS = 'http://symfony.com/schema/dic/services'; + + protected $autoRegisterAliasesForSinglyImplementedInterfaces = false; + + /** + * {@inheritdoc} + */ + public function load($resource, $type = null) + { + $path = $this->locator->locate($resource); + + $xml = $this->parseFileToDOM($path); + + $this->container->fileExists($path); + + $defaults = $this->getServiceDefaults($xml, $path); + + // anonymous services + $this->processAnonymousServices($xml, $path); + + // imports + $this->parseImports($xml, $path); + + // parameters + $this->parseParameters($xml, $path); + + // extensions + $this->loadFromExtensions($xml); + + // services + try { + $this->parseDefinitions($xml, $path, $defaults); + } finally { + $this->instanceof = []; + $this->registerAliasesForSinglyImplementedInterfaces(); + } + } + + /** + * {@inheritdoc} + */ + public function supports($resource, $type = null) + { + if (!\is_string($resource)) { + return false; + } + + if (null === $type && 'xml' === pathinfo($resource, PATHINFO_EXTENSION)) { + return true; + } + + return 'xml' === $type; + } + + private function parseParameters(\DOMDocument $xml, string $file) + { + if ($parameters = $this->getChildren($xml->documentElement, 'parameters')) { + $this->container->getParameterBag()->add($this->getArgumentsAsPhp($parameters[0], 'parameter', $file)); + } + } + + private function parseImports(\DOMDocument $xml, string $file) + { + $xpath = new \DOMXPath($xml); + $xpath->registerNamespace('container', self::NS); + + if (false === $imports = $xpath->query('//container:imports/container:import')) { + return; + } + + $defaultDirectory = \dirname($file); + foreach ($imports as $import) { + $this->setCurrentDir($defaultDirectory); + $this->import($import->getAttribute('resource'), XmlUtils::phpize($import->getAttribute('type')) ?: null, XmlUtils::phpize($import->getAttribute('ignore-errors')) ?: false, $file); + } + } + + private function parseDefinitions(\DOMDocument $xml, string $file, array $defaults) + { + $xpath = new \DOMXPath($xml); + $xpath->registerNamespace('container', self::NS); + + if (false === $services = $xpath->query('//container:services/container:service|//container:services/container:prototype')) { + return; + } + $this->setCurrentDir(\dirname($file)); + + $this->instanceof = []; + $this->isLoadingInstanceof = true; + $instanceof = $xpath->query('//container:services/container:instanceof'); + foreach ($instanceof as $service) { + $this->setDefinition((string) $service->getAttribute('id'), $this->parseDefinition($service, $file, [])); + } + + $this->isLoadingInstanceof = false; + foreach ($services as $service) { + if (null !== $definition = $this->parseDefinition($service, $file, $defaults)) { + if ('prototype' === $service->tagName) { + $excludes = array_column($this->getChildren($service, 'exclude'), 'nodeValue'); + if ($service->hasAttribute('exclude')) { + if (\count($excludes) > 0) { + throw new InvalidArgumentException('You cannot use both the attribute "exclude" and <exclude> tags at the same time.'); + } + $excludes = [$service->getAttribute('exclude')]; + } + $this->registerClasses($definition, (string) $service->getAttribute('namespace'), (string) $service->getAttribute('resource'), $excludes); + } else { + $this->setDefinition((string) $service->getAttribute('id'), $definition); + } + } + } + } + + /** + * Get service defaults. + */ + private function getServiceDefaults(\DOMDocument $xml, string $file): array + { + $xpath = new \DOMXPath($xml); + $xpath->registerNamespace('container', self::NS); + + if (null === $defaultsNode = $xpath->query('//container:services/container:defaults')->item(0)) { + return []; + } + + $bindings = []; + foreach ($this->getArgumentsAsPhp($defaultsNode, 'bind', $file) as $argument => $value) { + $bindings[$argument] = new BoundArgument($value, true, BoundArgument::DEFAULTS_BINDING, $file); + } + + $defaults = [ + 'tags' => $this->getChildren($defaultsNode, 'tag'), + 'bind' => $bindings, + ]; + + foreach ($defaults['tags'] as $tag) { + if ('' === $tag->getAttribute('name')) { + throw new InvalidArgumentException(sprintf('The tag name for tag "<defaults>" in %s must be a non-empty string.', $file)); + } + } + + if ($defaultsNode->hasAttribute('autowire')) { + $defaults['autowire'] = XmlUtils::phpize($defaultsNode->getAttribute('autowire')); + } + if ($defaultsNode->hasAttribute('public')) { + $defaults['public'] = XmlUtils::phpize($defaultsNode->getAttribute('public')); + } + if ($defaultsNode->hasAttribute('autoconfigure')) { + $defaults['autoconfigure'] = XmlUtils::phpize($defaultsNode->getAttribute('autoconfigure')); + } + + return $defaults; + } + + /** + * Parses an individual Definition. + */ + private function parseDefinition(\DOMElement $service, string $file, array $defaults): ?Definition + { + if ($alias = $service->getAttribute('alias')) { + $this->validateAlias($service, $file); + + $this->container->setAlias((string) $service->getAttribute('id'), $alias = new Alias($alias)); + if ($publicAttr = $service->getAttribute('public')) { + $alias->setPublic(XmlUtils::phpize($publicAttr)); + } elseif (isset($defaults['public'])) { + $alias->setPublic($defaults['public']); + } + + if ($deprecated = $this->getChildren($service, 'deprecated')) { + $alias->setDeprecated(true, $deprecated[0]->nodeValue ?: null); + } + + return null; + } + + if ($this->isLoadingInstanceof) { + $definition = new ChildDefinition(''); + } elseif ($parent = $service->getAttribute('parent')) { + if (!empty($this->instanceof)) { + throw new InvalidArgumentException(sprintf('The service "%s" cannot use the "parent" option in the same file where "instanceof" configuration is defined as using both is not supported. Move your child definitions to a separate file.', $service->getAttribute('id'))); + } + + foreach ($defaults as $k => $v) { + if ('tags' === $k) { + // since tags are never inherited from parents, there is no confusion + // thus we can safely add them as defaults to ChildDefinition + continue; + } + if ('bind' === $k) { + if ($defaults['bind']) { + throw new InvalidArgumentException(sprintf('Bound values on service "%s" cannot be inherited from "defaults" when a "parent" is set. Move your child definitions to a separate file.', $service->getAttribute('id'))); + } + + continue; + } + if (!$service->hasAttribute($k)) { + throw new InvalidArgumentException(sprintf('Attribute "%s" on service "%s" cannot be inherited from "defaults" when a "parent" is set. Move your child definitions to a separate file or define this attribute explicitly.', $k, $service->getAttribute('id'))); + } + } + + $definition = new ChildDefinition($parent); + } else { + $definition = new Definition(); + + if (isset($defaults['public'])) { + $definition->setPublic($defaults['public']); + } + if (isset($defaults['autowire'])) { + $definition->setAutowired($defaults['autowire']); + } + if (isset($defaults['autoconfigure'])) { + $definition->setAutoconfigured($defaults['autoconfigure']); + } + + $definition->setChanges([]); + } + + foreach (['class', 'public', 'shared', 'synthetic', 'abstract'] as $key) { + if ($value = $service->getAttribute($key)) { + $method = 'set'.$key; + $definition->$method($value = XmlUtils::phpize($value)); + } + } + + if ($value = $service->getAttribute('lazy')) { + $definition->setLazy((bool) $value = XmlUtils::phpize($value)); + if (\is_string($value)) { + $definition->addTag('proxy', ['interface' => $value]); + } + } + + if ($value = $service->getAttribute('autowire')) { + $definition->setAutowired(XmlUtils::phpize($value)); + } + + if ($value = $service->getAttribute('autoconfigure')) { + if (!$definition instanceof ChildDefinition) { + $definition->setAutoconfigured(XmlUtils::phpize($value)); + } elseif ($value = XmlUtils::phpize($value)) { + throw new InvalidArgumentException(sprintf('The service "%s" cannot have a "parent" and also have "autoconfigure". Try setting autoconfigure="false" for the service.', $service->getAttribute('id'))); + } + } + + if ($files = $this->getChildren($service, 'file')) { + $definition->setFile($files[0]->nodeValue); + } + + if ($deprecated = $this->getChildren($service, 'deprecated')) { + $definition->setDeprecated(true, $deprecated[0]->nodeValue ?: null); + } + + $definition->setArguments($this->getArgumentsAsPhp($service, 'argument', $file, $definition instanceof ChildDefinition)); + $definition->setProperties($this->getArgumentsAsPhp($service, 'property', $file)); + + if ($factories = $this->getChildren($service, 'factory')) { + $factory = $factories[0]; + if ($function = $factory->getAttribute('function')) { + $definition->setFactory($function); + } else { + if ($childService = $factory->getAttribute('service')) { + $class = new Reference($childService, ContainerInterface::EXCEPTION_ON_INVALID_REFERENCE); + } else { + $class = $factory->hasAttribute('class') ? $factory->getAttribute('class') : null; + } + + $definition->setFactory([$class, $factory->getAttribute('method') ?: '__invoke']); + } + } + + if ($configurators = $this->getChildren($service, 'configurator')) { + $configurator = $configurators[0]; + if ($function = $configurator->getAttribute('function')) { + $definition->setConfigurator($function); + } else { + if ($childService = $configurator->getAttribute('service')) { + $class = new Reference($childService, ContainerInterface::EXCEPTION_ON_INVALID_REFERENCE); + } else { + $class = $configurator->getAttribute('class'); + } + + $definition->setConfigurator([$class, $configurator->getAttribute('method') ?: '__invoke']); + } + } + + foreach ($this->getChildren($service, 'call') as $call) { + $definition->addMethodCall($call->getAttribute('method'), $this->getArgumentsAsPhp($call, 'argument', $file), XmlUtils::phpize($call->getAttribute('returns-clone'))); + } + + $tags = $this->getChildren($service, 'tag'); + + if (!empty($defaults['tags'])) { + $tags = array_merge($tags, $defaults['tags']); + } + + foreach ($tags as $tag) { + $parameters = []; + foreach ($tag->attributes as $name => $node) { + if ('name' === $name) { + continue; + } + + if (false !== strpos($name, '-') && false === strpos($name, '_') && !\array_key_exists($normalizedName = str_replace('-', '_', $name), $parameters)) { + $parameters[$normalizedName] = XmlUtils::phpize($node->nodeValue); + } + // keep not normalized key + $parameters[$name] = XmlUtils::phpize($node->nodeValue); + } + + if ('' === $tag->getAttribute('name')) { + throw new InvalidArgumentException(sprintf('The tag name for service "%s" in %s must be a non-empty string.', (string) $service->getAttribute('id'), $file)); + } + + $definition->addTag($tag->getAttribute('name'), $parameters); + } + + $bindings = $this->getArgumentsAsPhp($service, 'bind', $file); + $bindingType = $this->isLoadingInstanceof ? BoundArgument::INSTANCEOF_BINDING : BoundArgument::SERVICE_BINDING; + foreach ($bindings as $argument => $value) { + $bindings[$argument] = new BoundArgument($value, true, $bindingType, $file); + } + + if (isset($defaults['bind'])) { + // deep clone, to avoid multiple process of the same instance in the passes + $bindings = array_merge(unserialize(serialize($defaults['bind'])), $bindings); + } + if ($bindings) { + $definition->setBindings($bindings); + } + + if ($decorates = $service->getAttribute('decorates')) { + $decorationOnInvalid = $service->getAttribute('decoration-on-invalid') ?: 'exception'; + if ('exception' === $decorationOnInvalid) { + $invalidBehavior = ContainerInterface::EXCEPTION_ON_INVALID_REFERENCE; + } elseif ('ignore' === $decorationOnInvalid) { + $invalidBehavior = ContainerInterface::IGNORE_ON_INVALID_REFERENCE; + } elseif ('null' === $decorationOnInvalid) { + $invalidBehavior = ContainerInterface::NULL_ON_INVALID_REFERENCE; + } else { + throw new InvalidArgumentException(sprintf('Invalid value "%s" for attribute "decoration-on-invalid" on service "%s". Did you mean "exception", "ignore" or "null" in "%s"?', $decorationOnInvalid, (string) $service->getAttribute('id'), $file)); + } + + $renameId = $service->hasAttribute('decoration-inner-name') ? $service->getAttribute('decoration-inner-name') : null; + $priority = $service->hasAttribute('decoration-priority') ? $service->getAttribute('decoration-priority') : 0; + + $definition->setDecoratedService($decorates, $renameId, $priority, $invalidBehavior); + } + + return $definition; + } + + /** + * Parses a XML file to a \DOMDocument. + * + * @throws InvalidArgumentException When loading of XML file returns error + */ + private function parseFileToDOM(string $file): \DOMDocument + { + try { + $dom = XmlUtils::loadFile($file, [$this, 'validateSchema']); + } catch (\InvalidArgumentException $e) { + throw new InvalidArgumentException(sprintf('Unable to parse file "%s": %s', $file, $e->getMessage()), $e->getCode(), $e); + } + + $this->validateExtensions($dom, $file); + + return $dom; + } + + /** + * Processes anonymous services. + */ + private function processAnonymousServices(\DOMDocument $xml, string $file) + { + $definitions = []; + $count = 0; + $suffix = '~'.ContainerBuilder::hash($file); + + $xpath = new \DOMXPath($xml); + $xpath->registerNamespace('container', self::NS); + + // anonymous services as arguments/properties + if (false !== $nodes = $xpath->query('//container:argument[@type="service"][not(@id)]|//container:property[@type="service"][not(@id)]|//container:bind[not(@id)]|//container:factory[not(@service)]|//container:configurator[not(@service)]')) { + foreach ($nodes as $node) { + if ($services = $this->getChildren($node, 'service')) { + // give it a unique name + $id = sprintf('.%d_%s', ++$count, preg_replace('/^.*\\\\/', '', $services[0]->getAttribute('class')).$suffix); + $node->setAttribute('id', $id); + $node->setAttribute('service', $id); + + $definitions[$id] = [$services[0], $file]; + $services[0]->setAttribute('id', $id); + + // anonymous services are always private + // we could not use the constant false here, because of XML parsing + $services[0]->setAttribute('public', 'false'); + } + } + } + + // anonymous services "in the wild" + if (false !== $nodes = $xpath->query('//container:services/container:service[not(@id)]')) { + foreach ($nodes as $node) { + throw new InvalidArgumentException(sprintf('Top-level services must have "id" attribute, none found in %s at line %d.', $file, $node->getLineNo())); + } + } + + // resolve definitions + uksort($definitions, 'strnatcmp'); + foreach (array_reverse($definitions) as $id => list($domElement, $file)) { + if (null !== $definition = $this->parseDefinition($domElement, $file, [])) { + $this->setDefinition($id, $definition); + } + } + } + + private function getArgumentsAsPhp(\DOMElement $node, string $name, string $file, bool $isChildDefinition = false): array + { + $arguments = []; + foreach ($this->getChildren($node, $name) as $arg) { + if ($arg->hasAttribute('name')) { + $arg->setAttribute('key', $arg->getAttribute('name')); + } + + // this is used by ChildDefinition to overwrite a specific + // argument of the parent definition + if ($arg->hasAttribute('index')) { + $key = ($isChildDefinition ? 'index_' : '').$arg->getAttribute('index'); + } elseif (!$arg->hasAttribute('key')) { + // Append an empty argument, then fetch its key to overwrite it later + $arguments[] = null; + $keys = array_keys($arguments); + $key = array_pop($keys); + } else { + $key = $arg->getAttribute('key'); + } + + $onInvalid = $arg->getAttribute('on-invalid'); + $invalidBehavior = ContainerInterface::EXCEPTION_ON_INVALID_REFERENCE; + if ('ignore' == $onInvalid) { + $invalidBehavior = ContainerInterface::IGNORE_ON_INVALID_REFERENCE; + } elseif ('ignore_uninitialized' == $onInvalid) { + $invalidBehavior = ContainerInterface::IGNORE_ON_UNINITIALIZED_REFERENCE; + } elseif ('null' == $onInvalid) { + $invalidBehavior = ContainerInterface::NULL_ON_INVALID_REFERENCE; + } + + switch ($arg->getAttribute('type')) { + case 'service': + if ('' === $arg->getAttribute('id')) { + throw new InvalidArgumentException(sprintf('Tag "<%s>" with type="service" has no or empty "id" attribute in "%s".', $name, $file)); + } + + $arguments[$key] = new Reference($arg->getAttribute('id'), $invalidBehavior); + break; + case 'expression': + if (!class_exists(Expression::class)) { + throw new \LogicException(sprintf('The type="expression" attribute cannot be used without the ExpressionLanguage component. Try running "composer require symfony/expression-language".')); + } + + $arguments[$key] = new Expression($arg->nodeValue); + break; + case 'collection': + $arguments[$key] = $this->getArgumentsAsPhp($arg, $name, $file); + break; + case 'iterator': + $arg = $this->getArgumentsAsPhp($arg, $name, $file); + try { + $arguments[$key] = new IteratorArgument($arg); + } catch (InvalidArgumentException $e) { + throw new InvalidArgumentException(sprintf('Tag "<%s>" with type="iterator" only accepts collections of type="service" references in "%s".', $name, $file)); + } + break; + case 'service_locator': + $arg = $this->getArgumentsAsPhp($arg, $name, $file); + try { + $arguments[$key] = new ServiceLocatorArgument($arg); + } catch (InvalidArgumentException $e) { + throw new InvalidArgumentException(sprintf('Tag "<%s>" with type="service_locator" only accepts maps of type="service" references in "%s".', $name, $file)); + } + break; + case 'tagged': + case 'tagged_iterator': + case 'tagged_locator': + $type = $arg->getAttribute('type'); + $forLocator = 'tagged_locator' === $type; + + if (!$arg->getAttribute('tag')) { + throw new InvalidArgumentException(sprintf('Tag "<%s>" with type="%s" has no or empty "tag" attribute in "%s".', $name, $type, $file)); + } + + $arguments[$key] = new TaggedIteratorArgument($arg->getAttribute('tag'), $arg->getAttribute('index-by') ?: null, $arg->getAttribute('default-index-method') ?: null, $forLocator, $arg->getAttribute('default-priority-method') ?: null); + + if ($forLocator) { + $arguments[$key] = new ServiceLocatorArgument($arguments[$key]); + } + break; + case 'binary': + if (false === $value = base64_decode($arg->nodeValue)) { + throw new InvalidArgumentException(sprintf('Tag "<%s>" with type="binary" is not a valid base64 encoded string.', $name)); + } + $arguments[$key] = $value; + break; + case 'string': + $arguments[$key] = $arg->nodeValue; + break; + case 'constant': + $arguments[$key] = \constant(trim($arg->nodeValue)); + break; + default: + $arguments[$key] = XmlUtils::phpize($arg->nodeValue); + } + } + + return $arguments; + } + + /** + * Get child elements by name. + * + * @return \DOMElement[] + */ + private function getChildren(\DOMNode $node, string $name): array + { + $children = []; + foreach ($node->childNodes as $child) { + if ($child instanceof \DOMElement && $child->localName === $name && self::NS === $child->namespaceURI) { + $children[] = $child; + } + } + + return $children; + } + + /** + * Validates a documents XML schema. + * + * @return bool + * + * @throws RuntimeException When extension references a non-existent XSD file + */ + public function validateSchema(\DOMDocument $dom) + { + $schemaLocations = ['http://symfony.com/schema/dic/services' => str_replace('\\', '/', __DIR__.'/schema/dic/services/services-1.0.xsd')]; + + if ($element = $dom->documentElement->getAttributeNS('http://www.w3.org/2001/XMLSchema-instance', 'schemaLocation')) { + $items = preg_split('/\s+/', $element); + for ($i = 0, $nb = \count($items); $i < $nb; $i += 2) { + if (!$this->container->hasExtension($items[$i])) { + continue; + } + + if (($extension = $this->container->getExtension($items[$i])) && false !== $extension->getXsdValidationBasePath()) { + $ns = $extension->getNamespace(); + $path = str_replace([$ns, str_replace('http://', 'https://', $ns)], str_replace('\\', '/', $extension->getXsdValidationBasePath()).'/', $items[$i + 1]); + + if (!is_file($path)) { + throw new RuntimeException(sprintf('Extension "%s" references a non-existent XSD file "%s"', \get_class($extension), $path)); + } + + $schemaLocations[$items[$i]] = $path; + } + } + } + + $tmpfiles = []; + $imports = ''; + foreach ($schemaLocations as $namespace => $location) { + $parts = explode('/', $location); + $locationstart = 'file:///'; + if (0 === stripos($location, 'phar://')) { + $tmpfile = tempnam(sys_get_temp_dir(), 'symfony'); + if ($tmpfile) { + copy($location, $tmpfile); + $tmpfiles[] = $tmpfile; + $parts = explode('/', str_replace('\\', '/', $tmpfile)); + } else { + array_shift($parts); + $locationstart = 'phar:///'; + } + } + $drive = '\\' === \DIRECTORY_SEPARATOR ? array_shift($parts).'/' : ''; + $location = $locationstart.$drive.implode('/', array_map('rawurlencode', $parts)); + + $imports .= sprintf(' <xsd:import namespace="%s" schemaLocation="%s" />'."\n", $namespace, $location); + } + + $source = <<<EOF +<?xml version="1.0" encoding="utf-8" ?> +<xsd:schema xmlns="http://symfony.com/schema" + xmlns:xsd="http://www.w3.org/2001/XMLSchema" + targetNamespace="http://symfony.com/schema" + elementFormDefault="qualified"> + + <xsd:import namespace="http://www.w3.org/XML/1998/namespace"/> +$imports +</xsd:schema> +EOF + ; + + $disableEntities = libxml_disable_entity_loader(false); + $valid = @$dom->schemaValidateSource($source); + libxml_disable_entity_loader($disableEntities); + + foreach ($tmpfiles as $tmpfile) { + @unlink($tmpfile); + } + + return $valid; + } + + private function validateAlias(\DOMElement $alias, string $file) + { + foreach ($alias->attributes as $name => $node) { + if (!\in_array($name, ['alias', 'id', 'public'])) { + throw new InvalidArgumentException(sprintf('Invalid attribute "%s" defined for alias "%s" in "%s".', $name, $alias->getAttribute('id'), $file)); + } + } + + foreach ($alias->childNodes as $child) { + if (!$child instanceof \DOMElement || self::NS !== $child->namespaceURI) { + continue; + } + if (!\in_array($child->localName, ['deprecated'], true)) { + throw new InvalidArgumentException(sprintf('Invalid child element "%s" defined for alias "%s" in "%s".', $child->localName, $alias->getAttribute('id'), $file)); + } + } + } + + /** + * Validates an extension. + * + * @throws InvalidArgumentException When no extension is found corresponding to a tag + */ + private function validateExtensions(\DOMDocument $dom, string $file) + { + foreach ($dom->documentElement->childNodes as $node) { + if (!$node instanceof \DOMElement || 'http://symfony.com/schema/dic/services' === $node->namespaceURI) { + continue; + } + + // can it be handled by an extension? + if (!$this->container->hasExtension($node->namespaceURI)) { + $extensionNamespaces = array_filter(array_map(function (ExtensionInterface $ext) { return $ext->getNamespace(); }, $this->container->getExtensions())); + throw new InvalidArgumentException(sprintf('There is no extension able to load the configuration for "%s" (in %s). Looked for namespace "%s", found %s', $node->tagName, $file, $node->namespaceURI, $extensionNamespaces ? sprintf('"%s"', implode('", "', $extensionNamespaces)) : 'none')); + } + } + } + + /** + * Loads from an extension. + */ + private function loadFromExtensions(\DOMDocument $xml) + { + foreach ($xml->documentElement->childNodes as $node) { + if (!$node instanceof \DOMElement || self::NS === $node->namespaceURI) { + continue; + } + + $values = static::convertDomElementToArray($node); + if (!\is_array($values)) { + $values = []; + } + + $this->container->loadFromExtension($node->namespaceURI, $values); + } + } + + /** + * Converts a \DOMElement object to a PHP array. + * + * The following rules applies during the conversion: + * + * * Each tag is converted to a key value or an array + * if there is more than one "value" + * + * * The content of a tag is set under a "value" key (<foo>bar</foo>) + * if the tag also has some nested tags + * + * * The attributes are converted to keys (<foo foo="bar"/>) + * + * * The nested-tags are converted to keys (<foo><foo>bar</foo></foo>) + * + * @param \DOMElement $element A \DOMElement instance + * + * @return mixed + */ + public static function convertDomElementToArray(\DOMElement $element) + { + return XmlUtils::convertDomElementToArray($element); + } +} diff --git a/srcs/phpmyadmin/vendor/symfony/dependency-injection/Loader/YamlFileLoader.php b/srcs/phpmyadmin/vendor/symfony/dependency-injection/Loader/YamlFileLoader.php new file mode 100644 index 0000000..ee8c140 --- /dev/null +++ b/srcs/phpmyadmin/vendor/symfony/dependency-injection/Loader/YamlFileLoader.php @@ -0,0 +1,880 @@ +<?php + +/* + * This file is part of the Symfony package. + * + * (c) Fabien Potencier <fabien@symfony.com> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection\Loader; + +use Symfony\Component\DependencyInjection\Alias; +use Symfony\Component\DependencyInjection\Argument\ArgumentInterface; +use Symfony\Component\DependencyInjection\Argument\BoundArgument; +use Symfony\Component\DependencyInjection\Argument\IteratorArgument; +use Symfony\Component\DependencyInjection\Argument\ServiceLocatorArgument; +use Symfony\Component\DependencyInjection\Argument\TaggedIteratorArgument; +use Symfony\Component\DependencyInjection\ChildDefinition; +use Symfony\Component\DependencyInjection\ContainerBuilder; +use Symfony\Component\DependencyInjection\ContainerInterface; +use Symfony\Component\DependencyInjection\Definition; +use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException; +use Symfony\Component\DependencyInjection\Exception\RuntimeException; +use Symfony\Component\DependencyInjection\Extension\ExtensionInterface; +use Symfony\Component\DependencyInjection\Reference; +use Symfony\Component\ExpressionLanguage\Expression; +use Symfony\Component\Yaml\Exception\ParseException; +use Symfony\Component\Yaml\Parser as YamlParser; +use Symfony\Component\Yaml\Tag\TaggedValue; +use Symfony\Component\Yaml\Yaml; + +/** + * YamlFileLoader loads YAML files service definitions. + * + * @author Fabien Potencier <fabien@symfony.com> + */ +class YamlFileLoader extends FileLoader +{ + private static $serviceKeywords = [ + 'alias' => 'alias', + 'parent' => 'parent', + 'class' => 'class', + 'shared' => 'shared', + 'synthetic' => 'synthetic', + 'lazy' => 'lazy', + 'public' => 'public', + 'abstract' => 'abstract', + 'deprecated' => 'deprecated', + 'factory' => 'factory', + 'file' => 'file', + 'arguments' => 'arguments', + 'properties' => 'properties', + 'configurator' => 'configurator', + 'calls' => 'calls', + 'tags' => 'tags', + 'decorates' => 'decorates', + 'decoration_inner_name' => 'decoration_inner_name', + 'decoration_priority' => 'decoration_priority', + 'decoration_on_invalid' => 'decoration_on_invalid', + 'autowire' => 'autowire', + 'autoconfigure' => 'autoconfigure', + 'bind' => 'bind', + ]; + + private static $prototypeKeywords = [ + 'resource' => 'resource', + 'namespace' => 'namespace', + 'exclude' => 'exclude', + 'parent' => 'parent', + 'shared' => 'shared', + 'lazy' => 'lazy', + 'public' => 'public', + 'abstract' => 'abstract', + 'deprecated' => 'deprecated', + 'factory' => 'factory', + 'arguments' => 'arguments', + 'properties' => 'properties', + 'configurator' => 'configurator', + 'calls' => 'calls', + 'tags' => 'tags', + 'autowire' => 'autowire', + 'autoconfigure' => 'autoconfigure', + 'bind' => 'bind', + ]; + + private static $instanceofKeywords = [ + 'shared' => 'shared', + 'lazy' => 'lazy', + 'public' => 'public', + 'properties' => 'properties', + 'configurator' => 'configurator', + 'calls' => 'calls', + 'tags' => 'tags', + 'autowire' => 'autowire', + 'bind' => 'bind', + ]; + + private static $defaultsKeywords = [ + 'public' => 'public', + 'tags' => 'tags', + 'autowire' => 'autowire', + 'autoconfigure' => 'autoconfigure', + 'bind' => 'bind', + ]; + + private $yamlParser; + + private $anonymousServicesCount; + private $anonymousServicesSuffix; + + protected $autoRegisterAliasesForSinglyImplementedInterfaces = false; + + /** + * {@inheritdoc} + */ + public function load($resource, $type = null) + { + $path = $this->locator->locate($resource); + + $content = $this->loadFile($path); + + $this->container->fileExists($path); + + // empty file + if (null === $content) { + return; + } + + // imports + $this->parseImports($content, $path); + + // parameters + if (isset($content['parameters'])) { + if (!\is_array($content['parameters'])) { + throw new InvalidArgumentException(sprintf('The "parameters" key should contain an array in %s. Check your YAML syntax.', $path)); + } + + foreach ($content['parameters'] as $key => $value) { + $this->container->setParameter($key, $this->resolveServices($value, $path, true)); + } + } + + // extensions + $this->loadFromExtensions($content); + + // services + $this->anonymousServicesCount = 0; + $this->anonymousServicesSuffix = '~'.ContainerBuilder::hash($path); + $this->setCurrentDir(\dirname($path)); + try { + $this->parseDefinitions($content, $path); + } finally { + $this->instanceof = []; + $this->registerAliasesForSinglyImplementedInterfaces(); + } + } + + /** + * {@inheritdoc} + */ + public function supports($resource, $type = null) + { + if (!\is_string($resource)) { + return false; + } + + if (null === $type && \in_array(pathinfo($resource, PATHINFO_EXTENSION), ['yaml', 'yml'], true)) { + return true; + } + + return \in_array($type, ['yaml', 'yml'], true); + } + + private function parseImports(array $content, string $file) + { + if (!isset($content['imports'])) { + return; + } + + if (!\is_array($content['imports'])) { + throw new InvalidArgumentException(sprintf('The "imports" key should contain an array in %s. Check your YAML syntax.', $file)); + } + + $defaultDirectory = \dirname($file); + foreach ($content['imports'] as $import) { + if (!\is_array($import)) { + $import = ['resource' => $import]; + } + if (!isset($import['resource'])) { + throw new InvalidArgumentException(sprintf('An import should provide a resource in %s. Check your YAML syntax.', $file)); + } + + $this->setCurrentDir($defaultDirectory); + $this->import($import['resource'], $import['type'] ?? null, $import['ignore_errors'] ?? false, $file); + } + } + + private function parseDefinitions(array $content, string $file) + { + if (!isset($content['services'])) { + return; + } + + if (!\is_array($content['services'])) { + throw new InvalidArgumentException(sprintf('The "services" key should contain an array in %s. Check your YAML syntax.', $file)); + } + + if (\array_key_exists('_instanceof', $content['services'])) { + $instanceof = $content['services']['_instanceof']; + unset($content['services']['_instanceof']); + + if (!\is_array($instanceof)) { + throw new InvalidArgumentException(sprintf('Service "_instanceof" key must be an array, "%s" given in "%s".', \gettype($instanceof), $file)); + } + $this->instanceof = []; + $this->isLoadingInstanceof = true; + foreach ($instanceof as $id => $service) { + if (!$service || !\is_array($service)) { + throw new InvalidArgumentException(sprintf('Type definition "%s" must be a non-empty array within "_instanceof" in %s. Check your YAML syntax.', $id, $file)); + } + if (\is_string($service) && 0 === strpos($service, '@')) { + throw new InvalidArgumentException(sprintf('Type definition "%s" cannot be an alias within "_instanceof" in %s. Check your YAML syntax.', $id, $file)); + } + $this->parseDefinition($id, $service, $file, []); + } + } + + $this->isLoadingInstanceof = false; + $defaults = $this->parseDefaults($content, $file); + foreach ($content['services'] as $id => $service) { + $this->parseDefinition($id, $service, $file, $defaults); + } + } + + /** + * @throws InvalidArgumentException + */ + private function parseDefaults(array &$content, string $file): array + { + if (!\array_key_exists('_defaults', $content['services'])) { + return []; + } + $defaults = $content['services']['_defaults']; + unset($content['services']['_defaults']); + + if (!\is_array($defaults)) { + throw new InvalidArgumentException(sprintf('Service "_defaults" key must be an array, "%s" given in "%s".', \gettype($defaults), $file)); + } + + foreach ($defaults as $key => $default) { + if (!isset(self::$defaultsKeywords[$key])) { + throw new InvalidArgumentException(sprintf('The configuration key "%s" cannot be used to define a default value in "%s". Allowed keys are "%s".', $key, $file, implode('", "', self::$defaultsKeywords))); + } + } + + if (isset($defaults['tags'])) { + if (!\is_array($tags = $defaults['tags'])) { + throw new InvalidArgumentException(sprintf('Parameter "tags" in "_defaults" must be an array in %s. Check your YAML syntax.', $file)); + } + + foreach ($tags as $tag) { + if (!\is_array($tag)) { + $tag = ['name' => $tag]; + } + + if (!isset($tag['name'])) { + throw new InvalidArgumentException(sprintf('A "tags" entry in "_defaults" is missing a "name" key in %s.', $file)); + } + $name = $tag['name']; + unset($tag['name']); + + if (!\is_string($name) || '' === $name) { + throw new InvalidArgumentException(sprintf('The tag name in "_defaults" must be a non-empty string in %s.', $file)); + } + + foreach ($tag as $attribute => $value) { + if (!is_scalar($value) && null !== $value) { + throw new InvalidArgumentException(sprintf('Tag "%s", attribute "%s" in "_defaults" must be of a scalar-type in %s. Check your YAML syntax.', $name, $attribute, $file)); + } + } + } + } + + if (isset($defaults['bind'])) { + if (!\is_array($defaults['bind'])) { + throw new InvalidArgumentException(sprintf('Parameter "bind" in "_defaults" must be an array in %s. Check your YAML syntax.', $file)); + } + + foreach ($this->resolveServices($defaults['bind'], $file) as $argument => $value) { + $defaults['bind'][$argument] = new BoundArgument($value, true, BoundArgument::DEFAULTS_BINDING, $file); + } + } + + return $defaults; + } + + private function isUsingShortSyntax(array $service): bool + { + foreach ($service as $key => $value) { + if (\is_string($key) && ('' === $key || '$' !== $key[0])) { + return false; + } + } + + return true; + } + + /** + * Parses a definition. + * + * @param array|string $service + * + * @throws InvalidArgumentException When tags are invalid + */ + private function parseDefinition(string $id, $service, string $file, array $defaults) + { + if (preg_match('/^_[a-zA-Z0-9_]*$/', $id)) { + throw new InvalidArgumentException(sprintf('Service names that start with an underscore are reserved. Rename the "%s" service or define it in XML instead.', $id)); + } + + if (\is_string($service) && 0 === strpos($service, '@')) { + $this->container->setAlias($id, $alias = new Alias(substr($service, 1))); + if (isset($defaults['public'])) { + $alias->setPublic($defaults['public']); + } + + return; + } + + if (\is_array($service) && $this->isUsingShortSyntax($service)) { + $service = ['arguments' => $service]; + } + + if (null === $service) { + $service = []; + } + + if (!\is_array($service)) { + throw new InvalidArgumentException(sprintf('A service definition must be an array or a string starting with "@" but %s found for service "%s" in %s. Check your YAML syntax.', \gettype($service), $id, $file)); + } + + $this->checkDefinition($id, $service, $file); + + if (isset($service['alias'])) { + $this->container->setAlias($id, $alias = new Alias($service['alias'])); + if (\array_key_exists('public', $service)) { + $alias->setPublic($service['public']); + } elseif (isset($defaults['public'])) { + $alias->setPublic($defaults['public']); + } + + foreach ($service as $key => $value) { + if (!\in_array($key, ['alias', 'public', 'deprecated'])) { + throw new InvalidArgumentException(sprintf('The configuration key "%s" is unsupported for the service "%s" which is defined as an alias in "%s". Allowed configuration keys for service aliases are "alias", "public" and "deprecated".', $key, $id, $file)); + } + + if ('deprecated' === $key) { + $alias->setDeprecated(true, $value); + } + } + + return; + } + + if ($this->isLoadingInstanceof) { + $definition = new ChildDefinition(''); + } elseif (isset($service['parent'])) { + if (!empty($this->instanceof)) { + throw new InvalidArgumentException(sprintf('The service "%s" cannot use the "parent" option in the same file where "_instanceof" configuration is defined as using both is not supported. Move your child definitions to a separate file.', $id)); + } + + foreach ($defaults as $k => $v) { + if ('tags' === $k) { + // since tags are never inherited from parents, there is no confusion + // thus we can safely add them as defaults to ChildDefinition + continue; + } + if ('bind' === $k) { + throw new InvalidArgumentException(sprintf('Attribute "bind" on service "%s" cannot be inherited from "_defaults" when a "parent" is set. Move your child definitions to a separate file.', $id)); + } + if (!isset($service[$k])) { + throw new InvalidArgumentException(sprintf('Attribute "%s" on service "%s" cannot be inherited from "_defaults" when a "parent" is set. Move your child definitions to a separate file or define this attribute explicitly.', $k, $id)); + } + } + + if ('' !== $service['parent'] && '@' === $service['parent'][0]) { + throw new InvalidArgumentException(sprintf('The value of the "parent" option for the "%s" service must be the id of the service without the "@" prefix (replace "%s" with "%s").', $id, $service['parent'], substr($service['parent'], 1))); + } + + $definition = new ChildDefinition($service['parent']); + } else { + $definition = new Definition(); + + if (isset($defaults['public'])) { + $definition->setPublic($defaults['public']); + } + if (isset($defaults['autowire'])) { + $definition->setAutowired($defaults['autowire']); + } + if (isset($defaults['autoconfigure'])) { + $definition->setAutoconfigured($defaults['autoconfigure']); + } + + $definition->setChanges([]); + } + + if (isset($service['class'])) { + $definition->setClass($service['class']); + } + + if (isset($service['shared'])) { + $definition->setShared($service['shared']); + } + + if (isset($service['synthetic'])) { + $definition->setSynthetic($service['synthetic']); + } + + if (isset($service['lazy'])) { + $definition->setLazy((bool) $service['lazy']); + if (\is_string($service['lazy'])) { + $definition->addTag('proxy', ['interface' => $service['lazy']]); + } + } + + if (isset($service['public'])) { + $definition->setPublic($service['public']); + } + + if (isset($service['abstract'])) { + $definition->setAbstract($service['abstract']); + } + + if (\array_key_exists('deprecated', $service)) { + $definition->setDeprecated(true, $service['deprecated']); + } + + if (isset($service['factory'])) { + $definition->setFactory($this->parseCallable($service['factory'], 'factory', $id, $file)); + } + + if (isset($service['file'])) { + $definition->setFile($service['file']); + } + + if (isset($service['arguments'])) { + $definition->setArguments($this->resolveServices($service['arguments'], $file)); + } + + if (isset($service['properties'])) { + $definition->setProperties($this->resolveServices($service['properties'], $file)); + } + + if (isset($service['configurator'])) { + $definition->setConfigurator($this->parseCallable($service['configurator'], 'configurator', $id, $file)); + } + + if (isset($service['calls'])) { + if (!\is_array($service['calls'])) { + throw new InvalidArgumentException(sprintf('Parameter "calls" must be an array for service "%s" in %s. Check your YAML syntax.', $id, $file)); + } + + foreach ($service['calls'] as $k => $call) { + if (!\is_array($call) && (!\is_string($k) || !$call instanceof TaggedValue)) { + throw new InvalidArgumentException(sprintf('Invalid method call for service "%s": expected map or array, %s given in %s.', $id, $call instanceof TaggedValue ? '!'.$call->getTag() : \gettype($call), $file)); + } + + if (\is_string($k)) { + throw new InvalidArgumentException(sprintf('Invalid method call for service "%s", did you forgot a leading dash before "%s: ..." in %s?', $id, $k, $file)); + } + + if (isset($call['method'])) { + $method = $call['method']; + $args = $call['arguments'] ?? []; + $returnsClone = $call['returns_clone'] ?? false; + } else { + if (1 === \count($call) && \is_string(key($call))) { + $method = key($call); + $args = $call[$method]; + + if ($args instanceof TaggedValue) { + if ('returns_clone' !== $args->getTag()) { + throw new InvalidArgumentException(sprintf('Unsupported tag "!%s", did you mean "!returns_clone" for service "%s" in %s?', $args->getTag(), $id, $file)); + } + + $returnsClone = true; + $args = $args->getValue(); + } else { + $returnsClone = false; + } + } elseif (empty($call[0])) { + throw new InvalidArgumentException(sprintf('Invalid call for service "%s": the method must be defined as the first index of an array or as the only key of a map in %s.', $id, $file)); + } else { + $method = $call[0]; + $args = $call[1] ?? []; + $returnsClone = $call[2] ?? false; + } + } + + if (!\is_array($args)) { + throw new InvalidArgumentException(sprintf('The second parameter for function call "%s" must be an array of its arguments for service "%s" in %s. Check your YAML syntax.', $method, $id, $file)); + } + + $args = $this->resolveServices($args, $file); + $definition->addMethodCall($method, $args, $returnsClone); + } + } + + $tags = isset($service['tags']) ? $service['tags'] : []; + if (!\is_array($tags)) { + throw new InvalidArgumentException(sprintf('Parameter "tags" must be an array for service "%s" in %s. Check your YAML syntax.', $id, $file)); + } + + if (isset($defaults['tags'])) { + $tags = array_merge($tags, $defaults['tags']); + } + + foreach ($tags as $tag) { + if (!\is_array($tag)) { + $tag = ['name' => $tag]; + } + + if (!isset($tag['name'])) { + throw new InvalidArgumentException(sprintf('A "tags" entry is missing a "name" key for service "%s" in %s.', $id, $file)); + } + $name = $tag['name']; + unset($tag['name']); + + if (!\is_string($name) || '' === $name) { + throw new InvalidArgumentException(sprintf('The tag name for service "%s" in %s must be a non-empty string.', $id, $file)); + } + + foreach ($tag as $attribute => $value) { + if (!is_scalar($value) && null !== $value) { + throw new InvalidArgumentException(sprintf('A "tags" attribute must be of a scalar-type for service "%s", tag "%s", attribute "%s" in %s. Check your YAML syntax.', $id, $name, $attribute, $file)); + } + } + + $definition->addTag($name, $tag); + } + + if (null !== $decorates = $service['decorates'] ?? null) { + if ('' !== $decorates && '@' === $decorates[0]) { + throw new InvalidArgumentException(sprintf('The value of the "decorates" option for the "%s" service must be the id of the service without the "@" prefix (replace "%s" with "%s").', $id, $service['decorates'], substr($decorates, 1))); + } + + $decorationOnInvalid = \array_key_exists('decoration_on_invalid', $service) ? $service['decoration_on_invalid'] : 'exception'; + if ('exception' === $decorationOnInvalid) { + $invalidBehavior = ContainerInterface::EXCEPTION_ON_INVALID_REFERENCE; + } elseif ('ignore' === $decorationOnInvalid) { + $invalidBehavior = ContainerInterface::IGNORE_ON_INVALID_REFERENCE; + } elseif (null === $decorationOnInvalid) { + $invalidBehavior = ContainerInterface::NULL_ON_INVALID_REFERENCE; + } elseif ('null' === $decorationOnInvalid) { + throw new InvalidArgumentException(sprintf('Invalid value "%s" for attribute "decoration_on_invalid" on service "%s". Did you mean null (without quotes) in "%s"?', $decorationOnInvalid, $id, $file)); + } else { + throw new InvalidArgumentException(sprintf('Invalid value "%s" for attribute "decoration_on_invalid" on service "%s". Did you mean "exception", "ignore" or null in "%s"?', $decorationOnInvalid, $id, $file)); + } + + $renameId = isset($service['decoration_inner_name']) ? $service['decoration_inner_name'] : null; + $priority = isset($service['decoration_priority']) ? $service['decoration_priority'] : 0; + + $definition->setDecoratedService($decorates, $renameId, $priority, $invalidBehavior); + } + + if (isset($service['autowire'])) { + $definition->setAutowired($service['autowire']); + } + + if (isset($defaults['bind']) || isset($service['bind'])) { + // deep clone, to avoid multiple process of the same instance in the passes + $bindings = isset($defaults['bind']) ? unserialize(serialize($defaults['bind'])) : []; + + if (isset($service['bind'])) { + if (!\is_array($service['bind'])) { + throw new InvalidArgumentException(sprintf('Parameter "bind" must be an array for service "%s" in %s. Check your YAML syntax.', $id, $file)); + } + + $bindings = array_merge($bindings, $this->resolveServices($service['bind'], $file)); + $bindingType = $this->isLoadingInstanceof ? BoundArgument::INSTANCEOF_BINDING : BoundArgument::SERVICE_BINDING; + foreach ($bindings as $argument => $value) { + if (!$value instanceof BoundArgument) { + $bindings[$argument] = new BoundArgument($value, true, $bindingType, $file); + } + } + } + + $definition->setBindings($bindings); + } + + if (isset($service['autoconfigure'])) { + if (!$definition instanceof ChildDefinition) { + $definition->setAutoconfigured($service['autoconfigure']); + } elseif ($service['autoconfigure']) { + throw new InvalidArgumentException(sprintf('The service "%s" cannot have a "parent" and also have "autoconfigure". Try setting "autoconfigure: false" for the service.', $id)); + } + } + + if (\array_key_exists('namespace', $service) && !\array_key_exists('resource', $service)) { + throw new InvalidArgumentException(sprintf('A "resource" attribute must be set when the "namespace" attribute is set for service "%s" in %s. Check your YAML syntax.', $id, $file)); + } + + if (\array_key_exists('resource', $service)) { + if (!\is_string($service['resource'])) { + throw new InvalidArgumentException(sprintf('A "resource" attribute must be of type string for service "%s" in %s. Check your YAML syntax.', $id, $file)); + } + $exclude = isset($service['exclude']) ? $service['exclude'] : null; + $namespace = isset($service['namespace']) ? $service['namespace'] : $id; + $this->registerClasses($definition, $namespace, $service['resource'], $exclude); + } else { + $this->setDefinition($id, $definition); + } + } + + /** + * Parses a callable. + * + * @param string|array $callable A callable reference + * + * @throws InvalidArgumentException When errors occur + * + * @return string|array|Reference A parsed callable + */ + private function parseCallable($callable, string $parameter, string $id, string $file) + { + if (\is_string($callable)) { + if ('' !== $callable && '@' === $callable[0]) { + if (false === strpos($callable, ':')) { + return [$this->resolveServices($callable, $file), '__invoke']; + } + + throw new InvalidArgumentException(sprintf('The value of the "%s" option for the "%s" service must be the id of the service without the "@" prefix (replace "%s" with "%s" in "%s").', $parameter, $id, $callable, substr($callable, 1), $file)); + } + + if (false !== strpos($callable, ':') && false === strpos($callable, '::')) { + $parts = explode(':', $callable); + + @trigger_error(sprintf('Using short %s syntax for service "%s" is deprecated since Symfony 4.4, use "[\'@%s\', \'%s\']" instead.', $parameter, $id, ...$parts), E_USER_DEPRECATED); + + return [$this->resolveServices('@'.$parts[0], $file), $parts[1]]; + } + + return $callable; + } + + if (\is_array($callable)) { + if (isset($callable[0]) && isset($callable[1])) { + return [$this->resolveServices($callable[0], $file), $callable[1]]; + } + + if ('factory' === $parameter && isset($callable[1]) && null === $callable[0]) { + return $callable; + } + + throw new InvalidArgumentException(sprintf('Parameter "%s" must contain an array with two elements for service "%s" in %s. Check your YAML syntax.', $parameter, $id, $file)); + } + + throw new InvalidArgumentException(sprintf('Parameter "%s" must be a string or an array for service "%s" in %s. Check your YAML syntax.', $parameter, $id, $file)); + } + + /** + * Loads a YAML file. + * + * @param string $file + * + * @return array The file content + * + * @throws InvalidArgumentException when the given file is not a local file or when it does not exist + */ + protected function loadFile($file) + { + if (!class_exists('Symfony\Component\Yaml\Parser')) { + throw new RuntimeException('Unable to load YAML config files as the Symfony Yaml Component is not installed.'); + } + + if (!stream_is_local($file)) { + throw new InvalidArgumentException(sprintf('This is not a local file "%s".', $file)); + } + + if (!file_exists($file)) { + throw new InvalidArgumentException(sprintf('The file "%s" does not exist.', $file)); + } + + if (null === $this->yamlParser) { + $this->yamlParser = new YamlParser(); + } + + try { + $configuration = $this->yamlParser->parseFile($file, Yaml::PARSE_CONSTANT | Yaml::PARSE_CUSTOM_TAGS); + } catch (ParseException $e) { + throw new InvalidArgumentException(sprintf('The file "%s" does not contain valid YAML: %s', $file, $e->getMessage()), 0, $e); + } + + return $this->validate($configuration, $file); + } + + /** + * Validates a YAML file. + * + * @throws InvalidArgumentException When service file is not valid + */ + private function validate($content, string $file): ?array + { + if (null === $content) { + return $content; + } + + if (!\is_array($content)) { + throw new InvalidArgumentException(sprintf('The service file "%s" is not valid. It should contain an array. Check your YAML syntax.', $file)); + } + + foreach ($content as $namespace => $data) { + if (\in_array($namespace, ['imports', 'parameters', 'services'])) { + continue; + } + + if (!$this->container->hasExtension($namespace)) { + $extensionNamespaces = array_filter(array_map(function (ExtensionInterface $ext) { return $ext->getAlias(); }, $this->container->getExtensions())); + throw new InvalidArgumentException(sprintf('There is no extension able to load the configuration for "%s" (in %s). Looked for namespace "%s", found %s', $namespace, $file, $namespace, $extensionNamespaces ? sprintf('"%s"', implode('", "', $extensionNamespaces)) : 'none')); + } + } + + return $content; + } + + /** + * Resolves services. + * + * @return array|string|Reference|ArgumentInterface + */ + private function resolveServices($value, string $file, bool $isParameter = false) + { + if ($value instanceof TaggedValue) { + $argument = $value->getValue(); + if ('iterator' === $value->getTag()) { + if (!\is_array($argument)) { + throw new InvalidArgumentException(sprintf('"!iterator" tag only accepts sequences in "%s".', $file)); + } + $argument = $this->resolveServices($argument, $file, $isParameter); + try { + return new IteratorArgument($argument); + } catch (InvalidArgumentException $e) { + throw new InvalidArgumentException(sprintf('"!iterator" tag only accepts arrays of "@service" references in "%s".', $file)); + } + } + if ('service_locator' === $value->getTag()) { + if (!\is_array($argument)) { + throw new InvalidArgumentException(sprintf('"!service_locator" tag only accepts maps in "%s".', $file)); + } + + $argument = $this->resolveServices($argument, $file, $isParameter); + + try { + return new ServiceLocatorArgument($argument); + } catch (InvalidArgumentException $e) { + throw new InvalidArgumentException(sprintf('"!service_locator" tag only accepts maps of "@service" references in "%s".', $file)); + } + } + if (\in_array($value->getTag(), ['tagged', 'tagged_iterator', 'tagged_locator'], true)) { + $forLocator = 'tagged_locator' === $value->getTag(); + + if (\is_array($argument) && isset($argument['tag']) && $argument['tag']) { + if ($diff = array_diff(array_keys($argument), ['tag', 'index_by', 'default_index_method', 'default_priority_method'])) { + throw new InvalidArgumentException(sprintf('"!%s" tag contains unsupported key "%s"; supported ones are "tag", "index_by", "default_index_method", and "default_priority_method".', $value->getTag(), implode('"", "', $diff))); + } + + $argument = new TaggedIteratorArgument($argument['tag'], $argument['index_by'] ?? null, $argument['default_index_method'] ?? null, $forLocator, $argument['default_priority_method'] ?? null); + } elseif (\is_string($argument) && $argument) { + $argument = new TaggedIteratorArgument($argument, null, null, $forLocator); + } else { + throw new InvalidArgumentException(sprintf('"!%s" tags only accept a non empty string or an array with a key "tag" in "%s".', $value->getTag(), $file)); + } + + if ($forLocator) { + $argument = new ServiceLocatorArgument($argument); + } + + return $argument; + } + if ('service' === $value->getTag()) { + if ($isParameter) { + throw new InvalidArgumentException(sprintf('Using an anonymous service in a parameter is not allowed in "%s".', $file)); + } + + $isLoadingInstanceof = $this->isLoadingInstanceof; + $this->isLoadingInstanceof = false; + $instanceof = $this->instanceof; + $this->instanceof = []; + + $id = sprintf('.%d_%s', ++$this->anonymousServicesCount, preg_replace('/^.*\\\\/', '', isset($argument['class']) ? $argument['class'] : '').$this->anonymousServicesSuffix); + $this->parseDefinition($id, $argument, $file, []); + + if (!$this->container->hasDefinition($id)) { + throw new InvalidArgumentException(sprintf('Creating an alias using the tag "!service" is not allowed in "%s".', $file)); + } + + $this->container->getDefinition($id)->setPublic(false); + + $this->isLoadingInstanceof = $isLoadingInstanceof; + $this->instanceof = $instanceof; + + return new Reference($id); + } + + throw new InvalidArgumentException(sprintf('Unsupported tag "!%s".', $value->getTag())); + } + + if (\is_array($value)) { + foreach ($value as $k => $v) { + $value[$k] = $this->resolveServices($v, $file, $isParameter); + } + } elseif (\is_string($value) && 0 === strpos($value, '@=')) { + if (!class_exists(Expression::class)) { + throw new \LogicException(sprintf('The "@=" expression syntax cannot be used without the ExpressionLanguage component. Try running "composer require symfony/expression-language".')); + } + + return new Expression(substr($value, 2)); + } elseif (\is_string($value) && 0 === strpos($value, '@')) { + if (0 === strpos($value, '@@')) { + $value = substr($value, 1); + $invalidBehavior = null; + } elseif (0 === strpos($value, '@!')) { + $value = substr($value, 2); + $invalidBehavior = ContainerInterface::IGNORE_ON_UNINITIALIZED_REFERENCE; + } elseif (0 === strpos($value, '@?')) { + $value = substr($value, 2); + $invalidBehavior = ContainerInterface::IGNORE_ON_INVALID_REFERENCE; + } else { + $value = substr($value, 1); + $invalidBehavior = ContainerInterface::EXCEPTION_ON_INVALID_REFERENCE; + } + + if (null !== $invalidBehavior) { + $value = new Reference($value, $invalidBehavior); + } + } + + return $value; + } + + /** + * Loads from Extensions. + */ + private function loadFromExtensions(array $content) + { + foreach ($content as $namespace => $values) { + if (\in_array($namespace, ['imports', 'parameters', 'services'])) { + continue; + } + + if (!\is_array($values) && null !== $values) { + $values = []; + } + + $this->container->loadFromExtension($namespace, $values); + } + } + + /** + * Checks the keywords used to define a service. + */ + private function checkDefinition(string $id, array $definition, string $file) + { + if ($this->isLoadingInstanceof) { + $keywords = self::$instanceofKeywords; + } elseif (isset($definition['resource']) || isset($definition['namespace'])) { + $keywords = self::$prototypeKeywords; + } else { + $keywords = self::$serviceKeywords; + } + + foreach ($definition as $key => $value) { + if (!isset($keywords[$key])) { + throw new InvalidArgumentException(sprintf('The configuration key "%s" is unsupported for definition "%s" in "%s". Allowed configuration keys are "%s".', $key, $id, $file, implode('", "', $keywords))); + } + } + } +} diff --git a/srcs/phpmyadmin/vendor/symfony/dependency-injection/Loader/schema/dic/services/services-1.0.xsd b/srcs/phpmyadmin/vendor/symfony/dependency-injection/Loader/schema/dic/services/services-1.0.xsd new file mode 100644 index 0000000..2f745c3 --- /dev/null +++ b/srcs/phpmyadmin/vendor/symfony/dependency-injection/Loader/schema/dic/services/services-1.0.xsd @@ -0,0 +1,305 @@ +<?xml version="1.0" encoding="UTF-8" ?> + +<xsd:schema xmlns="http://symfony.com/schema/dic/services" + xmlns:xsd="http://www.w3.org/2001/XMLSchema" + targetNamespace="http://symfony.com/schema/dic/services" + elementFormDefault="qualified"> + + <xsd:annotation> + <xsd:documentation><![CDATA[ + Symfony XML Services Schema, version 1.0 + Authors: Fabien Potencier + + This defines a way to describe PHP objects (services) and their + dependencies. + ]]></xsd:documentation> + </xsd:annotation> + + <xsd:element name="container" type="container" /> + + <xsd:complexType name="container"> + <xsd:annotation> + <xsd:documentation><![CDATA[ + The root element of a service file. + ]]></xsd:documentation> + </xsd:annotation> + <xsd:sequence> + <xsd:group ref="foreign" /> + <xsd:sequence minOccurs="0"> + <xsd:element name="imports" type="imports" /> + <xsd:group ref="foreign" /> + </xsd:sequence> + <xsd:sequence minOccurs="0"> + <xsd:element name="parameters" type="parameters" /> + <xsd:group ref="foreign" /> + </xsd:sequence> + <xsd:sequence minOccurs="0"> + <xsd:element name="services" type="services" /> + <xsd:group ref="foreign" /> + </xsd:sequence> + </xsd:sequence> + </xsd:complexType> + + <xsd:group name="foreign"> + <xsd:sequence> + <xsd:any namespace="##other" processContents="lax" minOccurs="0" maxOccurs="unbounded" /> + </xsd:sequence> + </xsd:group> + + <xsd:complexType name="services"> + <xsd:annotation> + <xsd:documentation><![CDATA[ + Enclosing element for the definition of all services + ]]></xsd:documentation> + </xsd:annotation> + <xsd:choice maxOccurs="unbounded"> + <xsd:element name="service" type="service" minOccurs="1" /> + <xsd:element name="prototype" type="prototype" minOccurs="0" /> + <xsd:element name="defaults" type="defaults" minOccurs="0" maxOccurs="1" /> + <xsd:element name="instanceof" type="instanceof" minOccurs="0" /> + </xsd:choice> + </xsd:complexType> + + <xsd:complexType name="imports"> + <xsd:annotation> + <xsd:documentation><![CDATA[ + Enclosing element for the import elements + ]]></xsd:documentation> + </xsd:annotation> + <xsd:choice minOccurs="1" maxOccurs="unbounded"> + <xsd:element name="import" type="import" /> + </xsd:choice> + </xsd:complexType> + + <xsd:complexType name="import"> + <xsd:annotation> + <xsd:documentation><![CDATA[ + Import an external resource defining other services or parameters + ]]></xsd:documentation> + </xsd:annotation> + <xsd:attribute name="resource" type="xsd:string" use="required" /> + <xsd:attribute name="ignore-errors" type="ignore_errors" /> + <xsd:attribute name="type" type="xsd:string" /> + </xsd:complexType> + + <xsd:complexType name="callable"> + <xsd:choice minOccurs="0" maxOccurs="1"> + <xsd:element name="service" type="service" minOccurs="0" maxOccurs="1" /> + </xsd:choice> + <xsd:attribute name="service" type="xsd:string" /> + <xsd:attribute name="class" type="xsd:string" /> + <xsd:attribute name="method" type="xsd:string" /> + <xsd:attribute name="function" type="xsd:string" /> + </xsd:complexType> + + <xsd:complexType name="defaults"> + <xsd:annotation> + <xsd:documentation><![CDATA[ + Enclosing element for the service definitions' defaults for the current file + ]]></xsd:documentation> + </xsd:annotation> + <xsd:choice maxOccurs="unbounded"> + <xsd:element name="tag" type="tag" minOccurs="0" maxOccurs="unbounded" /> + <xsd:element name="bind" type="bind" minOccurs="0" maxOccurs="unbounded" /> + </xsd:choice> + <xsd:attribute name="public" type="boolean" /> + <xsd:attribute name="autowire" type="boolean" /> + <xsd:attribute name="autoconfigure" type="boolean" /> + </xsd:complexType> + + <xsd:complexType name="service"> + <xsd:choice maxOccurs="unbounded"> + <xsd:element name="file" type="xsd:string" minOccurs="0" maxOccurs="1" /> + <xsd:element name="argument" type="argument" minOccurs="0" maxOccurs="unbounded" /> + <xsd:element name="configurator" type="callable" minOccurs="0" maxOccurs="1" /> + <xsd:element name="factory" type="callable" minOccurs="0" maxOccurs="1" /> + <xsd:element name="deprecated" type="xsd:string" minOccurs="0" maxOccurs="1" /> + <xsd:element name="call" type="call" minOccurs="0" maxOccurs="unbounded" /> + <xsd:element name="tag" type="tag" minOccurs="0" maxOccurs="unbounded" /> + <xsd:element name="property" type="property" minOccurs="0" maxOccurs="unbounded" /> + <xsd:element name="bind" type="bind" minOccurs="0" maxOccurs="unbounded" /> + </xsd:choice> + <xsd:attribute name="id" type="xsd:string" /> + <xsd:attribute name="class" type="xsd:string" /> + <xsd:attribute name="shared" type="boolean" /> + <xsd:attribute name="public" type="boolean" /> + <xsd:attribute name="synthetic" type="boolean" /> + <xsd:attribute name="lazy" type="xsd:string" /> + <xsd:attribute name="abstract" type="boolean" /> + <xsd:attribute name="alias" type="xsd:string" /> + <xsd:attribute name="parent" type="xsd:string" /> + <xsd:attribute name="decorates" type="xsd:string" /> + <xsd:attribute name="decoration-on-invalid" type="invalid_decorated_service_sequence" /> + <xsd:attribute name="decoration-inner-name" type="xsd:string" /> + <xsd:attribute name="decoration-priority" type="xsd:integer" /> + <xsd:attribute name="autowire" type="boolean" /> + <xsd:attribute name="autoconfigure" type="boolean" /> + </xsd:complexType> + + <xsd:complexType name="instanceof"> + <xsd:choice maxOccurs="unbounded"> + <xsd:element name="configurator" type="callable" minOccurs="0" maxOccurs="1" /> + <xsd:element name="call" type="call" minOccurs="0" maxOccurs="unbounded" /> + <xsd:element name="tag" type="tag" minOccurs="0" maxOccurs="unbounded" /> + <xsd:element name="property" type="property" minOccurs="0" maxOccurs="unbounded" /> + <xsd:element name="bind" type="bind" minOccurs="0" maxOccurs="unbounded" /> + </xsd:choice> + <xsd:attribute name="id" type="xsd:string" use="required" /> + <xsd:attribute name="shared" type="boolean" /> + <xsd:attribute name="public" type="boolean" /> + <xsd:attribute name="lazy" type="xsd:string" /> + <xsd:attribute name="autowire" type="boolean" /> + <xsd:attribute name="autoconfigure" type="boolean" /> + </xsd:complexType> + + <xsd:complexType name="prototype"> + <xsd:choice maxOccurs="unbounded"> + <xsd:element name="argument" type="argument" minOccurs="0" maxOccurs="unbounded" /> + <xsd:element name="configurator" type="callable" minOccurs="0" maxOccurs="1" /> + <xsd:element name="factory" type="callable" minOccurs="0" maxOccurs="1" /> + <xsd:element name="deprecated" type="xsd:string" minOccurs="0" maxOccurs="1" /> + <xsd:element name="call" type="call" minOccurs="0" maxOccurs="unbounded" /> + <xsd:element name="tag" type="tag" minOccurs="0" maxOccurs="unbounded" /> + <xsd:element name="property" type="property" minOccurs="0" maxOccurs="unbounded" /> + <xsd:element name="bind" type="bind" minOccurs="0" maxOccurs="unbounded" /> + <xsd:element name="exclude" type="xsd:string" minOccurs="0" maxOccurs="unbounded" /> + </xsd:choice> + <xsd:attribute name="namespace" type="xsd:string" use="required" /> + <xsd:attribute name="resource" type="xsd:string" use="required" /> + <xsd:attribute name="exclude" type="xsd:string" /> + <xsd:attribute name="shared" type="boolean" /> + <xsd:attribute name="public" type="boolean" /> + <xsd:attribute name="lazy" type="xsd:string" /> + <xsd:attribute name="abstract" type="boolean" /> + <xsd:attribute name="parent" type="xsd:string" /> + <xsd:attribute name="autowire" type="boolean" /> + <xsd:attribute name="autoconfigure" type="boolean" /> + </xsd:complexType> + + <xsd:complexType name="tag"> + <xsd:attribute name="name" type="xsd:string" use="required" /> + <xsd:anyAttribute namespace="##any" processContents="lax" /> + </xsd:complexType> + + <xsd:complexType name="parameters"> + <xsd:choice minOccurs="1" maxOccurs="unbounded"> + <xsd:element name="parameter" type="parameter" /> + </xsd:choice> + <xsd:attribute name="type" type="parameter_type" /> + <xsd:attribute name="key" type="xsd:string" /> + </xsd:complexType> + + <xsd:complexType name="parameter" mixed="true"> + <xsd:choice minOccurs="0" maxOccurs="unbounded"> + <xsd:element name="parameter" type="parameter" /> + </xsd:choice> + <xsd:attribute name="type" type="parameter_type" /> + <xsd:attribute name="id" type="xsd:string" /> + <xsd:attribute name="key" type="xsd:string" /> + <xsd:attribute name="on-invalid" type="invalid_sequence" /> + </xsd:complexType> + + <xsd:complexType name="property" mixed="true"> + <xsd:choice minOccurs="0"> + <xsd:element name="property" type="property" maxOccurs="unbounded" /> + <xsd:element name="service" type="service" /> + </xsd:choice> + <xsd:attribute name="type" type="argument_type" /> + <xsd:attribute name="id" type="xsd:string" /> + <xsd:attribute name="key" type="xsd:string" /> + <xsd:attribute name="name" type="xsd:string" /> + <xsd:attribute name="on-invalid" type="invalid_sequence" /> + <xsd:attribute name="tag" type="xsd:string" /> + </xsd:complexType> + + <xsd:complexType name="bind" mixed="true"> + <xsd:choice maxOccurs="unbounded"> + <xsd:element name="bind" type="argument" minOccurs="0" maxOccurs="unbounded" /> + <xsd:element name="service" type="service" /> + </xsd:choice> + <xsd:attribute name="type" type="argument_type" /> + <xsd:attribute name="id" type="xsd:string" /> + <xsd:attribute name="key" type="xsd:string" use="required" /> + <xsd:attribute name="on-invalid" type="invalid_sequence" /> + <xsd:attribute name="method" type="xsd:string" /> + <xsd:attribute name="tag" type="xsd:string" /> + </xsd:complexType> + + <xsd:complexType name="argument" mixed="true"> + <xsd:choice minOccurs="0"> + <xsd:element name="argument" type="argument" maxOccurs="unbounded" /> + <xsd:element name="service" type="service" /> + </xsd:choice> + <xsd:attribute name="type" type="argument_type" /> + <xsd:attribute name="id" type="xsd:string" /> + <xsd:attribute name="key" type="xsd:string" /> + <xsd:attribute name="index" type="xsd:integer" /> + <xsd:attribute name="on-invalid" type="invalid_sequence" /> + <xsd:attribute name="tag" type="xsd:string" /> + <xsd:attribute name="index-by" type="xsd:string" /> + <xsd:attribute name="default-index-method" type="xsd:string" /> + <xsd:attribute name="default-priority-method" type="xsd:string" /> + </xsd:complexType> + + <xsd:complexType name="call"> + <xsd:choice minOccurs="0"> + <xsd:element name="argument" type="argument" maxOccurs="unbounded" /> + </xsd:choice> + <xsd:attribute name="method" type="xsd:string" /> + <xsd:attribute name="returns-clone" type="boolean" /> + </xsd:complexType> + + <xsd:simpleType name="parameter_type"> + <xsd:restriction base="xsd:string"> + <xsd:enumeration value="collection" /> + <xsd:enumeration value="string" /> + <xsd:enumeration value="constant" /> + <xsd:enumeration value="binary" /> + </xsd:restriction> + </xsd:simpleType> + + <xsd:simpleType name="argument_type"> + <xsd:restriction base="xsd:string"> + <xsd:enumeration value="collection" /> + <xsd:enumeration value="service" /> + <xsd:enumeration value="expression" /> + <xsd:enumeration value="string" /> + <xsd:enumeration value="constant" /> + <xsd:enumeration value="iterator" /> + <xsd:enumeration value="service_locator" /> + <!-- "tagged" is an alias of "tagged_iterator", using "tagged_iterator" is preferred. --> + <xsd:enumeration value="tagged" /> + <xsd:enumeration value="tagged_iterator" /> + <xsd:enumeration value="tagged_locator" /> + </xsd:restriction> + </xsd:simpleType> + + <xsd:simpleType name="ignore_errors"> + <xsd:restriction base="xsd:string"> + <xsd:pattern value="(true|false|not_found)" /> + </xsd:restriction> + </xsd:simpleType> + + <xsd:simpleType name="invalid_sequence"> + <xsd:restriction base="xsd:string"> + <xsd:enumeration value="null" /> + <xsd:enumeration value="ignore" /> + <xsd:enumeration value="exception" /> + <xsd:enumeration value="ignore_uninitialized" /> + </xsd:restriction> + </xsd:simpleType> + + <xsd:simpleType name="invalid_decorated_service_sequence"> + <xsd:restriction base="xsd:string"> + <xsd:enumeration value="null" /> + <xsd:enumeration value="ignore" /> + <xsd:enumeration value="exception" /> + </xsd:restriction> + </xsd:simpleType> + + <xsd:simpleType name="boolean"> + <xsd:restriction base="xsd:string"> + <xsd:pattern value="(%.+%|true|false)" /> + </xsd:restriction> + </xsd:simpleType> +</xsd:schema> diff --git a/srcs/phpmyadmin/vendor/symfony/dependency-injection/Parameter.php b/srcs/phpmyadmin/vendor/symfony/dependency-injection/Parameter.php new file mode 100644 index 0000000..d484ac0 --- /dev/null +++ b/srcs/phpmyadmin/vendor/symfony/dependency-injection/Parameter.php @@ -0,0 +1,35 @@ +<?php + +/* + * This file is part of the Symfony package. + * + * (c) Fabien Potencier <fabien@symfony.com> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection; + +/** + * Parameter represents a parameter reference. + * + * @author Fabien Potencier <fabien@symfony.com> + */ +class Parameter +{ + private $id; + + public function __construct(string $id) + { + $this->id = $id; + } + + /** + * @return string The parameter key + */ + public function __toString() + { + return $this->id; + } +} diff --git a/srcs/phpmyadmin/vendor/symfony/dependency-injection/ParameterBag/ContainerBag.php b/srcs/phpmyadmin/vendor/symfony/dependency-injection/ParameterBag/ContainerBag.php new file mode 100644 index 0000000..7671dfc --- /dev/null +++ b/srcs/phpmyadmin/vendor/symfony/dependency-injection/ParameterBag/ContainerBag.php @@ -0,0 +1,51 @@ +<?php + +/* + * This file is part of the Symfony package. + * + * (c) Fabien Potencier <fabien@symfony.com> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection\ParameterBag; + +use Symfony\Component\DependencyInjection\Container; + +/** + * @author Nicolas Grekas <p@tchwork.com> + */ +class ContainerBag extends FrozenParameterBag implements ContainerBagInterface +{ + private $container; + + public function __construct(Container $container) + { + $this->container = $container; + } + + /** + * {@inheritdoc} + */ + public function all() + { + return $this->container->getParameterBag()->all(); + } + + /** + * {@inheritdoc} + */ + public function get($name) + { + return $this->container->getParameter($name); + } + + /** + * {@inheritdoc} + */ + public function has($name) + { + return $this->container->hasParameter($name); + } +} diff --git a/srcs/phpmyadmin/vendor/symfony/dependency-injection/ParameterBag/ContainerBagInterface.php b/srcs/phpmyadmin/vendor/symfony/dependency-injection/ParameterBag/ContainerBagInterface.php new file mode 100644 index 0000000..1c1227a --- /dev/null +++ b/srcs/phpmyadmin/vendor/symfony/dependency-injection/ParameterBag/ContainerBagInterface.php @@ -0,0 +1,57 @@ +<?php + +/* + * This file is part of the Symfony package. + * + * (c) Fabien Potencier <fabien@symfony.com> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection\ParameterBag; + +use Psr\Container\ContainerInterface; +use Symfony\Component\DependencyInjection\Exception\ParameterNotFoundException; + +/** + * ContainerBagInterface is the interface implemented by objects that manage service container parameters. + * + * @author Nicolas Grekas <p@tchwork.com> + */ +interface ContainerBagInterface extends ContainerInterface +{ + /** + * Gets the service container parameters. + * + * @return array An array of parameters + */ + public function all(); + + /** + * Replaces parameter placeholders (%name%) by their values. + * + * @param mixed $value A value + * + * @throws ParameterNotFoundException if a placeholder references a parameter that does not exist + */ + public function resolveValue($value); + + /** + * Escape parameter placeholders %. + * + * @param mixed $value + * + * @return mixed + */ + public function escapeValue($value); + + /** + * Unescape parameter placeholders %. + * + * @param mixed $value + * + * @return mixed + */ + public function unescapeValue($value); +} diff --git a/srcs/phpmyadmin/vendor/symfony/dependency-injection/ParameterBag/EnvPlaceholderParameterBag.php b/srcs/phpmyadmin/vendor/symfony/dependency-injection/ParameterBag/EnvPlaceholderParameterBag.php new file mode 100644 index 0000000..8724086 --- /dev/null +++ b/srcs/phpmyadmin/vendor/symfony/dependency-injection/ParameterBag/EnvPlaceholderParameterBag.php @@ -0,0 +1,173 @@ +<?php + +/* + * This file is part of the Symfony package. + * + * (c) Fabien Potencier <fabien@symfony.com> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection\ParameterBag; + +use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException; +use Symfony\Component\DependencyInjection\Exception\RuntimeException; + +/** + * @author Nicolas Grekas <p@tchwork.com> + */ +class EnvPlaceholderParameterBag extends ParameterBag +{ + private $envPlaceholderUniquePrefix; + private $envPlaceholders = []; + private $unusedEnvPlaceholders = []; + private $providedTypes = []; + + private static $counter = 0; + + /** + * {@inheritdoc} + */ + public function get($name) + { + if (0 === strpos($name, 'env(') && ')' === substr($name, -1) && 'env()' !== $name) { + $env = substr($name, 4, -1); + + if (isset($this->envPlaceholders[$env])) { + foreach ($this->envPlaceholders[$env] as $placeholder) { + return $placeholder; // return first result + } + } + if (isset($this->unusedEnvPlaceholders[$env])) { + foreach ($this->unusedEnvPlaceholders[$env] as $placeholder) { + return $placeholder; // return first result + } + } + if (!preg_match('/^(?:\w*+:)*+\w++$/', $env)) { + throw new InvalidArgumentException(sprintf('Invalid %s name: only "word" characters are allowed.', $name)); + } + + if ($this->has($name)) { + $defaultValue = parent::get($name); + + if (null !== $defaultValue && !is_scalar($defaultValue)) { // !is_string in 5.0 + //throw new RuntimeException(sprintf('The default value of an env() parameter must be a string or null, but "%s" given to "%s".', \gettype($defaultValue), $name)); + throw new RuntimeException(sprintf('The default value of an env() parameter must be scalar or null, but "%s" given to "%s".', \gettype($defaultValue), $name)); + } elseif (is_scalar($defaultValue) && !\is_string($defaultValue)) { + @trigger_error(sprintf('A non-string default value of an env() parameter is deprecated since 4.3, cast "%s" to string instead.', $name), E_USER_DEPRECATED); + } + } + + $uniqueName = md5($name.'_'.self::$counter++); + $placeholder = sprintf('%s_%s_%s', $this->getEnvPlaceholderUniquePrefix(), str_replace(':', '_', $env), $uniqueName); + $this->envPlaceholders[$env][$placeholder] = $placeholder; + + return $placeholder; + } + + return parent::get($name); + } + + /** + * Gets the common env placeholder prefix for env vars created by this bag. + */ + public function getEnvPlaceholderUniquePrefix(): string + { + if (null === $this->envPlaceholderUniquePrefix) { + $reproducibleEntropy = unserialize(serialize($this->parameters)); + array_walk_recursive($reproducibleEntropy, function (&$v) { $v = null; }); + $this->envPlaceholderUniquePrefix = 'env_'.substr(md5(serialize($reproducibleEntropy)), -16); + } + + return $this->envPlaceholderUniquePrefix; + } + + /** + * Returns the map of env vars used in the resolved parameter values to their placeholders. + * + * @return string[][] A map of env var names to their placeholders + */ + public function getEnvPlaceholders() + { + return $this->envPlaceholders; + } + + public function getUnusedEnvPlaceholders(): array + { + return $this->unusedEnvPlaceholders; + } + + public function clearUnusedEnvPlaceholders() + { + $this->unusedEnvPlaceholders = []; + } + + /** + * Merges the env placeholders of another EnvPlaceholderParameterBag. + */ + public function mergeEnvPlaceholders(self $bag) + { + if ($newPlaceholders = $bag->getEnvPlaceholders()) { + $this->envPlaceholders += $newPlaceholders; + + foreach ($newPlaceholders as $env => $placeholders) { + $this->envPlaceholders[$env] += $placeholders; + } + } + + if ($newUnusedPlaceholders = $bag->getUnusedEnvPlaceholders()) { + $this->unusedEnvPlaceholders += $newUnusedPlaceholders; + + foreach ($newUnusedPlaceholders as $env => $placeholders) { + $this->unusedEnvPlaceholders[$env] += $placeholders; + } + } + } + + /** + * Maps env prefixes to their corresponding PHP types. + */ + public function setProvidedTypes(array $providedTypes) + { + $this->providedTypes = $providedTypes; + } + + /** + * Gets the PHP types corresponding to env() parameter prefixes. + * + * @return string[][] + */ + public function getProvidedTypes() + { + return $this->providedTypes; + } + + /** + * {@inheritdoc} + */ + public function resolve() + { + if ($this->resolved) { + return; + } + parent::resolve(); + + foreach ($this->envPlaceholders as $env => $placeholders) { + if (!$this->has($name = "env($env)")) { + continue; + } + if (is_numeric($default = $this->parameters[$name])) { + if (!\is_string($default)) { + @trigger_error(sprintf('A non-string default value of env parameter "%s" is deprecated since 4.3, cast it to string instead.', $env), E_USER_DEPRECATED); + } + $this->parameters[$name] = (string) $default; + } elseif (null !== $default && !is_scalar($default)) { // !is_string in 5.0 + //throw new RuntimeException(sprintf('The default value of env parameter "%s" must be a string or null, %s given.', $env, \gettype($default))); + throw new RuntimeException(sprintf('The default value of env parameter "%s" must be scalar or null, %s given.', $env, \gettype($default))); + } elseif (is_scalar($default) && !\is_string($default)) { + @trigger_error(sprintf('A non-string default value of env parameter "%s" is deprecated since 4.3, cast it to string instead.', $env), E_USER_DEPRECATED); + } + } + } +} diff --git a/srcs/phpmyadmin/vendor/symfony/dependency-injection/ParameterBag/FrozenParameterBag.php b/srcs/phpmyadmin/vendor/symfony/dependency-injection/ParameterBag/FrozenParameterBag.php new file mode 100644 index 0000000..a519993 --- /dev/null +++ b/srcs/phpmyadmin/vendor/symfony/dependency-injection/ParameterBag/FrozenParameterBag.php @@ -0,0 +1,68 @@ +<?php + +/* + * This file is part of the Symfony package. + * + * (c) Fabien Potencier <fabien@symfony.com> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection\ParameterBag; + +use Symfony\Component\DependencyInjection\Exception\LogicException; + +/** + * Holds read-only parameters. + * + * @author Fabien Potencier <fabien@symfony.com> + */ +class FrozenParameterBag extends ParameterBag +{ + /** + * For performance reasons, the constructor assumes that + * all keys are already lowercased. + * + * This is always the case when used internally. + * + * @param array $parameters An array of parameters + */ + public function __construct(array $parameters = []) + { + $this->parameters = $parameters; + $this->resolved = true; + } + + /** + * {@inheritdoc} + */ + public function clear() + { + throw new LogicException('Impossible to call clear() on a frozen ParameterBag.'); + } + + /** + * {@inheritdoc} + */ + public function add(array $parameters) + { + throw new LogicException('Impossible to call add() on a frozen ParameterBag.'); + } + + /** + * {@inheritdoc} + */ + public function set($name, $value) + { + throw new LogicException('Impossible to call set() on a frozen ParameterBag.'); + } + + /** + * {@inheritdoc} + */ + public function remove($name) + { + throw new LogicException('Impossible to call remove() on a frozen ParameterBag.'); + } +} diff --git a/srcs/phpmyadmin/vendor/symfony/dependency-injection/ParameterBag/ParameterBag.php b/srcs/phpmyadmin/vendor/symfony/dependency-injection/ParameterBag/ParameterBag.php new file mode 100644 index 0000000..48887c3 --- /dev/null +++ b/srcs/phpmyadmin/vendor/symfony/dependency-injection/ParameterBag/ParameterBag.php @@ -0,0 +1,289 @@ +<?php + +/* + * This file is part of the Symfony package. + * + * (c) Fabien Potencier <fabien@symfony.com> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection\ParameterBag; + +use Symfony\Component\DependencyInjection\Exception\ParameterCircularReferenceException; +use Symfony\Component\DependencyInjection\Exception\ParameterNotFoundException; +use Symfony\Component\DependencyInjection\Exception\RuntimeException; + +/** + * Holds parameters. + * + * @author Fabien Potencier <fabien@symfony.com> + */ +class ParameterBag implements ParameterBagInterface +{ + protected $parameters = []; + protected $resolved = false; + + /** + * @param array $parameters An array of parameters + */ + public function __construct(array $parameters = []) + { + $this->add($parameters); + } + + /** + * Clears all parameters. + */ + public function clear() + { + $this->parameters = []; + } + + /** + * Adds parameters to the service container parameters. + * + * @param array $parameters An array of parameters + */ + public function add(array $parameters) + { + foreach ($parameters as $key => $value) { + $this->set($key, $value); + } + } + + /** + * {@inheritdoc} + */ + public function all() + { + return $this->parameters; + } + + /** + * {@inheritdoc} + */ + public function get($name) + { + $name = (string) $name; + + if (!\array_key_exists($name, $this->parameters)) { + if (!$name) { + throw new ParameterNotFoundException($name); + } + + $alternatives = []; + foreach ($this->parameters as $key => $parameterValue) { + $lev = levenshtein($name, $key); + if ($lev <= \strlen($name) / 3 || false !== strpos($key, $name)) { + $alternatives[] = $key; + } + } + + $nonNestedAlternative = null; + if (!\count($alternatives) && false !== strpos($name, '.')) { + $namePartsLength = array_map('strlen', explode('.', $name)); + $key = substr($name, 0, -1 * (1 + array_pop($namePartsLength))); + while (\count($namePartsLength)) { + if ($this->has($key)) { + if (\is_array($this->get($key))) { + $nonNestedAlternative = $key; + } + break; + } + + $key = substr($key, 0, -1 * (1 + array_pop($namePartsLength))); + } + } + + throw new ParameterNotFoundException($name, null, null, null, $alternatives, $nonNestedAlternative); + } + + return $this->parameters[$name]; + } + + /** + * Sets a service container parameter. + * + * @param string $name The parameter name + * @param mixed $value The parameter value + */ + public function set($name, $value) + { + $this->parameters[(string) $name] = $value; + } + + /** + * {@inheritdoc} + */ + public function has($name) + { + return \array_key_exists((string) $name, $this->parameters); + } + + /** + * Removes a parameter. + * + * @param string $name The parameter name + */ + public function remove($name) + { + unset($this->parameters[(string) $name]); + } + + /** + * {@inheritdoc} + */ + public function resolve() + { + if ($this->resolved) { + return; + } + + $parameters = []; + foreach ($this->parameters as $key => $value) { + try { + $value = $this->resolveValue($value); + $parameters[$key] = $this->unescapeValue($value); + } catch (ParameterNotFoundException $e) { + $e->setSourceKey($key); + + throw $e; + } + } + + $this->parameters = $parameters; + $this->resolved = true; + } + + /** + * Replaces parameter placeholders (%name%) by their values. + * + * @param mixed $value A value + * @param array $resolving An array of keys that are being resolved (used internally to detect circular references) + * + * @return mixed The resolved value + * + * @throws ParameterNotFoundException if a placeholder references a parameter that does not exist + * @throws ParameterCircularReferenceException if a circular reference if detected + * @throws RuntimeException when a given parameter has a type problem + */ + public function resolveValue($value, array $resolving = []) + { + if (\is_array($value)) { + $args = []; + foreach ($value as $k => $v) { + $args[\is_string($k) ? $this->resolveValue($k, $resolving) : $k] = $this->resolveValue($v, $resolving); + } + + return $args; + } + + if (!\is_string($value) || 2 > \strlen($value)) { + return $value; + } + + return $this->resolveString($value, $resolving); + } + + /** + * Resolves parameters inside a string. + * + * @param string $value The string to resolve + * @param array $resolving An array of keys that are being resolved (used internally to detect circular references) + * + * @return mixed The resolved string + * + * @throws ParameterNotFoundException if a placeholder references a parameter that does not exist + * @throws ParameterCircularReferenceException if a circular reference if detected + * @throws RuntimeException when a given parameter has a type problem + */ + public function resolveString($value, array $resolving = []) + { + // we do this to deal with non string values (Boolean, integer, ...) + // as the preg_replace_callback throw an exception when trying + // a non-string in a parameter value + if (preg_match('/^%([^%\s]+)%$/', $value, $match)) { + $key = $match[1]; + + if (isset($resolving[$key])) { + throw new ParameterCircularReferenceException(array_keys($resolving)); + } + + $resolving[$key] = true; + + return $this->resolved ? $this->get($key) : $this->resolveValue($this->get($key), $resolving); + } + + return preg_replace_callback('/%%|%([^%\s]+)%/', function ($match) use ($resolving, $value) { + // skip %% + if (!isset($match[1])) { + return '%%'; + } + + $key = $match[1]; + if (isset($resolving[$key])) { + throw new ParameterCircularReferenceException(array_keys($resolving)); + } + + $resolved = $this->get($key); + + if (!\is_string($resolved) && !is_numeric($resolved)) { + throw new RuntimeException(sprintf('A string value must be composed of strings and/or numbers, but found parameter "%s" of type %s inside string value "%s".', $key, \gettype($resolved), $value)); + } + + $resolved = (string) $resolved; + $resolving[$key] = true; + + return $this->isResolved() ? $resolved : $this->resolveString($resolved, $resolving); + }, $value); + } + + public function isResolved() + { + return $this->resolved; + } + + /** + * {@inheritdoc} + */ + public function escapeValue($value) + { + if (\is_string($value)) { + return str_replace('%', '%%', $value); + } + + if (\is_array($value)) { + $result = []; + foreach ($value as $k => $v) { + $result[$k] = $this->escapeValue($v); + } + + return $result; + } + + return $value; + } + + /** + * {@inheritdoc} + */ + public function unescapeValue($value) + { + if (\is_string($value)) { + return str_replace('%%', '%', $value); + } + + if (\is_array($value)) { + $result = []; + foreach ($value as $k => $v) { + $result[$k] = $this->unescapeValue($v); + } + + return $result; + } + + return $value; + } +} diff --git a/srcs/phpmyadmin/vendor/symfony/dependency-injection/ParameterBag/ParameterBagInterface.php b/srcs/phpmyadmin/vendor/symfony/dependency-injection/ParameterBag/ParameterBagInterface.php new file mode 100644 index 0000000..6a4e0fa --- /dev/null +++ b/srcs/phpmyadmin/vendor/symfony/dependency-injection/ParameterBag/ParameterBagInterface.php @@ -0,0 +1,115 @@ +<?php + +/* + * This file is part of the Symfony package. + * + * (c) Fabien Potencier <fabien@symfony.com> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection\ParameterBag; + +use Symfony\Component\DependencyInjection\Exception\LogicException; +use Symfony\Component\DependencyInjection\Exception\ParameterNotFoundException; + +/** + * ParameterBagInterface is the interface implemented by objects that manage service container parameters. + * + * @author Fabien Potencier <fabien@symfony.com> + */ +interface ParameterBagInterface +{ + /** + * Clears all parameters. + * + * @throws LogicException if the ParameterBagInterface can not be cleared + */ + public function clear(); + + /** + * Adds parameters to the service container parameters. + * + * @param array $parameters An array of parameters + * + * @throws LogicException if the parameter can not be added + */ + public function add(array $parameters); + + /** + * Gets the service container parameters. + * + * @return array An array of parameters + */ + public function all(); + + /** + * Gets a service container parameter. + * + * @param string $name The parameter name + * + * @return mixed The parameter value + * + * @throws ParameterNotFoundException if the parameter is not defined + */ + public function get($name); + + /** + * Removes a parameter. + * + * @param string $name The parameter name + */ + public function remove($name); + + /** + * Sets a service container parameter. + * + * @param string $name The parameter name + * @param mixed $value The parameter value + * + * @throws LogicException if the parameter can not be set + */ + public function set($name, $value); + + /** + * Returns true if a parameter name is defined. + * + * @param string $name The parameter name + * + * @return bool true if the parameter name is defined, false otherwise + */ + public function has($name); + + /** + * Replaces parameter placeholders (%name%) by their values for all parameters. + */ + public function resolve(); + + /** + * Replaces parameter placeholders (%name%) by their values. + * + * @param mixed $value A value + * + * @throws ParameterNotFoundException if a placeholder references a parameter that does not exist + */ + public function resolveValue($value); + + /** + * Escape parameter placeholders %. + * + * @param mixed $value + * + * @return mixed + */ + public function escapeValue($value); + + /** + * Unescape parameter placeholders %. + * + * @param mixed $value + * + * @return mixed + */ + public function unescapeValue($value); +} diff --git a/srcs/phpmyadmin/vendor/symfony/dependency-injection/README.md b/srcs/phpmyadmin/vendor/symfony/dependency-injection/README.md new file mode 100644 index 0000000..932647f --- /dev/null +++ b/srcs/phpmyadmin/vendor/symfony/dependency-injection/README.md @@ -0,0 +1,14 @@ +DependencyInjection Component +============================= + +The DependencyInjection component allows you to standardize and centralize the +way objects are constructed in your application. + +Resources +--------- + + * [Documentation](https://symfony.com/doc/current/components/dependency_injection/index.html) + * [Contributing](https://symfony.com/doc/current/contributing/index.html) + * [Report issues](https://github.com/symfony/symfony/issues) and + [send Pull Requests](https://github.com/symfony/symfony/pulls) + in the [main Symfony repository](https://github.com/symfony/symfony) diff --git a/srcs/phpmyadmin/vendor/symfony/dependency-injection/Reference.php b/srcs/phpmyadmin/vendor/symfony/dependency-injection/Reference.php new file mode 100644 index 0000000..c13cf6f --- /dev/null +++ b/srcs/phpmyadmin/vendor/symfony/dependency-injection/Reference.php @@ -0,0 +1,47 @@ +<?php + +/* + * This file is part of the Symfony package. + * + * (c) Fabien Potencier <fabien@symfony.com> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection; + +/** + * Reference represents a service reference. + * + * @author Fabien Potencier <fabien@symfony.com> + */ +class Reference +{ + private $id; + private $invalidBehavior; + + public function __construct(string $id, int $invalidBehavior = ContainerInterface::EXCEPTION_ON_INVALID_REFERENCE) + { + $this->id = $id; + $this->invalidBehavior = $invalidBehavior; + } + + /** + * @return string The service identifier + */ + public function __toString() + { + return $this->id; + } + + /** + * Returns the behavior to be used when the service does not exist. + * + * @return int + */ + public function getInvalidBehavior() + { + return $this->invalidBehavior; + } +} diff --git a/srcs/phpmyadmin/vendor/symfony/dependency-injection/ResettableContainerInterface.php b/srcs/phpmyadmin/vendor/symfony/dependency-injection/ResettableContainerInterface.php new file mode 100644 index 0000000..b9714d2 --- /dev/null +++ b/srcs/phpmyadmin/vendor/symfony/dependency-injection/ResettableContainerInterface.php @@ -0,0 +1,35 @@ +<?php + +/* + * This file is part of the Symfony package. + * + * (c) Fabien Potencier <fabien@symfony.com> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection; + +use Symfony\Contracts\Service\ResetInterface; + +/** + * ResettableContainerInterface defines additional resetting functionality + * for containers, allowing to release shared services when the container is + * not needed anymore. + * + * @author Christophe Coevoet <stof@notk.org> + * + * @deprecated since Symfony 4.2, use "Symfony\Contracts\Service\ResetInterface" instead. + */ +interface ResettableContainerInterface extends ContainerInterface, ResetInterface +{ + /** + * Resets shared services from the container. + * + * The container is not intended to be used again after being reset in a normal workflow. This method is + * meant as a way to release references for ref-counting. + * A subsequent call to ContainerInterface::get will recreate a new instance of the shared service. + */ + public function reset(); +} diff --git a/srcs/phpmyadmin/vendor/symfony/dependency-injection/ReverseContainer.php b/srcs/phpmyadmin/vendor/symfony/dependency-injection/ReverseContainer.php new file mode 100644 index 0000000..076e624 --- /dev/null +++ b/srcs/phpmyadmin/vendor/symfony/dependency-injection/ReverseContainer.php @@ -0,0 +1,85 @@ +<?php + +/* + * This file is part of the Symfony package. + * + * (c) Fabien Potencier <fabien@symfony.com> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection; + +use Psr\Container\ContainerInterface; +use Symfony\Component\DependencyInjection\Exception\ServiceNotFoundException; + +/** + * Turns public and "container.reversible" services back to their ids. + * + * @author Nicolas Grekas <p@tchwork.com> + */ +final class ReverseContainer +{ + private $serviceContainer; + private $reversibleLocator; + private $tagName; + private $getServiceId; + + public function __construct(Container $serviceContainer, ContainerInterface $reversibleLocator, string $tagName = 'container.reversible') + { + $this->serviceContainer = $serviceContainer; + $this->reversibleLocator = $reversibleLocator; + $this->tagName = $tagName; + $this->getServiceId = \Closure::bind(function ($service): ?string { + return array_search($service, $this->services, true) ?: array_search($service, $this->privates, true) ?: null; + }, $serviceContainer, Container::class); + } + + /** + * Returns the id of the passed object when it exists as a service. + * + * To be reversible, services need to be either public or be tagged with "container.reversible". + * + * @param object $service + */ + public function getId($service): ?string + { + if ($this->serviceContainer === $service) { + return 'service_container'; + } + + if (null === $id = ($this->getServiceId)($service)) { + return null; + } + + if ($this->serviceContainer->has($id) || $this->reversibleLocator->has($id)) { + return $id; + } + + return null; + } + + /** + * @return object + * + * @throws ServiceNotFoundException When the service is not reversible + */ + public function getService(string $id) + { + if ($this->serviceContainer->has($id)) { + return $this->serviceContainer->get($id); + } + + if ($this->reversibleLocator->has($id)) { + return $this->reversibleLocator->get($id); + } + + if (isset($this->serviceContainer->getRemovedIds()[$id])) { + throw new ServiceNotFoundException($id, null, null, [], sprintf('The "%s" service is private and cannot be accessed by reference. You should either make it public, or tag it as "%s".', $id, $this->tagName)); + } + + // will throw a ServiceNotFoundException + $this->serviceContainer->get($id); + } +} diff --git a/srcs/phpmyadmin/vendor/symfony/dependency-injection/ServiceLocator.php b/srcs/phpmyadmin/vendor/symfony/dependency-injection/ServiceLocator.php new file mode 100644 index 0000000..e379f3b --- /dev/null +++ b/srcs/phpmyadmin/vendor/symfony/dependency-injection/ServiceLocator.php @@ -0,0 +1,145 @@ +<?php + +/* + * This file is part of the Symfony package. + * + * (c) Fabien Potencier <fabien@symfony.com> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection; + +use Psr\Container\ContainerExceptionInterface; +use Psr\Container\NotFoundExceptionInterface; +use Symfony\Component\DependencyInjection\Exception\RuntimeException; +use Symfony\Component\DependencyInjection\Exception\ServiceCircularReferenceException; +use Symfony\Component\DependencyInjection\Exception\ServiceNotFoundException; +use Symfony\Contracts\Service\ServiceLocatorTrait; +use Symfony\Contracts\Service\ServiceProviderInterface; +use Symfony\Contracts\Service\ServiceSubscriberInterface; + +/** + * @author Robin Chalas <robin.chalas@gmail.com> + * @author Nicolas Grekas <p@tchwork.com> + */ +class ServiceLocator implements ServiceProviderInterface +{ + use ServiceLocatorTrait { + get as private doGet; + } + + private $externalId; + private $container; + + public function get($id) + { + if (!$this->externalId) { + return $this->doGet($id); + } + + try { + return $this->doGet($id); + } catch (RuntimeException $e) { + $what = sprintf('service "%s" required by "%s"', $id, $this->externalId); + $message = preg_replace('/service "\.service_locator\.[^"]++"/', $what, $e->getMessage()); + + if ($e->getMessage() === $message) { + $message = sprintf('Cannot resolve %s: %s', $what, $message); + } + + $r = new \ReflectionProperty($e, 'message'); + $r->setAccessible(true); + $r->setValue($e, $message); + + throw $e; + } + } + + public function __invoke($id) + { + return isset($this->factories[$id]) ? $this->get($id) : null; + } + + /** + * @internal + * + * @return static + */ + public function withContext(string $externalId, Container $container) + { + $locator = clone $this; + $locator->externalId = $externalId; + $locator->container = $container; + + return $locator; + } + + private function createNotFoundException(string $id): NotFoundExceptionInterface + { + if ($this->loading) { + $msg = sprintf('The service "%s" has a dependency on a non-existent service "%s". This locator %s', end($this->loading), $id, $this->formatAlternatives()); + + return new ServiceNotFoundException($id, end($this->loading) ?: null, null, [], $msg); + } + + $class = debug_backtrace(DEBUG_BACKTRACE_PROVIDE_OBJECT | DEBUG_BACKTRACE_IGNORE_ARGS, 4); + $class = isset($class[3]['object']) ? \get_class($class[3]['object']) : null; + $externalId = $this->externalId ?: $class; + + $msg = []; + $msg[] = sprintf('Service "%s" not found:', $id); + + if (!$this->container) { + $class = null; + } elseif ($this->container->has($id) || isset($this->container->getRemovedIds()[$id])) { + $msg[] = 'even though it exists in the app\'s container,'; + } else { + try { + $this->container->get($id); + $class = null; + } catch (ServiceNotFoundException $e) { + if ($e->getAlternatives()) { + $msg[] = sprintf('did you mean %s? Anyway,', $this->formatAlternatives($e->getAlternatives(), 'or')); + } else { + $class = null; + } + } + } + if ($externalId) { + $msg[] = sprintf('the container inside "%s" is a smaller service locator that %s', $externalId, $this->formatAlternatives()); + } else { + $msg[] = sprintf('the current service locator %s', $this->formatAlternatives()); + } + + if (!$class) { + // no-op + } elseif (is_subclass_of($class, ServiceSubscriberInterface::class)) { + $msg[] = sprintf('Unless you need extra laziness, try using dependency injection instead. Otherwise, you need to declare it using "%s::getSubscribedServices()".', preg_replace('/([^\\\\]++\\\\)++/', '', $class)); + } else { + $msg[] = 'Try using dependency injection instead.'; + } + + return new ServiceNotFoundException($id, end($this->loading) ?: null, null, [], implode(' ', $msg)); + } + + private function createCircularReferenceException(string $id, array $path): ContainerExceptionInterface + { + return new ServiceCircularReferenceException($id, $path); + } + + private function formatAlternatives(array $alternatives = null, string $separator = 'and'): string + { + $format = '"%s"%s'; + if (null === $alternatives) { + if (!$alternatives = array_keys($this->factories)) { + return 'is empty...'; + } + $format = sprintf('only knows about the %s service%s.', $format, 1 < \count($alternatives) ? 's' : ''); + } + $last = array_pop($alternatives); + + return sprintf($format, $alternatives ? implode('", "', $alternatives) : $last, $alternatives ? sprintf(' %s "%s"', $separator, $last) : ''); + } +} diff --git a/srcs/phpmyadmin/vendor/symfony/dependency-injection/ServiceSubscriberInterface.php b/srcs/phpmyadmin/vendor/symfony/dependency-injection/ServiceSubscriberInterface.php new file mode 100644 index 0000000..a3b6ba7 --- /dev/null +++ b/srcs/phpmyadmin/vendor/symfony/dependency-injection/ServiceSubscriberInterface.php @@ -0,0 +1,23 @@ +<?php + +/* + * This file is part of the Symfony package. + * + * (c) Fabien Potencier <fabien@symfony.com> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection; + +use Symfony\Contracts\Service\ServiceSubscriberInterface as BaseServiceSubscriberInterface; + +/** + * {@inheritdoc} + * + * @deprecated since Symfony 4.2, use Symfony\Contracts\Service\ServiceSubscriberInterface instead. + */ +interface ServiceSubscriberInterface extends BaseServiceSubscriberInterface +{ +} diff --git a/srcs/phpmyadmin/vendor/symfony/dependency-injection/TaggedContainerInterface.php b/srcs/phpmyadmin/vendor/symfony/dependency-injection/TaggedContainerInterface.php new file mode 100644 index 0000000..90b297f --- /dev/null +++ b/srcs/phpmyadmin/vendor/symfony/dependency-injection/TaggedContainerInterface.php @@ -0,0 +1,29 @@ +<?php + +/* + * This file is part of the Symfony package. + * + * (c) Fabien Potencier <fabien@symfony.com> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection; + +/** + * TaggedContainerInterface is the interface implemented when a container knows how to deals with tags. + * + * @author Fabien Potencier <fabien@symfony.com> + */ +interface TaggedContainerInterface extends ContainerInterface +{ + /** + * Returns service ids for a given tag. + * + * @param string $name The tag name + * + * @return array An array of tags + */ + public function findTaggedServiceIds($name); +} diff --git a/srcs/phpmyadmin/vendor/symfony/dependency-injection/TypedReference.php b/srcs/phpmyadmin/vendor/symfony/dependency-injection/TypedReference.php new file mode 100644 index 0000000..56a8788 --- /dev/null +++ b/srcs/phpmyadmin/vendor/symfony/dependency-injection/TypedReference.php @@ -0,0 +1,74 @@ +<?php + +/* + * This file is part of the Symfony package. + * + * (c) Fabien Potencier <fabien@symfony.com> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection; + +/** + * Represents a PHP type-hinted service reference. + * + * @author Nicolas Grekas <p@tchwork.com> + */ +class TypedReference extends Reference +{ + private $type; + private $name; + private $requiringClass; + + /** + * @param string $id The service identifier + * @param string $type The PHP type of the identified service + * @param int $invalidBehavior The behavior when the service does not exist + * @param string $name The name of the argument targeting the service + */ + public function __construct(string $id, string $type, $invalidBehavior = ContainerInterface::EXCEPTION_ON_INVALID_REFERENCE, $name = null) + { + if (\is_string($invalidBehavior ?? '') || \is_int($name)) { + @trigger_error(sprintf('The $requiringClass argument of "%s()" is deprecated since Symfony 4.1.', __METHOD__), E_USER_DEPRECATED); + + $this->requiringClass = $invalidBehavior; + $invalidBehavior = 3 < \func_num_args() ? func_get_arg(3) : ContainerInterface::EXCEPTION_ON_INVALID_REFERENCE; + } else { + $this->name = $type === $id ? $name : null; + } + parent::__construct($id, $invalidBehavior); + $this->type = $type; + } + + public function getType() + { + return $this->type; + } + + public function getName(): ?string + { + return $this->name; + } + + /** + * @deprecated since Symfony 4.1 + */ + public function getRequiringClass() + { + @trigger_error(sprintf('The "%s()" method is deprecated since Symfony 4.1.', __METHOD__), E_USER_DEPRECATED); + + return $this->requiringClass ?? ''; + } + + /** + * @deprecated since Symfony 4.1 + */ + public function canBeAutoregistered() + { + @trigger_error(sprintf('The "%s()" method is deprecated since Symfony 4.1.', __METHOD__), E_USER_DEPRECATED); + + return $this->requiringClass && (false !== $i = strpos($this->type, '\\')) && 0 === strncasecmp($this->type, $this->requiringClass, 1 + $i); + } +} diff --git a/srcs/phpmyadmin/vendor/symfony/dependency-injection/Variable.php b/srcs/phpmyadmin/vendor/symfony/dependency-injection/Variable.php new file mode 100644 index 0000000..21d33eb --- /dev/null +++ b/srcs/phpmyadmin/vendor/symfony/dependency-injection/Variable.php @@ -0,0 +1,43 @@ +<?php + +/* + * This file is part of the Symfony package. + * + * (c) Fabien Potencier <fabien@symfony.com> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection; + +/** + * Represents a variable. + * + * $var = new Variable('a'); + * + * will be dumped as + * + * $a + * + * by the PHP dumper. + * + * @author Johannes M. Schmitt <schmittjoh@gmail.com> + */ +class Variable +{ + private $name; + + public function __construct(string $name) + { + $this->name = $name; + } + + /** + * @return string + */ + public function __toString() + { + return $this->name; + } +} diff --git a/srcs/phpmyadmin/vendor/symfony/dependency-injection/composer.json b/srcs/phpmyadmin/vendor/symfony/dependency-injection/composer.json new file mode 100644 index 0000000..df1727b --- /dev/null +++ b/srcs/phpmyadmin/vendor/symfony/dependency-injection/composer.json @@ -0,0 +1,57 @@ +{ + "name": "symfony/dependency-injection", + "type": "library", + "description": "Symfony DependencyInjection Component", + "keywords": [], + "homepage": "https://symfony.com", + "license": "MIT", + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "require": { + "php": "^7.1.3", + "psr/container": "^1.0", + "symfony/service-contracts": "^1.1.6|^2" + }, + "require-dev": { + "symfony/yaml": "^3.4|^4.0|^5.0", + "symfony/config": "^4.3", + "symfony/expression-language": "^3.4|^4.0|^5.0" + }, + "suggest": { + "symfony/yaml": "", + "symfony/config": "", + "symfony/finder": "For using double-star glob patterns or when GLOB_BRACE portability is required", + "symfony/expression-language": "For using expressions in service container configuration", + "symfony/proxy-manager-bridge": "Generate service proxies to lazy load them" + }, + "conflict": { + "symfony/config": "<4.3|>=5.0", + "symfony/finder": "<3.4", + "symfony/proxy-manager-bridge": "<3.4", + "symfony/yaml": "<3.4" + }, + "provide": { + "psr/container-implementation": "1.0", + "symfony/service-implementation": "1.0" + }, + "autoload": { + "psr-4": { "Symfony\\Component\\DependencyInjection\\": "" }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "minimum-stability": "dev", + "extra": { + "branch-alias": { + "dev-master": "4.4-dev" + } + } +} |
