Skip to content

Commit 5676386

Browse files
authored
Merge pull request #8247 from magento-l3/PR-04202023
Pr 04202023
2 parents f6543e2 + 9e0df17 commit 5676386

File tree

23 files changed

+781
-147
lines changed

23 files changed

+781
-147
lines changed

app/code/Magento/CatalogImportExport/Model/Import/Product.php

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
use Magento\CatalogImportExport\Model\Import\Product\Skip;
1919
use Magento\CatalogImportExport\Model\Import\Product\StatusProcessor;
2020
use Magento\CatalogImportExport\Model\Import\Product\StockProcessor;
21+
use Magento\CatalogImportExport\Model\Import\Product\Type\AbstractType;
2122
use Magento\CatalogImportExport\Model\StockItemImporterInterface;
2223
use Magento\CatalogImportExport\Model\StockItemProcessorInterface;
2324
use Magento\CatalogInventory\Api\Data\StockItemInterface;
@@ -463,7 +464,7 @@ class Product extends AbstractEntity
463464
/**
464465
* Array of supported product types as keys with appropriate model object as value.
465466
*
466-
* @var \Magento\CatalogImportExport\Model\Import\Product\Type\AbstractType[]
467+
* @var AbstractType[]
467468
*/
468469
protected $_productTypeModels = [];
469470

