Skip to content

Commit dbfe642

Browse files
author
Oleksii Korshenko
authored
MAGETWO-83131: #6948: CatalogImportExport categoryProcessor does not support escaped delimiter #11801
2 parents c638d82 + 660cbb0 commit dbfe642

File tree

7 files changed

+80
-10
lines changed

7 files changed

+80
-10
lines changed

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

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
*/
66
namespace Magento\CatalogImportExport\Model\Export;
77

8+
use Magento\CatalogImportExport\Model\Import\Product\CategoryProcessor;
89
use Magento\ImportExport\Model\Import;
910
use \Magento\Store\Model\Store;
1011
use \Magento\CatalogImportExport\Model\Import\Product as ImportProduct;
@@ -438,11 +439,12 @@ protected function initCategories()
438439
if ($pathSize > 1) {
439440
$path = [];
440441
for ($i = 1; $i < $pathSize; $i++) {
441-
$path[] = $collection->getItemById($structure[$i])->getName();
442+
$name = $collection->getItemById($structure[$i])->getName();
443+
$path[] = $this->quoteCategoryDelimiter($name);
442444
}
443445
$this->_rootCategories[$category->getId()] = array_shift($path);
444446
if ($pathSize > 2) {
445-
$this->_categories[$category->getId()] = implode('/', $path);
447+
$this->_categories[$category->getId()] = implode(CategoryProcessor::DELIMITER_CATEGORY, $path);
446448
}
447449
}
448450
}
@@ -1470,4 +1472,19 @@ protected function getProductEntityLinkField()
14701472
}
14711473
return $this->productEntityLinkField;
14721474
}
1475+
1476+
/**
1477+
* Quoting category delimiter character in string.
1478+
*
1479+
* @param string $string
1480+
* @return string
1481+
*/
1482+
private function quoteCategoryDelimiter($string)
1483+
{
1484+
return str_replace(
1485+
CategoryProcessor::DELIMITER_CATEGORY,
1486+
'\\' . CategoryProcessor::DELIMITER_CATEGORY,
1487+
$string
1488+
);
1489+
}
14731490
}

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

Lines changed: 26 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,8 @@ protected function initCategories()
8484
if ($pathSize > 1) {
8585
$path = [];
8686
for ($i = 1; $i < $pathSize; $i++) {
87-
$path[] = $collection->getItemById((int)$structure[$i])->getName();
87+
$name = $collection->getItemById((int)$structure[$i])->getName();
88+
$path[] = $this->quoteDelimiter($name);
8889
}
8990
/** @var string $index */
9091
$index = $this->standardizeString(
@@ -114,7 +115,7 @@ protected function createCategory($name, $parentId)
114115
}
115116
$category->setPath($parentCategory->getPath());
116117
$category->setParentId($parentId);
117-
$category->setName($name);
118+
$category->setName($this->unquoteDelimiter($name));
118119
$category->setIsActive(true);
119120
$category->setIncludeInMenu(true);
120121
$category->setAttributeSetId($category->getDefaultAttributeSetId());
@@ -137,7 +138,7 @@ protected function upsertCategory($categoryPath)
137138
$index = $this->standardizeString($categoryPath);
138139

139140
if (!isset($this->categories[$index])) {
140-
$pathParts = explode(self::DELIMITER_CATEGORY, $categoryPath);
141+
$pathParts = preg_split('~(?<!\\\)' . preg_quote(self::DELIMITER_CATEGORY, '~') . '~', $categoryPath);
141142
$parentId = \Magento\Catalog\Model\Category::TREE_ROOT_ID;
142143
$path = '';
143144

@@ -243,4 +244,26 @@ private function standardizeString($string)
243244
{
244245
return mb_strtolower($string);
245246
}
247+
248+
/**
249+
* Quoting delimiter character in string.
250+
*
251+
* @param string $string
252+
* @return string
253+
*/
254+
private function quoteDelimiter($string)
255+
{
256+
return str_replace(self::DELIMITER_CATEGORY, '\\' . self::DELIMITER_CATEGORY, $string);
257+
}
258+
259+
/**
260+
* Remove quoting delimiter in string.
261+
*
262+
* @param string $string
263+
* @return string
264+
*/
265+
private function unquoteDelimiter($string)
266+
{
267+
return str_replace('\\' . self::DELIMITER_CATEGORY, self::DELIMITER_CATEGORY, $string);
268+
}
246269
}
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
<?php
2+
/**
3+
* Copyright © Magento, Inc. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
7+
$category = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create(\Magento\Catalog\Model\Category::class);
8+
$category->isObjectNew(true);
9+
$category->setId(
10+
3331
11+
)->setCreatedAt(
12+
'2017-06-23 09:50:07'
13+
)->setName(
14+
'Category with slash/ symbol'
15+
)->setParentId(
16+
2
17+
)->setPath(
18+
'1/2/3331'
19+
)->setLevel(
20+
2
21+
)->setAvailableSortBy(
22+
['position', 'name']
23+
)->setDefaultSortBy(
24+
'name'
25+
)->setIsActive(
26+
true
27+
)->setPosition(
28+
1
29+
)->save();

dev/tests/integration/testsuite/Magento/CatalogImportExport/Model/Export/ProductTest.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,7 @@ public function testExportSpecialChars()
104104
);
105105
$exportData = $this->model->export();
106106
$this->assertContains('simple ""1""', $exportData);
107+
$this->assertContains('Category with slash\/ symbol', $exportData);
107108
}
108109

109110
/**
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
11
sku,product_type,store_view_code,name,price,attribute_set_code,categories,product_websites
2-
simple1,simple,,"simple 2",25,Default,"Default Category/Category 1|Default Category/Category 2",base
2+
simple1,simple,,"simple 2",25,Default,"Default Category/Category 1|Default Category/Category\/ 2",base
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
11
sku,product_type,store_view_code,name,price,attribute_set_code,categories,product_websites,url_key
2-
simple1,simple,,"simple 1",25,Default,"Default Category/Category 1,Default Category/Category 2",base,simple1-ds
2+
simple1,simple,,"simple 1",25,Default,"Default Category/Category 1,Default Category/Category\/ 2",base,simple1-ds

dev/tests/integration/testsuite/Magento/CatalogImportExport/_files/product_export_data_special_chars.php

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@
55
*/
66
/** Create category */
77
require dirname(dirname(__DIR__)) . '/Catalog/_files/category.php';
8+
/** Create category with special chars */
9+
require dirname(dirname(__DIR__)) . '/Catalog/_files/catalog_category_with_slash.php';
810
/** Create fixture store */
911
require dirname(dirname(__DIR__)) . '/Store/_files/second_store.php';
1012
/** Create product with multiselect attribute and values */
@@ -28,10 +30,8 @@
2830
->setVisibility(\Magento\Catalog\Model\Product\Visibility::VISIBILITY_BOTH)
2931
->setStatus(\Magento\Catalog\Model\Product\Attribute\Source\Status::STATUS_ENABLED)
3032
->setWebsiteIds([1])
31-
->setCateroryIds([])
3233
->setStockData(['qty' => 100, 'is_in_stock' => 1])
3334
->setCanSaveCustomOptions(true)
34-
->setCategoryIds([333])
35-
->setUpSellLinkData([$product->getId() => ['position' => 1]]);
35+
->setCategoryIds([333, 3331]);
3636

3737
$productModel->setOptions([])->save();

0 commit comments

Comments
 (0)