@@ -77,7 +77,7 @@ public function __construct(
7777 */
7878 public function read (): Repository
7979 {
80- $ appConfigFile = $ this ->fileList ->getAppConfig ();
80+ $ appConfigFile = $ this ->fileList ->getAppConfig ();
8181 $ servicesConfigFile = $ this ->fileList ->getServicesConfig ();
8282
8383 if (!$ this ->filesystem ->exists ($ appConfigFile ) || !$ this ->filesystem ->exists ($ servicesConfigFile )) {
@@ -162,49 +162,70 @@ public function read(): Repository
162162 }
163163
164164 /**
165- * Recursively unwrap Symfony YAML TaggedValue objects and handle common tags .
165+ * Recursively normalizes Symfony YAML TaggedValue objects into PHP-native values .
166166 *
167- * This method handles !env, !include, !php/const, and unknown tags,
168- * ensuring all YAML values are normalized to arrays or scalars for safe merging.
167+ * Handles the following YAML tags:
168+ * - !env: resolves environment variables.
169+ * - !include: parses and normalizes included YAML files.
170+ * - !php/const: resolves PHP constants (e.g. !php/const:\PDO::ATTR_ERRMODE).
171+ * - Other or unknown tags: recursively normalize their values.
169172 *
170- * @param mixed $data
171- * @return mixed
173+ * Ensures all YAML data is converted to scalars or arrays suitable for safe merging.
172174 *
173- * @SuppressWarnings("PHPMD.CyclomaticComplexity") Method is intentionally complex due to tag handling.
175+ * @param mixed $data The parsed YAML data (array, scalar, or TaggedValue).
176+ * @return mixed The normalized data structure.
177+ *
178+ * @SuppressWarnings("PHPMD.NPathComplexity")
179+ * @SuppressWarnings("PHPMD.CyclomaticComplexity") Method is intentionally complex due to tag resolution logic.
174180 */
175181 private function normalizeYamlData (mixed $ data ): mixed
176182 {
177183 if ($ data instanceof TaggedValue) {
178- $ tag = $ data ->getTag ();
184+ $ tag = $ data ->getTag (); // e.g. "php/const:\PDO::MYSQL_ATTR_LOCAL_INFILE"
179185 $ value = $ data ->getValue ();
180186
181- switch ($ tag ) {
182- case '!env ' :
183- $ envValue = getenv ((string )$ value );
184- return $ envValue !== false ? $ envValue : null ;
187+ // Handle php/const tags (Symfony strips leading '!')
188+ if (str_starts_with ($ tag , 'php/const: ' )) {
189+ // Extract the constant name
190+ $ constName = substr ($ tag , strlen ('php/const: ' ));
191+ $ constName = ltrim ($ constName , '\\' );
185192
186- case '!include ' :
187- if (file_exists ((string )$ value )) {
188- $ included = Yaml::parseFile ((string )$ value );
189- return $ this ->normalizeYamlData ($ included );
190- }
191- return null ;
193+ // Resolve the constant name to its value if defined
194+ $ constKey = defined ($ constName ) ? constant ($ constName ) : $ constName ;
195+
196+ // Handle YAML quirk where ": 1" is parsed literally
197+ $ raw = is_string ($ value ) ? $ value : (string )$ value ;
198+ $ cleanVal = str_replace ([': ' , ' ' ], '' , $ raw );
199+ $ constVal = is_numeric ($ cleanVal ) ? (int )$ cleanVal : $ cleanVal ;
200+
201+ return [$ constKey => $ constVal ];
202+ }
192203
193- case '!php/const ' :
194- // Evaluate the PHP constant
195- return defined ($ value ) ? constant ($ value ) : null ;
204+ // Handle !env
205+ if ($ tag === 'env ' ) {
206+ $ envValue = getenv ((string )$ value );
207+ return $ envValue !== false ? $ envValue : null ;
208+ }
196209
197- default :
198- $ val = $ this ->normalizeYamlData ($ value );
199- return is_array ($ val ) ? $ val : [$ val ];
210+ // Handle !include
211+ if ($ tag === 'include ' ) {
212+ if (file_exists ((string )$ value )) {
213+ $ included = Yaml::parseFile ((string )$ value );
214+ return $ this ->normalizeYamlData ($ included );
215+ }
216+ return null ;
200217 }
218+
219+ // Default — recursively normalize nested tagged structures
220+ $ normalized = $ this ->normalizeYamlData ($ value );
221+ return is_array ($ normalized ) ? $ normalized : [$ normalized ];
201222 }
202223
224+ // Recursively normalize arrays
203225 if (is_array ($ data )) {
204226 foreach ($ data as $ key => $ value ) {
205227 $ data [$ key ] = $ this ->normalizeYamlData ($ value );
206228 }
207- return $ data ;
208229 }
209230
210231 return $ data ;
0 commit comments