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

[RFC] Proposal for new configuration format. #38

Closed
wants to merge 13 commits into from
4 changes: 2 additions & 2 deletions AutoRoute/Factory.php
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,7 @@ protected function generateRouteStackChain($classFqn)

$routeStackChain = new BuilderUnitChain($this->builder);

foreach ($mapping['content_path'] as $builderName => $builderConfig) {
foreach ($mapping['content_path']['path_units'] as $builderName => $builderConfig) {
$builderUnit = $this->generateBuilderUnit($builderConfig);
$routeStackChain->addBuilderUnit($builderName, $builderUnit);
}
Expand Down Expand Up @@ -230,7 +230,7 @@ private function getBuilderService($builderConfig, $type, $aliasKey)
// to be stateless (which is good here)
$service = $this->container->get($serviceId);
unset($builderConfig[$type][$aliasKey]);
$service->init($builderConfig[$type]);
$service->init($builderConfig[$type]['options']);

return $service;
}
Expand Down
7 changes: 6 additions & 1 deletion DependencyInjection/CmfRoutingAutoExtension.php
Original file line number Diff line number Diff line change
Expand Up @@ -30,9 +30,14 @@ public function load(array $configs, ContainerBuilder $container)
$chainFactoryDef = $container->getDefinition('cmf_routing_auto.factory');

// normalize configuration
foreach ($config['auto_route_mapping'] as $classFqn => $config) {
foreach ($config['mappings'] as $classFqn => $config) {
$chainFactoryDef->addMethodCall('registerMapping', array($classFqn, $config));
}
}

public function getNamespace()
{
return 'http://cmf.symfony.com/schema/dic/routing_auto';
}
}

119 changes: 66 additions & 53 deletions DependencyInjection/Configuration.php
Original file line number Diff line number Diff line change
Expand Up @@ -32,67 +32,80 @@ public function getConfigTreeBuilder()

$treeBuilder = new TreeBuilder();
$treeBuilder->root('cmf_routing_auto')
->fixXmlConfig('mapping')
->children()
->arrayNode('auto_route_mapping')
->useAttributeAsKey('class')
->prototype('array')
->children()
->arrayNode('content_path')
->useAttributeAsKey('name')
->prototype('array')
->children()
->arrayNode('provider')
->beforeNormalization()
->ifTrue($needsNormalization)
->then($doNormalization)
->end()
->prototype('scalar')->end()
->end()
->arrayNode('exists_action')
->beforeNormalization()
->ifTrue($needsNormalization)
->then($doNormalization)
->arrayNode('mappings')
->useAttributeAsKey('class')
->prototype('array')
->children()
->arrayNode('content_path')
->fixXmlConfig('path_unit')
->children()
->arrayNode('path_units')
->useAttributeAsKey('name')
->prototype('array')
->children()
->append($this->getUnitConfigOption('provider', '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.

@wouterj I changed the name of this method to BuilderUnitConfigOption to UnitConfigOption .. slightly more generic.

->append($this->getUnitConfigOption('exists_action'))
->append($this->getUnitConfigOption('not_exists_action'))
->end()
->end()
->end() // path_units
->end()
->prototype('scalar')->end()
->end()
->arrayNode('not_exists_action')
->beforeNormalization()
->ifTrue($needsNormalization)
->then($doNormalization)
->end() // content_path
->arrayNode('content_name')
->children()
->append($this->getUnitConfigOption('provider', 'name'))
->append($this->getUnitConfigOption('exists_action'))
->append($this->getUnitConfigOption('not_exists_action'))
->end()
->prototype('scalar')->end()
->end()
->end()
->end() // content_name
->end()
->end()
->arrayNode('content_name')
->children()
->arrayNode('provider')
->beforeNormalization()
->ifTrue($needsNormalization)
->then($doNormalization)
->end()
->prototype('scalar')->end()
->end()
->arrayNode('exists_action')
->beforeNormalization()
->ifTrue($needsNormalization)
->then($doNormalization)
->end()
->prototype('scalar')->end()
->end()
->arrayNode('not_exists_action')
->beforeNormalization()
->ifTrue($needsNormalization)
->then($doNormalization)
->end()
->prototype('scalar')->end()
->end()
->end()
->end()
->end() // mappings
->end();

return $treeBuilder;
}

protected function getUnitConfigOption($name, $nameOption = 'strategy')
{
$builder = new TreeBuilder();
$node = $builder->root($name);

$node
->fixXmlConfig('option')
->beforeNormalization()
->ifTrue(function ($v) {
return is_string($v);
})
->then(function ($v) use ($nameOption) {
return array(
$nameOption => $v,
'options' => array(),
);
})
->end()
->beforeNormalization()
->ifTrue(function ($v) use ($nameOption) {
return !isset($v[$nameOption]);
})
->then(function ($v) use ($nameOption) {
return array(
$nameOption => $v[0],
'options' => isset($v[1]) ? $v[1] : array(),
);
})
->end()
->children()
->scalarNode($nameOption)->isRequired()->cannotBeEmpty()->end()
->arrayNode('options')
->useAttributeAsKey('name')
->prototype('scalar')->end()
->end()
->end();

return $node;
}
}

