@@ -29,7 +29,7 @@ class Image extends \Magento\Framework\Model\AbstractModel
29
29
/**
30
30
* Config path for the jpeg image quality value
31
31
*/
32
- const XML_PATH_JPEG_QUALITY = 'system/upload_configuration/jpeg_quality ' ;
32
+ public const XML_PATH_JPEG_QUALITY = 'system/upload_configuration/jpeg_quality ' ;
33
33
34
34
/**
35
35
* @var int
@@ -836,7 +836,37 @@ public function getWatermarkHeight()
836
836
public function clearCache ()
837
837
{
838
838
$ directory = $ this ->_catalogProductMediaConfig ->getBaseMediaPath () . '/cache ' ;
839
- $ this ->_mediaDirectory ->delete ($ directory );
839
+ $ directoryToDelete = $ directory ;
840
+ // Fixes issue when deleting cache directory at the same time that images are being
841
+ // lazy-loaded on storefront leading to new directories and files generation in the cache directory
842
+ // that would prevent deletion of the cache directory.
843
+ // RCA: the method delete() recursively enumerates and delete all subdirectories and files before deleting
844
+ // the target directory, which gives other processes time to create directories and files in the same directory.
845
+ // Solution: Rename the directory to simulate deletion and delete the destination directory afterward
846
+
847
+ try {
848
+ //generate name in format: \.[0-9A-ZA-z-_]{3} (e.g .QX3)
849
+ $ tmpDirBasename = strrev (strtr (base64_encode (random_bytes (2 )), '+/= ' , '-_. ' ));
850
+ $ tmpDirectory = $ this ->_catalogProductMediaConfig ->getBaseMediaPath () . '/ ' . $ tmpDirBasename ;
851
+ //delete temporary directory if exists
852
+ if ($ this ->_mediaDirectory ->isDirectory ($ tmpDirectory )) {
853
+ $ this ->_mediaDirectory ->delete ($ tmpDirectory );
854
+ }
855
+ //rename the directory to simulate deletion and delete the destination directory
856
+ if ($ this ->_mediaDirectory ->isDirectory ($ directory ) &&
857
+ true === $ this ->_mediaDirectory ->getDriver ()->rename (
858
+ $ this ->_mediaDirectory ->getAbsolutePath ($ directory ),
859
+ $ this ->_mediaDirectory ->getAbsolutePath ($ tmpDirectory )
860
+ )
861
+ ) {
862
+ $ directoryToDelete = $ tmpDirectory ;
863
+ }
864
+ } catch (\Throwable $ exception ) {
865
+ //ignore exceptions thrown during renaming
866
+ $ directoryToDelete = $ directory ;
867
+ }
868
+
869
+ $ this ->_mediaDirectory ->delete ($ directoryToDelete );
840
870
841
871
$ this ->_coreFileStorageDatabase ->deleteFolder ($ this ->_mediaDirectory ->getAbsolutePath ($ directory ));
842
872
$ this ->clearImageInfoFromCache ();
@@ -870,6 +900,7 @@ protected function _fileExists($filename)
870
900
public function getResizedImageInfo ()
871
901
{
872
902
try {
903
+ $ image = null ;
873
904
if ($ this ->isBaseFilePlaceholder () == true ) {
874
905
$ image = $ this ->imageAsset ->getSourceFile ();
875
906
} else {
@@ -920,6 +951,7 @@ private function getImageSize($imagePath)
920
951
{
921
952
$ imageInfo = $ this ->loadImageInfoFromCache ($ imagePath );
922
953
if (!isset ($ imageInfo ['size ' ])) {
954
+ // phpcs:ignore Magento2.Functions.DiscouragedFunction
923
955
$ imageSize = getimagesize ($ imagePath );
924
956
$ this ->saveImageInfoToCache (['size ' => $ imageSize ], $ imagePath );
925
957
return $ imageSize ;
0 commit comments