Skip to content

Commit 004dced

Browse files
committed
candidates strategy
1 parent 3eef9cd commit 004dced

29 files changed

+1379
-624
lines changed

Admin/RouteAdmin.php

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -66,8 +66,6 @@ protected function configureFormFields(FormMapper $formMapper)
6666
array('choice_list' => array(), 'select_root_node' => true, 'root_node' => $this->routeRoot)
6767
)
6868
->add('name', 'text')
69-
->add('addFormatPattern', null, array('required' => false, 'help' => 'form.help_add_format_pattern'))
70-
->add('addTrailingSlash', null, array('required' => false, 'help' => 'form.help_add_trailing_slash'))
7169
->end();
7270

7371
if (null === $this->getParentFieldDescription()) {
@@ -76,6 +74,7 @@ protected function configureFormFields(FormMapper $formMapper)
7674
->add('variablePattern', 'text', array('required' => false))
7775
->add('content', 'doctrine_phpcr_odm_tree', array('choice_list' => array(), 'required' => false, 'root_node' => $this->contentRoot))
7876
->add('defaults', 'sonata_type_immutable_array', array('keys' => $this->configureFieldsForDefaults()))
77+
->add('options', 'sonata_type_immutable_array', array('keys' => $this->configureFieldsForOptions()))
7978
->end();
8079
}
8180
}
@@ -110,7 +109,7 @@ public function getExportFormats()
110109

