* * 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\RuntimeException; use 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 Definition $definition * @param bool $required * * @return \ReflectionFunctionAbstract|null * * @throws RuntimeException */ protected function getConstructor(Definition $definition, $required) { 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": %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 Definition $definition * @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; } } __halt_compiler();----SIGNATURE:----BZSVzChWmPT7fBVqokwFvFjvWnublkqWAWAh104CbZtPEPE0Zbcz//NgQtY6Fp3eRPuXr/37tifde6cgJLTGkBLXYhywGBD51sGHeqeMrq4/zipe9BxrdakmWZI5cAAtAus9/o6WieAjTvabvzwi39kbQD1jv/0v6Cc4U6k0c2PeZ3Jyj5Ub8SYqZtcZOb+SgG6KUoup5y9RuXCxK9VnyqiiIPqkifutpYmVgTjPU9aW3VwwBCCmW457RuUDJaIQyuzOnlOvacgaI0SF1MA8mVsoH5yRJnv5rgvJlFRajV/1BApmaBuOy2uC+MWKUUzXzMoKu1Iyv7q/HN6k1waUQcoqm1Wkahu2vOf+dcpSZxS3/5r7eSiecRSsG7TeTqWYtzorVi+L4o1kMfVgEcDS2ojhU5+hhlz4IdgOWHz7eHsu4SZn8tx6mnJ0KmQD4+VIQ1ZuVhP6ZzX6V9grwkSGZoz1TXL9rOuFKIL44gahOSQMq+77nBRSwWF0xYimrFvLCwyA2dNJ2G9vZVkfZ/5y+Nu5ndCb0LR8zOMb8EaU/MJDG3nOJxbeTAGgUj1gW7k+YIo3clYiHmhCluOXIyiz+gSCbP6Fcnj1KpfArvTeHCN8Y0NxsBIsN2xckasKwkWqGggBDXPYngGE6vVdvMFuOgC2onN7SncEKhgaH9AFwtk=----ATTACHMENT:----OTA0ODcxNzI3NDE4NTAzOSA0MzU4ODQ0NTU1MjQ2NjI2IDU3MzIzNjMyNTc4OTY5MTg=