diff --git a/Controller/ThemeController.php b/Controller/ThemeController.php index f7e62ce..5c876ca 100644 --- a/Controller/ThemeController.php +++ b/Controller/ThemeController.php @@ -16,6 +16,7 @@ use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\RedirectResponse; use Symfony\Component\HttpKernel\Exception\NotFoundHttpException; +use Symfony\Component\Routing\RouterInterface; /** * Theme controller. @@ -40,18 +41,32 @@ class ThemeController */ protected $cookieOptions; + /** + * @var RouterInterface + */ + protected $router; + + /** + * @var string|null + */ + protected $defaultRoute; + /** * Theme controller construct. * * @param ActiveTheme $activeTheme active theme instance * @param array $themes Available themes * @param array|null $cookieOptions The options of the cookie we look for the theme to set + * @param RouterInterface $router + * @param string|null $defaultRoute */ - public function __construct(ActiveTheme $activeTheme, array $themes, array $cookieOptions = null) + public function __construct(ActiveTheme $activeTheme, array $themes, array $cookieOptions = null, RouterInterface $router, $defaultRoute = null) { $this->activeTheme = $activeTheme; $this->themes = $themes; $this->cookieOptions = $cookieOptions; + $this->router = $router; + $this->defaultRoute = $defaultRoute; } /** @@ -73,7 +88,15 @@ public function switchAction(Request $request) $this->activeTheme->setName($theme); - $url = $request->headers->get('Referer', '/'); + + if ($this->defaultRoute) { + $redirect = $this->router->generate($this->defaultRoute); + } else { + $redirect = '/'; + } + + $url = $request->headers->get('Referer', $redirect); + $response = new RedirectResponse($url); if (!empty($this->cookieOptions)) { diff --git a/DependencyInjection/Configuration.php b/DependencyInjection/Configuration.php index e77bd9f..c7f3e1d 100644 --- a/DependencyInjection/Configuration.php +++ b/DependencyInjection/Configuration.php @@ -41,6 +41,7 @@ public function getConfigTreeBuilder() ->prototype('scalar')->end() ->end() ->scalarNode('active_theme')->defaultNull()->end() + ->scalarNode('redirect_fallback')->defaultNull()->end() ->arrayNode('path_patterns') ->addDefaultsIfNotSet() ->children() diff --git a/DependencyInjection/LiipThemeExtension.php b/DependencyInjection/LiipThemeExtension.php index 4a048d0..5a52c1d 100644 --- a/DependencyInjection/LiipThemeExtension.php +++ b/DependencyInjection/LiipThemeExtension.php @@ -29,7 +29,7 @@ public function load(array $configs, ContainerBuilder $container) { $config = $this->processConfiguration(new Configuration(), $configs); - foreach (array('themes', 'active_theme', 'path_patterns', 'cache_warming') as $key) { + foreach (array('themes', 'active_theme', 'path_patterns', 'cache_warming', 'redirect_fallback') as $key) { $container->setParameter($this->getAlias().'.'.$key, $config[$key]); } diff --git a/Resources/config/controller.xml b/Resources/config/controller.xml index f027a9e..f50cbcb 100755 --- a/Resources/config/controller.xml +++ b/Resources/config/controller.xml @@ -9,6 +9,8 @@ %liip_theme.themes% %liip_theme.cookie% + + %liip_theme.redirect_fallback% diff --git a/Tests/UseCaseTest.php b/Tests/UseCaseTest.php index 2fee13d..ab4f214 100644 --- a/Tests/UseCaseTest.php +++ b/Tests/UseCaseTest.php @@ -68,39 +68,22 @@ protected function getEventMock($request, $response, $type = 'Symfony\Component\ return $event; } - protected function getMockRequest($theme, $cookieReturnValue = 'cookie', $userAgent = 'autodetect') + /** + * @return \Symfony\Bundle\FrameworkBundle\Routing\Router + */ + protected function getRouterMock() { - $request = $this->getMockBuilder('Symfony\Component\HttpFoundation\Request') - ->disableOriginalConstructor() - ->getMock(); + $router = $this->getMockBuilder('Symfony\Component\Routing\Router') + ->disableOriginalConstructor() + ->setMethods(['generate', 'supports', 'exists']) + ->getMock(); - $request->expects($this->any()) - ->method('get') - ->will($this->returnValue($theme)); - $request->cookies = $this->getMockBuilder('Symfony\Component\HttpFoundation\ParameterBag') - ->disableOriginalConstructor() - ->getMock(); - $request->cookies->expects($this->any()) - ->method('get') - ->will($this->returnValue($cookieReturnValue)); - $request->headers = $this->getMockBuilder('Symfony\Component\HttpFoundation\ParameterBag') - ->disableOriginalConstructor() - ->getMock(); - $request->headers->expects($this->any()) - ->method('get') - ->will($this->returnValue('/')); - $request->headers->expects($this->any()) - ->method('get') - ->will($this->returnValue($cookieReturnValue)); + $router->expects($this->any()) + ->method('generate') + ->with('test_route') + ->will($this->returnValue('/test_route')); - $request->server = $this->getMockBuilder('Symfony\Component\HttpFoundation\ParameterBag') - ->disableOriginalConstructor() - ->getMock(); - $request->server->expects($this->any()) - ->method('get') - ->will($this->returnValue($userAgent)); - - return $request; + return $router; } private function getCookieValueFromResponse($response) @@ -128,14 +111,17 @@ public function testThemeAction($config, $assertion, $hasAlreadyACookie = true) } $response = new \Symfony\Component\HttpFoundation\Response(); $request = new \Symfony\Component\HttpFoundation\Request(); - if ($hasAlreadyACookie) { - $request = $this->getMockRequest('cookie'); + $request->query->set('theme', 'cookie'); + $request->cookies->set('cookieName', 'cookie'); + $request->server->set('HTTP_USER_AGENT', 'autodetect'); } + $router = $this->getRouterMock(); + $controller = false; if ($config['load_controllers']) { - $controller = new ThemeController($activeTheme, $config['themes'], $config['cookie']); + $controller = new ThemeController($activeTheme, $config['themes'], $config['cookie'], $router, $config['redirect_fallback']); } $listener = new ThemeRequestListener($activeTheme, $config['cookie'], $device); @@ -145,10 +131,13 @@ public function testThemeAction($config, $assertion, $hasAlreadyACookie = true) $this->assertEquals($activeTheme->getName(), $assertion['themeAfterKernelRequest']); if ($controller) { + $request->query->set('theme', $assertion['themeAfterController']); + $response = $controller->switchAction( - $this->getMockRequest($assertion['themeAfterController']) + $request ); $this->assertCookieValue($response, $assertion['themeAfterController']); + $this->assertEquals($response->getTargetUrl(), $assertion['redirect']); } // onResponse will not set the cookie if the controller modified it @@ -178,6 +167,7 @@ public function dataProvider() // all-in Controller wins over Cookie and Autodetection array( 'themes' => array('default', 'controller', 'cookie', 'autodetect'), + 'redirect_fallback' => 'test_route', 'active_theme' => 'default', 'autodetect_theme' => true, 'load_controllers' => true, @@ -187,6 +177,7 @@ public function dataProvider() 'themeAfterKernelRequest' => 'cookie', 'themeAfterController' => 'controller', 'themeAfterKernelResponse' => 'controller', + 'redirect' => '/test_route', ), true, ), @@ -194,6 +185,7 @@ public function dataProvider() array( array( 'themes' => array('default', 'controller', 'cookie', 'autodetect'), + 'redirect_fallback' => 'test_route', 'active_theme' => 'default', 'autodetect_theme' => true, 'load_controllers' => true, @@ -203,6 +195,7 @@ public function dataProvider() 'themeAfterKernelRequest' => 'autodetect', 'themeAfterController' => 'controller', 'themeAfterKernelResponse' => 'controller', + 'redirect' => '/test_route', ), false, ), @@ -210,6 +203,7 @@ public function dataProvider() array( array( 'themes' => array('default', 'controller', 'cookie', 'autodetect'), + 'redirect_fallback' => 'test_route', 'active_theme' => 'default', 'autodetect_theme' => true, 'load_controllers' => false, @@ -219,6 +213,7 @@ public function dataProvider() 'themeAfterKernelRequest' => 'autodetect', 'themeAfterController' => 'autodetect', 'themeAfterKernelResponse' => 'autodetect', + 'redirect' => '/test_route', ), false, ), @@ -226,6 +221,7 @@ public function dataProvider() array( array( 'themes' => array('default', 'controller', 'cookie', 'autodetect'), + 'redirect_fallback' => 'test_route', 'active_theme' => 'default', 'autodetect_theme' => false, 'load_controllers' => true, @@ -235,6 +231,7 @@ public function dataProvider() 'themeAfterKernelRequest' => 'default', 'themeAfterController' => 'controller', 'themeAfterKernelResponse' => 'controller', + 'redirect' => '/test_route', ), false, ), @@ -242,6 +239,7 @@ public function dataProvider() array( array( 'themes' => array('default', 'controller', 'cookie', 'autodetect'), + 'redirect_fallback' => 'test_route', 'active_theme' => 'default', 'autodetect_theme' => false, 'load_controllers' => true, @@ -251,10 +249,10 @@ public function dataProvider() 'themeAfterKernelRequest' => 'cookie', 'themeAfterController' => 'controller', 'themeAfterKernelResponse' => 'controller', + 'redirect' => '/test_route', ), true, ), - ); } }