From 7e432db2ae84f8a9006ee8a3df8af8bf8188c4dd Mon Sep 17 00:00:00 2001 From: ElectricMaxxx Date: Sat, 22 Mar 2014 16:15:49 +0100 Subject: [PATCH 1/2] refactor route provider example --- bundles/routing/dynamic_customize.rst | 177 +++++++++++++++++++++----- 1 file changed, 144 insertions(+), 33 deletions(-) diff --git a/bundles/routing/dynamic_customize.rst b/bundles/routing/dynamic_customize.rst index 22c10da7..8bdf3c4a 100644 --- a/bundles/routing/dynamic_customize.rst +++ b/bundles/routing/dynamic_customize.rst @@ -41,74 +41,145 @@ Creating the Route Provider The route provider must implement the ``RouteProviderInterface``. The following class provides a simple solution using an ODM Repository. +As the RouteProvider is a symfony solution you should have a look at + .. code-block:: php + findOneBy(array( - 'url' => $url, - )); - - $pattern = $document->getUrl(); // e.g. "/this/is/a/url" + private $managerRegistry; - $collection = new RouteCollection(); + /** + * Injecting the Registry creates a implementation independent way of + * way to get the managers. + * + * @param ManagerRegistry $managerRegistry + */ + public function setManagerRegistry(ManagerRegistry $managerRegistry) + { + $this->managerRegistry = $managerRegistry; + } - // create a new Route and set our document as - // a default (so that we can retrieve it from the request) - $route = new SymfonyRoute($pattern, array( - 'document' => $document, - )); + /** + * To get the Document Manager out of the registry. + * + * @return DocumentManager + */ + private function getDocumentManager() + { + return $this->managerRegistry->getManager(); + } - // add the route to the RouteCollection using - // a unique ID as the key. - $collection->add('my_route_'.uniqid(), $route); + /** + * {@inheritDoc} + */ + public function getRouteCollectionForRequest(Request $request) + { + $path = $request->getPathInfo(); + $candidates = $this->getCandidates($path); + + $routeCandidates = $this->getDocumentManager()->findMany(null, $candidates); + $routeCollection = new RouteCollection(); + + $count = 0; + foreach ($routeCandidates as $candidate) { + $count++; + if ($candidate instanceof Route) { + $defaults = $candidate->getDefaults(); + $defaults[DynamicRouter::CONTENT_KEY] = $candidate->getContent(); + $routeCollection->add( + 'my_route_'.$count, + new SymfonyRoute($candidate->getPath(), $defaults) + ); + } + } - return $collection; + return $routeCollection; } /** - * This method is used to generate URLs, e.g. {{ path('foobar') }}. + * {@inheritDoc} */ - public function getRouteByName($name, $params = array()) + public function getRouteByName($name, $parameters = array()) { - $document = $this->findOneBy(array( - 'name' => $name, - )); + /** @var Route $route */ + $route = $this->getDocumentManager()->find(null, $name); if ($route) { - $route = new SymfonyRoute($route->getPattern(), array( - 'document' => $document, - )); + $defaults = $route->getDefaults(); + $defaults[DynamicRouter::CONTENT_KEY] = $route->getContent(); + $route = new SymfonyRoute($route->getPath(), $defaults); } return $route; } + + /** + * {@inheritDoc} + */ + public function getRoutesByNames($names, $parameters = array()) + { + + } + + /** + * Method to to create the paths to look for the current route. + * + * @param string + */ + private function getCandidates($path) + { + //add your different paths your routes have as base path + $prefixes = array( + '/cms/routes', + ); + + $result = array(); + foreach ($prefixes as $prefix) { + $result[] = $prefix.$path; + } + + return $result; + } } .. tip:: - As you may have noticed we return a ``RouteCollection`` object - why not + The ``RouteProviderInteface`` will force to implement the shown above. + As you may have noticed we return in ``getRouteCollectionForRequest`` + and ``getRoutesByNames`` a ``RouteCollection`` object - why not return a single ``Route``? The Dynamic Router allows us to return many *candidate* routes, in other words, routes that *might* match the incoming URL. This is important to enable the possibility of matching *dynamic* routes, ``/page/{page_id}/edit`` for example. In our example we match the given URL exactly and only ever return a single ``Route``. + If you set some defaults for your route (template, controller,...), they will + be added as options to the symfony route. As you may have noticed we added the + mapped document with a specific key ``DynamicRouter::CONTENT_KEY`` to the + defaults array. By doing this you will find your current document in the + requests parameter bag in ``$parameterBag[...]['my_route_1'][DynamicRouter::CONTENT_KEY]`` + to manipulate it in listeners for example. But most important part is: + The document will be injected to your action by adding a parameter with + that name. + Replacing the Default CMF Route Provider ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -150,7 +221,47 @@ configuration as follows: Where ``acme_demo.provider.endpoint`` is the service ID of your route provider. See `Creating and configuring services in the container`_ for -information on creating custom services. +information on creating custom services. In our example the service definition +will look like this: + +.. configuration-block:: + + .. code-block:: yaml + + services: + service: + + + .. code-block:: xml + + //app/config/config.xml + + + + + Acme\Repository\RouteProvider + + + + + + + + + + + + .. code-block:: php + + // app/config/config.php +As you can see we decided to inject the ``DocumentRegistry`` of doctrines +phpcr-odm. This will provides the document manger we will need to query +the persistence implementation. As the RouteProvider is a symfony solution +you can inject what you want - you should return somehow a ``Route`` or +``RouteCollection`` in your providers methods - it is up to you. .. _`Creating and configuring services in the container`: http://symfony.com/doc/current/book/service_container.html#creating-configuring-services-in-the-container/ .. _`PHPCR-ODM`: http://www.doctrine-project.org/projects/phpcr-odm.html +.. _`RouteProvider on Symfony`: From 2c0568b62707c2554f68b068c7823f6a6faf9fdc Mon Sep 17 00:00:00 2001 From: ElectricMaxxx Date: Sun, 23 Mar 2014 08:32:08 +0100 Subject: [PATCH 2/2] correct typos, add php+yml sevice setting --- bundles/routing/dynamic_customize.rst | 81 +++++++++++++-------------- 1 file changed, 39 insertions(+), 42 deletions(-) diff --git a/bundles/routing/dynamic_customize.rst b/bundles/routing/dynamic_customize.rst index 8bdf3c4a..204ad257 100644 --- a/bundles/routing/dynamic_customize.rst +++ b/bundles/routing/dynamic_customize.rst @@ -41,14 +41,12 @@ Creating the Route Provider The route provider must implement the ``RouteProviderInterface``. The following class provides a simple solution using an ODM Repository. -As the RouteProvider is a symfony solution you should have a look at - .. code-block:: php managerRegistry = $managerRegistry; - } - /** * To get the Document Manager out of the registry. * @@ -87,9 +74,11 @@ As the RouteProvider is a symfony solution you should have a look at return $this->managerRegistry->getManager(); } - /** - * {@inheritDoc} - */ + public function __construct(ManagerRegistry $managerRegistry) + { + $this->managerRegistry = $managerRegistry; + } + public function getRouteCollectionForRequest(Request $request) { $path = $request->getPathInfo(); @@ -131,9 +120,6 @@ As the RouteProvider is a symfony solution you should have a look at return $route; } - /** - * {@inheritDoc} - */ public function getRoutesByNames($names, $parameters = array()) { @@ -146,7 +132,7 @@ As the RouteProvider is a symfony solution you should have a look at */ private function getCandidates($path) { - //add your different paths your routes have as base path + // add your route base paths $prefixes = array( '/cms/routes', ); @@ -168,14 +154,14 @@ As the RouteProvider is a symfony solution you should have a look at return a single ``Route``? The Dynamic Router allows us to return many *candidate* routes, in other words, routes that *might* match the incoming URL. This is important to enable the possibility of matching *dynamic* - routes, ``/page/{page_id}/edit`` for example. In our example we match the - given URL exactly and only ever return a single ``Route``. - - If you set some defaults for your route (template, controller,...), they will - be added as options to the symfony route. As you may have noticed we added the - mapped document with a specific key ``DynamicRouter::CONTENT_KEY`` to the - defaults array. By doing this you will find your current document in the - requests parameter bag in ``$parameterBag[...]['my_route_1'][DynamicRouter::CONTENT_KEY]`` + routes, ``/page/{page_id}/edit`` for example. + + If you set some defaults for your route (template, controller, etc.), they will + be added as options to the Symfony route. As you may have noticed the example + added the mapped document with a specific key ``DynamicRouter::CONTENT_KEY`` + to the defaults array. By doing this you will find the current document in + the requests parameter bag in + ``$parameterBag[...]['my_route_1'][DynamicRouter::CONTENT_KEY]`` to manipulate it in listeners for example. But most important part is: The document will be injected to your action by adding a parameter with that name. @@ -190,7 +176,7 @@ configuration as follows: .. code-block:: yaml - # app/config/config.yml + // app/config/config.yml cmf_routing: dynamic: enabled: true @@ -228,13 +214,16 @@ will look like this: .. code-block:: yaml - services: - service: + parameters: + acme_demo.provider.endpoint.class: Acme\DemoBundle\Repository\RouteProvider + services: + acme_demo.provider.endpoint: + class: "%acme_demo.provider.endpoint.class%" + arguments: ["@doctrine_phpcr"] .. code-block:: xml - //app/config/config.xml Acme\Repository\RouteProvider + - - - + + .. code-block:: php - // app/config/config.php + $container->setParameter( + 'acme_demo.provider.endpoint.class', + 'Acme\DemoBundle\Repository\RouteProvider' + ); -As you can see we decided to inject the ``DocumentRegistry`` of doctrines -phpcr-odm. This will provides the document manger we will need to query -the persistence implementation. As the RouteProvider is a symfony solution -you can inject what you want - you should return somehow a ``Route`` or + $container + ->register('acme_demo.provider.endpoint', '%acme_demo.provider.endpoint.class%') + ->addArgument(new Reference('doctrine_phpcr')) + ; + +As you can see the ``DocumentRegistry`` of Doctrine PHPCR-ODM is injected. +This will provide the document manger the provider needs to query +the persistence implementation. As the RouteProvider is a Symfony solution +you can inject what you want - you should somehow return a ``Route`` or ``RouteCollection`` in your providers methods - it is up to you. + .. _`Creating and configuring services in the container`: http://symfony.com/doc/current/book/service_container.html#creating-configuring-services-in-the-container/ .. _`PHPCR-ODM`: http://www.doctrine-project.org/projects/phpcr-odm.html -.. _`RouteProvider on Symfony`: