Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit855f82d

Browse files
committed
Simplifying bundle extension/config definition
1 parent25a5eb2 commit855f82d

File tree

14 files changed

+533
-2
lines changed

14 files changed

+533
-2
lines changed

‎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+
6.1
5+
---
6+
7+
* Add`DefinitionFileLoader` class to load a TreeBuilder definition from an external file
8+
* Add`DefinitionConfigurator` helper
9+
410
6.0
511
---
612

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <fabien@symfony.com>
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+
namespaceSymfony\Component\Config\Definition\Configurator;
13+
14+
useSymfony\Component\Config\Definition\Builder\ArrayNodeDefinition;
15+
useSymfony\Component\Config\Definition\Builder\NodeDefinition;
16+
useSymfony\Component\Config\Definition\Builder\TreeBuilder;
17+
useSymfony\Component\Config\Definition\Loader\DefinitionFileLoader;
18+
19+
/**
20+
* @author Yonel Ceruto <yonelceruto@gmail.com>
21+
*/
22+
class DefinitionConfigurator
23+
{
24+
privateTreeBuilder$treeBuilder;
25+
privateDefinitionFileLoader$loader;
26+
privatestring$path;
27+
privatestring$file;
28+
29+
publicfunction__construct(TreeBuilder$treeBuilder,DefinitionFileLoader$loader,string$path,string$file)
30+
{
31+
$this->treeBuilder =$treeBuilder;
32+
$this->loader =$loader;
33+
$this->path =$path;
34+
$this->file =$file;
35+
}
36+
37+
finalpublicfunctionimport(string$resource,string$type =null,bool$ignoreErrors =false):void
38+
{
39+
$this->loader->setCurrentDir(\dirname($this->path));
40+
$this->loader->import($resource,$type,$ignoreErrors,$this->file);
41+
}
42+
43+
finalpublicfunctionrootNode():NodeDefinition|ArrayNodeDefinition
44+
{
45+
return$this->treeBuilder->getRootNode();
46+
}
47+
48+
finalpublicfunctionsetPathSeparator(string$separator):void
49+
{
50+
$this->treeBuilder->setPathSeparator($separator);
51+
}
52+
}
Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,110 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <fabien@symfony.com>
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+
namespaceSymfony\Component\Config\Definition\Loader;
13+
14+
useSymfony\Component\Config\Definition\Builder\TreeBuilder;
15+
useSymfony\Component\Config\Definition\Configurator\DefinitionConfigurator;
16+
useSymfony\Component\Config\FileLocatorInterface;
17+
useSymfony\Component\Config\Loader\FileLoader;
18+
useSymfony\Component\DependencyInjection\ContainerBuilder;
19+
20+
/**
21+
* @author Yonel Ceruto <yonelceruto@gmail.com>
22+
*/
23+
class DefinitionFileLoaderextends FileLoader
24+
{
25+
privateTreeBuilder$treeBuilder;
26+
private ?ContainerBuilder$container;
27+
28+
publicfunction__construct(TreeBuilder$treeBuilder,FileLocatorInterface$locator,ContainerBuilder$container =null)
29+
{
30+
$this->treeBuilder =$treeBuilder;
31+
$this->container =$container;
32+
33+
parent::__construct($locator);
34+
}
35+
36+
/**
37+
* {@inheritdoc}
38+
*/
39+
publicfunctionload(mixed$resource,string$type =null):mixed
40+
{
41+
// the loader variable are exposed to the included file below
42+
$loader =$this;
43+
44+
$path =$this->locator->locate($resource);
45+
$this->setCurrentDir(\dirname($path));
46+
$this->container?->fileExists($path);
47+
48+
// the closure forbids access to the private scope in the included file
49+
$load = \Closure::bind(staticfunction ($file)use ($loader) {
50+
returninclude$file;
51+
},null, ProtectedDefinitionFileLoader::class);
52+
53+
$callback =$load($path);
54+
55+
if (\is_object($callback) &&\is_callable($callback)) {
56+
$this->executeCallback($callback,newDefinitionConfigurator($this->treeBuilder,$this,$path,$resource),$path);
57+
}
58+
59+
returnnull;
60+
}
61+
62+
/**
63+
* {@inheritdoc}
64+
*/
65+
publicfunctionsupports(mixed$resource,string$type =null):bool
66+
{
67+
if (!\is_string($resource)) {
68+
returnfalse;
69+
}
70+
71+
if (null ===$type &&'php' ===pathinfo($resource, \PATHINFO_EXTENSION)) {
72+
returntrue;
73+
}
74+
75+
return'php' ===$type;
76+
}
77+
78+
privatefunctionexecuteCallback(callable$callback,DefinitionConfigurator$configurator,string$path):void
79+
{
80+
if (!$callbackinstanceof \Closure) {
81+
$callback = \Closure::fromCallable($callback);
82+
}
83+
84+
$arguments = [];
85+
$r =new \ReflectionFunction($callback);
86+
87+
foreach ($r->getParameters()as$parameter) {
88+
$reflectionType =$parameter->getType();
89+
90+
if (!$reflectionTypeinstanceof \ReflectionNamedType) {
91+
thrownew \InvalidArgumentException(sprintf('Could not resolve argument "$%s" for "%s". You must typehint it (for example with "%s").',$parameter->getName(),$path, DefinitionConfigurator::class));
92+
}
93+
94+
$arguments[] =match ($reflectionType->getName()) {
95+
DefinitionConfigurator::class =>$configurator,
96+
TreeBuilder::class =>$this->treeBuilder,
97+
FileLoader::class,self::class =>$this,
98+
};
99+
}
100+
101+
$callback(...$arguments);
102+
}
103+
}
104+
105+
/**
106+
* @internal
107+
*/
108+
finalclass ProtectedDefinitionFileLoaderextends DefinitionFileLoader
109+
{
110+
}
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <fabien@symfony.com>
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+
namespaceSymfony\Component\Config\Tests\Definition\Loader;
13+
14+
usePHPUnit\Framework\TestCase;
15+
useSymfony\Component\Config\Definition\BaseNode;
16+
useSymfony\Component\Config\Definition\Builder\TreeBuilder;
17+
useSymfony\Component\Config\Definition\Loader\DefinitionFileLoader;
18+
useSymfony\Component\Config\FileLocator;
19+
20+
class DefinitionFileLoaderTestextends TestCase
21+
{
22+
publicfunctiontestSupports()
23+
{
24+
$loader =newDefinitionFileLoader(newTreeBuilder('test'),newFileLocator());
25+
26+
$this->assertTrue($loader->supports('foo.php'),'->supports() returns true if the resource is loadable');
27+
$this->assertFalse($loader->supports('foo.foo'),'->supports() returns false if the resource is not loadable');
28+
$this->assertTrue($loader->supports('with_wrong_ext.yml','php'),'->supports() returns true if the resource with forced type is loadable');
29+
}
30+
31+
publicfunctiontestLoad()
32+
{
33+
$loader =newDefinitionFileLoader($treeBuilder =newTreeBuilder('test'),newFileLocator());
34+
$loader->load(__DIR__.'/../../Fixtures/Loader/node_simple.php');
35+
36+
$children =$treeBuilder->buildTree()->getChildren();
37+
38+
$this->assertArrayHasKey('foo',$children);
39+
$this->assertInstanceOf(BaseNode::class,$children['foo']);
40+
$this->assertSame('test.foo',$children['foo']->getPath(),'->load() loads a PHP file resource');
41+
}
42+
}
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
<?php
2+
3+
useSymfony\Component\Config\Definition\Builder\TreeBuilder;
4+
5+
returnstaticfunction (TreeBuilder$treeBuilder) {
6+
$treeBuilder->getRootNode()
7+
->children()
8+
->scalarNode('foo')->end()
9+
->end();
10+
};
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <fabien@symfony.com>
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+
namespaceSymfony\Component\HttpKernel\Bundle;
13+
14+
useSymfony\Component\Config\Definition\Builder\TreeBuilder;
15+
useSymfony\Component\Config\Definition\ConfigurationInterface;
16+
useSymfony\Component\Config\Definition\Configurator\DefinitionConfigurator;
17+
useSymfony\Component\Config\Definition\Loader\DefinitionFileLoader;
18+
useSymfony\Component\Config\FileLocator;
19+
useSymfony\Component\DependencyInjection\ContainerBuilder;
20+
21+
/**
22+
* @author Yonel Ceruto <yonelceruto@gmail.com>
23+
*
24+
* @internal
25+
*/
26+
class BundleConfigurationimplements ConfigurationInterface
27+
{
28+
privateMicroBundle$bundle;
29+
privateContainerBuilder$container;
30+
privatestring$alias;
31+
32+
publicfunction__construct(MicroBundle$bundle,ContainerBuilder$container,string$alias)
33+
{
34+
$this->bundle =$bundle;
35+
$this->container =$container;
36+
$this->alias =$alias;
37+
}
38+
39+
publicfunctiongetConfigTreeBuilder():TreeBuilder
40+
{
41+
$treeBuilder =newTreeBuilder($this->alias);
42+
$file = (new \ReflectionObject($this->bundle))->getFileName();
43+
$loader =newDefinitionFileLoader($treeBuilder,newFileLocator(\dirname($file)),$this->container);
44+
$configurator =newDefinitionConfigurator($treeBuilder,$loader,$file,$file);
45+
46+
$this->bundle->configuration($configurator);
47+
48+
return$treeBuilder;
49+
}
50+
}

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp