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

Commit493b781

Browse files
[FrameworkBundle] Auto-generateconfig/reference.php to assist in writing and discovering app's configuration
1 parent742d742 commit493b781

File tree

77 files changed

+1245
-1097
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

77 files changed

+1245
-1097
lines changed

‎UPGRADE-7.4.md‎

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -41,13 +41,15 @@ DependencyInjection
4141
* Deprecate`ExtensionInterface::getXsdValidationBasePath()` and`getNamespace()`;
4242
bundles that need to support older versions of Symfony can keep the methods
4343
but need to add the`@deprecated` annotation on them
44-
* Deprecate the fluent PHP format for semantic configuration,instantiate builders inline with the configarrayas argument and return theminstead:
44+
* Deprecate the fluent PHP format for semantic configuration,use`$container->extension()` or return anarray instead
4545
```diff
4646
-return function (AcmeConfig $config) {
4747
- $config->color('red');
4848
-}
49-
+return new AcmeConfig([
50-
+ 'color' => 'red',
49+
+return App::config([
50+
+ 'acme' => [
51+
+ 'color' => 'red',
52+
+ ],
5153
+]);
5254
```
5355

‎composer.json‎

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -197,10 +197,6 @@
197197
"Symfony\\Bridge\\Twig\\":"src/Symfony/Bridge/Twig/",
198198
"Symfony\\Bundle\\":"src/Symfony/Bundle/",
199199
"Symfony\\Component\\":"src/Symfony/Component/",
200-
"Symfony\\Config\\": [
201-
"src/Symfony/Component/DependencyInjection/Loader/Config/",
202-
"src/Symfony/Component/Routing/Loader/Config/"
203-
],
204200
"Symfony\\Runtime\\Symfony\\Component\\":"src/Symfony/Component/Runtime/Internal/"
205201
},
206202
"files": [

‎src/Symfony/Bundle/FrameworkBundle/CHANGELOG.md‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ CHANGELOG
44
7.4
55
---
66

7+
* Auto-generate`config/reference.php` to assist in writing and discovering app's configuration
78
* Auto-register routes from attributes found on controller services
89
* Add`ControllerHelper`; the helpers from AbstractController as a standalone service
910
* Allow using their name without added suffix when using`#[Target]` for custom services
Lines changed: 206 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,206 @@
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\Bundle\FrameworkBundle\DependencyInjection\Compiler;
13+
14+
useSymfony\Component\Config\Definition\ArrayShapeGenerator;
15+
useSymfony\Component\Config\Definition\ConfigurationInterface;
16+
useSymfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
17+
useSymfony\Component\DependencyInjection\ContainerBuilder;
18+
useSymfony\Component\DependencyInjection\Extension\ConfigurationExtensionInterface;
19+
useSymfony\Component\DependencyInjection\Loader\Configurator\AppReference;
20+
21+
/**
22+
* @internal
23+
*/
24+
class PhpConfigReferenceDumpPassimplements CompilerPassInterface
25+
{
26+
privateconstREFERENCE_TEMPLATE = <<<'EOPHP'
27+
<?php
28+
29+
namespace Symfony\Component\DependencyInjection\Loader\Configurator;
30+
31+
/**
32+
* This class provides array-shapes for configuring the services and bundles of an application.
33+
*
34+
* Services declared with the config() method are autowired and autoconfigured by default.
35+
*
36+
* All this is auto-generated and is for apps only. Bundles SHOULD NOT rely on it.
37+
*
38+
* Example:
39+
*
40+
* ```php
41+
* // config/services.php
42+
* namespace Symfony\Component\DependencyInjection\Loader\Configurator;
43+
*
44+
* return App::config([
45+
* 'services' => [
46+
* 'App\\' => [
47+
* 'resource' => '../src/',
48+
* ],
49+
* ],
50+
* ]);
51+
* ```
52+
*
53+
* @psalm-import-type ImportsConfig from AppReference
54+
* @psalm-import-type ParametersConfig from AppReference
55+
* @psalm-import-type ServicesConfig from AppReference
56+
*{APP_TYPES}
57+
*/
58+
final class App extends AppReference
59+
{
60+
{APP_SHAPE}
61+
public static function config(array $config): array
62+
{
63+
return parent::config($config);
64+
}
65+
}
66+
67+
namespace Symfony\Component\Routing\Loader\Configurator;
68+
69+
/**
70+
* This class provides array-shapes for configuring the routes of an application.
71+
*
72+
* All this is auto-generated and is for apps only. Bundles SHOULD NOT rely on it.
73+
*
74+
* Example:
75+
*
76+
* ```php
77+
* // config/routes.php
78+
* namespace Symfony\Component\Routing\Loader\Configurator;
79+
*
80+
* return Routes::config([
81+
* 'controllers' => [
82+
* 'resource' => 'attributes',
83+
* 'type' => 'tagged_services',
84+
* ],
85+
* ]);
86+
* ```
87+
*
88+
* @psalm-import-type RouteConfig from RoutesReference
89+
* @psalm-import-type ImportConfig from RoutesReference
90+
* @psalm-import-type AliasConfig from RoutesReference
91+
*
92+
* @psalm-type RoutesConfig = array{{ROUTES_SHAPE}
93+
* ...<string, ImportConfig|RouteConfig|AliasConfig>
94+
* }
95+
*/
96+
final class Routes extends RoutesReference
97+
{
98+
/**
99+
* @param RoutesConfig $config
100+
*
101+
* @return RoutesConfig
102+
*/
103+
public static function config(array $config): array
104+
{
105+
return parent::config($config);
106+
}
107+
}
108+
109+
EOPHP;
110+
111+
publicfunctionprocess(ContainerBuilder$container):void
112+
{
113+
if (!$container->hasParameter('.kernel.config_dir')) {
114+
return;
115+
}
116+
117+
$knownEnvs = [];
118+
if ($container->hasParameter('.container.known_envs')) {
119+
$knownEnvs =array_flip($container->getParameter('.container.known_envs'));
120+
}
121+
if ($container->hasParameter('.kernel.known_envs')) {
122+
$knownEnvs +=array_flip($container->getParameter('.kernel.known_envs'));
123+
}
124+
$knownEnvs =array_keys($knownEnvs);
125+
sort($knownEnvs);
126+
127+
if ($container->hasParameter('.kernel.all_bundles')) {
128+
$allBundles =$container->getParameter('.kernel.all_bundles');
129+
foreach ($allBundlesas$bundle =>$envs) {
130+
if (!$extension = (new$bundle())->getContainerExtension()) {
131+
continue;
132+
}
133+
$extensions[$bundle] =$extension;
134+
}
135+
}else {
136+
$extensions =$container->getExtensions();
137+
}
138+
139+
$types ='';
140+
$genericShape ='';
141+
foreach ($this->getConfigurations($extensions,$container)as$name =>$configuration) {
142+
$type =$this->camelCase($name).'Config';
143+
$types .=\sprintf("\n * @psalm-type %s = %s",$type, ArrayShapeGenerator::generate($configuration->getConfigTreeBuilder()->buildTree()));
144+
$genericShape .=\sprintf("\n %s?: %s,",$name,$type);
145+
}
146+
147+
$shape =str_replace("\n","\n *",$genericShape);
148+
$phpdoc = (new \ReflectionClass(AppReference::class))->getMethod('config')->getDocComment();
149+
150+
if ($phpdoc ===$shape =str_replace("\n * ...<string, ExtensionConfig>,",$shape,$phpdoc)) {
151+
thrownew \LogicException(\sprintf('Cannot find insertion point for config shape in "%s".', AppReference::class));
152+
}
153+
$phpdoc =$shape;
154+
155+
$shape =str_replace("\n","\n *",$genericShape);
156+
157+
if ($phpdoc ===$shape =str_replace("\n * ...<string, ExtensionConfig>,",$shape,$phpdoc)) {
158+
thrownew \LogicException(\sprintf('Cannot find insertion point for config shape in "%s".', AppReference::class));
159+
}
160+
$phpdoc =$shape;
161+
$routesShape ='';
162+
163+
if ($knownEnvs) {
164+
if ($phpdoc ===$shape =preg_replace('{\.\.\.<string, array\{ .* when@%env% .*}',\sprintf("...<'when@%s', array{",implode("'|'when@",$knownEnvs)),$phpdoc)) {
165+
thrownew \LogicException(\sprintf('Cannot find insertion point for config shape in "%s".', AppReference::class));
166+
}
167+
$phpdoc =$shape;
168+
169+
foreach ($knownEnvsas$env) {
170+
$routesShape .="\n * 'when@{$env}'?: array<string, RouteConfig|ImportConfig|AliasConfig>,";
171+
}
172+
}
173+
174+
$configReference =strtr(self::REFERENCE_TEMPLATE, [
175+
'{APP_TYPES}' =>$types,
176+
'{APP_SHAPE}' =>$shape,
177+
'{ROUTES_SHAPE}' =>$routesShape,
178+
]);
179+
180+
// Ignore errors when writing to the file
181+
@file_put_contents($container->getParameter('.kernel.config_dir').'/reference.php',$configReference);
182+
}
183+
184+
privatefunctioncamelCase(string$input):string
185+
{
186+
$output =ucfirst(str_replace('','',ucwords(str_replace('_','',$input))));
187+
188+
returnpreg_replace('#\W#','',$output);
189+
}
190+
191+
privatefunctiongetConfigurations(array$extensions,ContainerBuilder$container):array
192+
{
193+
$configurations = [];
194+
foreach ($extensionsas$extension) {
195+
if (null !==$configuration =match (true) {
196+
$extensioninstanceof ConfigurationInterface =>$extension,
197+
$extensioninstanceof ConfigurationExtensionInterface =>$extension->getConfiguration([],$container),
198+
default =>null,
199+
}) {
200+
$configurations[$extension->getAlias()] =$configuration;
201+
}
202+
}
203+
204+
return$configurations;
205+
}
206+
}

‎src/Symfony/Bundle/FrameworkBundle/FrameworkBundle.php‎

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
useSymfony\Bundle\FrameworkBundle\DependencyInjection\Compiler\AssetsContextPass;
1717
useSymfony\Bundle\FrameworkBundle\DependencyInjection\Compiler\ContainerBuilderDebugDumpPass;
1818
useSymfony\Bundle\FrameworkBundle\DependencyInjection\Compiler\ErrorLoggerCompilerPass;
19+
useSymfony\Bundle\FrameworkBundle\DependencyInjection\Compiler\PhpConfigReferenceDumpPass;
1920
useSymfony\Bundle\FrameworkBundle\DependencyInjection\Compiler\ProfilerPass;
2021
useSymfony\Bundle\FrameworkBundle\DependencyInjection\Compiler\RemoveUnusedSessionMarshallingHandlerPass;
2122
useSymfony\Bundle\FrameworkBundle\DependencyInjection\Compiler\TestServiceContainerRealRefPass;
@@ -148,7 +149,8 @@ public function build(ContainerBuilder $container): void
148149
]);
149150
}
150151