29 changes: 29 additions & 0 deletions Tests/Resources/Fixtures/config/config.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
<?php

$container->loadFromExtension('cmf_routing_auto', array(
'mappings' => array(
'Acme\BasicCmsBundle\Document\Page' => array(
'content_path' => array(
'path_units' => array(
'pages' => array(
'provider' => array('specified', array('path' => '/cms/routes/page')),
'exists_action' => 'use',
'not_exists_action' => array(
'strategy' => 'create',
),
),
),
),
'content_name' => array(
'provider' => array('content_method', array('method' => 'getTitle')),
'exists_action' => array(
'strategy' => 'auto_increment',
'options' => array(
'pattern' => '-%d',
),
),
'not_exists_action' => array('create'),
),
),
),
));
29 changes: 29 additions & 0 deletions Tests/Resources/Fixtures/config/config.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
<?xml version="1.0" encoding="UTF-8" ?>
<container xmlns="http://symfony.com/schema/dic/services">

<config xmlns="http://cmf.symfony.com/schema/dic/routing_auto">

<mapping class="Acme\BasicCmsBundle\Document\Page">

<content-path>
<path-unit name="pages">
<provider name="specified">
<option name="path" value="/cms/routes/page" />
</provider>
<exists-action strategy="use" />
<not-exists-action strategy="create" />
</path-unit>
</content-path>

<content-name>
<provider name="content_method">
<option name="method" value="getTitle" />
</provider>
<exists-action strategy="auto_increment">
<option name="pattern" value="-%d" />
</exists-action>
<not-exists-action strategy="create" />
</content-name>
</mapping>
</config>
</container>
17 changes: 17 additions & 0 deletions Tests/Resources/Fixtures/config/config.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
cmf_routing_auto:
mappings:
Acme\BasicCmsBundle\Document\Page:
content_path:
path_units:
Copy link
Member Author

Choose a reason for hiding this comment

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

Not sure I like this key, it is redundant. The content_path should already be a collection of "path-units". It also suggests that content_name should have a path_unit child.

content_path:
    pages: { provider: [ specified, { path: ... } ] }
    foobar: { provider: [ specified, { path: ... } ] }

Copy link
Member

Choose a reason for hiding this comment

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

I made the path_units child optional.

pages:
provider: [ specified, { path: /cms/routes/page } ]
exists_action: use
not_exists_action:
strategy: create
content_name:
provider: [ content_method, { method: getTitle } ]
exists_action:
strategy: auto_increment
options:
pattern: -%d
not_exists_action: [ create ]
90 changes: 33 additions & 57 deletions Tests/Resources/app/config/routingautoroute.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,75 +15,51 @@ cmf_routing:
route_basepath: /test/routing

cmf_routing_auto:

auto_route_mapping:

##
mappings:
# e.g. /cms/auto-route/blog/my-blogs-title
Symfony\Cmf\Bundle\RoutingAutoBundle\Tests\Resources\Document\Blog:

# generate or use path components leading up to the final part of the path
content_path:
base:
provider:
name: specified
path: test/auto-route
exists_action:
strategy: use
not_exists_action:
strategy: create
namespace:
provider:
name: specified
path: blog
exists_action:
strategy: use
not_exists_action:
strategy: create

path_units:
base:
provider: [ specified, { path: test/auto-route } ]
exists_action: use
not_exists_action: create
namespace:
provider: [ specified, { path: blog } ]
exists_action: use
not_exists_action: create
# using alternative syntax
content_name:
provider:
name: content_method
method: getTitle
options:
method: getTitle
exists_action:
strategy: auto_increment
pattern: -%d
not_exists_action:
options:
pattern: -%d
Copy link
Member

Choose a reason for hiding this comment

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

this is the same as [ auto_increment, { pattern: -%d } ] isn't it? Why did you use this (ugly) format?

Copy link
Member Author

Choose a reason for hiding this comment

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

This is just for getting an idea of what the configuration can look like when expanded.

not_exists_action:
strategy: create

##
# e.g. /cms/auto-route/blog/my-blogs-title/2013-04-09/my-post-title
Symfony\Cmf\Bundle\RoutingAutoBundle\Tests\Resources\Document\Post:

content_path:

# /cms/auto-route/blog/my-blogs-title
blog_path:
provider:
name: content_object
method: getBlog
exists_action:
strategy: use
not_exists_action:
strategy: throw_exception

date:
provider:
name: content_datetime
method: getDate
date_format: Y/m/d
exists_action:
strategy: use
not_exists_action:
strategy: create

path_units:
# /cms/auto-route/blog/my-blogs-title
blog_path:
provider: [ content_object, { method: getBlog } ]
exists_action: use
not_exists_action: throw_exception
date:
provider:
name: content_datetime
options:
method: getDate
date_format: Y/m/d
exists_action: use
not_exists_action: create
content_name:
# my-post-title
provider:
name: content_method
method: getTitle
exists_action:
strategy: auto_increment
pattern: -%d
not_exists_action:
strategy: create
provider: [ content_method, { method: getTitle } ]
exists_action: [ auto_increment, { pattern: -%d } ]
not_exists_action: [ create ]
Loading