Skip to content

Commit 6ce053d

Browse files
author
OlgaVasyltsun
committed
Merge remote-tracking branch 'origin/MC-21965' into 2.3.4-develop-pr83
2 parents 92fdebb + 8839afb commit 6ce053d

File tree

6 files changed

+226
-0
lines changed

6 files changed

+226
-0
lines changed

app/code/Magento/Catalog/Model/ResourceModel/Category.php

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -284,6 +284,9 @@ protected function _beforeSave(\Magento\Framework\DataObject $object)
284284
$object->setAttributeSetId(
285285
$object->getAttributeSetId() ?: $this->getEntityType()->getDefaultAttributeSetId()
286286
);
287+
288+
$this->castPathIdsToInt($object);
289+
287290
if ($object->isObjectNew()) {
288291
if ($object->getPosition() === null) {
289292
$object->setPosition($this->_getMaxPosition($object->getPath()) + 1);
@@ -1188,4 +1191,25 @@ public function getCategoryWithChildren(int $categoryId): array
11881191

11891192
return $connection->fetchAll($select);
11901193
}
1194+
1195+
/**
1196+
* Cast category path ids to int.
1197+
*
1198+
* @param DataObject $object
1199+
* @return void
1200+
*/
1201+
private function castPathIdsToInt(DataObject $object): void
1202+
{
1203+
if (is_string($object->getPath())) {
1204+
$pathIds = explode('/', $object->getPath());
1205+
1206+
array_walk(
1207+
$pathIds,
1208+
function (&$pathId) {
1209+
$pathId = (int)$pathId;
1210+
}
1211+
);
1212+
$object->setPath(implode('/', $pathIds));
1213+
}
1214+
}
11911215
}

app/code/Magento/Catalog/Model/ResourceModel/Category/Tree.php

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,17 @@
33
* Copyright © Magento, Inc. All rights reserved.
44
* See COPYING.txt for license details.
55
*/
6+
declare(strict_types=1);
7+
68
namespace Magento\Catalog\Model\ResourceModel\Category;
79

810
use Magento\Framework\Data\Tree\Dbp;
911
use Magento\Catalog\Api\Data\CategoryInterface;
1012
use Magento\Framework\EntityManager\MetadataPool;
1113

1214
/**
15+
* Category Tree model.
16+
*
1317
* @api
1418
* @SuppressWarnings(PHPMD.CouplingBetweenObjects)
1519
* @since 100.0.2
@@ -483,6 +487,14 @@ public function loadByIds($ids, $addCollectionData = true, $updateAnchorProductC
483487

484488
foreach ($this->_conn->fetchAll($select) as $item) {
485489
$pathIds = explode('/', $item['path']);
490+
491+
array_walk(
492+
$pathIds,
493+
function (&$pathId) {
494+
$pathId = (int)$pathId;
495+
}
496+
);
497+
486498
$level = (int)$item['level'];
487499
while ($level > 0) {
488500
$pathIds[count($pathIds) - 1] = '%';
@@ -680,6 +692,8 @@ public function getExistingCategoryIdsBySpecifiedIds($ids)
680692
}
681693

682694
/**
695+
* Return MetadataPool object.
696+
*
683697
* @return \Magento\Framework\EntityManager\MetadataPool
684698
*/
685699
private function getMetadataPool()

dev/tests/integration/testsuite/Magento/Catalog/Model/CategoryTest.php

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -467,4 +467,35 @@ protected function getCategoryByName($categoryName)
467467

