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

Skip to content

Commit 18664f4

Browse files
committed
Add feature allowing change of Path Separator
1 parent 1193c26 commit 18664f4

19 files changed

+257
-21
lines changed

UPGRADE-4.1.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
UPGRADE FROM 4.0 to 4.1
2+
=======================
3+
4+
Config
5+
------
6+
7+
* Implementing `ParentNodeDefinitionInterface` without the `getChildNodeDefinitions()` method
8+
is deprecated and will be unsupported in 5.0.

UPGRADE-5.0.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
UPGRADE FROM 4.x to 5.0
2+
=======================
3+
4+
Config
5+
------
6+
7+
* Added the `getChildNodeDefinitions()` method to `ParentNodeDefinitionInterface`.

src/Symfony/Component/Config/CHANGELOG.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,12 @@
11
CHANGELOG
22
=========
33

4+
4.1.0
5+
-----
6+
7+
* added `setPathSeparator` method to `NodeBuilder` class
8+
* added third `$pathSeparator` constructor argument to `BaseNode`
9+
410
4.0.0
511
-----
612

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

Lines changed: 9 additions & 7 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,18 +34,20 @@ abstract class BaseNode implements NodeInterface
3234
protected $deprecationMessage = null;
3335
protected $equivalentValues = array();
3436
protected $attributes = array();
37+
protected $pathSeparator;
3538

3639
/**
3740
* @throws \InvalidArgumentException if the name contains a period
3841
*/
39-
public function __construct(?string $name, NodeInterface $parent = null)
42+
public function __construct(?string $name, NodeInterface $parent = null, string $pathSeparator = self::DEFAULT_PATH_SEPARATOR)
4043
{
41-
if (false !== strpos($name, '.')) {
42-
throw new \InvalidArgumentException('The name must not contain ".".');
44+
if (false !== strpos($name, $pathSeparator)) {
45+
throw new \InvalidArgumentException('The name must not contain "'.$pathSeparator.'".');
4346
}
4447

4548
$this->name = $name;
4649
$this->parent = $parent;
50+
$this->pathSeparator = $pathSeparator;
4751
}
4852

4953
public function setAttribute($key, $value)
@@ -230,13 +234,11 @@ public function getName()
230234
*/
231235
public function getPath()
232236
{
233-
$path = $this->name;
234-
235237
if (null !== $this->parent) {
236-
$path = $this->parent->getPath().'.'.$path;
238+
return $this->parent->getPath().$this->pathSeparator.$this->name;
237239
}
238240

239-
return $path;
241+
return $this->name;
240242
}
241243

242244
/**

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

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -405,7 +405,7 @@ protected function getNodeBuilder()
405405
protected function createNode()
406406
{
407407
if (null === $this->prototype) {
408-
$node = new ArrayNode($this->name, $this->parent);
408+
$node = new ArrayNode($this->name, $this->parent, $this->pathSeparator);
409409

410410
$this->validateConcreteNode($node);
411411

@@ -416,7 +416,7 @@ protected function createNode()
416416
$node->addChild($child->getNode());
417417
}
418418
} else {
419-
$node = new PrototypedArrayNode($this->name, $this->parent);
419+
$node = new PrototypedArrayNode($this->name, $this->parent, $this->pathSeparator);
420420

421421
$this->validatePrototypeNode($node);
422422

@@ -543,4 +543,12 @@ protected function validatePrototypeNode(PrototypedArrayNode $node)
543543
}
544544
}
545545
}
546+
547+
/**
548+
* @return NodeDefinition[]
549+
*/
550+
public function getChildNodeDefinitions()
551+
{
552+
return $this->children;
553+
}
546554
}

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(?string $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
/**

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

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

54-
return new EnumNode($this->name, $this->parent, $this->values);
54+
return new EnumNode($this->name, $this->parent, $this->values, $this->pathSeparator);
5555
}
5656
}

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: 26 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
protected $parent;
3739
protected $attributes = array();
3840

@@ -346,4 +348,28 @@ protected function normalization()
346348
* @throws InvalidDefinitionException When the definition is invalid
347349
*/
348350
abstract protected function createNode();
351+
352+
/**
353+
* Set PathSeparator to use.
354+
*
355+
* @param string $separator
356+
*
357+
* @return $this
358+
*/
359+
public function setPathSeparator(string $separator)
360+
{
361+
if ($this instanceof ParentNodeDefinitionInterface) {
362+
if (method_exists($this, 'getChildNodeDefinitions')) {
363+
foreach ($this->getChildNodeDefinitions() as $child) {
364+
$child->setPathSeparator($separator);
365+
}
366+
} else {
367+
@trigger_error('Passing a ParentNodeDefinitionInterface without getChildNodeDefinitions() is deprecated since version 4.1 and will be removed in 5.0.', E_USER_DEPRECATED);
368+
}
369+
}
370+
371+
$this->pathSeparator = $separator;
372+
373+
return $this;
374+
}
349375
}

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

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,14 @@
1515
* An interface that must be implemented by nodes which can have children.
1616
*
1717
* @author Victor Berchet <[email protected]>
18+
*
19+
* @method NodeDefinition[] getChildNodeDefinitions() should be implemented since 4.1
1820
*/
1921
interface ParentNodeDefinitionInterface
2022
{
23+
/**
24+
* @return NodeBuilder
25+
*/
2126
public function children();
2227

2328
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: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -50,13 +50,31 @@ public function root($name, $type = 'array', NodeBuilder $builder = null)
5050
*/
5151
public function buildTree()
5252
{
53-
if (null === $this->root) {
54-
throw new \RuntimeException('The configuration tree has no root node.');
55-
}
53+
$this->assertTreeHasRootNode();
5654
if (null !== $this->tree) {
5755
return $this->tree;
5856
}
5957

6058
return $this->tree = $this->root->getNode(true);
6159
}
60+
61+
public function setPathSeparator(string $separator)
62+
{
63+
$this->assertTreeHasRootNode();
64+
65+
// unset last built as changing path separator changes all nodes
66+
$this->tree = null;
67+
68+
$this->root->setPathSeparator($separator);
69+
}
70+
71+
/**
72+
* @throws \RuntimeException if root node is not defined
73+
*/
74+
private function assertTreeHasRootNode()
75+
{
76+
if (null === $this->root) {
77+
throw new \RuntimeException('The configuration tree has no root node.');
78+
}
79+
}
6280
}

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: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ public function __construct(?string $name, NodeInterface $parent = null, array $
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(?string $name, NodeInterface $parent = null, $min = null, $max = null)
26+
public function __construct(?string $name, NodeInterface $parent = null, $min = null, $max = null, string $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+
}
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
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\Builder;
13+
14+
use PHPUnit\Framework\TestCase;
15+
use Symfony\Component\Config\Definition\Builder\ArrayNodeDefinition;
16+
use Symfony\Component\Config\Definition\Builder\NodeDefinition;
17+
use Symfony\Component\Config\Definition\Builder\ScalarNodeDefinition;
18+
19+
class NodeDefinitionTest extends TestCase
20+
{
21+
public function testDefaultPathSeparatorIsDot()
22+
{
23+
$node = $this->getMockForAbstractClass(NodeDefinition::class, array('foo'));
24+
25+
$this->assertAttributeSame('.', 'pathSeparator', $node);
26+
}
27+
28+
public function testSetPathSeparatorChangesChildren()
29+
{
30+
$node = new ArrayNodeDefinition('foo');
31+
$scalar = new ScalarNodeDefinition('bar');
32+
$node->append($scalar);
33+
34+
$node->setPathSeparator('/');
35+
36+
$this->assertAttributeSame('/', 'pathSeparator', $node);
37+
$this->assertAttributeSame('/', 'pathSeparator', $scalar);
38+
}
39+
}

0 commit comments

Comments
 (0)