diff --git a/DependencyInjection/CmfRoutingExtension.php b/DependencyInjection/CmfRoutingExtension.php index 48495366..2ebc62a6 100644 --- a/DependencyInjection/CmfRoutingExtension.php +++ b/DependencyInjection/CmfRoutingExtension.php @@ -34,6 +34,7 @@ public function load(array $configs, ContainerBuilder $container) { $config = $this->processConfiguration(new Configuration(), $configs); $loader = new XmlFileLoader($container, new FileLocator(__DIR__.'/../Resources/config')); + $loader->load('services.xml'); if ($config['dynamic']['enabled']) { // load this even if no explicit enabled value but some configuration diff --git a/Resources/config/services.xml b/Resources/config/services.xml new file mode 100644 index 00000000..e8968226 --- /dev/null +++ b/Resources/config/services.xml @@ -0,0 +1,20 @@ + + + + + Symfony\Cmf\Bundle\CoreBundle\Twig\Extension + 400 + + + + + + + %cmf_routing.twig_extension.route_not_found_log_level% + + + + + diff --git a/Tests/Unit/Twig/Extension/RoutingExtensionTest.php b/Tests/Unit/Twig/Extension/RoutingExtensionTest.php new file mode 100644 index 00000000..226ff23c --- /dev/null +++ b/Tests/Unit/Twig/Extension/RoutingExtensionTest.php @@ -0,0 +1,55 @@ +notFoundGenerator = $this->buildMock('Symfony\\Component\\Routing\\Generator\\UrlGeneratorInterface'); + $this->notFoundGenerator->expects($this->any()) + ->method('generate') + ->will($this->throwException(new RouteNotFoundException)); + } + + public function testCmfDocumentPathLogsRouteNotFoundException() + { + $logger = $this->buildMock('Psr\Log\LoggerInterface'); + + $logger->expects($this->once()) + ->method('log'); + + $extension = new RoutingExtension($this->notFoundGenerator, $logger); + + $extension->getDocumentPath('/test/bad/path'); + } + + public function testCmfDocumentUrlLogsRouteNotFoundException() + { + $logger = $this->buildMock('Psr\Log\LoggerInterface'); + + $logger->expects($this->once()) + ->method('log'); + + $extension = new RoutingExtension($this->notFoundGenerator, $logger); + + $extension->getDocumentUrl('/test/bad/path'); + } + +} diff --git a/Twig/Extension/RoutingExtension.php b/Twig/Extension/RoutingExtension.php new file mode 100644 index 00000000..bd25c64c --- /dev/null +++ b/Twig/Extension/RoutingExtension.php @@ -0,0 +1,105 @@ +generator = $generator; + $this->logger = $logger; + $this->routeNotFoundLogLevel = $routeNotFoundLogLevel; + } + + /** + * {@inheritdoc} + * TODO: Should Symfony\Bridge\Twig\Extension\RoutingExtension::isUrlGenerationSafe should be used/duplicated? + */ + public function getFunctions() + { + $functions = array( + new \Twig_SimpleFunction('cmf_document_path', array($this, 'getDocumentPath')), + new \Twig_SimpleFunction('cmf_document_url', array($this, 'getDocumentUrl')), + ); + + return $functions; + } + + public function getDocumentPath($id, array $parameters = array(), $relative = false) + { + try { + return $this->generator->generate($id, $parameters, $relative ? UrlGeneratorInterface::RELATIVE_PATH : UrlGeneratorInterface::ABSOLUTE_PATH); + } catch (RouteNotFoundException $e) { + $this->handleRouteNotFound($id, $parameters, $e); + } + } + + public function getDocumentUrl($id, array $parameters = array(), $schemeRelative = false) + { + try { + return $this->generator->generate($id, $parameters, $schemeRelative ? UrlGeneratorInterface::NETWORK_PATH : UrlGeneratorInterface::ABSOLUTE_URL); + } catch (RouteNotFoundException $e) { + $this->handleRouteNotFound($id, $parameters, $e); + } + } + + /** + * Handle a RouteNotFound exception + * + * @param string $id The document id (/cms/routes/route1) + * @param array $parameters Route parameters + */ + protected function handleRouteNotFound($id, array $parameters, RouteNotFoundException $exception) + { + if (!$this->logger) { + return false; + } + + $this->logger->log( + $this->routeNotFoundLogLevel, + 'Route Not Found: '.$id, + array( + 'id' => $id, + 'parameters' => $parameters, + 'exception' => $exception->getMessage() + ) + ); + } + + public function getName() + { + return 'cmf_routing'; + } +}