@@ -291,74 +291,112 @@ private function parseCompatModuleXml(string $moduleName): ?string
291291 return null ;
292292 }
293293
294- // Check frontend/di.xml first, then global di.xml
295- $ diFile = $ path . '/etc/frontend/di.xml ' ;
296- $ globalDiFile = $ path . '/etc/di.xml ' ;
297-
298- $ filesToCheck = [];
299- if ($ this ->fileDriver ->isExists ($ diFile )) {
300- $ filesToCheck [] = $ diFile ;
301- }
302- if ($ this ->fileDriver ->isExists ($ globalDiFile )) {
303- $ filesToCheck [] = $ globalDiFile ;
304- }
294+ $ filesToCheck = $ this ->getDiFilesToCheck ($ path );
305295
306296 foreach ($ filesToCheck as $ diPath ) {
307- if (!$ this ->fileDriver ->isFile ($ diPath )) { // Extra check for symlinks/is_file
308- continue ;
297+ $ originalModule = $ this ->parseDiFileForCompatModule ($ diPath , $ moduleName );
298+ if ($ originalModule ) {
299+ return $ originalModule ;
309300 }
301+ }
302+ } catch (\Throwable $ e ) {
303+ return null ;
304+ }
310305
311- $ content = $ this ->fileDriver ->fileGetContents ($ diPath );
312- if (!$ content ) {
313- continue ;
314- }
306+ return null ;
307+ }
315308
316- $ dom = new \DOMDocument ();
317- // Suppress warnings for malformed XML or namespace issues
318- $ libxmlState = libxml_use_internal_errors (true );
319- $ dom ->loadXML ($ content );
320- libxml_use_internal_errors ($ libxmlState );
309+ /**
310+ * Get DI files to check for compat module registration
311+ *
312+ * @param string $modulePath
313+ * @return array<string>
314+ */
315+ private function getDiFilesToCheck (string $ modulePath ): array
316+ {
317+ $ diFile = $ modulePath . '/etc/frontend/di.xml ' ;
318+ $ globalDiFile = $ modulePath . '/etc/di.xml ' ;
321319
322- $ xpath = new \DOMXPath ($ dom );
323- // Register namespace? Usually not needed if query is correct
324- // Try to find the compatModules argument node
325- $ query = "//argument[@name='compatModules'][@xsi:type='array']/item[@xsi:type='array'] " ;
326- $ items = $ xpath ->query ($ query );
320+ $ filesToCheck = [];
321+ if ($ this ->fileDriver ->isExists ($ diFile )) {
322+ $ filesToCheck [] = $ diFile ;
323+ }
324+ if ($ this ->fileDriver ->isExists ($ globalDiFile )) {
325+ $ filesToCheck [] = $ globalDiFile ;
326+ }
327327
328- if ($ items === false || $ items ->length === 0 ) {
329- continue ;
330- }
328+ return $ filesToCheck ;
329+ }
331330
332- foreach ($ items as $ item ) {
333- // Check children items for compat_module/original_module keys
334- $ compatModuleValue = null ;
335- $ originalModuleValue = null ;
331+ /**
332+ * Parse a single di.xml file for compat module registration
333+ *
334+ * @param string $diPath
335+ * @param string $moduleName
336+ * @return string|null
337+ */
338+ private function parseDiFileForCompatModule (string $ diPath , string $ moduleName ): ?string
339+ {
340+ if (!$ this ->fileDriver ->isFile ($ diPath )) {
341+ return null ;
342+ }
336343
337- /** @var \DOMElement $item */
338- $ childNodes = $ xpath ->query ('item ' , $ item );
339- if ($ childNodes === false ) {
340- continue ;
341- }
344+ $ content = $ this ->fileDriver ->fileGetContents ($ diPath );
345+ if (!$ content ) {
346+ return null ;
347+ }
342348
343- foreach ( $ childNodes as $ childNode ) {
344- /** @var \DOMElement $childNode */
345- $ nameAttr = $ childNode -> getAttribute ( ' name ' );
346- $ value = trim (( string ) $ childNode -> nodeValue );
349+ $ dom = new \ DOMDocument ();
350+ $ libxmlState = libxml_use_internal_errors ( true );
351+ $ dom -> loadXML ( $ content );
352+ libxml_use_internal_errors ( $ libxmlState );
347353
348- if ($ nameAttr === 'compat_module ' ) {
349- $ compatModuleValue = $ value ;
350- } elseif ($ nameAttr === 'original_module ' ) {
351- $ originalModuleValue = $ value ;
352- }
353- }
354+ $ xpath = new \DOMXPath ($ dom );
355+ $ query = "//argument[@name='compatModules'][@xsi:type='array']/item[@xsi:type='array'] " ;
356+ $ items = $ xpath ->query ($ query );
354357
355- if ($ compatModuleValue === $ moduleName && $ originalModuleValue ) {
356- return $ originalModuleValue ;
357- }
358+ if ($ items === false || $ items ->length === 0 ) {
359+ return null ;
360+ }
361+
362+ return $ this ->findOriginalModuleInXmlItems ($ items , $ xpath , $ moduleName );
363+ }
364+
365+ /**
366+ * Find original module in XML items
367+ *
368+ * @param \DOMNodeList<\DOMNode> $items
369+ * @param \DOMXPath $xpath
370+ * @param string $moduleName
371+ * @return string|null
372+ */
373+ private function findOriginalModuleInXmlItems (\DOMNodeList $ items , \DOMXPath $ xpath , string $ moduleName ): ?string
374+ {
375+ foreach ($ items as $ item ) {
376+ $ compatModuleValue = null ;
377+ $ originalModuleValue = null ;
378+
379+ /** @var \DOMElement $item */
380+ $ childNodes = $ xpath ->query ('item ' , $ item );
381+ if ($ childNodes === false ) {
382+ continue ;
383+ }
384+
385+ foreach ($ childNodes as $ childNode ) {
386+ /** @var \DOMElement $childNode */
387+ $ nameAttr = $ childNode ->getAttribute ('name ' );
388+ $ value = trim ((string ) $ childNode ->nodeValue );
389+
390+ if ($ nameAttr === 'compat_module ' ) {
391+ $ compatModuleValue = $ value ;
392+ } elseif ($ nameAttr === 'original_module ' ) {
393+ $ originalModuleValue = $ value ;
358394 }
359395 }
360- } catch (\Throwable $ e ) {
361- return null ;
396+
397+ if ($ compatModuleValue === $ moduleName && $ originalModuleValue ) {
398+ return $ originalModuleValue ;
399+ }
362400 }
363401
364402 return null ;
0 commit comments