Skip to content

Commit 3b1d41a

Browse files
committed
Merge remote-tracking branch 'origin/ACP2E-4038' into PR_2025_07_18_chittima
2 parents 3842a53 + 17a78fa commit 3b1d41a

File tree

2 files changed

+106
-45
lines changed
  • app/code/Magento/CatalogImportExport/Model/Import
  • dev/tests/integration/testsuite/Magento/CatalogImportExport/Model/Import/ProductTest

2 files changed

+106
-45
lines changed

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

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1688,10 +1688,11 @@ protected function _saveProducts()
16881688
}
16891689
$rowScope = $this->getRowScope($rowData);
16901690
$urlKey = $this->getUrlKey($rowData);
1691+
$rowSku = $rowData[self::COL_SKU];
16911692
if (!empty($rowData[self::URL_KEY])) {
16921693
// If url_key column and its value were in the CSV file
16931694
$rowData[self::URL_KEY] = $urlKey;
1694-
} elseif ($this->isNeedToChangeUrlKey($rowData)) {
1695+
} elseif ($this->isNeedToChangeUrlKey($rowData, isset($entityRowsIn[strtolower($rowSku)]))) {
16951696
// If url_key column was empty or even not declared in the CSV file but by the rules it needs
16961697
// to be settled. In case when url_key is generating from name column we have to ensure that
16971698
// the bunch of products will pass for the event with url_key column.
@@ -1701,7 +1702,6 @@ protected function _saveProducts()
17011702
// remove null byte character
17021703
$rowData[self::COL_NAME] = preg_replace(self::COL_NAME_FORMAT, '', $rowData[self::COL_NAME]);
17031704
}
1704-
$rowSku = $rowData[self::COL_SKU];
17051705
if (null === $rowSku) {
17061706
$this->getErrorAggregator()->addRowToSkip($rowNum);
17071707
continue;
@@ -3275,15 +3275,16 @@ protected function getResource()
32753275
* Whether a url key needs to change.
32763276
*
32773277
* @param array $rowData
3278+
* @param bool $hasParentRow
32783279
* @return bool
32793280
*/
3280-
private function isNeedToChangeUrlKey(array $rowData): bool
3281+
private function isNeedToChangeUrlKey(array $rowData, bool $hasParentRow = false): bool
32813282
{
32823283
$urlKey = $this->getUrlKey($rowData);
32833284
$productExists = $this->isSkuExist($rowData[self::COL_SKU]);
32843285
$markedToEraseUrlKey = isset($rowData[self::URL_KEY]);
32853286
// The product isn't new and the url key index wasn't marked for change.
3286-
if (!$urlKey && $productExists && !$markedToEraseUrlKey) {
3287+
if ($hasParentRow && empty($rowData[self::URL_KEY]) || !$urlKey && $productExists && !$markedToEraseUrlKey) {
32873288
// Seems there is no need to change the url key
32883289
return false;
32893290
}

dev/tests/integration/testsuite/Magento/CatalogImportExport/Model/Import/ProductTest/ProductUrlKeyTest.php

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

88
namespace Magento\CatalogImportExport\Model\Import\ProductTest;
99

10+
use Magento\Catalog\Api\Data\ProductInterface;
1011
use Magento\Catalog\Api\ProductRepositoryInterface;
12+
use Magento\Catalog\Model\Attribute\ScopeOverriddenValue;
1113
use Magento\Catalog\Test\Fixture\Product as ProductFixture;
1214
use Magento\CatalogImportExport\Model\Import\Product\RowValidatorInterface;
15+
use Magento\CatalogImportExport\Model\Import\Product\StoreResolver;
1316
use Magento\CatalogImportExport\Model\Import\ProductTestBase;
1417
use Magento\Framework\App\Filesystem\DirectoryList;
1518
use Magento\Framework\Exception\LocalizedException;
1619
use Magento\Framework\Filesystem;
1720
use Magento\ImportExport\Model\Import;
21+
use Magento\ImportExport\Model\Import\ErrorProcessing\ProcessingErrorAggregatorInterface;
1822
use Magento\ImportExport\Model\Import\Source\Csv;
23+
use Magento\ImportExport\Test\Fixture\CsvFile as CsvFileFixture;
24+
use Magento\Store\Test\Fixture\Store;
1925
use Magento\TestFramework\Fixture\Config;
2026
use Magento\TestFramework\Fixture\DataFixture;
27+
use Magento\TestFramework\Fixture\DataFixtureStorageManager;
28+
use Magento\TestFramework\Helper\Bootstrap;
2129

2230
/**
2331
* Integration test for \Magento\CatalogImportExport\Model\Import\Product class.
@@ -41,26 +49,26 @@ public function testImportWithoutUrlKeysAndName()
4149
'simple1' => 'url-key',
4250
'simple2' => 'url-key2',
4351
];
44-
$filesystem = $this->objectManager->create(\Magento\Framework\Filesystem::class);
52+
$filesystem = $this->objectManager->create(Filesystem::class);
4553
$directory = $filesystem->getDirectoryWrite(DirectoryList::ROOT);
4654
$source = $this->objectManager->create(
47-
\Magento\ImportExport\Model\Import\Source\Csv::class,
55+
Csv::class,
4856
[
4957
'file' => __DIR__ . '/../_files/products_to_import_without_url_keys_and_name.csv',
5058
'directory' => $directory
5159
]
5260
);
5361

5462
$errors = $this->_model->setParameters(
55-
['behavior' => \Magento\ImportExport\Model\Import::BEHAVIOR_APPEND, 'entity' => 'catalog_product']
63+
['behavior' => Import::BEHAVIOR_APPEND, 'entity' => 'catalog_product']
5664
)
5765
->setSource($source)
5866
->validateData();
5967

6068
$this->assertTrue($errors->getErrorsCount() == 0);
6169
$this->_model->importData();
6270

63-
$productRepository = $this->objectManager->create(\Magento\Catalog\Api\ProductRepositoryInterface::class);
71+
$productRepository = $this->objectManager->create(ProductRepositoryInterface::class);
6472
foreach ($products as $productSku => $productUrlKey) {
6573
$this->assertEquals($productUrlKey, $productRepository->get($productSku)->getUrlKey());
6674
}
@@ -75,21 +83,21 @@ public function testImportWithoutUrlKeysAndName()
7583
*/
7684
public function testValidateUrlKeys($importFile, $expectedErrors)
7785
{
78-
$filesystem = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create(
79-
\Magento\Framework\Filesystem::class
86+
$filesystem = Bootstrap::getObjectManager()->create(
87+
Filesystem::class
8088
);
8189
$directory = $filesystem->getDirectoryWrite(DirectoryList::ROOT);
8290

8391
$source = $this->objectManager->create(
84-
\Magento\ImportExport\Model\Import\Source\Csv::class,
92+
Csv::class,
8593
[
8694
'file' => __DIR__ . '/../_files/' . $importFile,
8795
'directory' => $directory
8896
]
8997
);
90-
/** @var \Magento\ImportExport\Model\Import\ErrorProcessing\ProcessingErrorAggregatorInterface $errors */
98+
/** @var ProcessingErrorAggregatorInterface $errors */
9199
$errors = $this->_model->setParameters(
92-
['behavior' => \Magento\ImportExport\Model\Import::BEHAVIOR_APPEND, 'entity' => 'catalog_product']
100+
['behavior' => Import::BEHAVIOR_APPEND, 'entity' => 'catalog_product']
93101
)->setSource(
94102
$source
95103
)->validateData();
@@ -139,20 +147,20 @@ public static function validateUrlKeysDataProvider()
139147
*/
140148
public function testValidateUrlKeysMultipleStores()
141149
{
142-
$filesystem = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create(
143-
\Magento\Framework\Filesystem::class
150+
$filesystem = Bootstrap::getObjectManager()->create(
151+
Filesystem::class
144152
);
145153
$directory = $filesystem->getDirectoryWrite(DirectoryList::ROOT);
146154

147155
$source = $this->objectManager->create(
148-
\Magento\ImportExport\Model\Import\Source\Csv::class,
156+
Csv::class,
149157
[
150158
'file' => __DIR__ . '/../_files/products_to_check_valid_url_keys_multiple_stores.csv',
151159
'directory' => $directory
152160
]
153161
);
154162
$errors = $this->_model->setParameters(
155-
['behavior' => \Magento\ImportExport\Model\Import::BEHAVIOR_APPEND, 'entity' => 'catalog_product']
163+
['behavior' => Import::BEHAVIOR_APPEND, 'entity' => 'catalog_product']
156164
)->setSource(
157165
$source
158166
)->validateData();
@@ -173,28 +181,28 @@ public function testExistingProductWithUrlKeys()
173181
// added by _files/products_to_import_with_valid_url_keys.csv
174182
$this->importedProducts[] = 'simple3';
175183

176-
$filesystem = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()
177-
->create(\Magento\Framework\Filesystem::class);
184+
$filesystem = Bootstrap::getObjectManager()
185+
->create(Filesystem::class);
178186
$directory = $filesystem->getDirectoryWrite(DirectoryList::ROOT);
179187
$source = $this->objectManager->create(
180-
\Magento\ImportExport\Model\Import\Source\Csv::class,
188+
Csv::class,
181189
[
182190
'file' => __DIR__ . '/../_files/products_to_import_with_valid_url_keys.csv',
183191
'directory' => $directory
184192
]
185193
);
186194

187195
$errors = $this->_model->setParameters(
188-
['behavior' => \Magento\ImportExport\Model\Import::BEHAVIOR_APPEND, 'entity' => 'catalog_product']
196+
['behavior' => Import::BEHAVIOR_APPEND, 'entity' => 'catalog_product']
189197
)->setSource(
190198
$source
191199
)->validateData();
192200

193201
$this->assertTrue($errors->getErrorsCount() == 0);
194202
$this->_model->importData();
195203

196-
$productRepository = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create(
197-
\Magento\Catalog\Api\ProductRepositoryInterface::class
204+
$productRepository = Bootstrap::getObjectManager()->create(
205+
ProductRepositoryInterface::class
198206
);
199207
foreach ($products as $productSku => $productUrlKey) {
200208
$this->assertEquals($productUrlKey, $productRepository->get($productSku)->getUrlKey());
@@ -214,28 +222,28 @@ public function testAddUpdateProductWithInvalidUrlKeys() : void
214222
// added by _files/products_to_import_with_invalid_url_keys.csv
215223
$this->importedProducts[] = 'simple3';
216224

217-
$filesystem = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()
218-
->create(\Magento\Framework\Filesystem::class);
225+
$filesystem = Bootstrap::getObjectManager()
226+
->create(Filesystem::class);
219227
$directory = $filesystem->getDirectoryWrite(DirectoryList::ROOT);
220228
$source = $this->objectManager->create(
221-
\Magento\ImportExport\Model\Import\Source\Csv::class,
229+
Csv::class,
222230
[
223231
'file' => __DIR__ . '/../_files/products_to_import_with_invalid_url_keys.csv',
224232
'directory' => $directory
225233
]
226234
);
227235

228236
$errors = $this->_model->setParameters(
229-
['behavior' => \Magento\ImportExport\Model\Import::BEHAVIOR_ADD_UPDATE, 'entity' => 'catalog_product']
237+
['behavior' => Import::BEHAVIOR_ADD_UPDATE, 'entity' => 'catalog_product']
230238
)->setSource(
231239
$source
232240
)->validateData();
233241

234242
$this->assertTrue($errors->getErrorsCount() == 0);
235243
$this->_model->importData();
236244

237-
$productRepository = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create(
238-
\Magento\Catalog\Api\ProductRepositoryInterface::class
245+
$productRepository = Bootstrap::getObjectManager()->create(
246+
ProductRepositoryInterface::class
239247
);
240248
foreach ($products as $productSku => $productUrlKey) {
241249
$this->assertEquals($productUrlKey, $productRepository->get($productSku)->getUrlKey());
@@ -282,26 +290,26 @@ public function testImportWithoutUrlKeys()
282290
// added by _files/products_to_import_without_url_keys.csv
283291
$this->importedProducts[] = 'simple3';
284292

285-
$filesystem = $this->objectManager->create(\Magento\Framework\Filesystem::class);
293+
$filesystem = $this->objectManager->create(Filesystem::class);
286294
$directory = $filesystem->getDirectoryWrite(DirectoryList::ROOT);
287295
$source = $this->objectManager->create(
288-
\Magento\ImportExport\Model\Import\Source\Csv::class,
296+
Csv::class,
289297
[
290298
'file' => __DIR__ . '/../_files/products_to_import_without_url_keys.csv',
291299
'directory' => $directory
292300
]
293301
);
294302

295303
$errors = $this->_model->setParameters(
296-
['behavior' => \Magento\ImportExport\Model\Import::BEHAVIOR_APPEND, 'entity' => 'catalog_product']
304+
['behavior' => Import::BEHAVIOR_APPEND, 'entity' => 'catalog_product']
297305
)
298306
->setSource($source)
299307
->validateData();
300308

301309
$this->assertTrue($errors->getErrorsCount() == 0);
302310
$this->_model->importData();
303311

304-
$productRepository = $this->objectManager->create(\Magento\Catalog\Api\ProductRepositoryInterface::class);
312+
$productRepository = $this->objectManager->create(ProductRepositoryInterface::class);
305313
foreach ($products as $productSku => $productUrlKey) {
306314
$this->assertEquals($productUrlKey, $productRepository->get($productSku)->getUrlKey());
307315
}
@@ -325,18 +333,18 @@ public function testImportWithNonLatinUrlKeys()
325333
$productSkuMap = array_merge($productsCreatedByFixture, $productsImportedByCsv);
326334
$this->importedProducts = array_keys($productsImportedByCsv);
327335

328-
$filesystem = $this->objectManager->create(\Magento\Framework\Filesystem::class);
336+
$filesystem = $this->objectManager->create(Filesystem::class);
329337
$directory = $filesystem->getDirectoryWrite(DirectoryList::ROOT);
330338
$source = $this->objectManager->create(
331-
\Magento\ImportExport\Model\Import\Source\Csv::class,
339+
Csv::class,
332340
[
333341
'file' => __DIR__ . '/../_files/products_to_import_with_non_latin_url_keys.csv',
334342
'directory' => $directory,
335343
]
336344
);
337345

338346
$errors = $this->_model->setParameters(
339-
['behavior' => \Magento\ImportExport\Model\Import::BEHAVIOR_ADD_UPDATE, 'entity' => 'catalog_product']
347+
['behavior' => Import::BEHAVIOR_ADD_UPDATE, 'entity' => 'catalog_product']
340348
)
341349
->setSource($source)
342350
->validateData();
@@ -364,17 +372,17 @@ public function testImportWithSpacesInUrlKeys()
364372
'simple1' => 'url-with-spaces-1',
365373
'simple2' => 'url-with-spaces-2'
366374
];
367-
$filesystem = $this->objectManager->create(\Magento\Framework\Filesystem::class);
375+
$filesystem = $this->objectManager->create(Filesystem::class);
368376
$directory = $filesystem->getDirectoryWrite(DirectoryList::ROOT);
369377
$source = $this->objectManager->create(
370-
\Magento\ImportExport\Model\Import\Source\Csv::class,
378+
Csv::class,
371379
[
372380
'file' => __DIR__ . '/../_files/products_to_import_with_spaces_in_url_keys.csv',
373381
'directory' => $directory,
374382
]
375383
);
376384
$errors = $this->_model->setParameters(
377-
['behavior' => \Magento\ImportExport\Model\Import::BEHAVIOR_ADD_UPDATE, 'entity' => 'catalog_product']
385+
['behavior' => Import::BEHAVIOR_ADD_UPDATE, 'entity' => 'catalog_product']
378386
)
379387
->setSource($source)
380388
->validateData();
@@ -408,25 +416,77 @@ public function testImportWithSpacesInUrlKeys()
408416
]
409417
public function testValidateMixedCharNumUrlKeysWithNullUrlSuffix()
410418
{
411-
$filesystem = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create(
412-
\Magento\Framework\Filesystem::class
419+
$filesystem = Bootstrap::getObjectManager()->create(
420+
Filesystem::class
413421
);
414422
$directory = $filesystem->getDirectoryWrite(DirectoryList::ROOT);
415423

416424
$source = $this->objectManager->create(
417-
\Magento\ImportExport\Model\Import\Source\Csv::class,
425+
Csv::class,
418426
[
419427
'file' => __DIR__ . '/../_files/products_to_check_valid_url_keys_mixed_chars_nums.csv',
420428
'directory' => $directory
421429
]
422430
);
423431

424432
$errors = $this->_model->setParameters(
425-
['behavior' => \Magento\ImportExport\Model\Import::BEHAVIOR_APPEND, 'entity' => 'catalog_product']
433+
['behavior' => Import::BEHAVIOR_APPEND, 'entity' => 'catalog_product']
426434
)->setSource(
427435
$source
428436
)->validateData();
429437

430438
$this->assertEmpty($errors->getAllErrors(), 'Assert that import validation returns no errors');
431439
}
440+
441+
#[
442+
DataFixture(Store::class, as: 'store2'),
443+
DataFixture(
444+
CsvFileFixture::class,
445+
[
446+
'rows' => [
447+
['sku', 'store_view_code', 'attribute_set_code', 'product_type', 'price', 'name', 'url_key'],
448+
// simple1 has url_key specified in the main row
449+
['simple1%uniqid%', '', 'Default', 'simple', '10.00', 'Simple Product 1%uniqid%', 's1%uniqid%'],
450+
['simple1%uniqid%', '$store2.code$', 'Default', 'simple', '', '', ''],
451+
// simple2 has no url_key specified in the main row
452+
['simple2%uniqid%', '', 'Default', 'simple', '10.00', 'Simple Product 1%uniqid%', ''],
453+
['simple2%uniqid%', '$store2.code$', 'Default', 'simple', '', '', '']
454+
]
455+
],
456+
'file'
457+
),
458+
]
459+
public function testStoreViewShouldInheritUrlKeyIfNotSpecified(): void
460+
{
461+
// reset store resolver cache to ensure that new store view code is resolved correctly
462+
$this->objectManager->removeSharedInstance(StoreResolver::class);
463+
$fixtures = DataFixtureStorageManager::getStorage();
464+
$store = $fixtures->get('store2')->getCode();
465+
$pathToFile = $fixtures->get('file')->getAbsolutePath();
466+
$model = $this->createImportModel($pathToFile);
467+
$this->assertErrorsCount(0, $model->validateData());
468+
$model->importData();
469+
[$headers, $row1,, $row3,] = $fixtures->get('file')->getRows();
470+
$row1 = array_combine($headers, $row1);
471+
$row3 = array_combine($headers, $row3);
472+
// generate url_key for simple2 based on name
473+
$row3['url_key'] = strtolower(preg_replace('/\s+/', '-', $row3['name']));
474+
foreach ([$row1, $row3] as $row) {
475+
$product = $this->getProductBySku($row['sku'], $store);
476+
$this->assertFalse(
477+
$this->objectManager->create(ScopeOverriddenValue::class)->containsValue(
478+
ProductInterface::class,
479+
$product,
480+
'url_key',
481+
$store
482+
),
483+
"Assert that url_key is not overridden in store '{$store}' for SKU '{$row['sku']}'"
484+
);
485+
$this->assertEquals(
486+
$row['url_key'],
487+
$product->getUrlKey(),
488+
"Assert that url_key is set to '{$row['url_key']}' for SKU '{$row['sku']}' in store '{$store}'"
489+
);
490+
}
491+
}
432492
}

0 commit comments

Comments
 (0)