diff --git a/bundles/routing/dynamic_customize.rst b/bundles/routing/dynamic_customize.rst index 22c10da7..204ad257 100644 --- a/bundles/routing/dynamic_customize.rst +++ b/bundles/routing/dynamic_customize.rst @@ -44,70 +44,127 @@ following class provides a simple solution using an ODM Repository. .. code-block:: php + findOneBy(array( - 'url' => $url, - )); + private $managerRegistry; - $pattern = $document->getUrl(); // e.g. "/this/is/a/url" - - $collection = new RouteCollection(); + /** + * To get the Document Manager out of the registry. + * + * @return DocumentManager + */ + private function getDocumentManager() + { + return $this->managerRegistry->getManager(); + } - // 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, - )); + public function __construct(ManagerRegistry $managerRegistry) + { + $this->managerRegistry = $managerRegistry; + } - // add the route to the RouteCollection using - // a unique ID as the key. - $collection->add('my_route_'.uniqid(), $route); + 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; } + + 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 route base paths + $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``. + 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. Replacing the Default CMF Route Provider ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -119,7 +176,7 @@ configuration as follows: .. code-block:: yaml - # app/config/config.yml + // app/config/config.yml cmf_routing: dynamic: enabled: true @@ -150,7 +207,58 @@ 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 + + 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 + + + + + + Acme\Repository\RouteProvider + + + + + + + + + + + + .. code-block:: php + + $container->setParameter( + 'acme_demo.provider.endpoint.class', + 'Acme\DemoBundle\Repository\RouteProvider' + ); + + $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