[Config] Introduce find method in ArrayNodeDefinition to ease configuration tree manipulation
This commit is contained in:
parent
9d7e9fcac9
commit
e3b248aee0
@ -523,4 +523,26 @@ class ArrayNodeDefinition extends NodeDefinition implements ParentNodeDefinition
|
|||||||
{
|
{
|
||||||
return $this->children;
|
return $this->children;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Finds a node defined by the given $nodePath.
|
||||||
|
*
|
||||||
|
* @param string $nodePath The path of the node to find. e.g "doctrine.orm.mappings"
|
||||||
|
*/
|
||||||
|
public function find(string $nodePath): NodeDefinition
|
||||||
|
{
|
||||||
|
$firstPathSegment = (false === $pathSeparatorPos = strpos($nodePath, $this->pathSeparator))
|
||||||
|
? $nodePath
|
||||||
|
: substr($nodePath, 0, $pathSeparatorPos);
|
||||||
|
|
||||||
|
if (null === $node = ($this->children[$firstPathSegment] ?? null)) {
|
||||||
|
throw new \RuntimeException(sprintf('Node with name "%s" does not exist in the current node "%s".', $firstPathSegment, $this->name));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (false === $pathSeparatorPos) {
|
||||||
|
return $node;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $node->find(substr($nodePath, $pathSeparatorPos + \strlen($this->pathSeparator)));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -13,6 +13,8 @@ namespace Symfony\Component\Config\Tests\Definition\Builder;
|
|||||||
|
|
||||||
use PHPUnit\Framework\TestCase;
|
use PHPUnit\Framework\TestCase;
|
||||||
use Symfony\Component\Config\Definition\Builder\ArrayNodeDefinition;
|
use Symfony\Component\Config\Definition\Builder\ArrayNodeDefinition;
|
||||||
|
use Symfony\Component\Config\Definition\Builder\BooleanNodeDefinition;
|
||||||
|
use Symfony\Component\Config\Definition\Builder\NodeDefinition;
|
||||||
use Symfony\Component\Config\Definition\Builder\ScalarNodeDefinition;
|
use Symfony\Component\Config\Definition\Builder\ScalarNodeDefinition;
|
||||||
use Symfony\Component\Config\Definition\Exception\InvalidDefinitionException;
|
use Symfony\Component\Config\Definition\Exception\InvalidDefinitionException;
|
||||||
use Symfony\Component\Config\Definition\Processor;
|
use Symfony\Component\Config\Definition\Processor;
|
||||||
@ -357,6 +359,85 @@ class ArrayNodeDefinitionTest extends TestCase
|
|||||||
$node->getNode()->finalize([]);
|
$node->getNode()->finalize([]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function testFindShouldThrowExceptionIfNodeDoesNotExistInRootNode()
|
||||||
|
{
|
||||||
|
$this->expectException(\RuntimeException::class);
|
||||||
|
$this->expectExceptionMessage('Node with name "child" does not exist in the current node "root".');
|
||||||
|
|
||||||
|
$rootNode = new ArrayNodeDefinition('root');
|
||||||
|
$rootNode
|
||||||
|
->children()
|
||||||
|
->arrayNode('social_media_channels')->end()
|
||||||
|
->end()
|
||||||
|
;
|
||||||
|
|
||||||
|
$rootNode->find('child');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testFindShouldHandleComplexConfigurationProperly()
|
||||||
|
{
|
||||||
|
$rootNode = new ArrayNodeDefinition('root');
|
||||||
|
$rootNode
|
||||||
|
->children()
|
||||||
|
->arrayNode('social_media_channels')
|
||||||
|
->children()
|
||||||
|
->booleanNode('enable')->end()
|
||||||
|
->arrayNode('twitter')->end()
|
||||||
|
->arrayNode('facebook')->end()
|
||||||
|
->arrayNode('instagram')
|
||||||
|
->children()
|
||||||
|
->booleanNode('enable')->end()
|
||||||
|
->arrayNode('accounts')->end()
|
||||||
|
->end()
|
||||||
|
->end()
|
||||||
|
->end()
|
||||||
|
->append(
|
||||||
|
$mailerNode = (new ArrayNodeDefinition('mailer'))
|
||||||
|
->children()
|
||||||
|
->booleanNode('enable')->end()
|
||||||
|
->arrayNode('transports')->end()
|
||||||
|
->end()
|
||||||
|
)
|
||||||
|
->end()
|
||||||
|
;
|
||||||
|
|
||||||
|
$this->assertNode('social_media_channels', ArrayNodeDefinition::class, $rootNode->find('social_media_channels'));
|
||||||
|
$this->assertNode('enable', BooleanNodeDefinition::class, $rootNode->find('social_media_channels.enable'));
|
||||||
|
$this->assertNode('twitter', ArrayNodeDefinition::class, $rootNode->find('social_media_channels.twitter'));
|
||||||
|
$this->assertNode('facebook', ArrayNodeDefinition::class, $rootNode->find('social_media_channels.facebook'));
|
||||||
|
$this->assertNode('instagram', ArrayNodeDefinition::class, $rootNode->find('social_media_channels.instagram'));
|
||||||
|
$this->assertNode('enable', BooleanNodeDefinition::class, $rootNode->find('social_media_channels.instagram.enable'));
|
||||||
|
$this->assertNode('accounts', ArrayNodeDefinition::class, $rootNode->find('social_media_channels.instagram.accounts'));
|
||||||
|
|
||||||
|
$this->assertNode('enable', BooleanNodeDefinition::class, $mailerNode->find('enable'));
|
||||||
|
$this->assertNode('transports', ArrayNodeDefinition::class, $mailerNode->find('transports'));
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testFindShouldWorkProperlyForNonDefaultPathSeparator()
|
||||||
|
{
|
||||||
|
$rootNode = new ArrayNodeDefinition('root');
|
||||||
|
$rootNode
|
||||||
|
->setPathSeparator('.|')
|
||||||
|
->children()
|
||||||
|
->arrayNode('mailer.configuration')
|
||||||
|
->children()
|
||||||
|
->booleanNode('enable')->end()
|
||||||
|
->arrayNode('transports')->end()
|
||||||
|
->end()
|
||||||
|
->end()
|
||||||
|
;
|
||||||
|
|
||||||
|
$this->assertNode('mailer.configuration', ArrayNodeDefinition::class, $rootNode->find('mailer.configuration'));
|
||||||
|
$this->assertNode('enable', BooleanNodeDefinition::class, $rootNode->find('mailer.configuration.|enable'));
|
||||||
|
$this->assertNode('transports', ArrayNodeDefinition::class, $rootNode->find('mailer.configuration.|transports'));
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function assertNode(string $expectedName, string $expectedType, NodeDefinition $actualNode): void
|
||||||
|
{
|
||||||
|
$this->assertInstanceOf($expectedType, $actualNode);
|
||||||
|
$this->assertSame($expectedName, $this->getField($actualNode, 'name'));
|
||||||
|
}
|
||||||
|
|
||||||
protected function getField($object, $field)
|
protected function getField($object, $field)
|
||||||
{
|
{
|
||||||
$reflection = new \ReflectionProperty($object, $field);
|
$reflection = new \ReflectionProperty($object, $field);
|
||||||
|
Reference in New Issue
Block a user