Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 7e38a5c

Browse files
committed
Add feature allowing change of Path Separator
1 parent 61cda3e commit 7e38a5c

18 files changed

+276
-26
lines changed

src/Symfony/Component/Config/CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@ CHANGELOG
77
* added `setDeprecated()` method to indicate a deprecated node
88
* added `XmlUtils::parse()` method to parse an XML string
99
* deprecated `ConfigCachePass`
10+
* added `setPathSeparator` method to `NodeBuilder` class
11+
* added third `$pathSeparator` constructor argument to `BaseNode`
1012

1113
3.3.0
1214
-----

src/Symfony/Component/Config/Definition/BaseNode.php

Lines changed: 15 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,8 @@
2323
*/
2424
abstract class BaseNode implements NodeInterface
2525
{
26+
const DEFAULT_PATH_SEPARATOR = '.';
27+
2628
protected $name;
2729
protected $parent;
2830
protected $normalizationClosures = array();
@@ -32,21 +34,26 @@ abstract class BaseNode implements NodeInterface
3234
protected $deprecationMessage = null;
3335
protected $equivalentValues = array();
3436
protected $attributes = array();
37+
protected $pathSeparator;
3538

3639
/**
37-
* @param string $name The name of the node
38-
* @param NodeInterface $parent The parent of this node
40+
* Constructor.
41+
*
42+
* @param string $name The name of the node
43+
* @param NodeInterface $parent The parent of this node
44+
* @param string $pathSeparator The Path Separator that is used
3945
*
40-
* @throws \InvalidArgumentException if the name contains a period
46+
* @throws \InvalidArgumentException if the name contains path separator
4147
*/
42-
public function __construct($name, NodeInterface $parent = null)
48+
public function __construct($name, NodeInterface $parent = null, $pathSeparator = self::DEFAULT_PATH_SEPARATOR)
4349
{
44-
if (false !== strpos($name, '.')) {
45-
throw new \InvalidArgumentException('The name must not contain ".".');
50+
if (false !== strpos($name, $pathSeparator)) {
51+
throw new \InvalidArgumentException('The name must not contain "'.$pathSeparator.'".');
4652
}
4753

4854
$this->name = $name;
4955
$this->parent = $parent;
56+
$this->pathSeparator = $pathSeparator;
5057
}
5158

5259
public function setAttribute($key, $value)
@@ -233,13 +240,11 @@ public function getName()
233240
*/
234241
public function getPath()
235242
{
236-
$path = $this->name;
237-
238243
if (null !== $this->parent) {
239-
$path = $this->parent->getPath().'.'.$path;
244+
return $this->parent->getPath().$this->pathSeparator.$this->name;
240245
}
241246

242-
return $path;
247+
return $this->name;
243248
}
244249

245250
/**

src/Symfony/Component/Config/Definition/Builder/ArrayNodeDefinition.php

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020
*
2121
* @author Johannes M. Schmitt <[email protected]>
2222
*/
23-
class ArrayNodeDefinition extends NodeDefinition implements ParentNodeDefinitionInterface
23+
class ArrayNodeDefinition extends NodeDefinition implements ChildrenAwareNodeDefinitionInterface
2424
{
2525
protected $performDeepMerging = true;
2626
protected $ignoreExtraKeys = false;
@@ -409,7 +409,7 @@ protected function getNodeBuilder()
409409
protected function createNode()
410410
{
411411
if (null === $this->prototype) {
412-
$node = new ArrayNode($this->name, $this->parent);
412+
$node = new ArrayNode($this->name, $this->parent, $this->pathSeparator);
413413

414414
$this->validateConcreteNode($node);
415415

@@ -420,7 +420,7 @@ protected function createNode()
420420
$node->addChild($child->getNode());
421421
}
422422
} else {
423-
$node = new PrototypedArrayNode($this->name, $this->parent);
423+
$node = new PrototypedArrayNode($this->name, $this->parent, $this->pathSeparator);
424424

425425
$this->validatePrototypeNode($node);
426426

@@ -553,4 +553,12 @@ protected function validatePrototypeNode(PrototypedArrayNode $node)
553553
}
554554
}
555555
}
556+
557+
/**
558+
* @return NodeDefinition[]
559+
*/
560+
public function getChildrenNodeDefinitions()
561+
{
562+
return $this->children;
563+
}
556564
}

src/Symfony/Component/Config/Definition/Builder/BooleanNodeDefinition.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ public function __construct($name, NodeParentInterface $parent = null)
3838
*/
3939
protected function instantiateNode()
4040
{
41-
return new BooleanNode($this->name, $this->parent);
41+
return new BooleanNode($this->name, $this->parent, $this->pathSeparator);
4242
}
4343

4444
/**
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <[email protected]>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\Component\Config\Definition\Builder;
13+
14+
/**
15+
* An interface that must be implemented by nodes which can have children.
16+
*/
17+
interface ChildrenAwareNodeDefinitionInterface extends ParentNodeDefinitionInterface
18+
{
19+
/**
20+
* @return NodeDefinition[]
21+
*/
22+
public function getChildrenNodeDefinitions();
23+
}

src/Symfony/Component/Config/Definition/Builder/EnumNodeDefinition.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,6 @@ protected function instantiateNode()
5353
throw new \RuntimeException('You must call ->values() on enum nodes.');
5454
}
5555

56-
return new EnumNode($this->name, $this->parent, $this->values);
56+
return new EnumNode($this->name, $this->parent, $this->values, $this->pathSeparator);
5757
}
5858
}

src/Symfony/Component/Config/Definition/Builder/FloatNodeDefinition.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,6 @@ class FloatNodeDefinition extends NumericNodeDefinition
2727
*/
2828
protected function instantiateNode()
2929
{
30-
return new FloatNode($this->name, $this->parent, $this->min, $this->max);
30+
return new FloatNode($this->name, $this->parent, $this->min, $this->max, $this->pathSeparator);
3131
}
3232
}

src/Symfony/Component/Config/Definition/Builder/IntegerNodeDefinition.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,6 @@ class IntegerNodeDefinition extends NumericNodeDefinition
2727
*/
2828
protected function instantiateNode()
2929
{
30-
return new IntegerNode($this->name, $this->parent, $this->min, $this->max);
30+
return new IntegerNode($this->name, $this->parent, $this->min, $this->max, $this->pathSeparator);
3131
}
3232
}

src/Symfony/Component/Config/Definition/Builder/NodeDefinition.php

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111

1212
namespace Symfony\Component\Config\Definition\Builder;
1313

14+
use Symfony\Component\Config\Definition\BaseNode;
1415
use Symfony\Component\Config\Definition\NodeInterface;
1516
use Symfony\Component\Config\Definition\Exception\InvalidDefinitionException;
1617

@@ -33,6 +34,7 @@ abstract class NodeDefinition implements NodeParentInterface
3334
protected $nullEquivalent;
3435
protected $trueEquivalent = true;
3536
protected $falseEquivalent = false;
37+
protected $pathSeparator = BaseNode::DEFAULT_PATH_SEPARATOR;
3638

3739
/**
3840
* @var NodeParentInterface|null
@@ -356,4 +358,26 @@ protected function normalization()
356358
* @throws InvalidDefinitionException When the definition is invalid
357359
*/
358360
abstract protected function createNode();
361+
362+
/**
363+
* Set PathSeparator to use.
364+
*
365+
* @param string $separator
366+
*
367+
* @return $this
368+
*/
369+
public function setPathSeparator($separator)
370+
{
371+
if ($this instanceof ChildrenAwareNodeDefinitionInterface) {
372+
foreach ($this->getChildrenNodeDefinitions() as $child) {
373+
$child->setPathSeparator($separator);
374+
}
375+
} elseif ($this instanceof ParentNodeDefinitionInterface) {
376+
@trigger_error('Passing a ParentNodeDefinitionInterface without ChildrenAwareNodeDefinitionInterface is deprecated since version 3.4 and will be removed in 4.0.', E_USER_DEPRECATED);
377+
}
378+
379+
$this->pathSeparator = $separator;
380+
381+
return $this;
382+
}
359383
}

src/Symfony/Component/Config/Definition/Builder/ParentNodeDefinitionInterface.php

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,9 @@
1818
*/
1919
interface ParentNodeDefinitionInterface
2020
{
21+
/**
22+
* @return NodeBuilder
23+
*/
2124
public function children();
2225

2326
public function append(NodeDefinition $node);

src/Symfony/Component/Config/Definition/Builder/ScalarNodeDefinition.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,6 @@ class ScalarNodeDefinition extends VariableNodeDefinition
2727
*/
2828
protected function instantiateNode()
2929
{
30-
return new ScalarNode($this->name, $this->parent);
30+
return new ScalarNode($this->name, $this->parent, $this->pathSeparator);
3131
}
3232
}

src/Symfony/Component/Config/Definition/Builder/TreeBuilder.php

