15
15
use Symfony \Component \DependencyInjection \Extension \ConfigurationExtensionInterface ;
16
16
use Symfony \Component \DependencyInjection \Extension \Extension ;
17
17
use Symfony \Component \DependencyInjection \Extension \PrependExtensionInterface ;
18
- use Symfony \Component \DependencyInjection \Parameterbag \EnvPlaceholderParameterBag ;
18
+ use Symfony \Component \DependencyInjection \ParameterBag \EnvPlaceholderParameterBag ;
19
19
20
20
/**
21
21
* Merges extension configs into the container builder.
@@ -45,12 +45,14 @@ public function process(ContainerBuilder $container)
45
45
// this extension was not called
46
46
continue ;
47
47
}
48
- // EnvPlaceholderParameterBag tracks env vars when calling resolveValue().
49
- // Clone so that tracking is done in a dedicated bag.
50
- $ resolvingBag = clone $ container ->getParameterBag ();
48
+ $ resolvingBag = $ container ->getParameterBag ();
49
+ if ($ resolvingBag instanceof EnvPlaceholderParameterBag && $ extension instanceof Extension) {
50
+ // create a dedicated bag so that we can track env vars per-extension
51
+ $ resolvingBag = new MergeExtensionConfigurationParameterBag ($ resolvingBag );
52
+ }
51
53
$ config = $ resolvingBag ->resolveValue ($ config );
52
54
53
- $ tmpContainer = new ContainerBuilder ($ container -> getParameterBag () );
55
+ $ tmpContainer = new ContainerBuilder ($ resolvingBag );
54
56
$ tmpContainer ->setResourceTracking ($ container ->isTrackingResources ());
55
57
$ tmpContainer ->addObjectResource ($ extension );
56
58
if ($ extension instanceof ConfigurationExtensionInterface && null !== $ configuration = $ extension ->getConfiguration ($ config , $ tmpContainer )) {
@@ -63,13 +65,9 @@ public function process(ContainerBuilder $container)
63
65
64
66
$ extension ->load ($ config , $ tmpContainer );
65
67
66
- if ($ resolvingBag instanceof EnvPlaceholderParameterBag) {
67
- // $resolvingBag keeps track of env vars encoutered *before* merging configs
68
- if ($ extension instanceof Extension) {
69
- // but we don't want to keep track of env vars that are *overridden* when configs are merged
70
- $ resolvingBag = new MergeExtensionConfigurationParameterBag ($ extension , $ resolvingBag );
71
- }
72
- $ container ->getParameterBag ()->mergeEnvPlaceholders ($ resolvingBag );
68
+ if ($ resolvingBag instanceof MergeExtensionConfigurationParameterBag) {
69
+ // don't keep track of env vars that are *overridden* when configs are merged
70
+ $ resolvingBag ->freezeAfterProcessing ($ extension );
73
71
}
74
72
75
73
$ container ->merge ($ tmpContainer );
@@ -86,60 +84,36 @@ public function process(ContainerBuilder $container)
86
84
*/
87
85
class MergeExtensionConfigurationParameterBag extends EnvPlaceholderParameterBag
88
86
{
89
- private $ beforeProcessingEnvPlaceholders ;
87
+ private $ processedEnvPlaceholders ;
90
88
91
- public function __construct (Extension $ extension , parent $ resolvingBag )
89
+ public function __construct (parent $ parameterBag )
92
90
{
93
- $ this ->beforeProcessingEnvPlaceholders = $ resolvingBag ->getEnvPlaceholders ();
94
- $ config = $ this ->resolveEnvPlaceholders ($ extension ->getProcessedConfigs ());
95
- parent ::__construct ($ this ->resolveValue ($ config ));
91
+ parent ::__construct ($ parameterBag ->all ());
92
+ $ this ->mergeEnvPlaceholders ($ parameterBag );
96
93
}
97
94
98
- /**
99
- * {@inheritdoc}
100
- */
101
- public function get ($ name )
95
+ public function freezeAfterProcessing (Extension $ extension )
102
96
{
103
- return $ this ->has ($ name ) || (0 === strpos ($ name , 'env( ' ) && ') ' === substr ($ name , -1 ) && 'env() ' !== $ name ) ? parent ::get ($ name ) : '' ;
104
- }
97
+ $ this ->processedEnvPlaceholders = array ();
105
98
106
- /**
107
- * {@inheritdoc}
108
- */
109
- public function getEnvPlaceholders ()
110
- {
111
- // contains the list of env vars that are still used after configs have been merged
112
- $ envPlaceholders = parent ::getEnvPlaceholders ();
99
+ // serialize config to catch env vars nested in object graphs
100
+ $ config = serialize ($ extension ->getProcessedConfigs ());
113
101
114
- foreach ($ envPlaceholders as $ env => $ placeholders ) {
115
- if (isset ($ this ->beforeProcessingEnvPlaceholders [$ env ])) {
116
- // for still-used env vars, keep track of their before-processing placeholders
117
- $ envPlaceholders [$ env ] += $ this ->beforeProcessingEnvPlaceholders [$ env ];
102
+ foreach (parent ::getEnvPlaceholders () as $ env => $ placeholders ) {
103
+ foreach ($ placeholders as $ placeholder ) {
104
+ if (false !== stripos ($ config , $ placeholder )) {
105
+ $ this ->processedEnvPlaceholders [$ env ] = $ placeholders ;
106
+ break ;
107
+ }
118
108
}
119
109
}
120
-
121
- return $ envPlaceholders ;
122
110
}
123
111
124
112
/**
125
- * Replaces-back env placeholders to their original "%env(FOO)%" version.
113
+ * {@inheritdoc}
126
114
*/
127
- private function resolveEnvPlaceholders ( $ value )
115
+ public function getEnvPlaceholders ( )
128
116
{
129
- if (is_array ($ value )) {
130
- foreach ($ value as $ k => $ v ) {
131
- $ value [$ this ->resolveEnvPlaceholders ($ k )] = $ this ->resolveEnvPlaceholders ($ v );
132
- }
133
- } elseif (is_string ($ value )) {
134
- foreach ($ this ->beforeProcessingEnvPlaceholders as $ env => $ placeholders ) {
135
- foreach ($ placeholders as $ placeholder ) {
136
- if (false !== stripos ($ value , $ placeholder )) {
137
- $ value = str_ireplace ($ placeholder , "%env( $ env)% " , $ value );
138
- }
139
- }
140
- }
141
- }
142
-
143
- return $ value ;
117
+ return null !== $ this ->processedEnvPlaceholders ? $ this ->processedEnvPlaceholders : parent ::getEnvPlaceholders ();
144
118
}
145
119
}
0 commit comments