From 964529698e2a7ab9c4ae79f35dd0ba961a58404b Mon Sep 17 00:00:00 2001 From: Jan Christiansen Date: Tue, 8 Mar 2016 14:46:57 +0100 Subject: [PATCH 1/6] Add exposing of special route options (exposed_options) Only route options in the exposed_options array are exposed if the new config parameter (fos_js_routing.expose_options) is true. --- Command/DumpCommand.php | 8 ++++- Controller/Controller.php | 12 +++++-- DependencyInjection/Configuration.php | 1 + DependencyInjection/FOSJsRoutingExtension.php | 1 + Resources/config/controllers.xml | 1 + Response/RoutesResponse.php | 21 ++++++++---- Tests/Command/DumpCommandTest.php | 16 +++++++++ Tests/Controller/ControllerTest.php | 19 +++++++++++ .../FOSJsRoutingExtensionTest.php | 33 +++++++++++++++++++ 9 files changed, 102 insertions(+), 10 deletions(-) diff --git a/Command/DumpCommand.php b/Command/DumpCommand.php index c8570943..1baf8a44 100644 --- a/Command/DumpCommand.php +++ b/Command/DumpCommand.php @@ -120,13 +120,19 @@ private function doDump(InputInterface $input, OutputInterface $output) $params = array(); } + $exposeRouteOptions = $this->getContainer()->hasParameter('fos_js_routing.expose_options') ? + $this->getContainer()->getParameter('fos_js_routing.expose_options') : + false; + $content = $this->serializer->serialize( new RoutesResponse( $baseUrl, $this->extractor->getRoutes(), $input->getOption('locale'), $this->extractor->getHost(), - $this->extractor->getScheme() + $this->extractor->getScheme(), + null, + $exposeRouteOptions ), 'json', $params diff --git a/Controller/Controller.php b/Controller/Controller.php index aea785f0..f8423cd9 100644 --- a/Controller/Controller.php +++ b/Controller/Controller.php @@ -47,6 +47,11 @@ class Controller */ protected $debug; + /** + * @var boolean + */ + private $exposeRouteOptions; + /** * Default constructor. * @@ -54,13 +59,15 @@ class Controller * @param ExposedRoutesExtractorInterface $exposedRoutesExtractor The extractor service. * @param array $cacheControl * @param boolean $debug + * @param boolean $exposeRouteOptions */ - public function __construct($serializer, ExposedRoutesExtractorInterface $exposedRoutesExtractor, array $cacheControl = array(), $debug = false) + public function __construct($serializer, ExposedRoutesExtractorInterface $exposedRoutesExtractor, array $cacheControl = array(), $debug = false, $exposeRouteOptions = false) { $this->serializer = $serializer; $this->exposedRoutesExtractor = $exposedRoutesExtractor; $this->cacheControlConfig = new CacheControlConfig($cacheControl); $this->debug = $debug; + $this->exposeRouteOptions = $exposeRouteOptions; } /** @@ -97,7 +104,8 @@ public function indexAction(Request $request, $_format) $this->exposedRoutesExtractor->getPrefix($request->getLocale()), $this->exposedRoutesExtractor->getHost(), $this->exposedRoutesExtractor->getScheme(), - $request->getLocale() + $request->getLocale(), + $this->exposeRouteOptions ); $content = $this->serializer->serialize($routesResponse, 'json'); diff --git a/DependencyInjection/Configuration.php b/DependencyInjection/Configuration.php index 39275a6c..15064d35 100644 --- a/DependencyInjection/Configuration.php +++ b/DependencyInjection/Configuration.php @@ -57,6 +57,7 @@ public function getConfigTreeBuilder() ->end() ->end() ->end() + ->booleanNode('expose_options')->defaultFalse()->end() ->end(); return $builder; diff --git a/DependencyInjection/FOSJsRoutingExtension.php b/DependencyInjection/FOSJsRoutingExtension.php index 50c12cbb..883364a9 100644 --- a/DependencyInjection/FOSJsRoutingExtension.php +++ b/DependencyInjection/FOSJsRoutingExtension.php @@ -64,5 +64,6 @@ public function load(array $configs, ContainerBuilder $container) } $container->setParameter('fos_js_routing.cache_control', $config['cache_control']); + $container->setParameter('fos_js_routing.expose_options', $config['expose_options']); } } diff --git a/Resources/config/controllers.xml b/Resources/config/controllers.xml index fe516d90..42a57531 100644 --- a/Resources/config/controllers.xml +++ b/Resources/config/controllers.xml @@ -11,6 +11,7 @@ %fos_js_routing.cache_control% %kernel.debug% + %fos_js_routing.expose_options% diff --git a/Response/RoutesResponse.php b/Response/RoutesResponse.php index 4acd6e56..0437218b 100644 --- a/Response/RoutesResponse.php +++ b/Response/RoutesResponse.php @@ -21,15 +21,17 @@ class RoutesResponse private $host; private $scheme; private $locale; + private $exposeRouteOptions; - public function __construct($baseUrl, RouteCollection $routes = null, $prefix = null, $host = null, $scheme = null, $locale = null) + public function __construct($baseUrl, RouteCollection $routes = null, $prefix = null, $host = null, $scheme = null, $locale = null, $exposeRouteOptions = false) { - $this->baseUrl = $baseUrl; - $this->routes = $routes ?: new RouteCollection(); - $this->prefix = $prefix; - $this->host = $host; - $this->scheme = $scheme; - $this->locale = $locale; + $this->baseUrl = $baseUrl; + $this->routes = $routes ?: new RouteCollection(); + $this->prefix = $prefix; + $this->host = $host; + $this->scheme = $scheme; + $this->locale = $locale; + $this->exposeRouteOptions = $exposeRouteOptions; } public function getBaseUrl() @@ -57,6 +59,11 @@ public function getRoutes() 'requirements' => $route->getRequirements(), 'hosttokens' => method_exists($compiledRoute, 'getHostTokens') ? $compiledRoute->getHostTokens() : array(), ); + + $options = $route->getOptions(); + if ($this->exposeRouteOptions && !empty($options['exposed_options'])) { + $exposedRoutes[$name]['options'] = $options['exposed_options']; + } } return $exposedRoutes; diff --git a/Tests/Command/DumpCommandTest.php b/Tests/Command/DumpCommandTest.php index dcaa614d..0b4358f3 100644 --- a/Tests/Command/DumpCommandTest.php +++ b/Tests/Command/DumpCommandTest.php @@ -13,9 +13,13 @@ use FOS\JsRoutingBundle\Command\DumpCommand; use Symfony\Component\Console\Tester\CommandTester; +use Symfony\Component\DependencyInjection\ContainerInterface; class DumpCommandTest extends \PHPUnit_Framework_TestCase { + /** + * @var ContainerInterface|\PHPUnit_Framework_MockObject_MockObject + */ protected $container; protected $extractor; protected $router; @@ -53,6 +57,18 @@ public function testExecute() ->with('fos_js_routing.serializer') ->will($this->returnValue($this->serializer)); + $this->container + ->method('hasParameter') + ->willReturnMap(array( + array('fos_js_routing.request_context_base_url', false), + array('fos_js_routing.expose_options', true), + )); + + $this->container->expects($this->atLeastOnce()) + ->method('getParameter') + ->with('fos_js_routing.expose_options') + ->will($this->returnValue(true)); + $command = new DumpCommand(); $command->setContainer($this->container); diff --git a/Tests/Controller/ControllerTest.php b/Tests/Controller/ControllerTest.php index 98af6438..e7072a7b 100644 --- a/Tests/Controller/ControllerTest.php +++ b/Tests/Controller/ControllerTest.php @@ -67,6 +67,25 @@ public function testIndexActionWithLocalizedRoutes() $this->assertEquals('{"base_url":"","routes":{"literal":{"tokens":[["text","\/homepage"]],"defaults":[],"requirements":[],"hosttokens":[]},"blog":{"tokens":[["variable","\/","[^\/]++","_locale"],["variable","\/","[^\/]++","slug"],["text","\/blog-post"]],"defaults":{"_locale":"en"},"requirements":[],"hosttokens":[["text","localhost"]]}},"prefix":"","host":"","scheme":""}', $response->getContent()); } + public function testIndexActionWithExposedOptions() + { + $routes = new RouteCollection(); + $routes->add('literal', new Route('/homepage')); + $routes->add('blog', new Route('/blog-post/{slug}', array(), array(), array('exposed_options' => array('whatever' => false, 'angular_controller' => 'test')), 'localhost')); + + $controller = new Controller( + $this->getSerializer(), + $this->getExtractor($routes), + array(), + false, + true + ); + + $response = $controller->indexAction($this->getRequest('/'), 'json'); + + $this->assertEquals('{"base_url":"","routes":{"literal":{"tokens":[["text","\/homepage"]],"defaults":[],"requirements":[],"hosttokens":[]},"blog":{"tokens":[["variable","\/","[^\/]++","slug"],["text","\/blog-post"]],"defaults":[],"requirements":[],"hosttokens":[["text","localhost"]],"options":{"whatever":false,"angular_controller":"test"}}},"prefix":"","host":"","scheme":""}', $response->getContent()); + } + public function testConfigCache() { $routes = new RouteCollection(); diff --git a/Tests/DependencyInjection/FOSJsRoutingExtensionTest.php b/Tests/DependencyInjection/FOSJsRoutingExtensionTest.php index 7be59dc9..3cefbed7 100644 --- a/Tests/DependencyInjection/FOSJsRoutingExtensionTest.php +++ b/Tests/DependencyInjection/FOSJsRoutingExtensionTest.php @@ -53,6 +53,39 @@ public function testLoadSetupsSerializerIfNotGiven() $this->assertEquals('{"foo":"bar"}', $serializer->serialize(array('foo' => 'bar'), 'json')); } + public function testExposeOptionsNotSet() + { + $container = $this->load(array()); + + $this->assertTrue($container->hasParameter('fos_js_routing.expose_options')); + $parameter = $container->getParameter('fos_js_routing.expose_options'); + + $this->assertFalse($parameter); + } + + public function provideExposeOptions() + { + return array( + array(true, true), + array(false, false), + ); + } + + /** + * @param bool $configValue + * @param bool $expectedParameter + * @dataProvider provideExposeOptions + */ + public function testExposeOptionsSet($configValue, $expectedParameter) + { + $container = $this->load(array(array('expose_options' => $configValue))); + + $this->assertTrue($container->hasParameter('fos_js_routing.expose_options')); + $parameter = $container->getParameter('fos_js_routing.expose_options'); + + $this->assertEquals($expectedParameter, $parameter); + } + private function load(array $configs) { $container = new ContainerBuilder(); From 5251edc056121cdb5e779aa53d85944501841def Mon Sep 17 00:00:00 2001 From: Jan Christiansen Date: Tue, 8 Mar 2016 15:07:20 +0100 Subject: [PATCH 2/6] Changed documentation for exposed_options --- Resources/doc/index.md | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/Resources/doc/index.md b/Resources/doc/index.md index a05b6281..25452654 100644 --- a/Resources/doc/index.md +++ b/Resources/doc/index.md @@ -153,6 +153,38 @@ my_very_secret_route: expose: false ``` +### Expose Route Options to JS +If you want to expose some options from the routing definition to the JS definitions +you can set the config parameter: +```yaml +fos_js_routing.expose_options: true +``` +Every option which is defined in the exposed_options option is then added to the generated JS routes. + + +```yaml +# app/config/routing.yml +my_route_to_expose: + pattern: /foo/{id}/bar + defaults: { _controller: HelloBundle:Hello:index } + options: + expose: true + exposed_options: + callback: doStuff + is_single_page: true +``` + +Or using annotations: + +```php +// src/Acme/DemoBundle/Controller/DefaultController.php +/** + * @Route("/foo/{id}/bar", name="my_route_to_expose", options={"expose"=true, exposed_options={callback="doStuff", is_single_page=true}}) + */ +public function exposedAction($foo) +``` + + ### Router service By default, this bundle exports routes from the default service `router`. You From 2ffb53c87c9f4f5bd50b90b7e15fc93e0735f657 Mon Sep 17 00:00:00 2001 From: Jan Christiansen Date: Tue, 8 Mar 2016 15:53:13 +0100 Subject: [PATCH 3/6] Loading closure from cdn.rawkit --- Resources/js/router_test.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Resources/js/router_test.html b/Resources/js/router_test.html index 973dd77f..37cc4a69 100644 --- a/Resources/js/router_test.html +++ b/Resources/js/router_test.html @@ -5,7 +5,7 @@ Router Test - + From 5b35d39cf74ee6022b257bce5f9e42131c2767c7 Mon Sep 17 00:00:00 2001 From: Jan Christiansen Date: Tue, 8 Mar 2016 16:04:20 +0100 Subject: [PATCH 4/6] Loading closure from githubusercontent.com --- Resources/js/router_test.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Resources/js/router_test.html b/Resources/js/router_test.html index 37cc4a69..3540e68b 100644 --- a/Resources/js/router_test.html +++ b/Resources/js/router_test.html @@ -5,7 +5,7 @@ Router Test - + From 7a1f56ced8a38dd7ac69b957e7e73e6487a05fae Mon Sep 17 00:00:00 2001 From: Jan Christiansen Date: Tue, 8 Mar 2016 17:08:32 +0100 Subject: [PATCH 5/6] Complete example in documentation --- Resources/doc/index.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Resources/doc/index.md b/Resources/doc/index.md index 25452654..aea64982 100644 --- a/Resources/doc/index.md +++ b/Resources/doc/index.md @@ -184,6 +184,10 @@ Or using annotations: public function exposedAction($foo) ``` +Will result in the options property: +```JavaScript +{"base_url":"","routes":{"my_route_to_expose":{"tokens":[["text","\/bar"],["variable","\/","[^\/]++","id"],["text","\/development\/foo"]],"defaults":[],"requirements":[],"hosttokens":[],"options":{"callback":"doStuff","is_single_page":true}}},"prefix":"","host":"localhost","scheme":"http"} +``` ### Router service From fd47af570a3601fae07312717a3560f89d899217 Mon Sep 17 00:00:00 2001 From: Jan Christiansen Date: Mon, 7 Jan 2019 08:21:19 +0100 Subject: [PATCH 6/6] inject parameter in constructor instead of fetching from container --- Command/DumpCommand.php | 14 ++++++++------ Resources/config/services.xml | 1 + 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/Command/DumpCommand.php b/Command/DumpCommand.php index 9023be42..6a89cdd8 100644 --- a/Command/DumpCommand.php +++ b/Command/DumpCommand.php @@ -53,12 +53,18 @@ class DumpCommand extends Command */ private $requestContextBaseUrl; - public function __construct(ExposedRoutesExtractorInterface $extractor, SerializerInterface $serializer, $rootDir, $requestContextBaseUrl = null) + /** + * @var bool + */ + private $exposeOptions; + + public function __construct(ExposedRoutesExtractorInterface $extractor, SerializerInterface $serializer, $rootDir, $requestContextBaseUrl = null, $exposeOptions = false) { $this->extractor = $extractor; $this->serializer = $serializer; $this->rootDir = $rootDir; $this->requestContextBaseUrl = $requestContextBaseUrl; + $this->exposeOptions = $exposeOptions; parent::__construct(); } @@ -161,10 +167,6 @@ private function doDump(InputInterface $input, OutputInterface $output) $params = array(); } - $exposeRouteOptions = $this->getContainer()->hasParameter('fos_js_routing.expose_options') ? - $this->getContainer()->getParameter('fos_js_routing.expose_options') : - false; - $content = $serializer->serialize( new RoutesResponse( $baseUrl, @@ -174,7 +176,7 @@ private function doDump(InputInterface $input, OutputInterface $output) $extractor->getPort(), $extractor->getScheme(), null, - $exposeRouteOptions + $this->exposeOptions ), 'json', $params diff --git a/Resources/config/services.xml b/Resources/config/services.xml index ea3ae385..d48d01c1 100644 --- a/Resources/config/services.xml +++ b/Resources/config/services.xml @@ -20,6 +20,7 @@ %kernel.root_dir% %fos_js_routing.request_context_base_url% + %fos_js_routing.expose_options%