468468
return $collection->getItemByColumnValue('name', $categoryName);
469469
}
470+
471+
/**
472+
* @return void
473+
*/
474+
public function testSaveCategoryWithWrongPath(): void
475+
{
476+
/** @var CategoryRepositoryInterface $categoryRepository */
477+
$categoryRepository = $this->objectManager->get(CategoryRepositoryInterface::class);
478+
$categoryFactory = $this->objectManager->get(\Magento\Catalog\Api\Data\CategoryInterfaceFactory::class);
479+
480+
/** @var \Magento\Catalog\Api\Data\CategoryInterface $category */
481+
$category = $categoryFactory->create(
482+
[
483+
'data' => [
484+
'name' => 'Category With Wrong Path',
485+
'parent_id' => 2,
486+
'path' => 'wrong/path',
487+
'level' => 2,
488+
'available_sort_by' =>['position', 'name'],
489+
'default_sort_by' => 'name',
490+
'is_active' => true,
491+
'position' => 1,
492+
],
493+
]
494+
);
495+
$category->isObjectNew(true);
496+
$category->save();
497+
498+
$createdCategory = $categoryRepository->get($category->getId());
499+
$this->assertEquals('0/0/'. $createdCategory->getId(), $createdCategory->getPath());
500+
}
470501
}
Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
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\Catalog\Model\ResourceModel\Category;
9+
10+
use Magento\Catalog\Api\Data\CategoryInterface;
11+
use Magento\Catalog\Model\CategoryList;
12+
use Magento\Framework\Api\SearchCriteriaBuilder;
13+
use Magento\Framework\Data\Tree\Node;
14+
15+
/**
16+
* Test for \Magento\Catalog\Model\ResourceModel\Category\Tree.
17+
*
18+
* @magentoDbIsolation enabled
19+
*/
20+
class TreeTest extends \PHPUnit\Framework\TestCase
21+
{
22+
/**
23+
* @var Tree
24+
*/
25+
private $treeModel;
26+
27+
/**
28+
* @var CategoryList
29+
*/
30+
private $categoryList;
31+
32+
/**
33+
* @var SearchCriteriaBuilder
34+
*/
35+
private $searchCriteriaBuilder;
36+
37+
/**
38+
* @inheritDoc
39+
*/
40+
protected function setUp()
41+
{
42+
$objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager();
43+
$this->treeModel = $objectManager->create(Tree::class);
44+
$this->categoryList = $objectManager->get(CategoryList::class);
45+
$this->searchCriteriaBuilder = $objectManager->get(SearchCriteriaBuilder::class);
46+
}
47+
48+
/**
49+
* @magentoDataFixture Magento/Catalog/_files/category.php
50+
* @return void
51+
*/
52+
public function testLoadByIds(): void
53+
{
54+
$categoryId = $this->getCategoryIdByName('Category 1');
55+
// Load category nodes by created category
56+
$this->treeModel->loadByIds([$categoryId]);
57+
$this->assertCount(3, $this->treeModel->getNodes());
58+
$this->assertInstanceOf(Node::class, $this->treeModel->getNodeById($categoryId));
59+
}
60+
61+
/**
62+
* @magentoDataFixture Magento/Catalog/_files/category_with_wrong_path.php
63+
* @return void
64+
*/
65+
public function testLoadByIdsWithWrongCategoryPath(): void
66+
{
67+
$categoryId = $this->getCategoryIdByName('Category With Wrong Path');
68+
// Load category nodes by created category
69+
$this->treeModel->loadByIds([$categoryId]);
70+
$this->assertCount(1, $this->treeModel->getNodes());
71+
$this->assertNull($this->treeModel->getNodeById($categoryId));
72+
}
73+
74+
/**
75+
* Return category id by category name.
76+
*
77+
* @param string $categoryName
78+
* @return int
79+
*/
80+
private function getCategoryIdByName(string $categoryName): int
81+
{
82+
$searchCriteria = $this->searchCriteriaBuilder
83+
->addFilter(CategoryInterface::KEY_NAME, $categoryName)
84+
->create();
85+
$categories = $this->categoryList->getList($searchCriteria)->getItems();
86+
$category = reset($categories);
87+
$categoryId = $category->getId();
88+
89+
return (int)$categoryId;
90+
}
91+
}
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+
declare(strict_types=1);
7+
8+
$objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager();
9+
/** @var \Magento\Catalog\Api\Data\CategoryInterfaceFactory $categoryFactory */
10+
$categoryFactory = $objectManager->get(\Magento\Catalog\Api\Data\CategoryInterfaceFactory::class);
11+
12+
/** @var \Magento\Catalog\Api\Data\CategoryInterface $category */
13+
$category = $categoryFactory->create(
14+
[
15+
'data' => [
16+
'name' => 'Category With Wrong Path',
17+
'parent_id' => 2,
18+
'path' => 'wrong/path',
19+
'level' => 2,
20+
'available_sort_by' =>['position', 'name'],
21+
'default_sort_by' => 'name',
22+
'is_active' => true,
23+
'position' => 1,
24+
],
25+
]
26+
);
27+
28+
$category->isObjectNew(true);
29+
$category->save();
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
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+
use Magento\Catalog\Api\Data\CategoryInterface;
9+
use Magento\Catalog\Model\CategoryList;
10+
use Magento\Catalog\Model\CategoryRepository;
11+
use Magento\Framework\Api\SearchCriteriaBuilder;
12+
use Magento\Framework\Registry;
13+
use Magento\TestFramework\Helper\Bootstrap;
14+
15+
$objectManager = Bootstrap::getObjectManager();
16+
/** @var SearchCriteriaBuilder $searchCriteriaBuilder */
17+
$searchCriteriaBuilder = $objectManager->get(SearchCriteriaBuilder::class);
18+
/** @var CategoryRepository $categoryRepository */
19+
$categoryRepository = $objectManager->get(CategoryRepository::class);
20+
/** @var CategoryList $categoryList */
21+
$categoryList = $objectManager->get(CategoryList::class);
22+
/** @var Registry $registry */
23+
$registry = $objectManager->get(Registry::class);
24+
$registry->unregister('isSecureArea');
25+
$registry->register('isSecureArea', true);
26+
27+
$searchCriteria = $searchCriteriaBuilder
28+
->addFilter(CategoryInterface::KEY_NAME, 'Category With Wrong Path')
29+
->create();
30+
$categories = $categoryList->getList($searchCriteria)->getItems();
31+
32+
foreach ($categories as $category) {
33+
$categoryRepository->delete($category);
34+
}
35+
36+
$registry->unregister('isSecureArea');
37+
$registry->register('isSecureArea', false);

0 commit comments

Comments
 (0)