151-
$container->addCompilerPass(newAssetsContextPass(), PassConfig::TYPE_BEFORE_OPTIMIZATION);
152+
$container->addCompilerPass(newPhpConfigReferenceDumpPass());
153+
$container->addCompilerPass(newAssetsContextPass());
152154
$container->addCompilerPass(newLoggerPass(), PassConfig::TYPE_BEFORE_OPTIMIZATION, -32);
153155
$container->addCompilerPass(newRegisterControllerArgumentLocatorsPass());
154156
$container->addCompilerPass(newRemoveEmptyControllerArgumentLocatorsPass(), PassConfig::TYPE_BEFORE_REMOVING);

‎src/Symfony/Bundle/FrameworkBundle/Kernel/MicroKernelTrait.php‎

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -230,4 +230,27 @@ public function loadRoutes(LoaderInterface $loader): RouteCollection
230230

231231
return$collection;
232232
}
233+
234+
/**
235+
* Returns the kernel parameters.
236+
*
237+
* @return array<string, array|bool|string|int|float|\UnitEnum|null>
238+
*/
239+
protectedfunctiongetKernelParameters():array
240+
{
241+
$parameters =parent::getKernelParameters();
242+
$bundlesPath =$this->getBundlesPath();
243+
$allBundles = !is_file($bundlesPath) ? [FrameworkBundle::class => ['all' =>true]] :require$bundlesPath;
244+
$knownEnvs = [$this->environment =>true];
245+
246+
foreach ($allBundlesas$envs) {
247+
$knownEnvs +=$envs;
248+
}
249+
unset($knownEnvs['all']);
250+
$parameters['.kernel.config_dir'] =$this->getConfigDir();
251+
$parameters['.kernel.known_envs'] =array_keys($knownEnvs);
252+
$parameters['.kernel.all_bundles'] =$allBundles;
253+
254+
return$parameters;
255+
}
233256
}

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp