Argument
2 years ago
Attribute
2 years ago
Exception
2 years ago
ParameterBag
3 years ago
Alias.php
4 years ago
ChildDefinition.php
4 years ago
Container.php
2 years ago
ContainerAwareInterface.php
2 years ago
ContainerAwareTrait.php
2 years ago
ContainerBuilder.php
2 years ago
ContainerInterface.php
4 years ago
Definition.php
2 years ago
EnvVarLoaderInterface.php
4 years ago
EnvVarProcessor.php
2 years ago
EnvVarProcessorInterface.php
4 years ago
ExpressionLanguage.php
2 years ago
ExpressionLanguageProvider.php
2 years ago
Parameter.php
4 years ago
Reference.php
4 years ago
ReverseContainer.php
2 years ago
ServiceLocator.php
2 years ago
TaggedContainerInterface.php
4 years ago
TypedReference.php
2 years ago
Variable.php
4 years ago
index.php
3 years ago
Container.php
254 lines
| 1 | <?php |
| 2 | namespace MailPoetVendor\Symfony\Component\DependencyInjection; |
| 3 | if (!defined('ABSPATH')) exit; |
| 4 | use MailPoetVendor\Symfony\Component\DependencyInjection\Argument\RewindableGenerator; |
| 5 | use MailPoetVendor\Symfony\Component\DependencyInjection\Argument\ServiceLocator as ArgumentServiceLocator; |
| 6 | use MailPoetVendor\Symfony\Component\DependencyInjection\Exception\EnvNotFoundException; |
| 7 | use MailPoetVendor\Symfony\Component\DependencyInjection\Exception\InvalidArgumentException; |
| 8 | use MailPoetVendor\Symfony\Component\DependencyInjection\Exception\ParameterCircularReferenceException; |
| 9 | use MailPoetVendor\Symfony\Component\DependencyInjection\Exception\RuntimeException; |
| 10 | use MailPoetVendor\Symfony\Component\DependencyInjection\Exception\ServiceCircularReferenceException; |
| 11 | use MailPoetVendor\Symfony\Component\DependencyInjection\Exception\ServiceNotFoundException; |
| 12 | use MailPoetVendor\Symfony\Component\DependencyInjection\ParameterBag\EnvPlaceholderParameterBag; |
| 13 | use MailPoetVendor\Symfony\Component\DependencyInjection\ParameterBag\FrozenParameterBag; |
| 14 | use MailPoetVendor\Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface; |
| 15 | use MailPoetVendor\Symfony\Contracts\Service\ResetInterface; |
| 16 | // Help opcache.preload discover always-needed symbols |
| 17 | \class_exists(RewindableGenerator::class); |
| 18 | \class_exists(ArgumentServiceLocator::class); |
| 19 | class Container implements ContainerInterface, ResetInterface |
| 20 | { |
| 21 | protected $parameterBag; |
| 22 | protected $services = []; |
| 23 | protected $privates = []; |
| 24 | protected $fileMap = []; |
| 25 | protected $methodMap = []; |
| 26 | protected $factories = []; |
| 27 | protected $aliases = []; |
| 28 | protected $loading = []; |
| 29 | protected $resolving = []; |
| 30 | protected $syntheticIds = []; |
| 31 | private $envCache = []; |
| 32 | private $compiled = \false; |
| 33 | private $getEnv; |
| 34 | public function __construct(?ParameterBagInterface $parameterBag = null) |
| 35 | { |
| 36 | $this->parameterBag = $parameterBag ?? new EnvPlaceholderParameterBag(); |
| 37 | } |
| 38 | public function compile() |
| 39 | { |
| 40 | $this->parameterBag->resolve(); |
| 41 | $this->parameterBag = new FrozenParameterBag($this->parameterBag->all()); |
| 42 | $this->compiled = \true; |
| 43 | } |
| 44 | public function isCompiled() |
| 45 | { |
| 46 | return $this->compiled; |
| 47 | } |
| 48 | public function getParameterBag() |
| 49 | { |
| 50 | return $this->parameterBag; |
| 51 | } |
| 52 | public function getParameter(string $name) |
| 53 | { |
| 54 | return $this->parameterBag->get($name); |
| 55 | } |
| 56 | public function hasParameter(string $name) |
| 57 | { |
| 58 | return $this->parameterBag->has($name); |
| 59 | } |
| 60 | public function setParameter(string $name, $value) |
| 61 | { |
| 62 | $this->parameterBag->set($name, $value); |
| 63 | } |
| 64 | public function set(string $id, ?object $service) |
| 65 | { |
| 66 | // Runs the internal initializer; used by the dumped container to include always-needed files |
| 67 | if (isset($this->privates['service_container']) && $this->privates['service_container'] instanceof \Closure) { |
| 68 | $initialize = $this->privates['service_container']; |
| 69 | unset($this->privates['service_container']); |
| 70 | $initialize(); |
| 71 | } |
| 72 | if ('service_container' === $id) { |
| 73 | throw new InvalidArgumentException('You cannot set service "service_container".'); |
| 74 | } |
| 75 | if (!(isset($this->fileMap[$id]) || isset($this->methodMap[$id]))) { |
| 76 | if (isset($this->syntheticIds[$id]) || !isset($this->getRemovedIds()[$id])) { |
| 77 | // no-op |
| 78 | } elseif (null === $service) { |
| 79 | throw new InvalidArgumentException(\sprintf('The "%s" service is private, you cannot unset it.', $id)); |
| 80 | } else { |
| 81 | throw new InvalidArgumentException(\sprintf('The "%s" service is private, you cannot replace it.', $id)); |
| 82 | } |
| 83 | } elseif (isset($this->services[$id])) { |
| 84 | throw new InvalidArgumentException(\sprintf('The "%s" service is already initialized, you cannot replace it.', $id)); |
| 85 | } |
| 86 | if (isset($this->aliases[$id])) { |
| 87 | unset($this->aliases[$id]); |
| 88 | } |
| 89 | if (null === $service) { |
| 90 | unset($this->services[$id]); |
| 91 | return; |
| 92 | } |
| 93 | $this->services[$id] = $service; |
| 94 | } |
| 95 | public function has(string $id) |
| 96 | { |
| 97 | if (isset($this->aliases[$id])) { |
| 98 | $id = $this->aliases[$id]; |
| 99 | } |
| 100 | if (isset($this->services[$id])) { |
| 101 | return \true; |
| 102 | } |
| 103 | if ('service_container' === $id) { |
| 104 | return \true; |
| 105 | } |
| 106 | return isset($this->fileMap[$id]) || isset($this->methodMap[$id]); |
| 107 | } |
| 108 | public function get(string $id, int $invalidBehavior = 1) |
| 109 | { |
| 110 | return $this->services[$id] ?? $this->services[$id = $this->aliases[$id] ?? $id] ?? ('service_container' === $id ? $this : ($this->factories[$id] ?? [$this, 'make'])($id, $invalidBehavior)); |
| 111 | } |
| 112 | private function make(string $id, int $invalidBehavior) |
| 113 | { |
| 114 | if (isset($this->loading[$id])) { |
| 115 | throw new ServiceCircularReferenceException($id, \array_merge(\array_keys($this->loading), [$id])); |
| 116 | } |
| 117 | $this->loading[$id] = \true; |
| 118 | try { |
| 119 | if (isset($this->fileMap[$id])) { |
| 120 | return 4 === $invalidBehavior ? null : $this->load($this->fileMap[$id]); |
| 121 | } elseif (isset($this->methodMap[$id])) { |
| 122 | return 4 === $invalidBehavior ? null : $this->{$this->methodMap[$id]}(); |
| 123 | } |
| 124 | } catch (\Exception $e) { |
| 125 | unset($this->services[$id]); |
| 126 | throw $e; |
| 127 | } finally { |
| 128 | unset($this->loading[$id]); |
| 129 | } |
| 130 | if (1 === $invalidBehavior) { |
| 131 | if (!$id) { |
| 132 | throw new ServiceNotFoundException($id); |
| 133 | } |
| 134 | if (isset($this->syntheticIds[$id])) { |
| 135 | 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)); |
| 136 | } |
| 137 | if (isset($this->getRemovedIds()[$id])) { |
| 138 | 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)); |
| 139 | } |
| 140 | $alternatives = []; |
| 141 | foreach ($this->getServiceIds() as $knownId) { |
| 142 | if ('' === $knownId || '.' === $knownId[0]) { |
| 143 | continue; |
| 144 | } |
| 145 | $lev = \levenshtein($id, $knownId); |
| 146 | if ($lev <= \strlen($id) / 3 || \str_contains($knownId, $id)) { |
| 147 | $alternatives[] = $knownId; |
| 148 | } |
| 149 | } |
| 150 | throw new ServiceNotFoundException($id, null, null, $alternatives); |
| 151 | } |
| 152 | return null; |
| 153 | } |
| 154 | public function initialized(string $id) |
| 155 | { |
| 156 | if (isset($this->aliases[$id])) { |
| 157 | $id = $this->aliases[$id]; |
| 158 | } |
| 159 | if ('service_container' === $id) { |
| 160 | return \false; |
| 161 | } |
| 162 | return isset($this->services[$id]); |
| 163 | } |
| 164 | public function reset() |
| 165 | { |
| 166 | $services = $this->services + $this->privates; |
| 167 | $this->services = $this->factories = $this->privates = []; |
| 168 | foreach ($services as $service) { |
| 169 | try { |
| 170 | if ($service instanceof ResetInterface) { |
| 171 | $service->reset(); |
| 172 | } |
| 173 | } catch (\Throwable $e) { |
| 174 | continue; |
| 175 | } |
| 176 | } |
| 177 | } |
| 178 | public function getServiceIds() |
| 179 | { |
| 180 | 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)))); |
| 181 | } |
| 182 | public function getRemovedIds() |
| 183 | { |
| 184 | return []; |
| 185 | } |
| 186 | public static function camelize(string $id) |
| 187 | { |
| 188 | return \strtr(\ucwords(\strtr($id, ['_' => ' ', '.' => '_ ', '\\' => '_ '])), [' ' => '']); |
| 189 | } |
| 190 | public static function underscore(string $id) |
| 191 | { |
| 192 | return \strtolower(\preg_replace(['/([A-Z]+)([A-Z][a-z])/', '/([a-z\\d])([A-Z])/'], ['\\1_\\2', '\\1_\\2'], \str_replace('_', '.', $id))); |
| 193 | } |
| 194 | protected function load(string $file) |
| 195 | { |
| 196 | return require $file; |
| 197 | } |
| 198 | protected function getEnv(string $name) |
| 199 | { |
| 200 | if (isset($this->resolving[$envName = "env({$name})"])) { |
| 201 | throw new ParameterCircularReferenceException(\array_keys($this->resolving)); |
| 202 | } |
| 203 | if (isset($this->envCache[$name]) || \array_key_exists($name, $this->envCache)) { |
| 204 | return $this->envCache[$name]; |
| 205 | } |
| 206 | if (!$this->has($id = 'container.env_var_processors_locator')) { |
| 207 | $this->set($id, new ServiceLocator([])); |
| 208 | } |
| 209 | if (!$this->getEnv) { |
| 210 | $this->getEnv = \Closure::fromCallable([$this, 'getEnv']); |
| 211 | } |
| 212 | $processors = $this->get($id); |
| 213 | if (\false !== ($i = \strpos($name, ':'))) { |
| 214 | $prefix = \substr($name, 0, $i); |
| 215 | $localName = \substr($name, 1 + $i); |
| 216 | } else { |
| 217 | $prefix = 'string'; |
| 218 | $localName = $name; |
| 219 | } |
| 220 | $processor = $processors->has($prefix) ? $processors->get($prefix) : new EnvVarProcessor($this); |
| 221 | if (\false === $i) { |
| 222 | $prefix = ''; |
| 223 | } |
| 224 | $this->resolving[$envName] = \true; |
| 225 | try { |
| 226 | return $this->envCache[$name] = $processor->getEnv($prefix, $localName, $this->getEnv); |
| 227 | } finally { |
| 228 | unset($this->resolving[$envName]); |
| 229 | } |
| 230 | } |
| 231 | protected final function getService($registry, string $id, ?string $method, $load) |
| 232 | { |
| 233 | if ('service_container' === $id) { |
| 234 | return $this; |
| 235 | } |
| 236 | if (\is_string($load)) { |
| 237 | throw new RuntimeException($load); |
| 238 | } |
| 239 | if (null === $method) { |
| 240 | return \false !== $registry ? $this->{$registry}[$id] ?? null : null; |
| 241 | } |
| 242 | if (\false !== $registry) { |
| 243 | return $this->{$registry}[$id] ?? ($this->{$registry}[$id] = $load ? $this->load($method) : $this->{$method}()); |
| 244 | } |
| 245 | if (!$load) { |
| 246 | return $this->{$method}(); |
| 247 | } |
| 248 | return ($factory = $this->factories[$id] ?? $this->factories['service_container'][$id] ?? null) ? $factory() : $this->load($method); |
| 249 | } |
| 250 | private function __clone() |
| 251 | { |
| 252 | } |
| 253 | } |
| 254 |