Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

port features from simple cms into routing bundle to simplify things #210

Merged
merged 12 commits into from
Apr 1, 2014
24 changes: 20 additions & 4 deletions Admin/RouteAdmin.php
Original file line number Diff line number Diff line change
Expand Up @@ -66,8 +66,6 @@ protected function configureFormFields(FormMapper $formMapper)
array('choice_list' => array(), 'select_root_node' => true, 'root_node' => $this->routeRoot)
)
->add('name', 'text')
->add('addFormatPattern', null, array('required' => false, 'help' => 'form.help_add_format_pattern'))
->add('addTrailingSlash', null, array('required' => false, 'help' => 'form.help_add_trailing_slash'))
->end();

if (null === $this->getParentFieldDescription()) {
Expand All @@ -76,6 +74,7 @@ protected function configureFormFields(FormMapper $formMapper)
->add('variablePattern', 'text', array('required' => false))
->add('content', 'doctrine_phpcr_odm_tree', array('choice_list' => array(), 'required' => false, 'root_node' => $this->contentRoot))
->add('defaults', 'sonata_type_immutable_array', array('keys' => $this->configureFieldsForDefaults()))
->add('options', 'sonata_type_immutable_array', array('keys' => $this->configureFieldsForOptions()))
->end();
}
}
Expand Down Expand Up @@ -110,7 +109,7 @@ public function getExportFormats()