Lines changed: 32 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,19 @@
2020
*/
2121
class TreeBuilder implements NodeParentInterface
2222
{
23+
/**
24+
* @var NodeInterface|null
25+
*/
2326
protected $tree;
27+
28+
/**
29+
* @var NodeDefinition|null
30+
*/
2431
protected $root;
32+
33+
/**
34+
* @deprecated since version 3.4, to be removed in 4.0
35+
*/
2536
protected $builder;
2637

2738
/**
@@ -51,13 +62,31 @@ public function root($name, $type = 'array', NodeBuilder $builder = null)
5162
*/
5263
public function buildTree()
5364
{
54-
if (null === $this->root) {
55-
throw new \RuntimeException('The configuration tree has no root node.');
56-
}
65+
$this->assertTreeHasRootNode();
5766
if (null !== $this->tree) {
5867
return $this->tree;
5968
}
6069

6170
return $this->tree = $this->root->getNode(true);
6271
}
72+
73+
public function setPathSeparator($separator)
74+
{
75+
$this->assertTreeHasRootNode();
76+
77+
// unset last built as changing path separator changes all nodes
78+
$this->tree = null;
79+
80+
$this->root->setPathSeparator($separator);
81+
}
82+
83+
/**
84+
* @throws \RuntimeException if root node is not defined
85+
*/
86+
private function assertTreeHasRootNode()
87+
{
88+
if (null === $this->root) {
89+
throw new \RuntimeException('The configuration tree has no root node.');
90+
}
91+
}
6392
}

src/Symfony/Component/Config/Definition/Builder/VariableNodeDefinition.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ class VariableNodeDefinition extends NodeDefinition
2727
*/
2828
protected function instantiateNode()
2929
{
30-
return new VariableNode($this->name, $this->parent);
30+
return new VariableNode($this->name, $this->parent, $this->pathSeparator);
3131
}
3232

3333
/**

src/Symfony/Component/Config/Definition/EnumNode.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,14 +22,14 @@ class EnumNode extends ScalarNode
2222
{
2323
private $values;
2424

25-
public function __construct($name, NodeInterface $parent = null, array $values = array())
25+
public function __construct($name, NodeInterface $parent = null, array $values = array(), $pathSeparator = BaseNode::DEFAULT_PATH_SEPARATOR)
2626
{
2727
$values = array_unique($values);
2828
if (empty($values)) {
2929
throw new \InvalidArgumentException('$values must contain at least one element.');
3030
}
3131

32-
parent::__construct($name, $parent);
32+
parent::__construct($name, $parent, $pathSeparator);
3333
$this->values = $values;
3434
}
3535

src/Symfony/Component/Config/Definition/NumericNode.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,9 +23,9 @@ class NumericNode extends ScalarNode
2323
protected $min;
2424
protected $max;
2525

26-
public function __construct($name, NodeInterface $parent = null, $min = null, $max = null)
26+
public function __construct($name, NodeInterface $parent = null, $min = null, $max = null, $pathSeparator = BaseNode::DEFAULT_PATH_SEPARATOR)
2727
{
28-
parent::__construct($name, $parent);
28+
parent::__construct($name, $parent, $pathSeparator);
2929
$this->min = $min;
3030
$this->max = $max;
3131
}
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <[email protected]>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\Component\Config\Tests\Definition;
13+
14+
use PHPUnit\Framework\TestCase;
15+
use Symfony\Component\Config\Definition\BaseNode;
16+
use Symfony\Component\Config\Definition\NodeInterface;
17+
18+
class BaseNodeTest extends TestCase
19+
{
20+
/**
21+
* @dataProvider providePath
22+
*/
23+
public function testGetPathForChildNode($expected, array $params)
24+
{
25+
$constructorArgs = array();
26+
$constructorArgs[] = $params[0];
27+
28+
if (isset($params[1])) {
29+
// Handle old PHPUnit version for PHP 5.5
30+
$parent = method_exists($this, 'createMock')
31+
? $this->createMock(NodeInterface::class)
32+
: $this->getMock(NodeInterface::class);
33+
$parent->method('getPath')->willReturn($params[1]);
34+
35+
$constructorArgs[] = $parent;
36+
37+
if (isset($params[2])) {
38+
$constructorArgs[] = $params[2];
39+
}
40+
}
41+
42+
$node = $this->getMockForAbstractClass(BaseNode::class, $constructorArgs);
43+
44+
$this->assertSame($expected, $node->getPath());
45+
}
46+
47+
public function providePath()
48+
{
49+
return array(
50+
'name only' => array('root', array('root')),
51+
'name and parent' => array('foo.bar.baz.bim', array('bim', 'foo.bar.baz')),
52+
'name and separator' => array('foo', array('foo', null, '/')),
53+
'name, parent and separator' => array('foo.bar/baz/bim', array('bim', 'foo.bar/baz', '/')),
54+
);
55+
}
56+
}

0 commit comments

Comments
 (0)