@@ -1225,6 +1226,11 @@ private function initImagesArrayKeys()
12251226
*/
12261227
protected function _initTypeModels()
12271228
{
1229+
// When multiple imports are processed in a single php process,
1230+
// these memory caches may interfere with the import result.
1231+
AbstractType::$commonAttributesCache = [];
1232+
AbstractType::$invAttributesCache = [];
1233+
AbstractType::$attributeCodeToId = [];
12281234
$productTypes = $this->_importConfig->getEntityTypes($this->getEntityTypeCode());
12291235
$fieldsMap = [];
12301236
$specialAttributes = [];
@@ -1236,11 +1242,11 @@ protected function _initTypeModels()
12361242
__('Entity type model \'%1\' is not found', $productTypeConfig['model'])
12371243
);
12381244
}
1239-
if (!$model instanceof \Magento\CatalogImportExport\Model\Import\Product\Type\AbstractType) {
1245+
if (!$model instanceof AbstractType) {
12401246
throw new LocalizedException(
12411247
__(
12421248
'Entity type model must be an instance of '
1243-
. \Magento\CatalogImportExport\Model\Import\Product\Type\AbstractType::class
1249+
. AbstractType::class
12441250
)
12451251
);
12461252
}
@@ -2686,7 +2692,7 @@ public function validateRow(array $rowData, $rowNum)
26862692
// set attribute set code into row data for followed attribute validation in type model
26872693
$rowData[self::COL_ATTR_SET] = $newSku['attr_set_code'];
26882694

2689-
/** @var \Magento\CatalogImportExport\Model\Import\Product\Type\AbstractType $productTypeValidator */
2695+
/** @var AbstractType $productTypeValidator */
26902696
// isRowValid can add error to general errors pull if row is invalid
26912697
$productTypeValidator = $this->_productTypeModels[$newSku['type_id']];
26922698
$productTypeValidator->isRowValid(

app/code/Magento/ImportExport/Model/Export.php

Lines changed: 33 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,12 @@
66

77
namespace Magento\ImportExport\Model;
88

9+
use Magento\Framework\App\ObjectManager;
10+
use Magento\Framework\Filesystem;
11+
use Magento\ImportExport\Model\Export\ConfigInterface;
12+
use Magento\ImportExport\Model\Export\Entity\Factory;
13+
use Psr\Log\LoggerInterface;
14+
915
/**
1016
* Export model
1117
*
@@ -78,25 +84,33 @@ class Export extends \Magento\ImportExport\Model\AbstractModel
7884
];
7985

8086
/**
81-
* @param \Psr\Log\LoggerInterface $logger
82-
* @param \Magento\Framework\Filesystem $filesystem
83-
* @param \Magento\ImportExport\Model\Export\ConfigInterface $exportConfig
84-
* @param \Magento\ImportExport\Model\Export\Entity\Factory $entityFactory
87+
* @var LocaleEmulatorInterface
88+
*/
89+
private $localeEmulator;
90+
91+
/**
92+
* @param LoggerInterface $logger
93+
* @param Filesystem $filesystem
94+
* @param ConfigInterface $exportConfig
95+
* @param Factory $entityFactory
8596
* @param \Magento\ImportExport\Model\Export\Adapter\Factory $exportAdapterFac
8697
* @param array $data
98+
* @param LocaleEmulatorInterface|null $localeEmulator
8799
*/
88100
public function __construct(
89101
\Psr\Log\LoggerInterface $logger,
90102
\Magento\Framework\Filesystem $filesystem,
91103
\Magento\ImportExport\Model\Export\ConfigInterface $exportConfig,
92104
\Magento\ImportExport\Model\Export\Entity\Factory $entityFactory,
93105
\Magento\ImportExport\Model\Export\Adapter\Factory $exportAdapterFac,
94-
array $data = []
106+
array $data = [],
107+
?LocaleEmulatorInterface $localeEmulator = null
95108
) {
96109
$this->_exportConfig = $exportConfig;
97110
$this->_entityFactory = $entityFactory;
98111
$this->_exportAdapterFac = $exportAdapterFac;
99112
parent::__construct($logger, $filesystem, $data);
113+
$this->localeEmulator = $localeEmulator ?? ObjectManager::getInstance()->get(LocaleEmulatorInterface::class);
100114
}
101115

102116
/**
@@ -188,6 +202,20 @@ protected function _getWriter()
188202
* @throws \Magento\Framework\Exception\LocalizedException
189203
*/
190204
public function export()
205+
{
206+
return $this->localeEmulator->emulate(
207+
$this->exportCallback(...),
208+
$this->getData('locale') ?: null
209+
);
210+
}
211+
212+
/**
213+
* Export data.
214+
*
215+
* @return string
216+
* @throws \Magento\Framework\Exception\LocalizedException
217+
*/
218+
private function exportCallback()
191219
{
192220
if (isset($this->_data[self::FILTER_ELEMENT_GROUP])) {
193221
$this->addLogComment(__('Begin export of %1', $this->getEntity()));

app/code/Magento/ImportExport/Model/Export/Consumer.php

Lines changed: 1 addition & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@
1111
use Magento\Framework\Exception\FileSystemException;
1212
use Magento\Framework\Exception\LocalizedException;
1313
use Magento\Framework\Filesystem;
14-
use Magento\Framework\Locale\ResolverInterface;
1514
use Magento\ImportExport\Api\Data\LocalizedExportInfoInterface;
1615
use Magento\ImportExport\Api\ExportManagementInterface;
1716
use Magento\Framework\Notification\NotifierInterface;
@@ -41,31 +40,23 @@ class Consumer
4140
*/
4241
private $filesystem;
4342

44-
/**
45-
* @var ResolverInterface
46-
*/
47-
private $localeResolver;
48-
4943
/**
5044
* Consumer constructor.
5145
* @param \Psr\Log\LoggerInterface $logger
5246
* @param ExportManagementInterface $exportManager
5347
* @param Filesystem $filesystem
5448
* @param NotifierInterface $notifier
55-
* @param ResolverInterface $localeResolver
5649
*/
5750
public function __construct(
5851
\Psr\Log\LoggerInterface $logger,
5952
ExportManagementInterface $exportManager,
6053
Filesystem $filesystem,
61-
NotifierInterface $notifier,
62-
ResolverInterface $localeResolver
54+
NotifierInterface $notifier
6355
) {
6456
$this->logger = $logger;
6557
$this->exportManager = $exportManager;
6658
$this->filesystem = $filesystem;
6759
$this->notifier = $notifier;
68-
$this->localeResolver = $localeResolver;
6960
}
7061

7162
/**
@@ -76,11 +67,6 @@ public function __construct(
7667
*/
7768
public function process(LocalizedExportInfoInterface $exportInfo)
7869
{
79-
$currentLocale = $this->localeResolver->getLocale();
80-
if ($exportInfo->getLocale()) {
81-
$this->localeResolver->setLocale($exportInfo->getLocale());
82-
}
83-
8470
try {
8571
$data = $this->exportManager->export($exportInfo);
8672
$fileName = $exportInfo->getFileName();
@@ -97,8 +83,6 @@ public function process(LocalizedExportInfoInterface $exportInfo)
9783
__('Error during export process occurred. Please check logs for detail')
9884
);
9985
$this->logger->critical('Something went wrong while export process. ' . $exception->getMessage());
100-
} finally {
101-
$this->localeResolver->setLocale($currentLocale);
10286
}
10387
}
10488
}

app/code/Magento/ImportExport/Model/Import.php

Lines changed: 63 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -210,25 +210,31 @@ class Import extends AbstractModel
210210
*/
211211
private $upload;
212212

213+
/**
214+
* @var LocaleEmulatorInterface
215+
*/
216+
private $localeEmulator;
217+
213218
/**
214219
* @param LoggerInterface $logger
215220
* @param Filesystem $filesystem
216221
* @param DataHelper $importExportData
217222
* @param ScopeConfigInterface $coreConfig
218-
* @param Import\ConfigInterface $importConfig
219-
* @param Import\Entity\Factory $entityFactory
223+
* @param ConfigInterface $importConfig
224+
* @param Factory $entityFactory
220225
* @param Data $importData
221-
* @param Export\Adapter\CsvFactory $csvFactory
226+
* @param CsvFactory $csvFactory
222227
* @param FileTransferFactory $httpFactory
223228
* @param UploaderFactory $uploaderFactory
224-
* @param Source\Import\Behavior\Factory $behaviorFactory
229+
* @param Factory $behaviorFactory
225230
* @param IndexerRegistry $indexerRegistry
226231
* @param History $importHistoryModel
227232
* @param DateTime $localeDate
228233
* @param array $data
229234
* @param ManagerInterface|null $messageManager
230235
* @param Random|null $random
231236
* @param Upload|null $upload
237+
* @param LocaleEmulatorInterface|null $localeEmulator
232238
* @SuppressWarnings(PHPMD.ExcessiveParameterList)
233239
*/
234240
public function __construct(
@@ -249,7 +255,8 @@ public function __construct(
249255
array $data = [],
250256
ManagerInterface $messageManager = null,
251257
Random $random = null,
252-
Upload $upload = null
258+
Upload $upload = null,
259+
LocaleEmulatorInterface $localeEmulator = null
253260
) {
254261
$this->_importExportData = $importExportData;
255262
$this->_coreConfig = $coreConfig;
@@ -270,16 +277,36 @@ public function __construct(
270277
->get(Random::class);
271278
$this->upload = $upload ?: ObjectManager::getInstance()
272279
->get(Upload::class);
280+
$this->localeEmulator = $localeEmulator ?: ObjectManager::getInstance()
281+
->get(LocaleEmulatorInterface::class);
273282
parent::__construct($logger, $filesystem, $data);
274283
}
275284

276285
/**
277-
* Create instance of entity adapter and return it
286+
* Returns or create existing instance of entity adapter
278287
*
279288
* @throws LocalizedException
280289
* @return EntityInterface
281290
*/
282291
protected function _getEntityAdapter()
292+
{
293+
if (!$this->_entityAdapter) {
294+
$this->_entityAdapter = $this->localeEmulator->emulate(
295+
$this->createEntityAdapter(...),
296+
$this->getData('locale') ?: null
297+
);
298+
}
299+
300+
return $this->_entityAdapter;
301+
}
302+
303+
/**
304+
* Create instance of entity adapter and return it
305+
*
306+
* @throws LocalizedException
307+
* @return EntityInterface
308+
*/
309+
private function createEntityAdapter()
283310
{
284311
if (!$this->_entityAdapter) {
285312
$entities = $this->_importConfig->getEntities();
@@ -479,6 +506,20 @@ public function getWorkingDir()
479506
* @throws LocalizedException
480507
*/
481508
public function importSource()
509+
{
510+
return $this->localeEmulator->emulate(
511+
$this->importSourceCallback(...),
512+
$this->getData('locale') ?: null
513+
);
514+
}
515+
516+
/**
517+
* Import source file structure to DB.
518+
*
519+
* @return bool
520+
* @throws LocalizedException
521+
*/
522+
private function importSourceCallback()
482523
{
483524
$ids = $this->_getEntityAdapter()->getIds();
484525
if (empty($ids)) {
@@ -629,6 +670,21 @@ protected function _removeBom($sourceFile)
629670
return $this;
630671
}
631672

673+
/**
674+
* Validates source file and returns validation result
675+
*
676+
* @param AbstractSource $source
677+
* @return bool
678+
* @throws LocalizedException
679+
*/
680+
public function validateSource(AbstractSource $source)
681+
{
682+
return $this->localeEmulator->emulate(
683+
fn () => $this->validateSourceCallback($source),
684+
$this->getData('locale') ?: null
685+
);
686+
}
687+
632688
/**
633689
* Validates source file and returns validation result
634690
*
@@ -639,7 +695,7 @@ protected function _removeBom($sourceFile)
639695
* @return bool
640696
* @throws LocalizedException
641697
*/
642-
public function validateSource(AbstractSource $source)
698+
private function validateSourceCallback(AbstractSource $source)
643699
{
644700
$this->addLogComment(__('Begin data validation'));
645701

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
<?php
2+
/**
3+
* Copyright © Magento, Inc. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
declare(strict_types=1);
7+
8+
namespace Magento\ImportExport\Model;
9+
10+
use Magento\Framework\Locale\ResolverInterface;
11+
use Magento\Framework\Phrase;
12+
use Magento\Framework\Phrase\RendererInterface;
13+
use Magento\Framework\TranslateInterface;
14+
15+
class LocaleEmulator implements LocaleEmulatorInterface
16+
{
17+
/**
18+
* @var bool
19+
*/
20+
private bool $isEmulating = false;
21+
22+
/**
23+
* @param TranslateInterface $translate
24+
* @param RendererInterface $phraseRenderer
25+
* @param ResolverInterface $localeResolver
26+
* @param ResolverInterface $defaultLocaleResolver
27+
*/
28+
public function __construct(
29+
private readonly TranslateInterface $translate,
30+
private readonly RendererInterface $phraseRenderer,
31+
private readonly ResolverInterface $localeResolver,
32+
private readonly ResolverInterface $defaultLocaleResolver
33+
) {
34+
}
35+
36+
/**
37+
* @inheritdoc
38+
*/
39+
public function emulate(callable $callback, ?string $locale = null): mixed
40+
{
41+
if ($this->isEmulating) {
42+
return $callback();
43+
}
44+
$this->isEmulating = true;
45+
$locale ??= $this->defaultLocaleResolver->getLocale();
46+
$initialLocale = $this->localeResolver->getLocale();
47+
$initialPhraseRenderer = Phrase::getRenderer();
48+
Phrase::setRenderer($this->phraseRenderer);
49+
$this->localeResolver->setLocale($locale);
50+
$this->translate->setLocale($locale);
51+
$this->translate->loadData();
52+
try {
53+
$result = $callback();
54+
} finally {
55+
Phrase::setRenderer($initialPhraseRenderer);
56+
$this->localeResolver->setLocale($initialLocale);
57+
$this->translate->setLocale($initialLocale);
58+
$this->translate->loadData();
59+
$this->isEmulating = false;
60+
}
61+
return $result;
62+
}
63+
}

0 commit comments

Comments
 (0)