23
23
use Magento \Framework \Exception \NoSuchEntityException ;
24
24
use Magento \Framework \Filesystem ;
25
25
use Magento \Framework \Filesystem \Driver \File ;
26
+ use Magento \Framework \Filesystem \DriverPool ;
26
27
use Magento \Framework \Intl \DateTimeFactory ;
27
28
use Magento \Framework \Model \ResourceModel \Db \ObjectRelationProcessor ;
28
29
use Magento \Framework \Model \ResourceModel \Db \TransactionManagerInterface ;
@@ -767,11 +768,6 @@ class Product extends AbstractEntity
767
768
*/
768
769
private $ linkProcessor ;
769
770
770
- /**
771
- * @var File
772
- */
773
- private $ fileDriver ;
774
-
775
771
/**
776
772
* @param \Magento\Framework\Json\Helper\Data $jsonHelper
777
773
* @param \Magento\ImportExport\Helper\Data $importExportData
@@ -938,7 +934,6 @@ public function __construct(
938
934
$ this ->dateTimeFactory = $ dateTimeFactory ?? ObjectManager::getInstance ()->get (DateTimeFactory::class);
939
935
$ this ->productRepository = $ productRepository ?? ObjectManager::getInstance ()
940
936
->get (ProductRepositoryInterface::class);
941
- $ this ->fileDriver = $ fileDriver ?: ObjectManager::getInstance ()->get (File::class);
942
937
}
943
938
944
939
/**
@@ -1580,7 +1575,6 @@ protected function _saveProducts()
1580
1575
$ previousType = null ;
1581
1576
$ prevAttributeSet = null ;
1582
1577
1583
- $ importDir = $ this ->_mediaDirectory ->getAbsolutePath ($ this ->getUploader ()->getTmpDir ());
1584
1578
$ existingImages = $ this ->getExistingImages ($ bunch );
1585
1579
$ this ->addImageHashes ($ existingImages );
1586
1580
@@ -1750,7 +1744,10 @@ protected function _saveProducts()
1750
1744
$ position = 0 ;
1751
1745
foreach ($ rowImages as $ column => $ columnImages ) {
1752
1746
foreach ($ columnImages as $ columnImageKey => $ columnImage ) {
1753
- $ uploadedFile = $ this ->getAlreadyExistedImage ($ rowExistingImages , $ columnImage , $ importDir );
1747
+ $ hash = filter_var ($ columnImage , FILTER_VALIDATE_URL )
1748
+ ? $ this ->getRemoteFileHash ($ columnImage )
1749
+ : $ this ->getFileHash ($ this ->joinFilePaths ($ this ->getUploader ()->getTmpDir (), $ columnImage ));
1750
+ $ uploadedFile = $ this ->findImageByHash ($ rowExistingImages , $ hash );
1754
1751
if (!$ uploadedFile && !isset ($ uploadedImages [$ columnImage ])) {
1755
1752
$ uploadedFile = $ this ->uploadMediaFiles ($ columnImage );
1756
1753
$ uploadedFile = $ uploadedFile ?: $ this ->getSystemFile ($ columnImage );
@@ -1955,40 +1952,29 @@ protected function _saveProducts()
1955
1952
*
1956
1953
* @param string $path
1957
1954
* @return string
1955
+ * @throws \Magento\Framework\Exception\FileSystemException
1958
1956
*/
1959
1957
private function getFileHash (string $ path ): string
1960
1958
{
1961
- return hash_file (self ::HASH_ALGORITHM , $ path );
1959
+ $ content = '' ;
1960
+ if ($ this ->_mediaDirectory ->isFile ($ path )
1961
+ && $ this ->_mediaDirectory ->isReadable ($ path )
1962
+ ) {
1963
+ $ content = $ this ->_mediaDirectory ->readFile ($ path );
1964
+ }
1965
+ return $ content ? hash (self ::HASH_ALGORITHM , $ content ) : '' ;
1962
1966
}
1963
1967
1964
1968
/**
1965
- * Returns existed image
1969
+ * Returns hash for remote file
1966
1970
*
1967
- * @param array $imageRow
1968
- * @param string $columnImage
1969
- * @param string $importDir
1971
+ * @param string $filename
1970
1972
* @return string
1971
1973
*/
1972
- private function getAlreadyExistedImage ( array $ imageRow , string $ columnImage , string $ importDir ): string
1974
+ private function getRemoteFileHash ( string $ filename ): string
1973
1975
{
1974
- if (filter_var ($ columnImage , FILTER_VALIDATE_URL )) {
1975
- $ hash = $ this ->getFileHash ($ columnImage );
1976
- } else {
1977
- $ path = $ importDir . DIRECTORY_SEPARATOR . $ columnImage ;
1978
- $ hash = $ this ->isFileExists ($ path ) ? $ this ->getFileHash ($ path ) : '' ;
1979
- }
1980
-
1981
- return array_reduce (
1982
- $ imageRow ,
1983
- function ($ exists , $ file ) use ($ hash ) {
1984
- if (!$ exists && isset ($ file ['hash ' ]) && $ file ['hash ' ] === $ hash ) {
1985
- return $ file ['value ' ];
1986
- }
1987
-
1988
- return $ exists ;
1989
- },
1990
- ''
1991
- );
1976
+ $ hash = hash_file (self ::HASH_ALGORITHM , $ filename );
1977
+ return $ hash !== false ? $ hash : '' ;
1992
1978
}
1993
1979
1994
1980
/**
@@ -1999,38 +1985,19 @@ function ($exists, $file) use ($hash) {
1999
1985
*/
2000
1986
private function addImageHashes (array &$ images ): void
2001
1987
{
2002
- $ productMediaPath = $ this ->filesystem ->getDirectoryRead (DirectoryList::MEDIA )
2003
- ->getAbsolutePath (DIRECTORY_SEPARATOR . 'catalog ' . DIRECTORY_SEPARATOR . 'product ' );
2004
-
1988
+ $ productMediaPath = $ this ->getProductMediaPath ();
2005
1989
foreach ($ images as $ storeId => $ skus ) {
2006
1990
foreach ($ skus as $ sku => $ files ) {
2007
1991
foreach ($ files as $ path => $ file ) {
2008
- if ( $ this ->fileDriver -> isExists ($ productMediaPath . $ file ['value ' ])) {
2009
- $ fileName = $ productMediaPath . $ file [ ' value ' ];
2010
- $ images [$ storeId ][$ sku ][$ path ]['hash ' ] = $ this -> getFileHash ( $ fileName ) ;
1992
+ $ hash = $ this ->getFileHash ( $ this -> joinFilePaths ($ productMediaPath, $ file ['value ' ]));
1993
+ if ( $ hash ) {
1994
+ $ images [$ storeId ][$ sku ][$ path ]['hash ' ] = $ hash ;
2011
1995
}
2012
1996
}
2013
1997
}
2014
1998
}
2015
1999
}
2016
2000
2017
- /**
2018
- * Is file exists
2019
- *
2020
- * @param string $path
2021
- * @return bool
2022
- */
2023
- private function isFileExists (string $ path ): bool
2024
- {
2025
- try {
2026
- $ fileExists = $ this ->fileDriver ->isExists ($ path );
2027
- } catch (\Exception $ exception ) {
2028
- $ fileExists = false ;
2029
- }
2030
-
2031
- return $ fileExists ;
2032
- }
2033
-
2034
2001
/**
2035
2002
* Clears entries from Image Set and Row Data marked as no_selection
2036
2003
*
@@ -2214,23 +2181,15 @@ protected function _getUploader()
2214
2181
2215
2182
$ fileUploader ->init ();
2216
2183
2217
- $ dirConfig = DirectoryList::getDefaultConfig ();
2218
- $ dirAddon = $ dirConfig [DirectoryList::MEDIA ][DirectoryList::PATH ];
2219
-
2220
- // make media folder a primary folder for media in external storages
2221
- if (!is_a ($ this ->_mediaDirectory ->getDriver (), File::class)) {
2222
- $ dirAddon = DirectoryList::MEDIA ;
2223
- }
2224
-
2225
2184
$ tmpPath = $ this ->getImportDir ();
2226
2185
2227
2186
if (!$ fileUploader ->setTmpDir ($ tmpPath )) {
2228
2187
throw new LocalizedException (
2229
2188
__ ('File directory \'%1 \' is not readable. ' , $ tmpPath )
2230
2189
);
2231
2190
}
2232
- $ destinationDir = " catalog/product " ;
2233
- $ destinationPath = $ dirAddon . ' / ' . $ this ->_mediaDirectory -> getRelativePath ( $ destinationDir );
2191
+
2192
+ $ destinationPath = $ this ->getProductMediaPath ( );
2234
2193
2235
2194
$ this ->_mediaDirectory ->create ($ destinationPath );
2236
2195
if (!$ fileUploader ->setDestDir ($ destinationPath )) {
@@ -2284,11 +2243,11 @@ protected function uploadMediaFiles($fileName, $renameFileOff = false)
2284
2243
*/
2285
2244
private function getSystemFile ($ fileName )
2286
2245
{
2287
- $ filePath = 'catalog ' . DIRECTORY_SEPARATOR . 'product ' . DIRECTORY_SEPARATOR . $ fileName ;
2288
- /** @var \Magento\Framework\Filesystem\Directory\ReadInterface $read */
2289
- $ read = $ this ->filesystem ->getDirectoryRead (DirectoryList::MEDIA );
2246
+ $ filePath = $ this ->joinFilePaths ($ this ->getProductMediaPath (), $ fileName );
2290
2247
2291
- return $ read ->isExist ($ filePath ) && $ read ->isReadable ($ filePath ) ? $ fileName : '' ;
2248
+ return $ this ->_mediaDirectory ->isFile ($ filePath ) && $ this ->_mediaDirectory ->isReadable ($ filePath )
2249
+ ? $ fileName
2250
+ : '' ;
2292
2251
}
2293
2252
2294
2253
/**
@@ -3280,4 +3239,68 @@ private function getRowExistingStockItem(array $rowData): StockItemInterface
3280
3239
$ websiteId = $ this ->stockConfiguration ->getDefaultScopeId ();
3281
3240
return $ this ->stockRegistry ->getStockItem ($ productId , $ websiteId );
3282
3241
}
3242
+
3243
+ /**
3244
+ * Returns image that matches the provided hash
3245
+ *
3246
+ * @param array $images
3247
+ * @param string $hash
3248
+ * @return string
3249
+ */
3250
+ private function findImageByHash (array $ images , string $ hash ): string
3251
+ {
3252
+ $ value = '' ;
3253
+ if ($ hash ) {
3254
+ foreach ($ images as $ image ) {
3255
+ if (isset ($ image ['hash ' ]) && $ image ['hash ' ] === $ hash ) {
3256
+ $ value = $ image ['value ' ];
3257
+ break ;
3258
+ }
3259
+ }
3260
+ }
3261
+ return $ value ;
3262
+ }
3263
+
3264
+ /**
3265
+ * Returns product media
3266
+ *
3267
+ * @return string relative path to root folder
3268
+ */
3269
+ private function getProductMediaPath (): string
3270
+ {
3271
+ return $ this ->joinFilePaths ($ this ->getMediaBasePath (), 'catalog ' ,'product ' );
3272
+ }
3273
+
3274
+ /**
3275
+ * Returns media base path
3276
+ *
3277
+ * @return string relative path to root folder
3278
+ */
3279
+ private function getMediaBasePath (): string
3280
+ {
3281
+ $ mediaDir = !is_a ($ this ->_mediaDirectory ->getDriver (), File::class)
3282
+ // make media folder a primary folder for media in external storages
3283
+ ? $ this ->filesystem ->getDirectoryReadByPath (DirectoryList::MEDIA )
3284
+ : $ this ->filesystem ->getDirectoryRead (DirectoryList::MEDIA );
3285
+
3286
+ return $ this ->_mediaDirectory ->getRelativePath ($ mediaDir ->getAbsolutePath ());
3287
+ }
3288
+
3289
+ /**
3290
+ * Joins two paths and remove redundant directory separator
3291
+ *
3292
+ * @param string ...$paths
3293
+ * @return string
3294
+ */
3295
+ private function joinFilePaths (...$ paths ): string
3296
+ {
3297
+ $ result = '' ;
3298
+ if ($ paths ) {
3299
+ $ result = rtrim (array_shift ($ paths ), DIRECTORY_SEPARATOR );
3300
+ foreach ($ paths as $ path ) {
3301
+ $ result .= DIRECTORY_SEPARATOR . ltrim ($ path , DIRECTORY_SEPARATOR );
3302
+ }
3303
+ }
3304
+ return $ result ;
3305
+ }
3283
3306
}
0 commit comments