← All changes
|
vendor_prefixed/symfony/dependency-injection/Container.php
+113
-189
18.1
→
trunk
View file →
| @@ -9,16 +9,23 @@ | ||
| 9 | 9 | * file that was distributed with this source code. |
| 10 | 10 | */ |
| 11 | 11 | namespace YoastSEO_Vendor\Symfony\Component\DependencyInjection; |
| 12 | 12 | |
| 13 | +use YoastSEO_Vendor\Symfony\Component\DependencyInjection\Argument\RewindableGenerator; | |
| 14 | +use YoastSEO_Vendor\Symfony\Component\DependencyInjection\Argument\ServiceLocator as ArgumentServiceLocator; | |
| 13 | 15 | use YoastSEO_Vendor\Symfony\Component\DependencyInjection\Exception\EnvNotFoundException; |
| 14 | 16 | use YoastSEO_Vendor\Symfony\Component\DependencyInjection\Exception\InvalidArgumentException; |
| 15 | 17 | use YoastSEO_Vendor\Symfony\Component\DependencyInjection\Exception\ParameterCircularReferenceException; |
| 18 | +use YoastSEO_Vendor\Symfony\Component\DependencyInjection\Exception\RuntimeException; | |
| 16 | 19 | use YoastSEO_Vendor\Symfony\Component\DependencyInjection\Exception\ServiceCircularReferenceException; |
| 17 | 20 | use YoastSEO_Vendor\Symfony\Component\DependencyInjection\Exception\ServiceNotFoundException; |
| 18 | 21 | use YoastSEO_Vendor\Symfony\Component\DependencyInjection\ParameterBag\EnvPlaceholderParameterBag; |
| 19 | 22 | use YoastSEO_Vendor\Symfony\Component\DependencyInjection\ParameterBag\FrozenParameterBag; |
| 20 | 23 | use YoastSEO_Vendor\Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface; |
| 24 | +use YoastSEO_Vendor\Symfony\Contracts\Service\ResetInterface; | |
| 25 | +// Help opcache.preload discover always-needed symbols | |
| 26 | +\class_exists(\YoastSEO_Vendor\Symfony\Component\DependencyInjection\Argument\RewindableGenerator::class); | |
| 27 | +\class_exists(\YoastSEO_Vendor\Symfony\Component\DependencyInjection\Argument\ServiceLocator::class); | |
| 21 | 28 | /** |
| 22 | 29 | * Container is a dependency injection container. |
| 23 | 30 | * |
| 24 | 31 | * It gives access to object instances (services). |
| @@ -25,42 +32,36 @@ | ||
| 25 | 32 | * Services and parameters are simple key/pair stores. |
| 26 | 33 | * The container can have four possible behaviors when a service |
| 27 | 34 | * does not exist (or is not initialized for the last case): |
| 28 | 35 | * |
| 29 | - * * EXCEPTION_ON_INVALID_REFERENCE: Throws an exception (the default) | |
| 36 | + * * EXCEPTION_ON_INVALID_REFERENCE: Throws an exception at compilation time (the default) | |
| 30 | 37 | * * NULL_ON_INVALID_REFERENCE: Returns null |
| 31 | 38 | * * IGNORE_ON_INVALID_REFERENCE: Ignores the wrapping command asking for the reference |
| 32 | 39 | * (for instance, ignore a setter if the service does not exist) |
| 33 | 40 | * * IGNORE_ON_UNINITIALIZED_REFERENCE: Ignores/returns null for uninitialized services or invalid references |
| 41 | + * * RUNTIME_EXCEPTION_ON_INVALID_REFERENCE: Throws an exception at runtime | |
| 34 | 42 | * |
| 35 | 43 | * @author Fabien Potencier <[email protected]> |
| 36 | 44 | * @author Johannes M. Schmitt <[email protected]> |
| 37 | 45 | */ |
| 38 | -class Container implements \YoastSEO_Vendor\Symfony\Component\DependencyInjection\ResettableContainerInterface | |
| 46 | +class Container implements \YoastSEO_Vendor\Symfony\Component\DependencyInjection\ContainerInterface, \YoastSEO_Vendor\Symfony\Contracts\Service\ResetInterface | |
| 39 | 47 | { |
| 40 | 48 | protected $parameterBag; |
| 41 | 49 | protected $services = []; |
| 50 | + protected $privates = []; | |
| 42 | 51 | protected $fileMap = []; |
| 43 | 52 | protected $methodMap = []; |
| 53 | + protected $factories = []; | |
| 44 | 54 | protected $aliases = []; |
| 45 | 55 | protected $loading = []; |
| 46 | 56 | protected $resolving = []; |
| 47 | 57 | protected $syntheticIds = []; |
| 48 | - /** | |
| 49 | - * @internal | |
| 50 | - */ | |
| 51 | - protected $privates = []; | |
| 52 | - /** | |
| 53 | - * @internal | |
| 54 | - */ | |
| 55 | - protected $normalizedIds = []; | |
| 56 | - private $underscoreMap = ['_' => '', '.' => '_', '\\' => '_']; | |
| 57 | 58 | private $envCache = []; |
| 58 | 59 | private $compiled = \false; |
| 59 | 60 | private $getEnv; |
| 60 | - public function __construct(\YoastSEO_Vendor\Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface $parameterBag = null) | |
| 61 | + public function __construct(?\YoastSEO_Vendor\Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface $parameterBag = null) | |
| 61 | 62 | { |
| 62 | - $this->parameterBag = $parameterBag ?: new \YoastSEO_Vendor\Symfony\Component\DependencyInjection\ParameterBag\EnvPlaceholderParameterBag(); | |
| 63 | + $this->parameterBag = $parameterBag ?? new \YoastSEO_Vendor\Symfony\Component\DependencyInjection\ParameterBag\EnvPlaceholderParameterBag(); | |
| 63 | 64 | } |
| 64 | 65 | /** |
| 65 | 66 | * Compiles the container. |
| 66 | 67 | * |
| @@ -84,23 +85,11 @@ | ||
| 84 | 85 | { |
| 85 | 86 | return $this->compiled; |
| 86 | 87 | } |
| 87 | 88 | /** |
| 88 | - * Returns true if the container parameter bag are frozen. | |
| 89 | - * | |
| 90 | - * @deprecated since version 3.3, to be removed in 4.0. | |
| 91 | - * | |
| 92 | - * @return bool true if the container parameter bag are frozen, false otherwise | |
| 93 | - */ | |
| 94 | - public function isFrozen() | |
| 95 | - { | |
| 96 | - @\trigger_error(\sprintf('The %s() method is deprecated since Symfony 3.3 and will be removed in 4.0. Use the isCompiled() method instead.', __METHOD__), \E_USER_DEPRECATED); | |
| 97 | - return $this->parameterBag instanceof \YoastSEO_Vendor\Symfony\Component\DependencyInjection\ParameterBag\FrozenParameterBag; | |
| 98 | - } | |
| 99 | - /** | |
| 100 | 89 | * Gets the service container parameter bag. |
| 101 | 90 | * |
| 102 | - * @return ParameterBagInterface A ParameterBagInterface instance | |
| 91 | + * @return ParameterBagInterface | |
| 103 | 92 | */ |
| 104 | 93 | public function getParameterBag() |
| 105 | 94 | { |
| 106 | 95 | return $this->parameterBag; |
| @@ -107,26 +96,20 @@ | ||
| 107 | 96 | } |
| 108 | 97 | /** |
| 109 | 98 | * Gets a parameter. |
| 110 | 99 | * |
| 111 | - * @param string $name The parameter name | |
| 100 | + * @return array|bool|string|int|float|\UnitEnum|null | |
| 112 | 101 | * |
| 113 | - * @return mixed The parameter value | |
| 114 | - * | |
| 115 | 102 | * @throws InvalidArgumentException if the parameter is not defined |
| 116 | 103 | */ |
| 117 | - public function getParameter($name) | |
| 104 | + public function getParameter(string $name) | |
| 118 | 105 | { |
| 119 | 106 | return $this->parameterBag->get($name); |
| 120 | 107 | } |
| 121 | 108 | /** |
| 122 | - * Checks if a parameter exists. | |
| 123 | - * | |
| 124 | - * @param string $name The parameter name | |
| 125 | - * | |
| 126 | - * @return bool The presence of parameter in container | |
| 109 | + * @return bool | |
| 127 | 110 | */ |
| 128 | - public function hasParameter($name) | |
| 111 | + public function hasParameter(string $name) | |
| 129 | 112 | { |
| 130 | 113 | return $this->parameterBag->has($name); |
| 131 | 114 | } |
| 132 | 115 | /** |
| @@ -131,12 +114,12 @@ | ||
| 131 | 114 | } |
| 132 | 115 | /** |
| 133 | 116 | * Sets a parameter. |
| 134 | 117 | * |
| 135 | - * @param string $name The parameter name | |
| 136 | - * @param mixed $value The parameter value | |
| 118 | + * @param string $name The parameter name | |
| 119 | + * @param array|bool|string|int|float|\UnitEnum|null $value The parameter value | |
| 137 | 120 | */ |
| 138 | - public function setParameter($name, $value) | |
| 121 | + public function setParameter(string $name, $value) | |
| 139 | 122 | { |
| 140 | 123 | $this->parameterBag->set($name, $value); |
| 141 | 124 | } |
| 142 | 125 | /** |
| @@ -143,13 +126,10 @@ | ||
| 143 | 126 | * Sets a service. |
| 144 | 127 | * |
| 145 | 128 | * Setting a synthetic service to null resets it: has() returns false and get() |
| 146 | 129 | * behaves in the same way as if the service was never created. |
| 147 | - * | |
| 148 | - * @param string $id The service identifier | |
| 149 | - * @param object|null $service The service instance | |
| 150 | 130 | */ |
| 151 | - public function set($id, $service) | |
| 131 | + public function set(string $id, ?object $service) | |
| 152 | 132 | { |
| 153 | 133 | // Runs the internal initializer; used by the dumped container to include always-needed files |
| 154 | 134 | if (isset($this->privates['service_container']) && $this->privates['service_container'] instanceof \Closure) { |
| 155 | 135 | $initialize = $this->privates['service_container']; |
| @@ -155,27 +135,21 @@ | ||
| 155 | 135 | $initialize = $this->privates['service_container']; |
| 156 | 136 | unset($this->privates['service_container']); |
| 157 | 137 | $initialize(); |
| 158 | 138 | } |
| 159 | - $id = $this->normalizeId($id); | |
| 160 | 139 | if ('service_container' === $id) { |
| 161 | 140 | throw new \YoastSEO_Vendor\Symfony\Component\DependencyInjection\Exception\InvalidArgumentException('You cannot set service "service_container".'); |
| 162 | 141 | } |
| 163 | - if (isset($this->privates[$id]) || !(isset($this->fileMap[$id]) || isset($this->methodMap[$id]))) { | |
| 164 | - if (!isset($this->privates[$id]) && !isset($this->getRemovedIds()[$id])) { | |
| 142 | + if (!(isset($this->fileMap[$id]) || isset($this->methodMap[$id]))) { | |
| 143 | + if (isset($this->syntheticIds[$id]) || !isset($this->getRemovedIds()[$id])) { | |
| 165 | 144 | // no-op |
| 166 | 145 | } elseif (null === $service) { |
| 167 | - @\trigger_error(\sprintf('The "%s" service is private, unsetting it is deprecated since Symfony 3.2 and will fail in 4.0.', $id), \E_USER_DEPRECATED); | |
| 168 | - unset($this->privates[$id]); | |
| 146 | + throw new \YoastSEO_Vendor\Symfony\Component\DependencyInjection\Exception\InvalidArgumentException(\sprintf('The "%s" service is private, you cannot unset it.', $id)); | |
| 169 | 147 | } else { |
| 170 | - @\trigger_error(\sprintf('The "%s" service is private, replacing it is deprecated since Symfony 3.2 and will fail in 4.0.', $id), \E_USER_DEPRECATED); | |
| 148 | + throw new \YoastSEO_Vendor\Symfony\Component\DependencyInjection\Exception\InvalidArgumentException(\sprintf('The "%s" service is private, you cannot replace it.', $id)); | |
| 171 | 149 | } |
| 172 | 150 | } elseif (isset($this->services[$id])) { |
| 173 | - if (null === $service) { | |
| 174 | - @\trigger_error(\sprintf('The "%s" service is already initialized, unsetting it is deprecated since Symfony 3.3 and will fail in 4.0.', $id), \E_USER_DEPRECATED); | |
| 175 | - } else { | |
| 176 | - @\trigger_error(\sprintf('The "%s" service is already initialized, replacing it is deprecated since Symfony 3.3 and will fail in 4.0.', $id), \E_USER_DEPRECATED); | |
| 177 | - } | |
| 151 | + throw new \YoastSEO_Vendor\Symfony\Component\DependencyInjection\Exception\InvalidArgumentException(\sprintf('The "%s" service is already initialized, you cannot replace it.', $id)); | |
| 178 | 152 | } |
| 179 | 153 | if (isset($this->aliases[$id])) { |
| 180 | 154 | unset($this->aliases[$id]); |
| 181 | 155 | } |
| @@ -189,52 +163,28 @@ | ||
| 189 | 163 | * Returns true if the given service is defined. |
| 190 | 164 | * |
| 191 | 165 | * @param string $id The service identifier |
| 192 | 166 | * |
| 193 | - * @return bool true if the service is defined, false otherwise | |
| 167 | + * @return bool | |
| 194 | 168 | */ |
| 195 | - public function has($id) | |
| 169 | + public function has(string $id) | |
| 196 | 170 | { |
| 197 | - for ($i = 2;;) { | |
| 198 | - if (isset($this->privates[$id])) { | |
| 199 | - @\trigger_error(\sprintf('The "%s" service is private, checking for its existence is deprecated since Symfony 3.2 and will fail in 4.0.', $id), \E_USER_DEPRECATED); | |
| 200 | - } | |
| 201 | - if (isset($this->aliases[$id])) { | |
| 202 | - $id = $this->aliases[$id]; | |
| 203 | - } | |
| 204 | - if (isset($this->services[$id])) { | |
| 205 | - return \true; | |
| 206 | - } | |
| 207 | - if ('service_container' === $id) { | |
| 208 | - return \true; | |
| 209 | - } | |
| 210 | - if (isset($this->fileMap[$id]) || isset($this->methodMap[$id])) { | |
| 211 | - return \true; | |
| 212 | - } | |
| 213 | - if (--$i && $id !== ($normalizedId = $this->normalizeId($id))) { | |
| 214 | - $id = $normalizedId; | |
| 215 | - continue; | |
| 216 | - } | |
| 217 | - // We only check the convention-based factory in a compiled container (i.e. a child class other than a ContainerBuilder, | |
| 218 | - // and only when the dumper has not generated the method map (otherwise the method map is considered to be fully populated by the dumper) | |
| 219 | - if (!$this->methodMap && !$this instanceof \YoastSEO_Vendor\Symfony\Component\DependencyInjection\ContainerBuilder && __CLASS__ !== static::class && \method_exists($this, 'get' . \strtr($id, $this->underscoreMap) . 'Service')) { | |
| 220 | - @\trigger_error('Generating a dumped container without populating the method map is deprecated since Symfony 3.2 and will be unsupported in 4.0. Update your dumper to generate the method map.', \E_USER_DEPRECATED); | |
| 221 | - return \true; | |
| 222 | - } | |
| 223 | - return \false; | |
| 171 | + if (isset($this->aliases[$id])) { | |
| 172 | + $id = $this->aliases[$id]; | |
| 224 | 173 | } |
| 174 | + if (isset($this->services[$id])) { | |
| 175 | + return \true; | |
| 176 | + } | |
| 177 | + if ('service_container' === $id) { | |
| 178 | + return \true; | |
| 179 | + } | |
| 180 | + return isset($this->fileMap[$id]) || isset($this->methodMap[$id]); | |
| 225 | 181 | } |
| 226 | 182 | /** |
| 227 | 183 | * Gets a service. |
| 228 | 184 | * |
| 229 | - * If a service is defined both through a set() method and | |
| 230 | - * with a get{$id}Service() method, the former has always precedence. | |
| 185 | + * @return object|null | |
| 231 | 186 | * |
| 232 | - * @param string $id The service identifier | |
| 233 | - * @param int $invalidBehavior The behavior when the service does not exist | |
| 234 | - * | |
| 235 | - * @return object|null The associated service | |
| 236 | - * | |
| 237 | 187 | * @throws ServiceCircularReferenceException When a circular reference is detected |
| 238 | 188 | * @throws ServiceNotFoundException When the service is not defined |
| 239 | 189 | * @throws \Exception if an exception has been thrown when the service has been resolved |
| 240 | 190 | * |
| @@ -239,54 +189,34 @@ | ||
| 239 | 189 | * @throws \Exception if an exception has been thrown when the service has been resolved |
| 240 | 190 | * |
| 241 | 191 | * @see Reference |
| 242 | 192 | */ |
| 243 | - public function get($id, $invalidBehavior = 1) | |
| 193 | + public function get(string $id, int $invalidBehavior = 1) | |
| 244 | 194 | { |
| 245 | - // Attempt to retrieve the service by checking first aliases then | |
| 246 | - // available services. Service IDs are case insensitive, however since | |
| 247 | - // this method can be called thousands of times during a request, avoid | |
| 248 | - // calling $this->normalizeId($id) unless necessary. | |
| 249 | - for ($i = 2;;) { | |
| 250 | - if (isset($this->privates[$id])) { | |
| 251 | - @\trigger_error(\sprintf('The "%s" service is private, getting it from the container is deprecated since Symfony 3.2 and will fail in 4.0. You should either make the service public, or stop using the container directly and use dependency injection instead.', $id), \E_USER_DEPRECATED); | |
| 195 | + return $this->services[$id] ?? $this->services[$id = $this->aliases[$id] ?? $id] ?? ('service_container' === $id ? $this : ($this->factories[$id] ?? [$this, 'make'])($id, $invalidBehavior)); | |
| 196 | + } | |
| 197 | + /** | |
| 198 | + * Creates a service. | |
| 199 | + * | |
| 200 | + * As a separate method to allow "get()" to use the really fast `??` operator. | |
| 201 | + */ | |
| 202 | + private function make(string $id, int $invalidBehavior) | |
| 203 | + { | |
| 204 | + if (isset($this->loading[$id])) { | |
| 205 | + throw new \YoastSEO_Vendor\Symfony\Component\DependencyInjection\Exception\ServiceCircularReferenceException($id, \array_merge(\array_keys($this->loading), [$id])); | |
| 206 | + } | |
| 207 | + $this->loading[$id] = \true; | |
| 208 | + try { | |
| 209 | + if (isset($this->fileMap[$id])) { | |
| 210 | + return 4 === $invalidBehavior ? null : $this->load($this->fileMap[$id]); | |
| 211 | + } elseif (isset($this->methodMap[$id])) { | |
| 212 | + return 4 === $invalidBehavior ? null : $this->{$this->methodMap[$id]}(); | |
| 252 | 213 | } |
| 253 | - if (isset($this->aliases[$id])) { | |
| 254 | - $id = $this->aliases[$id]; | |
| 255 | - } | |
| 256 | - // Re-use shared service instance if it exists. | |
| 257 | - if (isset($this->services[$id])) { | |
| 258 | - return $this->services[$id]; | |
| 259 | - } | |
| 260 | - if ('service_container' === $id) { | |
| 261 | - return $this; | |
| 262 | - } | |
| 263 | - if (isset($this->loading[$id])) { | |
| 264 | - throw new \YoastSEO_Vendor\Symfony\Component\DependencyInjection\Exception\ServiceCircularReferenceException($id, \array_merge(\array_keys($this->loading), [$id])); | |
| 265 | - } | |
| 266 | - $this->loading[$id] = \true; | |
| 267 | - try { | |
| 268 | - if (isset($this->fileMap[$id])) { | |
| 269 | - return 4 === $invalidBehavior ? null : $this->load($this->fileMap[$id]); | |
| 270 | - } elseif (isset($this->methodMap[$id])) { | |
| 271 | - return 4 === $invalidBehavior ? null : $this->{$this->methodMap[$id]}(); | |
| 272 | - } elseif (--$i && $id !== ($normalizedId = $this->normalizeId($id))) { | |
| 273 | - unset($this->loading[$id]); | |
| 274 | - $id = $normalizedId; | |
| 275 | - continue; | |
| 276 | - } elseif (!$this->methodMap && !$this instanceof \YoastSEO_Vendor\Symfony\Component\DependencyInjection\ContainerBuilder && __CLASS__ !== static::class && \method_exists($this, $method = 'get' . \strtr($id, $this->underscoreMap) . 'Service')) { | |
| 277 | - // We only check the convention-based factory in a compiled container (i.e. a child class other than a ContainerBuilder, | |
| 278 | - // and only when the dumper has not generated the method map (otherwise the method map is considered to be fully populated by the dumper) | |
| 279 | - @\trigger_error('Generating a dumped container without populating the method map is deprecated since Symfony 3.2 and will be unsupported in 4.0. Update your dumper to generate the method map.', \E_USER_DEPRECATED); | |
| 280 | - return 4 === $invalidBehavior ? null : $this->{$method}(); | |
| 281 | - } | |
| 282 | - break; | |
| 283 | - } catch (\Exception $e) { | |
| 284 | - unset($this->services[$id]); | |
| 285 | - throw $e; | |
| 286 | - } finally { | |
| 287 | - unset($this->loading[$id]); | |
| 288 | - } | |
| 214 | + } catch (\Exception $e) { | |
| 215 | + unset($this->services[$id]); | |
| 216 | + throw $e; | |
| 217 | + } finally { | |
| 218 | + unset($this->loading[$id]); | |
| 289 | 219 | } |
| 290 | 220 | if (1 === $invalidBehavior) { |
| 291 | 221 | if (!$id) { |
| 292 | 222 | throw new \YoastSEO_Vendor\Symfony\Component\DependencyInjection\Exception\ServiceNotFoundException($id); |
| @@ -298,29 +228,27 @@ | ||
| 298 | 228 | throw new \YoastSEO_Vendor\Symfony\Component\DependencyInjection\Exception\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)); |
| 299 | 229 | } |
| 300 | 230 | $alternatives = []; |
| 301 | 231 | foreach ($this->getServiceIds() as $knownId) { |
| 232 | + if ('' === $knownId || '.' === $knownId[0]) { | |
| 233 | + continue; | |
| 234 | + } | |
| 302 | 235 | $lev = \levenshtein($id, $knownId); |
| 303 | - if ($lev <= \strlen($id) / 3 || \false !== \strpos($knownId, $id)) { | |
| 236 | + if ($lev <= \strlen($id) / 3 || \str_contains($knownId, $id)) { | |
| 304 | 237 | $alternatives[] = $knownId; |
| 305 | 238 | } |
| 306 | 239 | } |
| 307 | 240 | throw new \YoastSEO_Vendor\Symfony\Component\DependencyInjection\Exception\ServiceNotFoundException($id, null, null, $alternatives); |
| 308 | 241 | } |
| 242 | + return null; | |
| 309 | 243 | } |
| 310 | 244 | /** |
| 311 | 245 | * Returns true if the given service has actually been initialized. |
| 312 | 246 | * |
| 313 | - * @param string $id The service identifier | |
| 314 | - * | |
| 315 | - * @return bool true if service has already been initialized, false otherwise | |
| 247 | + * @return bool | |
| 316 | 248 | */ |
| 317 | - public function initialized($id) | |
| 249 | + public function initialized(string $id) | |
| 318 | 250 | { |
| 319 | - $id = $this->normalizeId($id); | |
| 320 | - if (isset($this->privates[$id])) { | |
| 321 | - @\trigger_error(\sprintf('Checking for the initialization of the "%s" private service is deprecated since Symfony 3.4 and won\'t be supported anymore in Symfony 4.0.', $id), \E_USER_DEPRECATED); | |
| 322 | - } | |
| 323 | 251 | if (isset($this->aliases[$id])) { |
| 324 | 252 | $id = $this->aliases[$id]; |
| 325 | 253 | } |
| 326 | 254 | if ('service_container' === $id) { |
| @@ -332,30 +260,28 @@ | ||
| 332 | 260 | * {@inheritdoc} |
| 333 | 261 | */ |
| 334 | 262 | public function reset() |
| 335 | 263 | { |
| 336 | - $this->services = []; | |
| 264 | + $services = $this->services + $this->privates; | |
| 265 | + foreach ($services as $service) { | |
| 266 | + try { | |
| 267 | + if ($service instanceof \YoastSEO_Vendor\Symfony\Contracts\Service\ResetInterface) { | |
| 268 | + $service->reset(); | |
| 269 | + } | |
| 270 | + } catch (\Throwable $e) { | |
| 271 | + continue; | |
| 272 | + } | |
| 273 | + } | |
| 274 | + $this->services = $this->factories = $this->privates = []; | |
| 337 | 275 | } |
| 338 | 276 | /** |
| 339 | 277 | * Gets all service ids. |
| 340 | 278 | * |
| 341 | - * @return string[] An array of all defined service ids | |
| 279 | + * @return string[] | |
| 342 | 280 | */ |
| 343 | 281 | public function getServiceIds() |
| 344 | 282 | { |
| 345 | - $ids = []; | |
| 346 | - if (!$this->methodMap && !$this instanceof \YoastSEO_Vendor\Symfony\Component\DependencyInjection\ContainerBuilder && __CLASS__ !== static::class) { | |
| 347 | - // We only check the convention-based factory in a compiled container (i.e. a child class other than a ContainerBuilder, | |
| 348 | - // and only when the dumper has not generated the method map (otherwise the method map is considered to be fully populated by the dumper) | |
| 349 | - @\trigger_error('Generating a dumped container without populating the method map is deprecated since Symfony 3.2 and will be unsupported in 4.0. Update your dumper to generate the method map.', \E_USER_DEPRECATED); | |
| 350 | - foreach (\get_class_methods($this) as $method) { | |
| 351 | - if (\preg_match('/^get(.+)Service$/', $method, $match)) { | |
| 352 | - $ids[] = self::underscore($match[1]); | |
| 353 | - } | |
| 354 | - } | |
| 355 | - } | |
| 356 | - $ids[] = 'service_container'; | |
| 357 | - return \array_map('strval', \array_unique(\array_merge($ids, \array_keys($this->methodMap), \array_keys($this->fileMap), \array_keys($this->aliases), \array_keys($this->services)))); | |
| 283 | + 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)))); | |
| 358 | 284 | } |
| 359 | 285 | /** |
| 360 | 286 | * Gets service ids that existed at compile time. |
| 361 | 287 | * |
| @@ -367,13 +293,11 @@ | ||
| 367 | 293 | } |
| 368 | 294 | /** |
| 369 | 295 | * Camelizes a string. |
| 370 | 296 | * |
| 371 | - * @param string $id A string to camelize | |
| 372 | - * | |
| 373 | - * @return string The camelized string | |
| 297 | + * @return string | |
| 374 | 298 | */ |
| 375 | - public static function camelize($id) | |
| 299 | + public static function camelize(string $id) | |
| 376 | 300 | { |
| 377 | 301 | return \strtr(\ucwords(\strtr($id, ['_' => ' ', '.' => '_ ', '\\' => '_ '])), [' ' => '']); |
| 378 | 302 | } |
| 379 | 303 | /** |
| @@ -378,13 +302,11 @@ | ||
| 378 | 302 | } |
| 379 | 303 | /** |
| 380 | 304 | * A string to underscore. |
| 381 | 305 | * |
| 382 | - * @param string $id The string to underscore | |
| 383 | - * | |
| 384 | - * @return string The underscored string | |
| 306 | + * @return string | |
| 385 | 307 | */ |
| 386 | - public static function underscore($id) | |
| 308 | + public static function underscore(string $id) | |
| 387 | 309 | { |
| 388 | 310 | return \strtolower(\preg_replace(['/([A-Z]+)([A-Z][a-z])/', '/([a-z\\d])([A-Z])/'], ['\\1_\\2', '\\1_\\2'], \str_replace('_', '.', $id))); |
| 389 | 311 | } |
| 390 | 312 | /** |
| @@ -389,9 +311,9 @@ | ||
| 389 | 311 | } |
| 390 | 312 | /** |
| 391 | 313 | * Creates a service by requiring its factory file. |
| 392 | 314 | */ |
| 393 | - protected function load($file) | |
| 315 | + protected function load(string $file) | |
| 394 | 316 | { |
| 395 | 317 | return require $file; |
| 396 | 318 | } |
| 397 | 319 | /** |
| @@ -396,15 +318,13 @@ | ||
| 396 | 318 | } |
| 397 | 319 | /** |
| 398 | 320 | * Fetches a variable from the environment. |
| 399 | 321 | * |
| 400 | - * @param string $name The name of the environment variable | |
| 322 | + * @return mixed | |
| 401 | 323 | * |
| 402 | - * @return mixed The value to use for the provided environment variable name | |
| 403 | - * | |
| 404 | 324 | * @throws EnvNotFoundException When the environment variable is not found and has no default value |
| 405 | 325 | */ |
| 406 | - protected function getEnv($name) | |
| 326 | + protected function getEnv(string $name) | |
| 407 | 327 | { |
| 408 | 328 | if (isset($this->resolving[$envName = "env({$name})"])) { |
| 409 | 329 | throw new \YoastSEO_Vendor\Symfony\Component\DependencyInjection\Exception\ParameterCircularReferenceException(\array_keys($this->resolving)); |
| 410 | 330 | } |
| @@ -414,11 +334,9 @@ | ||
| 414 | 334 | if (!$this->has($id = 'container.env_var_processors_locator')) { |
| 415 | 335 | $this->set($id, new \YoastSEO_Vendor\Symfony\Component\DependencyInjection\ServiceLocator([])); |
| 416 | 336 | } |
| 417 | 337 | if (!$this->getEnv) { |
| 418 | - $this->getEnv = new \ReflectionMethod($this, __FUNCTION__); | |
| 419 | - $this->getEnv->setAccessible(\true); | |
| 420 | - $this->getEnv = $this->getEnv->getClosure($this); | |
| 338 | + $this->getEnv = \Closure::fromCallable([$this, 'getEnv']); | |
| 421 | 339 | } |
| 422 | 340 | $processors = $this->get($id); |
| 423 | 341 | if (\false !== ($i = \strpos($name, ':'))) { |
| 424 | 342 | $prefix = \substr($name, 0, $i); |
| @@ -427,8 +345,11 @@ | ||
| 427 | 345 | $prefix = 'string'; |
| 428 | 346 | $localName = $name; |
| 429 | 347 | } |
| 430 | 348 | $processor = $processors->has($prefix) ? $processors->get($prefix) : new \YoastSEO_Vendor\Symfony\Component\DependencyInjection\EnvVarProcessor($this); |
| 349 | + if (\false === $i) { | |
| 350 | + $prefix = ''; | |
| 351 | + } | |
| 431 | 352 | $this->resolving[$envName] = \true; |
| 432 | 353 | try { |
| 433 | 354 | return $this->envCache[$name] = $processor->getEnv($prefix, $localName, $this->getEnv); |
| 434 | 355 | } finally { |
| @@ -435,30 +356,33 @@ | ||
| 435 | 356 | unset($this->resolving[$envName]); |
| 436 | 357 | } |
| 437 | 358 | } |
| 438 | 359 | /** |
| 439 | - * Returns the case sensitive id used at registration time. | |
| 360 | + * @param string|false $registry | |
| 361 | + * @param string|bool $load | |
| 440 | 362 | * |
| 441 | - * @param string $id | |
| 363 | + * @return mixed | |
| 442 | 364 | * |
| 443 | - * @return string | |
| 444 | - * | |
| 445 | 365 | * @internal |
| 446 | 366 | */ |
| 447 | - public function normalizeId($id) | |
| 367 | + protected final function getService($registry, string $id, ?string $method, $load) | |
| 448 | 368 | { |
| 449 | - if (!\is_string($id)) { | |
| 450 | - $id = (string) $id; | |
| 369 | + if ('service_container' === $id) { | |
| 370 | + return $this; | |
| 451 | 371 | } |
| 452 | - if (isset($this->normalizedIds[$normalizedId = \strtolower($id)])) { | |
| 453 | - $normalizedId = $this->normalizedIds[$normalizedId]; | |
| 454 | - if ($id !== $normalizedId) { | |
| 455 | - @\trigger_error(\sprintf('Service identifiers will be made case sensitive in Symfony 4.0. Using "%s" instead of "%s" is deprecated since Symfony 3.3.', $id, $normalizedId), \E_USER_DEPRECATED); | |
| 456 | - } | |
| 457 | - } else { | |
| 458 | - $normalizedId = $this->normalizedIds[$normalizedId] = $id; | |
| 372 | + if (\is_string($load)) { | |
| 373 | + throw new \YoastSEO_Vendor\Symfony\Component\DependencyInjection\Exception\RuntimeException($load); | |
| 459 | 374 | } |
| 460 | - return $normalizedId; | |
| 375 | + if (null === $method) { | |
| 376 | + return \false !== $registry ? $this->{$registry}[$id] ?? null : null; | |
| 377 | + } | |
| 378 | + if (\false !== $registry) { | |
| 379 | + return $this->{$registry}[$id] ?? ($this->{$registry}[$id] = $load ? $this->load($method) : $this->{$method}()); | |
| 380 | + } | |
| 381 | + if (!$load) { | |
| 382 | + return $this->{$method}(); | |
| 383 | + } | |
| 384 | + return ($factory = $this->factories[$id] ?? $this->factories['service_container'][$id] ?? null) ? $factory() : $this->load($method); | |
| 461 | 385 | } |
| 462 | 386 | private function __clone() |
| 463 | 387 | { |
| 464 | 388 | } |