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

[WIP] candidates strategy #213

Closed
wants to merge 5 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
1 change: 1 addition & 0 deletions DependencyInjection/CmfRoutingExtension.php
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,7 @@ private function setupDynamicRouter(array $config, ContainerBuilder $container,
$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 Down
1 change: 1 addition & 0 deletions DependencyInjection/Configuration.php
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,7 @@ public function getConfigTreeBuilder()
->arrayNode('locales')
->prototype('scalar')->end()
->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
2 changes: 1 addition & 1 deletion Doctrine/Orm/RouteProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ public function getRoutesByNames($names = null)
$routes = array();
foreach ($names as $name) {
try {
$routes[] = $this->getRouteByName($name, $parameters);
$routes[] = $this->getRouteByName($name);
} catch (RouteNotFoundException $e) {
// not found
}
Expand Down
46 changes: 33 additions & 13 deletions Doctrine/Phpcr/IdPrefixListener.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,32 +13,44 @@
namespace Symfony\Cmf\Bundle\RoutingBundle\Doctrine\Phpcr;

use Doctrine\Common\Persistence\Event\LifecycleEventArgs;
use Symfony\Cmf\Component\Routing\Candidates\PrefixCandidates;

/**
* Doctrine PHPCR-ODM listener to set the idPrefix on routes
* Doctrine PHPCR-ODM listener to tell routes what part of their id is the URL.
*
* This listener knows about the RouteProvider and uses its prefixes to
* identify routes that could need the prefix. In case prefixes overlap, the
* order matters as the first matching prefix is taken.
*
* @author David Buchmann <[email protected]>
*/
class IdPrefixListener
{
/**
* The prefix to add to the url to create the repository path
* Used to ask for the possible prefixes to remove from the repository ID
* to create the URL.
*
* @var string
* @var PrefixCandidates
*/
protected $idPrefix = '';
protected $candidates;

public function __construct($prefix)
/**
* This listener only makes sense together with the PrefixCandidates
* strategy.
*
* @param PrefixCandidates $candidates
*/
public function __construct(PrefixCandidates $candidates)
{
$this->idPrefix = $prefix;
$this->candidates = $candidates;
}

/**
* @param $prefix
* @return array
*/
public function setPrefix($prefix)
protected function getPrefixes()
{
$this->idPrefix = $prefix;
return $this->candidates->getPrefixes();
}

public function postLoad(LifecycleEventArgs $args)
Expand All @@ -51,16 +63,24 @@ public function postPersist(LifecycleEventArgs $args)
$this->updateId($args);
}

public function postMove(LifecycleEventArgs $args)
{
$this->updateId($args);
}

protected function updateId(LifecycleEventArgs $args)
{
$doc = $args->getObject();

// only update route objects and only if the prefix can match, to allow
// for more than one listener and more than one route root
if (($doc instanceof PrefixInterface)
&& ! strncmp($this->idPrefix, $doc->getId(), strlen($this->idPrefix))
) {
$doc->setPrefix($this->idPrefix);
if ($doc instanceof PrefixInterface) {
foreach ($this->getPrefixes() as $prefix) {
if (! strncmp($prefix, $doc->getId(), strlen($prefix))) {
$doc->setPrefix($prefix);
break;
}
}
}
}
}
61 changes: 45 additions & 16 deletions Doctrine/Phpcr/LocaleListener.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
use Doctrine\Common\Persistence\Event\LifecycleEventArgs;

use Symfony\Cmf\Bundle\RoutingBundle\Doctrine\Phpcr\Route;
use Symfony\Cmf\Component\Routing\Candidates\PrefixCandidates;

/**
* Doctrine PHPCR-ODM listener to update the locale on routes based on the URL.
Expand All @@ -29,11 +30,12 @@
class LocaleListener
{
/**
* The prefix to add to the url to create the repository path
* Used to ask for the possible prefixes to determine the possible locale
* segment of the id.
*
* @var string
* @var RouteProvider
*/
protected $idPrefix = '';
protected $candidates;

/**
* List of possible locales to detect on URL after idPrefix
Expand All @@ -42,20 +44,26 @@ class LocaleListener
*/
protected $locales;

public function __construct($prefix, array $locales)
{
$this->idPrefix = $prefix;
$this->locales = $locales;
}
/**
* If set, call Route::setAddLocalePattern.
* @var boolean
*/
protected $addLocalePattern;

/**
* The repository path prefix where routes handled by this listener are located.
* This listener is built to work with the prefix candidates strategy.
*
* @param $prefix
* @param PrefixCandidates $candidates To get prefixes from.
* @param array $locales Locales that should be detected.
* @param bool $addLocalePattern Whether to make route prepend the
* locale pattern if it does not have
* one of the allowed locals in its id.
*/
public function setPrefix($prefix)
public function __construct(PrefixCandidates $candidates, array $locales, $addLocalePattern = false)
{
$this->idPrefix = $prefix;
$this->candidates = $candidates;
$this->locales = $locales;
$this->addLocalePattern = $addLocalePattern;
}

/**
Expand All @@ -68,6 +76,17 @@ public function setLocales(array $locales)
$this->locales = $locales;
}

/**
* Whether to make the route prepend the locale pattern if it does not
* have one of the allowed locals in its id.
*
* @param boolean $addLocalePattern
*/
public function setAddLocalePattern($addLocalePattern)
{
$this->addLocalePattern = $addLocalePattern;
}

/**
* Update locale after loading a route.
*
Expand Down Expand Up @@ -110,6 +129,14 @@ public function postMove(MoveEventArgs $args)
$this->updateLocale($doc, $args->getTargetPath(), true);
}

/**
* @return array
*/
protected function getPrefixes()
{
return $this->candidates->getPrefixes();
}

/**
* Update the locale of a route if $id starts with the prefix and has a
* valid locale right after.
Expand All @@ -126,17 +153,19 @@ protected function updateLocale(Route $doc, $id, $force = false)

// only update route objects and only if the prefix can match, to allow
// for more than one listener and more than one route root
if (! preg_match('#' . $this->idPrefix . '/([^/]+)(/|$)#', $id, $matches)) {
if (! preg_match('#(' . implode('|', $this->getPrefixes()) . ')/([^/]+)(/|$)#', $id, $matches)) {
return;
}

if (in_array($matches[1], $this->locales)) {
if (in_array($locale = $matches[2], $this->locales)) {
if ($force || ! $doc->getDefault('_locale')) {
$doc->setDefault('_locale', $matches[1]);
$doc->setDefault('_locale', $locale);
}
if ($force || ! $doc->getRequirement('_locale')) {
$doc->setRequirement('_locale', $matches[1]);
$doc->setRequirement('_locale', $locale);
}
} elseif ($this->addLocalePattern) {
$doc->setOption('add_locale_pattern', true);
}
}
}
Loading