Skip to content

Commit c3c0e1d

Browse files
committed
Merge remote-tracking branch 'origin/AC-10573' into spartans_pr_04082025
2 parents b98d464 + f7b9eb3 commit c3c0e1d

File tree

3 files changed

+118
-9
lines changed

3 files changed

+118
-9
lines changed

app/code/Magento/Deploy/Package/Processor/PostProcessor/CssUrls.php

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
<?php
22
/**
3-
* Copyright © Magento, Inc. All rights reserved.
4-
* See COPYING.txt for license details.
3+
* Copyright 2017 Adobe
4+
* All rights reserved.
55
*/
66
namespace Magento\Deploy\Package\Processor\PostProcessor;
77

@@ -66,7 +66,7 @@ public function process(Package $package, array $options)
6666
return false;
6767
}
6868
$urlMap = [];
69-
/** @var PackageFile $file */
69+
/** @var string $fileId */
7070
foreach (array_keys($package->getMap()) as $fileId) {
7171
$filePath = str_replace(\Magento\Framework\View\Asset\Repository::FILE_ID_SEPARATOR, '/', $fileId);
7272
// phpcs:ignore Magento2.Functions.DiscouragedFunction
@@ -227,7 +227,9 @@ private function getValidExternalUrl($url, Package $package)
227227
if (!$this->isFileExistsInPackage($filePath, $package)) {
228228
/** @var PackageFile $matchedFile */
229229
$matchedFile = $this->getFileFromParent($filePath, $package);
230-
$package = $matchedFile->getPackage();
230+
if ($matchedFile && $matchedFile->getPackage()) {
231+
$package = $matchedFile->getPackage();
232+
}
231233
}
232234
return preg_replace(
233235
'/(?<=}})(.*)(?=\/{{)/',

lib/internal/Magento/Framework/App/Test/Unit/View/Asset/PublisherTest.php

Lines changed: 42 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
<?php
22
/**
3-
* Copyright © Magento, Inc. All rights reserved.
4-
* See COPYING.txt for license details.
3+
* Copyright 2014 Adobe
4+
* All rights reserved.
55
*/
66
declare(strict_types=1);
77

@@ -115,6 +115,46 @@ public function testPublish()
115115
$this->assertTrue($this->object->publish($this->getAsset()));
116116
}
117117

118+
public function testPublishWithSourceFileNewer()
119+
{
120+
$this->staticDirRead->expects($this->once())
121+
->method('isExist')
122+
->with('some/file.ext')
123+
->willReturn(true);
124+
$this->staticDirRead->expects($this->once())
125+
->method('readFile')
126+
->with('some/file.ext')
127+
->willReturn('test');
128+
129+
$materializationStrategy =
130+
$this->getMockForAbstractClass(StrategyInterface::class);
131+
132+
$this->materializationStrategyFactory->expects($this->once())
133+
->method('create')
134+
->with($this->getAsset())
135+
->willReturn($materializationStrategy);
136+
$materializationStrategy->expects($this->once())
137+
->method('publishFile')
138+
->with($this->sourceDirWrite, $this->staticDirWrite, 'file.ext', 'some/file.ext')
139+
->willReturn(true);
140+
141+
$this->assertTrue($this->object->publish($this->getAsset()));
142+
}
143+
144+
public function testPublishWithSourceFileOlder()
145+
{
146+
$this->staticDirRead->expects($this->once())
147+
->method('isExist')
148+
->with('some/file.ext')
149+
->willReturn(true);
150+
$this->staticDirRead->expects($this->once())
151+
->method('readFile')
152+
->with('some/file.ext')
153+
->willReturn(null);
154+
155+
$this->assertTrue($this->object->publish($this->getAsset()));
156+
}
157+
118158
/**
119159
* Create an asset mock
120160
*

lib/internal/Magento/Framework/App/View/Asset/Publisher.php

Lines changed: 70 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
<?php
22
/**
3-
* Copyright © Magento, Inc. All rights reserved.
4-
* See COPYING.txt for license details.
3+
* Copyright 2011 Adobe
4+
* All rights reserved.
55
*/
66

77
namespace Magento\Framework\App\View\Asset;
@@ -33,6 +33,11 @@ class Publisher
3333
*/
3434
private $writeFactory;
3535

36+
/**
37+
* @var array
38+
*/
39+
private static $fileHashes = [];
40+
3641
/**
3742
* @param \Magento\Framework\Filesystem $filesystem
3843
* @param MaterializationStrategy\Factory $materializationStrategyFactory
@@ -49,19 +54,81 @@ public function __construct(
4954
}
5055

5156
/**
57+
* Publish the asset
58+
*
5259
* @param Asset\LocalInterface $asset
5360
* @return bool
5461
*/
5562
public function publish(Asset\LocalInterface $asset)
5663
{
5764
$dir = $this->filesystem->getDirectoryRead(DirectoryList::STATIC_VIEW);
58-
if ($dir->isExist($asset->getPath())) {
65+
$targetPath = $asset->getPath();
66+
67+
// Check if target file exists and content hasn't changed
68+
if ($dir->isExist($targetPath) && !$this->hasSourceFileChanged($asset, $dir, $targetPath)) {
5969
return true;
6070
}
6171

6272
return $this->publishAsset($asset);
6373
}
6474

75+
/**
76+
* Check if source file content has changed compared to target file
77+
*
78+
* @param Asset\LocalInterface $asset
79+
* @param \Magento\Framework\Filesystem\Directory\ReadInterface $dir
80+
* @param string $targetPath
81+
* @return bool
82+
*/
83+
private function hasSourceFileChanged(Asset\LocalInterface $asset, $dir, $targetPath)
84+
{
85+
$sourceFile = $asset->getSourceFile();
86+
// Get source file hash
87+
$sourceHash = $this->getFileHash($sourceFile);
88+
89+
// Get target file hash
90+
$targetHash = $this->getTargetFileHash($dir, $targetPath);
91+
92+
// Compare hashes
93+
return $sourceHash !== $targetHash;
94+
}
95+
96+
/**
97+
* Get file hash with caching
98+
*
99+
* @param string $filePath
100+
* @return string|false
101+
*/
102+
private function getFileHash($filePath)
103+
{
104+
if (!isset(self::$fileHashes[$filePath])) {
105+
$content = @file_get_contents($filePath);
106+
if ($content === false) {
107+
self::$fileHashes[$filePath] = false;
108+
} else {
109+
self::$fileHashes[$filePath] = hash('sha256', $content);
110+
}
111+
}
112+
return self::$fileHashes[$filePath];
113+
}
114+
115+
/**
116+
* Get target file hash
117+
*
118+
* @param \Magento\Framework\Filesystem\Directory\ReadInterface $dir
119+
* @param string $targetPath
120+
* @return string|false
121+
*/
122+
private function getTargetFileHash($dir, $targetPath)
123+
{
124+
try {
125+
$content = $dir->readFile($targetPath);
126+
return hash('sha256', $content);
127+
} catch (\Exception $e) {
128+
return false;
129+
}
130+
}
131+
65132
/**
66133
* Publish the asset
67134
*

0 commit comments

Comments
 (0)