Skip to content

Commit 91efad8

Browse files
committed
feat: enhance VendorFileMapper to check file existence in original module
1 parent be9380c commit 91efad8

1 file changed

Lines changed: 40 additions & 55 deletions

File tree

src/Service/VendorFileMapper.php

Lines changed: 40 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -73,18 +73,39 @@ public function mapToThemePath(string $sourcePath, string $themePath, ?string $t
7373
// Start with clean path (e.g. templates/Original_Module/foo.phtml or templates/foo.phtml)
7474
$targetPath = ltrim($cleanPath, '/');
7575

76-
// If path contains the Original Module name as a subdirectory (Hyva convention), strip it
77-
// Example: templates/Mollie_Payment/foo.phtml -> templates/foo.phtml
78-
// This prevents Theme/Mollie_Payment/templates/Mollie_Payment/foo.phtml
79-
// Note: Check both strict and case-insensitive to be safe
80-
if (str_contains($targetPath, '/' . $originalModule . '/')) {
81-
$targetPath = str_replace('/' . $originalModule . '/', '/', $targetPath);
82-
} elseif (stripos($targetPath, '/' . $originalModule . '/') !== false) {
83-
// Case-insensitive replacement if strict failed
84-
$targetPath = str_ireplace('/' . $originalModule . '/', '/', $targetPath);
76+
// Check if file actually exists in the original module's path
77+
$originalModulePath = $this->componentRegistrar->getPath(ComponentRegistrar::MODULE, $originalModule);
78+
$existsInOriginal = false;
79+
80+
if ($originalModulePath) {
81+
$pathInOriginal = $originalModulePath . '/' . $pathInsideModule;
82+
$existsInOriginal = $this->fileDriver->isExists($pathInOriginal);
83+
84+
// If not found in current area (e.g. frontend), check if original uses 'base' area instead
85+
if (!$existsInOriginal && str_starts_with($pathInsideModule, 'view/' . $themeArea . '/')) {
86+
$basePathInOriginal = $originalModulePath . '/' . str_replace('view/' . $themeArea . '/', 'view/base/', $pathInsideModule);
87+
$existsInOriginal = $this->fileDriver->isExists($basePathInOriginal);
88+
}
8589
}
8690

87-
return rtrim($themePath, '/') . '/' . $originalModule . '/' . $targetPath;
91+
if ($existsInOriginal) {
92+
// File exists in original module: resolve path with original module namespace
93+
// If path contains the Original Module name as a subdirectory (Hyva convention), strip it
94+
// Example: templates/Mollie_Payment/foo.phtml -> templates/foo.phtml
95+
// This prevents Theme/Mollie_Payment/templates/Mollie_Payment/foo.phtml
96+
if (str_contains($targetPath, '/' . $originalModule . '/')) {
97+
$targetPath = str_replace('/' . $originalModule . '/', '/', $targetPath);
98+
} elseif (stripos($targetPath, '/' . $originalModule . '/') !== false) {
99+
// Case-insensitive replacement if strict failed
100+
$targetPath = str_ireplace('/' . $originalModule . '/', '/', $targetPath);
101+
}
102+
103+
return rtrim($themePath, '/') . '/' . $originalModule . '/' . $targetPath;
104+
}
105+
106+
// File does NOT exist in original module (e.g. compat-specific template):
107+
// resolve path with compat module namespace
108+
return rtrim($themePath, '/') . '/' . $moduleName . '/' . $targetPath;
88109
}
89110

90111
return rtrim($themePath, '/') . '/' . $moduleName . '/' . ltrim($cleanPath, '/');
@@ -358,54 +379,18 @@ private function parseDiFileForCompatModule(string $diPath, string $moduleName):
358379
libxml_use_internal_errors($libxmlState);
359380

360381
$xpath = new \DOMXPath($dom);
361-
$query = "//argument[@name='compatModules'][@xsi:type='array']/item[@xsi:type='array']";
362-
$items = $xpath->query($query);
363-
364-
if ($items === false || $items->length === 0) {
365-
return null;
366-
}
367-
368-
/** @var \DOMNodeList<\DOMNode> $items */
369-
return $this->findOriginalModuleInXmlItems($items, $xpath, $moduleName);
370-
}
371-
372-
/**
373-
* Find original module in XML items
374-
*
375-
* @param \DOMNodeList<\DOMNode> $items
376-
* @param \DOMXPath $xpath
377-
* @param string $moduleName
378-
* @return string|null
379-
*/
380-
private function findOriginalModuleInXmlItems(\DOMNodeList $items, \DOMXPath $xpath, string $moduleName): ?string
381-
{
382-
foreach ($items as $item) {
383-
$compatModuleValue = null;
384-
$originalModuleValue = null;
385-
386-
/** @var \DOMElement $item */
387-
$childNodes = $xpath->query('item', $item);
388-
if ($childNodes === false) {
389-
continue;
390-
}
391-
392-
foreach ($childNodes as $childNode) {
393-
/** @var \DOMElement $childNode */
394-
$nameAttr = $childNode->getAttribute('name');
395-
$value = trim((string) $childNode->nodeValue);
396-
397-
if ($nameAttr === 'compat_module') {
398-
$compatModuleValue = $value;
399-
} elseif ($nameAttr === 'original_module') {
400-
$originalModuleValue = $value;
401-
}
402-
}
403-
404-
if ($compatModuleValue === $moduleName && $originalModuleValue) {
405-
return $originalModuleValue;
382+
// Look for original_module specifically within CompatModuleRegistry arguments
383+
$query = "//type[@name='Hyva\CompatModuleFallback\Model\CompatModuleRegistry']//item[@name='original_module']";
384+
$nodes = $xpath->query($query);
385+
386+
if ($nodes !== false && $nodes->length > 0) {
387+
$node = $nodes->item(0);
388+
if ($node) {
389+
return trim((string) $node->nodeValue);
406390
}
407391
}
408392

393+
// Fallback to older logic if needed or just return null
409394
return null;
410395
}
411396
}

0 commit comments

Comments
 (0)