Skip to content
This repository was archived by the owner on Sep 16, 2021. It is now read-only.

Commit bce0728

Browse files
committed
Merge pull request #511 from symfony-cmf/routing_auto_1.0
Updated routing auto documentation for 1.0
2 parents 28ab1e3 + 548109c commit bce0728

12 files changed

+488
-564
lines changed

_exts/sensio/sphinx/configurationblock.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@
66

77
from docutils.parsers.rst import Directive, directives
88
from docutils import nodes
9-
from string import upper
109

1110
class configurationblock(nodes.General, nodes.Element):
1211
pass

_exts/sensio/sphinx/phpcode.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
from docutils import nodes, utils
88

99
from sphinx.util.nodes import split_explicit_title
10-
from string import lower
10+
import sys
1111

1212
def php_namespace_role(typ, rawtext, text, lineno, inliner, options={}, content=[]):
1313
text = utils.unescape(text)
@@ -82,7 +82,7 @@ def php_phpclass_role(typ, rawtext, text, lineno, inliner, options={}, content=[
8282
text = utils.unescape(text)
8383
has_explicit_title, title, full_class = split_explicit_title(text)
8484

85-
full_url = 'http://php.net/manual/en/class.%s.php' % lower(full_class)
85+
full_url = 'http://php.net/manual/en/class.%s.php' % full_class.lower()
8686

8787
if not has_explicit_title:
8888
title = full_class
@@ -94,7 +94,7 @@ def php_phpfunction_role(typ, rawtext, text, lineno, inliner, options={}, conten
9494
text = utils.unescape(text)
9595
has_explicit_title, title, full_function = split_explicit_title(text)
9696

97-
full_url = 'http://php.net/manual/en/function.%s.php' % lower(full_function.replace('_', '-'))
97+
full_url = 'http://php.net/manual/en/function.%s.php' % full_function.replace('_', '-').lower()
9898

9999
if not has_explicit_title:
100100
title = full_function

bundles/map.rst.inc

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -50,9 +50,9 @@ library or they introduce a complete new concept.
5050
* :doc:`routing_auto/index` (in development)
5151

5252
* :doc:`routing_auto/introduction`
53-
* :doc:`routing_auto/providers`
54-
* :doc:`routing_auto/exists_actions`
55-
* :doc:`routing_auto/not_exists_actions`
53+
* :doc:`routing_auto/token_providers`
54+
* :doc:`routing_auto/conflict_resolvers`
55+
* :doc:`routing_auto/defunct_route_handlers`
5656
* :doc:`routing_auto/customization`
5757

5858
* :doc:`search/index`
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
.. index::
2+
single: Conflict Resolvers; RoutingAutoBundle
3+
4+
Conflict Resolvers
5+
------------------
6+
7+
Conflict resolvers are invoked when the system detects that a newly generated
8+
route would conflict with an route already existing in the route repository.
9+
10+
This section details the conflict resolvers which are provided by default.
11+
12+
auto_increment
13+
~~~~~~~~~~~~~~
14+
15+
The ``auto_increment`` conflict resolver will add a numerical suffix to the path, for
16+
example if ``my/path`` already exists, it would first become ``my/path-1`` and if that path *also*
17+
exists it will try ``my/path-2``, ``my/path-3`` and so on into infinity until
18+
it finds a path which *doesn't* exist.
19+
20+
.. configuration-block::
21+
22+
.. code-block:: yaml
23+
24+
stdClass:
25+
uri_schema: /cmf/blog
26+
conflict_resolver: auto_increment
27+
28+
.. code-block:: xml
29+
30+
<auto-mapping xmlns="http://cmf.symfony.com/schema/routing_auto">
31+
<mapping class="stdClass" uri-schema="/cmf/blog">
32+
<conflict-resolver name="auto_increment" />
33+
</mapping>
34+
</auto-mapping>
35+
36+
throw_exception
37+
~~~~~~~~~~~~~~~
38+
39+
The ``throw_exception`` efficiently "resolves" conflicts by throwing exceptions.
40+
This is the default action.
41+
42+
.. configuration-block::
43+
44+
.. code-block:: yaml
45+
46+
stdClass:
47+
uri_schema: /cmf/blog
48+
conflict_resolver: throw_exception
49+
50+
.. code-block:: xml
51+
52+
<auto-mapping xmlns="http://cmf.symfony.com/schema/routing_auto">
53+
<mapping class="stdClass" uri-schema="/cmf/blog">
54+
<conflict-resolver name="throw_exception" />
55+
</mapping>
56+
</auto-mapping>

bundles/routing_auto/customization.rst

Lines changed: 128 additions & 77 deletions
Original file line numberDiff line numberDiff line change
@@ -4,154 +4,205 @@
44
Customization
55
-------------
66

7-
.. _routingauto_customization_pathproviders:
7+
.. _routingauto_customization_tokenproviders:
88

9-
Adding Path Providers
10-
~~~~~~~~~~~~~~~~~~~~~
9+
Token Providers
10+
~~~~~~~~~~~~~~~
1111

12-
The goal of a ``PathProvider`` class is to add one or several path elements to
13-
the route stack. For example, the following provider will add the path
14-
``foo/bar`` to the route stack::
12+
The goal of a ``TokenProvider`` class is to provide values for tokens in the
13+
URI schema. Such values can be derived form the object for which the route
14+
is being generated, or from the environment (e.g. the you could use the
15+
current locale in the route).
1516

16-
// src/Acme/CmsBundle/RoutingAuto/PathProvider/FoobarProvider.php
17-
namespace Acme\CmsBundle\RoutingAuto\PathProvider;
17+
The following token provider will simply provide the value "foobar"::
1818

19-
use Symfony\Cmf\Bundle\RoutingAutoBundle\AutoRoute\PathProviderInterface;
20-
use Symfony\Cmf\Bundle\RoutingAutoBundle\AutoRoute\RouteStack;
19+
// src/Acme/CmsBundle/RoutingAuto/PathProvider/FoobarTokenProvider.php
20+
namespace Symfony\Cmf\Component\RoutingAuto\TokenProvider;
2121

22-
class FoobarProvider implements PathProviderInterface
22+
use Symfony\Cmf\Component\RoutingAuto\TokenProviderInterface;
23+
use Symfony\Component\OptionsResolver\OptionsResolverInterface;
24+
use Symfony\Cmf\Component\RoutingAuto\UriContext;
25+
26+
class FoobarTokenProvider implements TokenProviderInterface
2327
{
24-
public function providePath(RouteStack $routeStack)
28+
/**
29+
* {@inheritDoc}
30+
*/
31+
public function provideValue(UriContext $uriContext, $options)
32+
{
33+
return 'foobar';
34+
}
35+
36+
/**
37+
* {@inheritDoc}
38+
*/
39+
public function configureOptions(OptionsResolverInterface $optionsResolver)
2540
{
26-
$routeStack->addPathElements(array('foo', 'bar'));
2741
}
2842
}
2943

3044
To use the path provider you must register it in the container and add the
31-
``cmf_routing_auto.provider`` tag and set the **alias** accordingly:
45+
``cmf_routing_auto.token_provider`` tag and set the **alias** accordingly:
3246

3347
.. configuration-block::
3448

3549
.. code-block:: yaml
3650
3751
services:
38-
acme_cms.path_provider.foobar:
39-
class: Acme\CmsBundle\RoutingAuto\PathProvider\FoobarProvider
40-
scope: prototype
52+
acme_cms.token_provider.foobar:
53+
class: Acme\CmsBundle\RoutingAuto\PathProvider\FoobarTokenProvider
4154
tags:
42-
- { name: cmf_routing_auto.provider, alias: "foobar"}
55+
- { name: cmf_routing_auto.token_provider, alias: "foobar" }
4356
4457
.. code-block:: xml
4558
4659
<?xml version="1.0" encoding="UTF-8" ?>
4760
<container xmlns="http://symfony.com/schema/dic/services">
4861
<service
49-
id="acme_cms.path_provider.foobar"
50-
class="Acme\CmsBundle\RoutingAuto\PathProvider\FoobarProvider"
51-
scope="prototype"
62+
id="acme_cms.token_provider.foobar"
63+
class="Acme\CmsBundle\RoutingAuto\PathProvider\FoobarTokenProvider"
5264
>
53-
<tag name="cmf_routing_auto.provider" alias="foobar"/>
65+
<tag name="cmf_routing_auto.token_provider" alias="foobar"/>
5466
</service>
5567
</container>
5668
5769
.. code-block:: php
5870
5971
use Symfony\Component\DependencyInjection\Definition;
6072
61-
$definition = new Definition('Acme\CmsBundle\RoutingAuto\PathProvider\FoobarProvider');
62-
$definition->addTag('cmf_routing_auto.provider', array('alias' => 'foobar'));
63-
$definition->setScope('prototype');
73+
$definition = new Definition('Acme\CmsBundle\RoutingAuto\PathProvider\FoobarTokenProvider');
74+
$definition->addTag('cmf_routing_auto.token_provider', array('alias' => 'foobar'));
6475
65-
$container->setDefinition('acme_cms.path_provider.foobar', $definition);
76+
$container->setDefinition('acme_cms.token_provider.foobar', $definition);
6677
67-
The ``FoobarProvider`` is now available as **foobar** in the routing auto
78+
The ``FoobarTokenProvider`` is now available as **foobar** in the routing auto
6879
configuration.
6980

70-
.. caution::
81+
Conflict Resolvers
82+
~~~~~~~~~~~~~~~~~~
83+
84+
Conflict resolvers decide what happens if a generated route already exists in
85+
the route repository and is not related to the context object.
86+
87+
The following example will append an unique string to the URI to resolve a
88+
conflict::
89+
90+
namespace Symfony\Cmf\Component\RoutingAuto\ConflictResolver;
91+
92+
use Symfony\Cmf\Component\RoutingAuto\ConflictResolverInterface;
93+
use Symfony\Cmf\Component\RoutingAuto\UriContext;
94+
use Symfony\Cmf\Component\RoutingAuto\Adapter\AdapterInterface;
95+
96+
class UniqidConflictResolver implements ConflictResolverInterface
97+
{
98+
public function resolveConflict(UriContext $uriContext)
99+
{
100+
$uri = $uriContext->getUri();
101+
return sprintf('%s-%s', uniqid());
102+
}
103+
}
104+
105+
It is registered in the DI configuration as follows:
106+
107+
.. configuration-block::
108+
109+
.. code-block:: yaml
110+
111+
services:
112+
acme_cms.conflict_resolver.foobar:
113+
class: Acme\CmsBundle\RoutingAuto\ConflictResolver\UniqidConflictResolver
114+
tags:
115+
- { name: cmf_routing_auto.conflict_resolver, alias: "uniqid"}
116+
117+
.. code-block:: xml
118+
119+
<?xml version="1.0" encoding="UTF-8" ?>
120+
<container xmlns="http://symfony.com/schema/dic/services">
121+
<service
122+
id="acme_cms.conflict_resolver.foobar"
123+
class="Acme\CmsBundle\RoutingAuto\ConflictResolver\UniqidConflictResolver"
124+
>
125+
<tag name="cmf_routing_auto.conflict_resolver" alias="uniqid"/>
126+
</service>
127+
</container>
128+
129+
.. code-block:: php
130+
131+
use Symfony\Component\DependencyInjection\Definition;
71132
72-
Both path providers and path actions need to be defined with a scope of
73-
"prototype". This ensures that each time the auto routing system requests
74-
the class a new one is given and you do not have any state problems.
133+
$definition = new Definition('Acme\CmsBundle\RoutingAuto\ConflictResolver\UniqidConflictResolver');
134+
$definition->addTag('cmf_routing_auto.conflict_resolver', array('alias' => 'foobar'));
75135
76-
Adding Path Actions
77-
~~~~~~~~~~~~~~~~~~~
136+
$container->setDefinition('acme_cms.conflict_resolver.uniqid', $definition);
78137
79-
In the auto routing system, a "path action" is an action to take if the path
80-
provided by the "path provider" exists or not.
138+
Defunct Route Handlers
139+
~~~~~~~~~~~~~~~~~~~~~~
81140

82-
You can add a path action by extending the ``PathActionInterface`` and
83-
registering your new class correctly in the DI configuration.
141+
Defunct Route Handlers decide what happens to old routes when an object is
142+
updated and its generated URI changes.
84143

85-
This is a very simple implementation from the bundle - it is used to throw an
86-
exception when a path already exists::
144+
They are not all-together trivial - the following handler removes old routes and is
145+
the default handler::
87146

88-
namespace Symfony\Cmf\Bundle\RoutingAutoBundle\RoutingAuto\PathNotExists;
147+
namespace Symfony\Cmf\Component\RoutingAuto\DefunctRouteHandler;
89148

90-
use Symfony\Cmf\Bundle\RoutingAutoBundle\AutoRoute\PathActionInterface;
91-
use Symfony\Cmf\Bundle\RoutingAutoBundle\AutoRoute\Exception\CouldNotFindRouteException;
92-
use Symfony\Cmf\Bundle\RoutingAutoBundle\AutoRoute\RouteStack;
149+
use Symfony\Cmf\Component\RoutingAuto\DefunctRouteHandlerInterface;
150+
use Symfony\Cmf\Component\RoutingAuto\UriContextCollection;
151+
use Symfony\Cmf\Component\RoutingAuto\Adapter\AdapterInterface;
93152

94-
class ThrowException implements PathActionInterface
153+
class RemoveDefunctRouteHandler implements DefunctRouteHandlerInterface
95154
{
96-
public function init(array $options)
155+
protected $adapter;
156+
157+
public function __construct(AdapterInterface $adapter)
97158
{
159+
$this->adapter = $adapter;
98160
}
99161

100-
public function execute(RouteStack $routeStack)
162+
public function handleDefunctRoutes(UriContextCollection $uriContextCollection)
101163
{
102-
throw new CouldNotFindRouteException('/'.$routeStack->getFullPath());
164+
$referringAutoRouteCollection = $this->adapter->getReferringAutoRoutes($uriContextCollection->getSubjectObject());
165+
166+
foreach ($referringAutoRouteCollection as $referringAutoRoute) {
167+
if (false === $uriContextCollection->containsAutoRoute($referringAutoRoute)) {
168+
$newRoute = $uriContextCollection->getAutoRouteByTag($referringAutoRoute->getAutoRouteTag());
169+
170+
$this->adapter->migrateAutoRouteChildren($referringAutoRoute, $newRoute);
171+
$this->adapter->removeAutoRoute($referringAutoRoute);
172+
}
173+
}
103174
}
104175
}
105176

106-
The ``init()`` method configures the provider (throwing errors when required
107-
options do not exists) and the ``execute()`` method executes the action.
108-
109177
It is registered in the DI configuration as follows:
110178

111179
.. configuration-block::
112180

113181
.. code-block:: yaml
114182
115183
services:
116-
cmf_routing_auto.not_exists_action.throw_exception:
117-
class: Symfony\Cmf\Bundle\RoutingAutoBundle\RoutingAuto\PathNotExists\ThrowException
118-
scope: prototype
184+
acme_cms.defunct_route_handler.foobar:
185+
class: Acme\CmsBundle\RoutingAuto\DefunctRouteHandler\RemoveConflictResolver
119186
tags:
120-
- { name: cmf_routing_auto.not_exists_action, alias: "throw_exception"}
187+
- { name: cmf_routing_auto.defunct_route_handler, alias: "remove"}
121188
122189
.. code-block:: xml
123190
124191
<?xml version="1.0" encoding="UTF-8" ?>
125192
<container xmlns="http://symfony.com/schema/dic/services">
126193
<service
127-
id="cmf_routing_auto.not_exists_action.throw_exception"
128-
class="Symfony\Cmf\Bundle\RoutingAutoBundle\RoutingAuto\PathNotExists\ThrowException"
129-
scope="prototype"
130-
>
131-
<tag name="cmf_routing_auto.not_exists_action" alias="throw_exception"/>
194+
id="acme_cms.defunct_route_handler.foobar"
195+
class="Acme\CmsBundle\RoutingAuto\DefunctRouteHandler\RemoveConflictResolver"
196+
>
197+
<tag name="cmf_routing_auto.defunct_route_handler" alias="remove"/>
132198
</service>
133199
</container>
134200
135201
.. code-block:: php
136202
137203
use Symfony\Component\DependencyInjection\Definition;
138204
139-
$definition = new Definition('Symfony\Cmf\Bundle\RoutingAutoBundle\RoutingAuto\PathNotExists\ThrowException');
140-
$definition->addTag('cmf_routing_auto.provider', array('alias' => 'throw_exception'));
141-
$definition->setScope('prototype');
142-
143-
$container->setDefinition('cmf_routing_auto.not_exists_action.throw_exception', $definition);
144-
145-
Note the following:
146-
147-
* **Scope**: Must *always* be set to *prototype*;
148-
* **Tag**: The tag registers the service with the auto routing system, it can
149-
be one of the following:
150-
151-
* ``cmf_routing_auto.exists.action`` - if the action is to be used when a
152-
path exists;
153-
* ``cmf_routing_auto.not_exists.action`` - if the action is to be used when
154-
a path does not exist;
205+
$definition = new Definition('Acme\CmsBundle\RoutingAuto\DefunctRouteHandler\RemoveConflictResolver');
206+
$definition->addTag('cmf_routing_auto.defunct_route_handler', array('alias' => 'foobar'));
155207
156-
* **Alias**: The alias of the tag is the name by which you will reference this
157-
action in the auto routing configuration.
208+
$container->setDefinition('acme_cms.defunct_route_handler.remove', $definition);

0 commit comments

Comments
 (0)