protected function configureFieldsForDefaults()
{
$defaults = array(
$defaults = array(
'_controller' => array('_controller', 'text', array('required' => false)),
'_template' => array('_template', 'text', array('required' => false)),
'type' => array('type', 'cmf_routing_route_type', array(
Expand All @@ -125,7 +124,7 @@ protected function configureFieldsForDefaults()
$defaults[$name] = array($name, 'text', array('required' => false));
}
}

//parse variable pattern and add defaults for it - taken from routecompiler
/** @var $route Route */
$route = $this->subject;
Expand All @@ -142,6 +141,23 @@ protected function configureFieldsForDefaults()
return $defaults;
}

protected function configureFieldsForOptions()
{
$options = array(
'addFormatPattern' => array('addFormatPattern', 'text', array('required' => false), array('help' => 'form.help_add_format_pattern')),
'addTrailingSlash' => array('addTrailingSlash', 'text', array('required' => false), array('help' => 'form.help_add_trailing_slash')),
);

$dynamicOptions = $this->getSubject()->getOptions();
foreach ($dynamicOptions as $name => $value) {
if (!isset($options[$name])) {
$options[$name] = array($name, 'text', array('required' => false));
}
}

return $options;
}

public function prePersist($object)
{
$defaults = array_filter($object->getDefaults());
Expand Down
8 changes: 6 additions & 2 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,15 +1,19 @@
Changelog
=========

* **2014-03-26**: [ORM] Applied the cleanup for the PHPCR provider to the ORM
provider now: If the route matched a pattern with a format extension, the
format extension is no longer set as route a default.

* **2014-03-25**: setParent() and getParent() are now deprecated.
Use setParentDocument() and getParentDocument() instead.
Moreover, you should now enable the ChildExtension from the CoreBundle.

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

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

1.1.0
-----
Expand Down
55 changes: 43 additions & 12 deletions DependencyInjection/CmfRoutingExtension.php
Original file line number Diff line number Diff line change
Expand Up @@ -95,9 +95,10 @@ private function setupDynamicRouter(array $config, ContainerBuilder $container,
$container->setParameter($this->getAlias() . '.route_collection_limit', $config['route_collection_limit']);

$locales = false;
if (isset($config['locales'])) {
if (!empty($config['locales'])) {
$locales = $config['locales'];
$container->setParameter($this->getAlias() . '.dynamic.locales', $locales);
$container->setParameter($this->getAlias() . '.dynamic.auto_locale_pattern', $config['auto_locale_pattern']);
}

$loader->load('routing-dynamic.xml');
Expand All @@ -109,13 +110,13 @@ private function setupDynamicRouter(array $config, ContainerBuilder $container,
}

if ($config['persistence']['phpcr']['enabled']) {
$this->loadPhpcrProvider($config['persistence']['phpcr'], $loader, $container, $locales);
$this->loadPhpcrProvider($config['persistence']['phpcr'], $loader, $container, $locales, $config['match_implicit_locale']);
$hasProvider = true;
$hasContentRepository = true;
}

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

Expand Down Expand Up @@ -226,22 +227,41 @@ private function setupDynamicRouter(array $config, ContainerBuilder $container,
}
}

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

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

$container->setParameter($this->getAlias() . '.dynamic.persistence.phpcr.route_basepath', $config['route_basepath']);
$container->setParameter($this->getAlias() . '.dynamic.persistence.phpcr.content_basepath', $config['content_basepath']);

$container->setParameter($this->getAlias() . '.dynamic.persistence.phpcr.manager_name', $config['manager_name']);

$container->setAlias($this->getAlias() . '.route_provider', $this->getAlias() . '.phpcr_route_provider');
$container->setAlias($this->getAlias() . '.content_repository', $this->getAlias() . '.phpcr_content_repository');
$container->setParameter(
$this->getAlias() . '.dynamic.persistence.phpcr.route_basepaths',
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

do we need to keep the route_basepath parameter in the DI for BC or not?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think so

$config['route_basepaths']
);
$container->setParameter(
$this->getAlias() . '.dynamic.persistence.phpcr.content_basepath',
$config['content_basepath']
);

$container->setParameter(
$this->getAlias() . '.dynamic.persistence.phpcr.manager_name',
$config['manager_name']
);

$container->setAlias(
$this->getAlias() . '.route_provider',
$this->getAlias() . '.phpcr_route_provider'
);
$container->setAlias(
$this->getAlias() . '.content_repository',
$this->getAlias() . '.phpcr_content_repository'
);

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

if ($config['use_sonata_admin']) {
Expand All @@ -256,14 +276,25 @@ public function loadSonataPhpcrAdmin($config, XmlFileLoader $loader, ContainerBu
return;
}

$basePath = empty($config['admin_basepath']) ? reset($config['route_basepaths']) : $config['admin_basepath'];

$container->setParameter($this->getAlias() . '.dynamic.persistence.phpcr.admin_basepath', $basePath);


$loader->load('admin-phpcr.xml');
}

public function loadOrmProvider($config, XmlFileLoader $loader, ContainerBuilder $container)
public function loadOrmProvider($config, XmlFileLoader $loader, ContainerBuilder $container, $matchImplicitLocale)
{
$container->setParameter($this->getAlias() . '.dynamic.persistence.orm.manager_name', $config['manager_name']);
$container->setParameter($this->getAlias() . '.backend_type_orm', true);
$loader->load('provider-orm.xml');

if (!$matchImplicitLocale) {
// remove the locales argument from the candidates
$definition = $container->getDefinition($this->getAlias() . '.orm_candidates');
$definition->setArguments(array());
}
}

/**
Expand Down
27 changes: 26 additions & 1 deletion DependencyInjection/Configuration.php
Original file line number Diff line number Diff line change
Expand Up @@ -77,9 +77,32 @@ public function getConfigTreeBuilder()
->arrayNode('phpcr')
->addDefaultsIfNotSet()
->canBeEnabled()
->fixXmlConfig('route_basepath')
->beforeNormalization()
->ifTrue(function ($v) {
return isset($v['route_basepath']);
})
->then(function ($v) {
$base = isset($v['route_basepaths']) ? $v['route_basepaths'] : array();
if (is_array($v['route_basepath'])) {
// xml configuration
$base += $v['route_basepath'];
} else {
$base[] = $v['route_basepath'];
}
$v['route_basepaths'] = array_unique($base);
unset($v['route_basepath']);

return $v;
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@wouterj there is no easier way to do this, right? i kind of collide with the fixXmlConfig thing. should i even remove fixXmlConfig('route_basepath') above, as it won't ever happen?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would handle it something different. Or you configure the route_basepaths option or the route_basepath, but not both. It'll look like:

->validate()
    ->ifTrue(function ($v) { isset($v['route_basepath']) && isset($v['route_basepaths']); })
    ->thenInvalid('Found values for both "route_basepath" and "route_basepaths", use "route_basepaths" instead.')
->end()

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

And then you can remove the normalizer and just use the fixXmlConfig

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

oh, that will "accidentally" fix it even if i am using the old format with yml / php configuration, right?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It will fix it if you use the old format, and it'll break if you use both the old and new format

})
->end()
->children()
->scalarNode('manager_name')->defaultNull()->end()
->scalarNode('route_basepath')->defaultValue('/cms/routes')->end()
->arrayNode('route_basepaths')
->prototype('scalar')->end()
->defaultValue(array('/cms/routes'))
->end()
->scalarNode('admin_basepath')->end()
->scalarNode('content_basepath')->defaultValue('/cms/content')->end()
->enumNode('use_sonata_admin')
->beforeNormalization()
Expand Down Expand Up @@ -122,6 +145,8 @@ public function getConfigTreeBuilder()
->arrayNode('locales')
->prototype('scalar')->end()
->end()
->booleanNode('match_implicit_locale')->defaultValue(true)->end()
->booleanNode('auto_locale_pattern')->defaultValue(false)->end()
->end()
->end()
->end()
Expand Down
5 changes: 3 additions & 2 deletions Doctrine/DoctrineProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -73,8 +73,9 @@ public function setManagerName($managerName)
}

/**
* Set the limit to apply when calling getRoutesByNames() with null.
* Note that setting the limit to null means no limit applied.
* Set the limit to apply when calling getAllRoutes().
*
* Setting the limit to null means no limit is applied.
*
* @param integer|null $routeCollectionLimit
*/
Expand Down
95 changes: 37 additions & 58 deletions Doctrine/Orm/RouteProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,9 @@

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

use Doctrine\Common\Persistence\ManagerRegistry;
use Doctrine\Common\Persistence\ObjectRepository;
use Symfony\Cmf\Component\Routing\Candidates\CandidatesInterface;
use Symfony\Component\Routing\RouteCollection;
use Symfony\Component\Routing\Exception\RouteNotFoundException;

Expand All @@ -32,37 +35,46 @@
class RouteProvider extends DoctrineProvider implements RouteProviderInterface
{
/**
* @param $url
*
* @return array
* @var CandidatesInterface
*/
protected function getCandidates($url)
private $candidatesStrategy;

public function __construct(ManagerRegistry $managerRegistry, CandidatesInterface $candidatesStrategy, $className)
{
$candidates = array();
if ('/' !== $url) {
if (preg_match('/(.+)\.[a-z]+$/i', $url, $matches)) {
$candidates[] = $url;
$url = $matches[1];
}
parent::__construct($managerRegistry, $className);
$this->candidatesStrategy = $candidatesStrategy;
}

$part = $url;
while (false !== ($pos = strrpos($part, '/'))) {
$candidates[] = $part;
$part = substr($url, 0, $pos);
}
}
/**
* {@inheritDoc}
*/
public function getRouteCollectionForRequest(Request $request)
{
$collection = new RouteCollection();

$candidates[] = '/';
$candidates = $this->candidatesStrategy->getCandidates($request);
if (empty($candidates)) {
return $collection;
}
$routes = $this->getRouteRepository()->findByStaticPrefix($candidates, array('position' => 'ASC'));
/** @var $route Route */
foreach ($routes as $route) {
$collection->add($route->getName(), $route);
}

return $candidates;
return $collection;
}

/**
* {@inheritDoc}
*/
public function getRouteByName($name)
{
$route = $this->getRoutesRepository()->findOneBy(array('name' => $name));
if (!$this->candidatesStrategy->isCandidate($name)) {
throw new RouteNotFoundException(sprintf('Route "%s" is not handled by this route provider', $name));
}

$route = $this->getRouteRepository()->findOneBy(array('name' => $name));
if (!$route) {
throw new RouteNotFoundException("No route found for name '$name'");
}
Expand All @@ -76,21 +88,18 @@ public function getRouteByName($name)
public function getRoutesByNames($names = null)
{
if (null === $names) {
$names = array();
if (0 === $this->routeCollectionLimit) {
return $names;
}
if (null !== $this->routeCollectionLimit) {
return $this->getRoutesRepository()->findBy(array(), null, $this->routeCollectionLimit);
return array();
}

return $this->getRoutesRepository()->findAll();
return $this->getRouteRepository()->findBy(array(), null, $this->routeCollectionLimit);
}

$routes = array();
foreach ($names as $name) {
// TODO: if we do findByName with multivalue, we need to filter with isCandidate afterwards
try {
$routes[] = $this->getRouteByName($name, $parameters);
$routes[] = $this->getRouteByName($name);
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why is this not $routeRepository->findByName instead? in the request candidates we assume that passing an array to findByYX works.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

since when does PHPCR support dynamic findByXx methods? I don't think passing an array to it works for ORM.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we are in the orm part here so that works.
you are right, for phpcr-odm it would not work, though it could be ported from the orm or ported into commons as its just a shortcut.

} catch (RouteNotFoundException $e) {
// not found
}
Expand All @@ -100,39 +109,9 @@ public function getRoutesByNames($names = null)
}

/**
* {@inheritDoc}
*/
public function getRouteCollectionForRequest(Request $request)
{
$url = $request->getPathInfo();

$candidates = $this->getCandidates($url);

$collection = new RouteCollection();

if (empty($candidates)) {
return $collection;
}

$routes = $this->getRoutesRepository()->findByStaticPrefix($candidates, array('position' => 'ASC'));
foreach ($routes as $key => $route) {
if (preg_match('/.+\.([a-z]+)$/i', $url, $matches)) {
if ($route->getDefault('_format') === $matches[1]) {
continue;
}

$route->setDefault('_format', $matches[1]);
}
$collection->add($key, $route);
}

return $collection;
}

/**
* @return \Doctrine\Common\Persistence\ObjectRepository
* @return ObjectRepository
*/
protected function getRoutesRepository()
protected function getRouteRepository()
{
return $this->getObjectManager()->getRepository($this->className);
}
Expand Down
Loading