Skip to content

Instantly share code, notes, and snippets.

@steve-todorov
Last active December 10, 2017 16:37
Show Gist options
  • Select an option

  • Save steve-todorov/0797d3764f1ace60e8fff393365d947d to your computer and use it in GitHub Desktop.

Select an option

Save steve-todorov/0797d3764f1ace60e8fff393365d947d to your computer and use it in GitHub Desktop.

Readme

This is a camelCase version of the Sensio\Bundle\FrameworkExtraBundle\Templating\TemplateGuesser. Feel free to use and enhance.

<?php
namespace App\BaseBundle\Listener;
use Doctrine\Common\Util\ClassUtils;
use Sensio\Bundle\FrameworkExtraBundle\Templating\TemplateGuesser as BaseTemplateGuesser;
use Symfony\Bundle\FrameworkBundle\Templating\TemplateReference;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpKernel\KernelInterface;
/**
* https://github.com/sensiolabs/SensioFrameworkExtraBundle/issues/538
*
* The TemplateGuesser class handles the guessing of template name based on controller
*
* @author Fabien Potencier <fabien@symfony.com>
*/
class TemplateGuesser extends BaseTemplateGuesser
{
/**
* @var KernelInterface
*/
private $kernel;
/**
* @var string[]
*/
private $controllerPatterns;
/**
* @param string[] $controllerPatterns Regexps extracting the controller name from its FQN
*/
public function __construct(KernelInterface $kernel, array $controllerPatterns = array())
{
$controllerPatterns[] = '/Controller\\\(.+)Controller$/';
$this->kernel = $kernel;
$this->controllerPatterns = $controllerPatterns;
}
/**
* 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')
{
if (is_object($controller) && method_exists($controller, '__invoke')) {
$controller = array($controller, '__invoke');
} elseif (!is_array($controller)) {
throw new \InvalidArgumentException(sprintf('First argument of %s must be an array callable or an object defining the magic method __invoke. "%s" given.', __METHOD__, gettype($controller)));
}
$className = class_exists('Doctrine\Common\Util\ClassUtils') ? ClassUtils::getClass($controller[0]) : get_class($controller[0]);
$matchController = null;
foreach ($this->controllerPatterns as $pattern) {
if (preg_match($pattern, $className, $tempMatch)) {
$matchController = str_replace('\\', '/', ucwords($tempMatch[1]));
break;
}
}
if (null === $matchController) {
throw new \InvalidArgumentException(sprintf('The "%s" class does not look like a controller class (its FQN must match one of the following regexps: "%s")', get_class($controller[0]), implode('", "', $this->controllerPatterns)));
}
if ('__invoke' === $controller[1]) {
$matchAction = $matchController;
$matchController = null;
} else {
$matchAction = preg_replace('/Action$/', '', $controller[1]);
}
$matchAction = strtolower($matchAction);
$bundleName = $this->getBundleForClass($className);
$matchController = ucwords($matchController, '/');
$templateName = sprintf(($bundleName ? '@'.$bundleName.'/' : '').$matchController.($matchController ? '/' : '').$matchAction.'.'.$request->getRequestFormat().'.twig');
return $templateName;
}
/**
* Returns the bundle name in which the given class name is located.
*
* @param string $class A fully qualified controller class name
*
* @return string|null $bundle A bundle name
*/
private function getBundleForClass($class)
{
$reflectionClass = new \ReflectionClass($class);
$bundles = $this->kernel->getBundles();
do {
$namespace = $reflectionClass->getNamespaceName();
foreach ($bundles as $bundle) {
if ('Symfony\Bundle\FrameworkBundle' === $bundle->getNamespace()) {
continue;
}
if (0 === strpos($namespace, $bundle->getNamespace())) {
return preg_replace('/Bundle$/', '', $bundle->getName());
}
}
$reflectionClass = $reflectionClass->getParentClass();
} while ($reflectionClass);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment