diff --git a/src/Symfony/Component/Config/Definition/Builder/ArrayNodeDefinition.php b/src/Symfony/Component/Config/Definition/Builder/ArrayNodeDefinition.php index dca5687a2045..e40d97b2fb89 100644 --- a/src/Symfony/Component/Config/Definition/Builder/ArrayNodeDefinition.php +++ b/src/Symfony/Component/Config/Definition/Builder/ArrayNodeDefinition.php @@ -523,4 +523,26 @@ public function getChildNodeDefinitions() { 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))); + } } diff --git a/src/Symfony/Component/Config/Tests/Definition/Builder/ArrayNodeDefinitionTest.php b/src/Symfony/Component/Config/Tests/Definition/Builder/ArrayNodeDefinitionTest.php index 0aa2a08ab40c..0c414a9b9d26 100644 --- a/src/Symfony/Component/Config/Tests/Definition/Builder/ArrayNodeDefinitionTest.php +++ b/src/Symfony/Component/Config/Tests/Definition/Builder/ArrayNodeDefinitionTest.php @@ -13,6 +13,8 @@ use PHPUnit\Framework\TestCase; 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\Exception\InvalidDefinitionException; use Symfony\Component\Config\Definition\Processor; @@ -357,6 +359,85 @@ public function testCannotBeEmptyOnConcreteNode() $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) { $reflection = new \ReflectionProperty($object, $field); pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy