* * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace PrestaShop\Module\PsAccounts\Vendor\Symfony\Component\DependencyInjection\Compiler; use PrestaShop\Module\PsAccounts\Vendor\Symfony\Component\DependencyInjection\Argument\ArgumentInterface; use PrestaShop\Module\PsAccounts\Vendor\Symfony\Component\DependencyInjection\ContainerBuilder; use PrestaShop\Module\PsAccounts\Vendor\Symfony\Component\DependencyInjection\Definition; use PrestaShop\Module\PsAccounts\Vendor\Symfony\Component\DependencyInjection\Exception\RuntimeException; use PrestaShop\Module\PsAccounts\Vendor\Symfony\Component\DependencyInjection\Reference; /** * @author Nicolas Grekas
*/ abstract class AbstractRecursivePass implements CompilerPassInterface { /** * @var ContainerBuilder */ protected $container; protected $currentId; /** * {@inheritdoc} */ public function process(ContainerBuilder $container) { $this->container = $container; try { $this->processValue($container->getDefinitions(), \true); } finally { $this->container = null; } } /** * 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 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 (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": ', $this->currentId) . \lcfirst($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": ', $this->currentId) . \sprintf($class !== $this->currentId ? 'constructor of class "%s"' : 'its constructor', $class) . ' must be public.'); } 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; } }