diff --git a/src/Symfony/Bundle/WebProfilerBundle/Controller/ProfilerController.php b/src/Symfony/Bundle/WebProfilerBundle/Controller/ProfilerController.php index 7640e4d4bc..90bb1a431d 100644 --- a/src/Symfony/Bundle/WebProfilerBundle/Controller/ProfilerController.php +++ b/src/Symfony/Bundle/WebProfilerBundle/Controller/ProfilerController.php @@ -41,6 +41,7 @@ class ProfilerController extends ContainerAware $panel = $this->container->get('request')->query->get('panel', 'request'); $page = $this->container->get('request')->query->get('page', 'home'); + if (!$profile = $profiler->loadProfile($token)) { return $this->container->get('templating')->renderResponse('WebProfilerBundle:Profiler:info.html.twig', array('about' => 'no_token', 'token' => $token)); } @@ -49,13 +50,17 @@ class ProfilerController extends ContainerAware throw new NotFoundHttpException(sprintf('Panel "%s" is not available for token "%s".', $panel, $token)); } - return $this->container->get('templating')->renderResponse($this->getTemplateName($profile, $panel), array( + /** @var $templateManager \Symfony\Bundle\WebProfilerBundle\Profiler\Template */ + $templateManager = $this->container->get('web_profiler.profiler_template'); + $templateManager->setProfiler($profiler); + + return $this->container->get('templating')->renderResponse($templateManager->getName($profile, $panel), array( 'token' => $token, 'profile' => $profile, 'collector' => $profile->getCollector($panel), 'panel' => $panel, 'page' => $page, - 'templates' => $this->getTemplates($profile), + 'templates' => $templateManager->getTemplates($profile), 'is_ajax' => $request->isXmlHttpRequest(), )); } @@ -178,10 +183,14 @@ class ProfilerController extends ContainerAware // the profiler is not enabled } + /** @var $templateManager \Symfony\Bundle\WebProfilerBundle\Profiler\Template */ + $templateManager = $this->container->get('web_profiler.profiler_template'); + $templateManager->setProfiler($profiler); + return $this->container->get('templating')->renderResponse('WebProfilerBundle:Profiler:toolbar.html.twig', array( 'position' => $position, 'profile' => $profile, - 'templates' => $this->getTemplates($profile), + 'templates' => $templateManager->getTemplates($profile), 'profiler_url' => $url, 'verbose' => $this->container->get('web_profiler.debug_toolbar')->isVerbose() )); @@ -292,60 +301,4 @@ class ProfilerController extends ContainerAware ))); } - /** - * Gets template names of templates that are - * present in the viewed profile - * - * @param $profile - * @return array - * @throws \UnexpectedValueException - */ - protected function getTemplateNames($profile) - { - $templates = array(); - - foreach ($this->container->getParameter('data_collector.templates') as $arguments) { - if (null === $arguments) { - continue; - } - - list($name, $template) = $arguments; - if (!$profile->hasCollector($name)) { - continue; - } - - if ('.html.twig' === substr($template, -10)) { - $template = substr($template, 0, -10); - } - - if (!$this->container->get('templating')->exists($template.'.html.twig')) { - throw new \UnexpectedValueException(sprintf('The profiler template "%s.html.twig" for data collector "%s" does not exist.', $template, $name)); - } - - $templates[$name] = $template.'.html.twig'; - } - - return $templates; - } - - protected function getTemplateName($profile, $panel) - { - $templates = $this->getTemplateNames($profile); - - if (!isset($templates[$panel])) { - throw new NotFoundHttpException(sprintf('Panel "%s" is not registered.', $panel)); - } - - return $templates[$panel]; - } - - protected function getTemplates($profile) - { - $templates = $this->getTemplateNames($profile); - foreach ($templates as $name => $template) { - $templates[$name] = $this->container->get('twig')->loadTemplate($template); - } - - return $templates; - } } diff --git a/src/Symfony/Bundle/WebProfilerBundle/Profiler/Template.php b/src/Symfony/Bundle/WebProfilerBundle/Profiler/Template.php new file mode 100644 index 0000000000..ee0260633b --- /dev/null +++ b/src/Symfony/Bundle/WebProfilerBundle/Profiler/Template.php @@ -0,0 +1,133 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Bundle\WebProfilerBundle\Profiler; + +use Symfony\Component\HttpKernel\Exception\NotFoundHttpException; +use Symfony\Component\HttpKernel\Profiler\Profiler; +use Symfony\Component\HttpKernel\Profiler\Profile; +use Symfony\Bundle\TwigBundle\TwigEngine; + +/** + * ProfilerController. + * + * @author Fabien Potencier + * @author Artur Wielogórski + */ +class Template { + + /** + * @var \Symfony\Bundle\TwigBundle\TwigEngine + */ + public $templating; + + /** + * @var \Twig_Environment + */ + public $twig; + + /** + * @var array + */ + public $templates; + + /** + * @var \Symfony\Component\HttpKernel\Profiler\Profiler + */ + protected $profiler; + + /** + * @param \Symfony\Bundle\TwigBundle\TwigEngine $templating + * @param \Twig_Environment $twig + * @param array $templates + */ + public function __construct(TwigEngine $templating, \Twig_Environment $twig, array $templates) + { + $this->templating = $templating; + $this->twig = $twig; + $this->templates = $templates; + } + + /** + * @param \Symfony\Component\HttpKernel\Profiler\Profile $profile + * @param $panel + * @return mixed + * @throws \Symfony\Component\HttpKernel\Exception\NotFoundHttpException + */ + public function getName(Profile $profile, $panel) + { + $templates = $this->getNames($profile); + + if (!isset($templates[$panel])) { + throw new NotFoundHttpException(sprintf('Panel "%s" is not registered in profiler or is not present in viewed profile.', $panel)); + } + + return $templates[$panel]; + } + + /** + * @param \Symfony\Component\HttpKernel\Profiler\Profile $profile + * @return array + */ + public function getTemplates(Profile $profile) + { + $templates = $this->getNames($profile); + foreach ($templates as $name => $template) { + $templates[$name] = $this->twig->loadTemplate($template); + } + + return $templates; + } + + /** + * @param \Symfony\Component\HttpKernel\Profiler\Profiler $profiler + */ + public function setProfiler(Profiler $profiler) + { + $this->profiler = $profiler; + } + + /** + * Gets template names of templates that are + * present in the viewed profile + * @param \Symfony\Component\HttpKernel\Profiler\Profile $profile + * @return array + * @throws \UnexpectedValueException + */ + protected function getNames(Profile $profile) + { + $templates = array(); + + foreach ($this->templates as $arguments) { + if (null === $arguments) { + continue; + } + + list($name, $template) = $arguments; + + if (!$this->profiler->has($name) || !$profile->hasCollector($name)) { + continue; + } + + if ('.html.twig' === substr($template, -10)) { + $template = substr($template, 0, -10); + } + + if (!$this->templating->exists($template.'.html.twig')) { + throw new \UnexpectedValueException(sprintf('The profiler template "%s.html.twig" for data collector "%s" does not exist.', $template, $name)); + } + + $templates[$name] = $template.'.html.twig'; + } + + return $templates; + } +} \ No newline at end of file diff --git a/src/Symfony/Bundle/WebProfilerBundle/Resources/config/toolbar.xml b/src/Symfony/Bundle/WebProfilerBundle/Resources/config/toolbar.xml index 5ce61a0889..eca157f5a1 100644 --- a/src/Symfony/Bundle/WebProfilerBundle/Resources/config/toolbar.xml +++ b/src/Symfony/Bundle/WebProfilerBundle/Resources/config/toolbar.xml @@ -6,6 +6,7 @@ Symfony\Bundle\WebProfilerBundle\EventListener\WebDebugToolbarListener + Symfony\Bundle\WebProfilerBundle\Profiler\Template @@ -16,5 +17,11 @@ %web_profiler.debug_toolbar.mode% %web_profiler.debug_toolbar.position% + + + + + %data_collector.templates% + diff --git a/src/Symfony/Bundle/WebProfilerBundle/Tests/DependencyInjection/WebProfilerExtensionTest.php b/src/Symfony/Bundle/WebProfilerBundle/Tests/DependencyInjection/WebProfilerExtensionTest.php index 1d8e5c7cc7..db92a4b545 100644 --- a/src/Symfony/Bundle/WebProfilerBundle/Tests/DependencyInjection/WebProfilerExtensionTest.php +++ b/src/Symfony/Bundle/WebProfilerBundle/Tests/DependencyInjection/WebProfilerExtensionTest.php @@ -65,6 +65,7 @@ class WebProfilerExtensionTest extends TestCase $this->container->setParameter('kernel.cache_dir', __DIR__); $this->container->setParameter('kernel.debug', false); $this->container->setParameter('kernel.root_dir', __DIR__); + $this->container->setParameter('data_collector.templates', array()); $this->container->set('kernel', $this->kernel); } diff --git a/src/Symfony/Bundle/WebProfilerBundle/Tests/Profiler/TemplateTest.php b/src/Symfony/Bundle/WebProfilerBundle/Tests/Profiler/TemplateTest.php new file mode 100644 index 0000000000..514acc658b --- /dev/null +++ b/src/Symfony/Bundle/WebProfilerBundle/Tests/Profiler/TemplateTest.php @@ -0,0 +1,175 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Bundle\WebProfilerBundle\Tests\Profiler; + +use Symfony\Bundle\WebProfilerBundle\Tests\TestCase; +use Symfony\Bundle\WebProfilerBundle\Profiler\Template; + +/** + * Test for Template class. + * + * @author Artur Wielogórski + */ +class TemplateTest extends TestCase +{ + /** + * @var \Symfony\Bundle\TwigBundle\TwigEngine + */ + protected $twigEngine; + + /** + * @var \Twig_Environment + */ + protected $twigEnvironment; + + /** + * @var \Symfony\Component\HttpKernel\Profiler\Profiler + */ + protected $profiler; + + /** + * @var \PHPUnit_Framework_MockObject_MockObject + */ + protected $profile; + + /** + * @var \Symfony\Bundle\WebProfilerBundle\Profiler\Template + */ + protected $templateManager; + + public function setUp() + { + parent::setUp(); + + $twigEngine = $this->mockTwigEngine(); + $twigEnvironment = $this->mockTwigEnvironment(); + $templates = array( + 'data_collector.foo'=>array('foo','FooBundle:Collector:foo'), + 'data_collector.bar'=>array('bar','FooBundle:Collector:bar'), + 'data_collector.baz'=>array('baz','FooBundle:Collector:baz') + ); + + $this->templateManager = new Template($twigEngine, $twigEnvironment, $templates); + $this->templateManager->setProfiler($this->mockProfiler()); + } + + /** + * @expectedException Symfony\Component\HttpKernel\Exception\NotFoundHttpException + */ + public function testGetNameOfInvalidTemplate() + { + $profile = $this->mockProfile(); + $this->templateManager->getName($profile, 'notexisitingpanel'); + } + + /** + * if template exists in both profile and profiler then it's name should be returned + */ + public function testGetNameValidTemplate() + { + $this->profiler->expects($this->any()) + ->method('has') + ->withAnyParameters() + ->will($this->returnCallback(array($this, 'profilerHasCallback'))); + + $profile = $this->mockProfile(); + $profile->expects($this->any()) + ->method('hasCollector') + ->will($this->returnCallback(array($this, 'profileHasCollectorCallback'))); + + $this->assertEquals('FooBundle:Collector:foo.html.twig', $this->templateManager->getName($profile, 'foo')); + } + + /** + * template should be loaded for 'foo' because other collectors are + * missing in profile or in profiler + */ + public function testGetTemplates() { + + $profile = $this->mockProfile(); + $profile->expects($this->any()) + ->method('hasCollector') + ->will($this->returnCallback(array($this, 'profilerHasCallback'))); + + $this->profiler->expects($this->any()) + ->method('has') + ->withAnyParameters() + ->will($this->returnCallback(array($this, 'profileHasCollectorCallback'))); + + $result = $this->templateManager->getTemplates($profile); + $this->assertArrayHasKey('foo',$result); + $this->assertArrayNotHasKey('bar',$result); + $this->assertArrayNotHasKey('baz',$result); + } + + public function profilerHasCallback($panel) { + switch ($panel) { + case 'foo': + case 'bar': + return true; + default: + return false; + } + } + + public function profileHasCollectorCallback($panel) { + switch ($panel) { + case 'foo': + case 'baz': + return true; + default: + return false; + } + } + + protected function mockProfile() { + $this->profile = $this->getMockBuilder('Symfony\Component\HttpKernel\Profiler\Profile') + ->disableOriginalConstructor() + ->getMock(); + + return $this->profile; + } + + protected function mockTwigEnvironment() + { + $this->twigEnvironment = $this->getMockBuilder('Twig_Environment')->getMock(); + + $this->twigEnvironment->expects($this->any()) + ->method('loadTemplate') + ->will($this->returnValue('loadedTemplate')); + + return $this->twigEnvironment; + + } + + protected function mockTwigEngine() + { + $this->twigEngine = $this->getMockBuilder('Symfony\Bundle\TwigBundle\TwigEngine') + ->disableOriginalConstructor() + ->getMock(); + + $this->twigEngine->expects($this->any()) + ->method('exists') + ->will($this->returnValue(true)); + + return $this->twigEngine; + + } + + protected function mockProfiler() { + $this->profiler = $this->getMockBuilder('Symfony\Component\HttpKernel\Profiler\Profiler') + ->disableOriginalConstructor() + ->getMock(); + + return $this->profiler; + } +}