* * This source file is subject to the MIT license that is bundled * with this source code in the file LICENSE. */ /** * The TemplateGuesser class handles the guessing of template name based on controller * * @author Fabien Potencier */ class TemplateGuesser { /** * @var Symfony\Component\HttpKernel\KernelInterface */ protected $kernel; /** * Constructor. * * @param KernelInterface $kernel A KernelInterface instance */ public function __construct(KernelInterface $kernel) { $this->kernel = $kernel; } /** * Guesses and returns the template name to render based on the controller * and action names. * * @param array $controller An array storing the controller object and action method * @param Request $request A Request instance * @param string $engine * @return TemplateReference template reference * @throws \InvalidArgumentException */ public function guessTemplateName($controller, Request $request, $engine = 'twig') { $className = class_exists('Doctrine\Common\Util\ClassUtils') ? ClassUtils::getClass($controller[0]) : get_class($controller[0]); if (!preg_match('/Controller\\\(.+)Controller$/', $className, $matchController)) { throw new \InvalidArgumentException(sprintf('The "%s" class does not look like a controller class (it must be in a "Controller" sub-namespace and the class name must end with "Controller")', get_class($controller[0]))); } if (!preg_match('/^(.+)Action$/', $controller[1], $matchAction)) { throw new \InvalidArgumentException(sprintf('The "%s" method does not look like an action method (it does not end with Action)', $controller[1])); } $bundle = $this->getBundleForClass($className); return new TemplateReference($bundle->getName(), $matchController[1], $matchAction[1], $request->getRequestFormat(), $engine); } /** * Returns the Bundle instance in which the given class name is located. * * @param string $class A fully qualified controller class name * @param Bundle $bundle A Bundle instance * @throws \InvalidArgumentException */ protected function getBundleForClass($class) { $reflectionClass = new \ReflectionClass($class); $bundles = $this->kernel->getBundles(); do { $namespace = $reflectionClass->getNamespaceName(); foreach ($bundles as $bundle) { if (0 === strpos($namespace, $bundle->getNamespace())) { return $bundle; } } $reflectionClass = $reflectionClass->getParentClass(); } while ($reflectionClass); throw new \InvalidArgumentException(sprintf('The "%s" class does not belong to a registered bundle.', $class)); } }