111110
protected function configureFieldsForDefaults()
112111
{
113-
$defaults = array(
112+
$defaults = array(
114113
'_controller' => array('_controller', 'text', array('required' => false)),
115114
'_template' => array('_template', 'text', array('required' => false)),
116115
'type' => array('type', 'cmf_routing_route_type', array(
@@ -125,7 +124,7 @@ protected function configureFieldsForDefaults()
125124
$defaults[$name] = array($name, 'text', array('required' => false));
126125
}
127126
}
128-
127+
129128
//parse variable pattern and add defaults for it - taken from routecompiler
130129
/** @var $route Route */
131130
$route = $this->subject;
@@ -142,6 +141,23 @@ protected function configureFieldsForDefaults()
142141
return $defaults;
143142
}
144143

144+
protected function configureFieldsForOptions()
145+
{
146+
$options = array(
147+
'addFormatPattern' => array('addFormatPattern', 'text', array('required' => false), array('help' => 'form.help_add_format_pattern')),
148+
'addTrailingSlash' => array('addTrailingSlash', 'text', array('required' => false), array('help' => 'form.help_add_trailing_slash')),
149+
);
150+
151+
$dynamicOptions = $this->getSubject()->getOptions();
152+
foreach ($dynamicOptions as $name => $value) {
153+
if (!isset($options[$name])) {
154+
$options[$name] = array($name, 'text', array('required' => false));
155+
}
156+
}
157+
158+
return $options;
159+
}
160+
145161
public function prePersist($object)
146162
{
147163
$defaults = array_filter($object->getDefaults());

CHANGELOG.md

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,19 @@
11
Changelog
22
=========
33

4+
* **2014-03-26**: [ORM] Applied the cleanup for the PHPCR provider to the ORM
5+
provider now: If the route matched a pattern with a format extension, the
6+
format extension is no longer set as route a default.
7+
48
* **2014-03-25**: setParent() and getParent() are now deprecated.
59
Use setParentDocument() and getParentDocument() instead.
610
Moreover, you should now enable the ChildExtension from the CoreBundle.
711

812
* **2014-03-23**: When using PHPCR-ODM, routes can now be generated with their
913
uuid as route name as well, in addition to the repository path.
1014

11-
* **2013-11-28**: [BC BREAK] the alias attribute of the <template-by-class> is
12-
renamed to class in the bundle configuration.
15+
* **2013-11-28**: [BC BREAK for xml configuration] the alias attribute of the
16+
<template-by-class> is renamed to class in the bundle configuration.
1317

1418
1.1.0
1519
-----

DependencyInjection/CmfRoutingExtension.php

Lines changed: 43 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -95,11 +95,11 @@ private function setupDynamicRouter(array $config, ContainerBuilder $container,
9595
$container->setParameter($this->getAlias() . '.route_collection_limit', $config['route_collection_limit']);
9696

9797
$locales = false;
98-
if (isset($config['locales'])) {
98+
if (!empty($config['locales'])) {
9999
$locales = $config['locales'];
100100
$container->setParameter($this->getAlias() . '.dynamic.locales', $locales);
101+
$container->setParameter($this->getAlias() . '.dynamic.auto_locale_pattern', $config['auto_locale_pattern']);
101102
}
102-
$container->setParameter($this->getAlias() . '.dynamic.auto_locale_pattern', $config['auto_locale_pattern']);
103103

104104
$loader->load('routing-dynamic.xml');
105105

@@ -110,13 +110,13 @@ private function setupDynamicRouter(array $config, ContainerBuilder $container,
110110
}
111111

112112
if ($config['persistence']['phpcr']['enabled']) {
113-
$this->loadPhpcrProvider($config['persistence']['phpcr'], $loader, $container, $locales);
113+
$this->loadPhpcrProvider($config['persistence']['phpcr'], $loader, $container, $locales, $config['match_implicit_locale']);
114114
$hasProvider = true;
115115
$hasContentRepository = true;
116116
}
117117

118118
if ($config['persistence']['orm']['enabled']) {
119-
$this->loadOrmProvider($config['persistence']['orm'], $loader, $container);
119+
$this->loadOrmProvider($config['persistence']['orm'], $loader, $container, $locales, $config['match_implicit_locale']);
120120
$hasProvider = true;
121121
}
122122

@@ -227,22 +227,41 @@ private function setupDynamicRouter(array $config, ContainerBuilder $container,
227227
}
228228
}
229229

230-
public function loadPhpcrProvider($config, XmlFileLoader $loader, ContainerBuilder $container, $locales)
230+
public function loadPhpcrProvider($config, XmlFileLoader $loader, ContainerBuilder $container, $locales, $matchImplicitLocale)
231231
{
232232
$loader->load('provider-phpcr.xml');
233233

234234
$container->setParameter($this->getAlias() . '.backend_type_phpcr', true);
235235

236-
$container->setParameter($this->getAlias() . '.dynamic.persistence.phpcr.route_basepath', $config['route_basepath']);
237-
$container->setParameter($this->getAlias() . '.dynamic.persistence.phpcr.content_basepath', $config['content_basepath']);
238-
239-
$container->setParameter($this->getAlias() . '.dynamic.persistence.phpcr.manager_name', $config['manager_name']);
240-
241-
$container->setAlias($this->getAlias() . '.route_provider', $this->getAlias() . '.phpcr_route_provider');
242-
$container->setAlias($this->getAlias() . '.content_repository', $this->getAlias() . '.phpcr_content_repository');
236+
$container->setParameter(
237+
$this->getAlias() . '.dynamic.persistence.phpcr.route_basepaths',
238+
$config['route_basepaths']
239+
);
240+
$container->setParameter(
241+
$this->getAlias() . '.dynamic.persistence.phpcr.content_basepath',
242+
$config['content_basepath']
243+
);
244+
245+
$container->setParameter(
246+
$this->getAlias() . '.dynamic.persistence.phpcr.manager_name',
247+
$config['manager_name']
248+
);
249+
250+
$container->setAlias(
251+
$this->getAlias() . '.route_provider',
252+
$this->getAlias() . '.phpcr_route_provider'
253+
);
254+
$container->setAlias(
255+
$this->getAlias() . '.content_repository',
256+
$this->getAlias() . '.phpcr_content_repository'
257+
);
243258

244259
if (!$locales) {
245260
$container->removeDefinition($this->getAlias() . '.phpcrodm_route_locale_listener');
261+
} elseif (!$matchImplicitLocale) {
262+
// remove all but the prefixes configuration from the service definition.
263+
$definition = $container->getDefinition($this->getAlias() . '.phpcr_candidates_prefix');
264+
$definition->setArguments(array($definition->getArgument(0)));
246265
}
247266

248267
if ($config['use_sonata_admin']) {
@@ -257,14 +276,25 @@ public function loadSonataPhpcrAdmin($config, XmlFileLoader $loader, ContainerBu
257276
return;
258277
}
259278

279+
$basePath = empty($config['admin_basepath']) ? reset($config['route_basepaths']) : $config['admin_basepath'];
280+
281+
$container->setParameter($this->getAlias() . '.dynamic.persistence.phpcr.admin_basepath', $basePath);
282+
283+
260284
$loader->load('admin-phpcr.xml');
261285
}
262286

263-
public function loadOrmProvider($config, XmlFileLoader $loader, ContainerBuilder $container)
287+
public function loadOrmProvider($config, XmlFileLoader $loader, ContainerBuilder $container, $matchImplicitLocale)
264288
{
265289
$container->setParameter($this->getAlias() . '.dynamic.persistence.orm.manager_name', $config['manager_name']);
266290
$container->setParameter($this->getAlias() . '.backend_type_orm', true);
267291
$loader->load('provider-orm.xml');
292+
293+
if (!$matchImplicitLocale) {
294+
// remove the locales argument from the candidates
295+
$definition = $container->getDefinition($this->getAlias() . '.orm_candidates');
296+
$definition->setArguments(array());
297+
}
268298
}
269299

270300
/**

DependencyInjection/Configuration.php

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -77,9 +77,32 @@ public function getConfigTreeBuilder()
7777
->arrayNode('phpcr')
7878
->addDefaultsIfNotSet()
7979
->canBeEnabled()
80+
->fixXmlConfig('route_basepath')
81+
->beforeNormalization()
82+
->ifTrue(function ($v) {
83+
return isset($v['route_basepath']);
84+
})
85+
->then(function ($v) {
86+
$base = isset($v['route_basepaths']) ? $v['route_basepaths'] : array();
87+
if (is_array($v['route_basepath'])) {
88+
// xml configuration
89+
$base += $v['route_basepath'];
90+
} else {
91+
$base[] = $v['route_basepath'];
92+
}
93+
$v['route_basepaths'] = array_unique($base);
94+
unset($v['route_basepath']);
95+
96+
return $v;
97+
})
98+
->end()
8099
->children()
81100
->scalarNode('manager_name')->defaultNull()->end()
82-
->scalarNode('route_basepath')->defaultValue('/cms/routes')->end()
101+
->arrayNode('route_basepaths')
102+
->prototype('scalar')->end()
103+
->defaultValue(array('/cms/routes'))
104+
->end()
105+
->scalarNode('admin_basepath')->end()
83106
->scalarNode('content_basepath')->defaultValue('/cms/content')->end()
84107
->enumNode('use_sonata_admin')
85108
->beforeNormalization()
@@ -122,6 +145,7 @@ public function getConfigTreeBuilder()
122145
->arrayNode('locales')
123146
->prototype('scalar')->end()
124147
->end()
148+
->booleanNode('match_implicit_locale')->defaultValue(true)->end()
125149
->booleanNode('auto_locale_pattern')->defaultValue(false)->end()
126150
->end()
127151
->end()

Doctrine/DoctrineProvider.php

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -73,8 +73,9 @@ public function setManagerName($managerName)
7373
}
7474

7575
/**
76-
* Set the limit to apply when calling getRoutesByNames() with null.
77-
* Note that setting the limit to null means no limit applied.
76+
* Set the limit to apply when calling getAllRoutes().
77+
*
78+
* Setting the limit to null means no limit is applied.
7879
*
7980
* @param integer|null $routeCollectionLimit
8081
*/

Doctrine/Orm/RouteProvider.php

Lines changed: 36 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,9 @@
1212

1313
namespace Symfony\Cmf\Bundle\RoutingBundle\Doctrine\Orm;
1414

15+
use Doctrine\Common\Persistence\ManagerRegistry;
16+
use Doctrine\Common\Persistence\ObjectRepository;
17+
use Symfony\Cmf\Component\Routing\Candidates\CandidatesInterface;
1518
use Symfony\Component\Routing\RouteCollection;
1619
use Symfony\Component\Routing\Exception\RouteNotFoundException;
1720

@@ -32,37 +35,46 @@
3235
class RouteProvider extends DoctrineProvider implements RouteProviderInterface
3336
{
3437
/**
35-
* @param $url
36-
*
37-
* @return array
38+
* @var CandidatesInterface
3839
*/
39-
protected function getCandidates($url)
40+
private $candidatesStrategy;
41+
42+
public function __construct(ManagerRegistry $managerRegistry, CandidatesInterface $candidatesStrategy, $className)
4043
{
41-
$candidates = array();
42-
if ('/' !== $url) {
43-
if (preg_match('/(.+)\.[a-z]+$/i', $url, $matches)) {
44-
$candidates[] = $url;
45-
$url = $matches[1];
46-
}
44+
parent::__construct($managerRegistry, $className);
45+
$this->candidatesStrategy = $candidatesStrategy;
46+
}
4747

48-
$part = $url;
49-
while (false !== ($pos = strrpos($part, '/'))) {
50-
$candidates[] = $part;
51-
$part = substr($url, 0, $pos);
52-
}
53-
}
48+
/**
49+
* {@inheritDoc}
50+
*/
51+
public function getRouteCollectionForRequest(Request $request)
52+
{
53+
$collection = new RouteCollection();
5454

55-
$candidates[] = '/';
55+
$candidates = $this->candidatesStrategy->getCandidates($request);
56+
if (empty($candidates)) {
57+
return $collection;
58+
}
59+
$routes = $this->getRouteRepository()->findByStaticPrefix($candidates, array('position' => 'ASC'));
60+
/** @var $route Route */
61+
foreach ($routes as $route) {
62+
$collection->add($route->getName(), $route);
63+
}
5664

57-
return $candidates;
65+
return $collection;
5866
}
5967

6068
/**
6169
* {@inheritDoc}
6270
*/
6371
public function getRouteByName($name)
6472
{
65-
$route = $this->getRoutesRepository()->findOneBy(array('name' => $name));
73+
if (!$this->candidatesStrategy->isCandidate($name)) {
74+
throw new RouteNotFoundException(sprintf('Route "%s" is not handled by this route provider', $name));
75+
}
76+
77+
$route = $this->getRouteRepository()->findOneBy(array('name' => $name));
6678
if (!$route) {
6779
throw new RouteNotFoundException("No route found for name '$name'");
6880
}
@@ -76,19 +88,16 @@ public function getRouteByName($name)
7688
public function getRoutesByNames($names = null)
7789
{
7890
if (null === $names) {
79-
$names = array();
8091
if (0 === $this->routeCollectionLimit) {
81-
return $names;
82-
}
83-
if (null !== $this->routeCollectionLimit) {
84-
return $this->getRoutesRepository()->findBy(array(), null, $this->routeCollectionLimit);
92+
return array();
8593
}
8694

87-
return $this->getRoutesRepository()->findAll();
95+
return $this->getRouteRepository()->findBy(array(), null, $this->routeCollectionLimit);
8896
}
8997

9098
$routes = array();
9199
foreach ($names as $name) {
100+
// TODO: if we do findByName with multivalue, we need to filter with isCandidate afterwards
92101
try {
93102
$routes[] = $this->getRouteByName($name);
94103
} catch (RouteNotFoundException $e) {
@@ -100,39 +109,9 @@ public function getRoutesByNames($names = null)
100109
}
101110

102111
/**
103-
* {@inheritDoc}
104-
*/
105-
public function getRouteCollectionForRequest(Request $request)
106-
{
107-
$url = $request->getPathInfo();
108-
109-
$candidates = $this->getCandidates($url);
110-
111-
$collection = new RouteCollection();
112-
113-
if (empty($candidates)) {
114-
return $collection;
115-
}
116-
117-
$routes = $this->getRoutesRepository()->findByStaticPrefix($candidates, array('position' => 'ASC'));
118-
foreach ($routes as $key => $route) {
119-
if (preg_match('/.+\.([a-z]+)$/i', $url, $matches)) {
120-
if ($route->getDefault('_format') === $matches[1]) {
121-
continue;
122-
}
123-
124-
$route->setDefault('_format', $matches[1]);
125-
}
126-
$collection->add($key, $route);
127-
}
128-
129-
return $collection;
130-
}
131-
132-
/**
133-
* @return \Doctrine\Common\Persistence\ObjectRepository
112+
* @return ObjectRepository
134113
*/
135-
protected function getRoutesRepository()
114+
protected function getRouteRepository()
136115
{
137116
return $this->getObjectManager()->getRepository($this->className);
138117
}

0 commit comments

Comments
 (0)