Skip to content

Commit 62fd888

Browse files
committed
Show only active categories
1 parent 8dfe26a commit 62fd888

File tree

4 files changed

+113
-43
lines changed

4 files changed

+113
-43
lines changed

app/code/Magento/CatalogGraphQl/Model/Resolver/Products/DataProvider/CategoryTree.php

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -101,11 +101,21 @@ public function getTree(ResolveInfo $resolveInfo, int $rootCategoryId): \Iterato
101101

102102
$collection->addFieldToFilter('level', ['gt' => $level]);
103103
$collection->addFieldToFilter('level', ['lteq' => $level + $depth - self::DEPTH_OFFSET]);
104+
$collection->addAttributeToFilter('is_active', 1, "left");
104105
$collection->setOrder('level');
106+
$collection->setOrder(
107+
'position',
108+
$collection::SORT_ORDER_DESC
109+
);
105110
$collection->getSelect()->orWhere(
106-
$this->metadata->getMetadata(CategoryInterface::class)->getIdentifierField() . ' = ?',
111+
$collection->getSelect()
112+
->getConnection()
113+
->quoteIdentifier(
114+
'e.' . $this->metadata->getMetadata(CategoryInterface::class)->getIdentifierField()
115+
) . ' = ?',
107116
$rootCategoryId
108117
);
118+
109119
return $collection->getIterator();
110120
}
111121

app/code/Magento/CatalogGraphQl/Model/Resolver/Products/DataProvider/ExtractDataFromCategoryTree.php

Lines changed: 59 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,9 @@
44
* See COPYING.txt for license details.
55
*/
66
declare(strict_types=1);
7-
87
namespace Magento\CatalogGraphQl\Model\Resolver\Products\DataProvider;
9-
108
use Magento\CatalogGraphQl\Model\Category\Hydrator;
119
use Magento\Catalog\Api\Data\CategoryInterface;
12-
1310
/**
1411
* Extract data from category tree
1512
*/
@@ -19,7 +16,14 @@ class ExtractDataFromCategoryTree
1916
* @var Hydrator
2017
*/
2118
private $categoryHydrator;
22-
19+
/**
20+
* @var CategoryInterface;
21+
*/
22+
private $iteratingCategory;
23+
/**
24+
* @var int
25+
*/
26+
private $startCategoryFetchLevel = 1;
2327
/**
2428
* @param Hydrator $categoryHydrator
2529
*/
@@ -28,7 +32,6 @@ public function __construct(
2832
) {
2933
$this->categoryHydrator = $categoryHydrator;
3034
}
31-
3235
/**
3336
* Extract data from category tree
3437
*
@@ -42,14 +45,58 @@ public function execute(\Iterator $iterator): array
4245
/** @var CategoryInterface $category */
4346
$category = $iterator->current();
4447
$iterator->next();
45-
$nextCategory = $iterator->current();
46-
$tree[$category->getId()] = $this->categoryHydrator->hydrateCategory($category);
47-
$tree[$category->getId()]['model'] = $category;
48-
if ($nextCategory && (int) $nextCategory->getLevel() !== (int) $category->getLevel()) {
49-
$tree[$category->getId()]['children'] = $this->execute($iterator);
48+
$pathElements = explode("/", $category->getPath());
49+
if (empty($tree)) {
50+
$this->startCategoryFetchLevel = count($pathElements) - 1;
51+
}
52+
$this->iteratingCategory = $category;
53+
$currentLevelTree = $this->explodePathToArray($pathElements, $this->startCategoryFetchLevel);
54+
if (empty($tree)) {
55+
$tree = $currentLevelTree;
5056
}
57+
$tree = $this->mergeCategoriesTrees($currentLevelTree, $tree);
58+
}
59+
return $tree;
60+
}
61+
/**
62+
* Merge together complex categories trees
63+
*
64+
* @param array $tree1
65+
* @param array $tree2
66+
* @return array
67+
*/
68+
private function mergeCategoriesTrees(array &$tree1, array &$tree2): array
69+
{
70+
$mergedTree = $tree1;
71+
foreach ($tree2 as $currentKey => &$value) {
72+
if (is_array($value) && isset($mergedTree[$currentKey]) && is_array($mergedTree[$currentKey])) {
73+
$mergedTree[$currentKey] = $this->mergeCategoriesTrees($mergedTree[$currentKey], $value);
74+
} else {
75+
$mergedTree[$currentKey] = $value;
76+
}
77+
}
78+
return $mergedTree;
79+
}
80+
/**
81+
* Recursive method to generate tree for one category path
82+
*
83+
* @param array $pathElements
84+
* @param int $index
85+
* @return array
86+
*/
87+
private function explodePathToArray(array $pathElements, int $index): array
88+
{
89+
$tree = [];
90+
$tree[$pathElements[$index]]['id'] = $pathElements[$index];
91+
if ($index === count($pathElements) - 1) {
92+
$tree[$pathElements[$index]] = $this->categoryHydrator->hydrateCategory($this->iteratingCategory);
93+
$tree[$pathElements[$index]]['model'] = $this->iteratingCategory;
94+
}
95+
$currentIndex = $index;
96+
$index++;
97+
if (isset($pathElements[$index])) {
98+
$tree[$pathElements[$currentIndex]]['children'] = $this->explodePathToArray($pathElements, $index);
5199
}
52-
53100
return $tree;
54101
}
55-
}
102+
}

dev/tests/api-functional/testsuite/Magento/GraphQl/Catalog/CategoryTest.php

Lines changed: 42 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -4,29 +4,24 @@
44
* See COPYING.txt for license details.
55
*/
66
declare(strict_types=1);
7-
87
namespace Magento\GraphQl\Catalog;
9-
108
use Magento\Catalog\Api\Data\CategoryInterface;
119
use Magento\Catalog\Model\ResourceModel\Category\Collection as CategoryCollection;
1210
use Magento\Framework\DataObject;
1311
use Magento\TestFramework\TestCase\GraphQlAbstract;
1412
use Magento\Catalog\Api\Data\ProductInterface;
1513
use Magento\Catalog\Api\ProductRepositoryInterface;
1614
use Magento\TestFramework\ObjectManager;
17-
1815
class CategoryTest extends GraphQlAbstract
1916
{
2017
/**
2118
* @var \Magento\TestFramework\ObjectManager
2219
*/
2320
private $objectManager;
24-
2521
protected function setUp()
2622
{
2723
$this->objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager();
2824
}
29-
3025
/**
3126
* @magentoApiDataFixture Magento/Customer/_files/customer.php
3227
* @magentoApiDataFixture Magento/Catalog/_files/categories.php
@@ -70,21 +65,19 @@ public function testCategoriesTree()
7065
}
7166
}
7267
QUERY;
73-
7468
// get customer ID token
7569
/** @var \Magento\Integration\Api\CustomerTokenServiceInterface $customerTokenService */
7670
$customerTokenService = $this->objectManager->create(
7771
\Magento\Integration\Api\CustomerTokenServiceInterface::class
7872
);
7973
$customerToken = $customerTokenService->createCustomerAccessToken('[email protected]', 'password');
80-
8174
$headerMap = ['Authorization' => 'Bearer ' . $customerToken];
8275
$response = $this->graphQlQuery($query, [], '', $headerMap);
8376
$responseDataObject = new DataObject($response);
8477
//Some sort of smoke testing
8578
self::assertEquals(
86-
'Ololo',
87-
$responseDataObject->getData('category/children/7/children/1/description')
79+
'Its a description of Test Category 1.2',
80+
$responseDataObject->getData('category/children/0/children/1/description')
8881
);
8982
self::assertEquals(
9083
'default-category',
@@ -99,19 +92,53 @@ public function testCategoriesTree()
9992
$responseDataObject->getData('category/children/0/default_sort_by')
10093
);
10194
self::assertCount(
102-
8,
95+
7,
10396
$responseDataObject->getData('category/children')
10497
);
10598
self::assertCount(
10699
2,
107-
$responseDataObject->getData('category/children/7/children')
100+
$responseDataObject->getData('category/children/0/children')
108101
);
109102
self::assertEquals(
110-
5,
111-
$responseDataObject->getData('category/children/7/children/1/children/0/id')
103+
13,
104+
$responseDataObject->getData('category/children/0/children/1/id')
105+
);
106+
}
107+
/**
108+
* @magentoApiDataFixture Magento/Customer/_files/customer.php
109+
* @magentoApiDataFixture Magento/Catalog/_files/categories.php
110+
* @SuppressWarnings(PHPMD.ExcessiveMethodLength)
111+
*/
112+
public function testGetCategoryById()
113+
{
114+
$rootCategoryId = 13;
115+
$query = <<<QUERY
116+
{
117+
category(id: {$rootCategoryId}) {
118+
id
119+
name
120+
}
121+
}
122+
QUERY;
123+
// get customer ID token
124+
/** @var \Magento\Integration\Api\CustomerTokenServiceInterface $customerTokenService */
125+
$customerTokenService = $this->objectManager->create(
126+
\Magento\Integration\Api\CustomerTokenServiceInterface::class
127+
);
128+
$customerToken = $customerTokenService->createCustomerAccessToken('[email protected]', 'password');
129+
$headerMap = ['Authorization' => 'Bearer ' . $customerToken];
130+
$response = $this->graphQlQuery($query, [], '', $headerMap);
131+
$responseDataObject = new DataObject($response);
132+
//Some sort of smoke testing
133+
self::assertEquals(
134+
'Category 1.2',
135+
$responseDataObject->getData('category/name')
136+
);
137+
self::assertEquals(
138+
13,
139+
$responseDataObject->getData('category/id')
112140
);
113141
}
114-
115142
/**
116143
* @magentoApiDataFixture Magento/Catalog/_files/categories.php
117144
* @SuppressWarnings(PHPMD.ExcessiveMethodLength)
@@ -259,17 +286,14 @@ public function testCategoryProducts()
259286
}
260287
}
261288
QUERY;
262-
263289
$response = $this->graphQlQuery($query);
264290
$this->assertArrayHasKey('products', $response['category']);
265291
$this->assertArrayHasKey('total_count', $response['category']['products']);
266292
$this->assertGreaterThanOrEqual(1, $response['category']['products']['total_count']);
267293
$this->assertEquals(1, $response['category']['products']['page_info']['current_page']);
268294
$this->assertEquals(20, $response['category']['products']['page_info']['page_size']);
269-
270295
$this->assertArrayHasKey('sku', $response['category']['products']['items'][0]);
271296
$firstProductSku = $response['category']['products']['items'][0]['sku'];
272-
273297
/**
274298
* @var ProductRepositoryInterface $productRepository
275299
*/
@@ -279,7 +303,6 @@ public function testCategoryProducts()
279303
$this->assertAttributes($response['category']['products']['items'][0]);
280304
$this->assertWebsites($firstProduct, $response['category']['products']['items'][0]['websites']);
281305
}
282-
283306
/**
284307
* @magentoApiDataFixture Magento/Catalog/_files/categories.php
285308
*/
@@ -291,9 +314,7 @@ public function testAnchorCategory()
291314
/** @var CategoryInterface $category */
292315
$category = $categoryCollection->getFirstItem();
293316
$categoryId = $category->getId();
294-
295317
$this->assertNotEmpty($categoryId, "Preconditions failed: category is not available.");
296-
297318
$query = <<<QUERY
298319
{
299320
category(id: {$categoryId}) {
@@ -307,7 +328,6 @@ public function testAnchorCategory()
307328
}
308329
}
309330
QUERY;
310-
311331
$response = $this->graphQlQuery($query);
312332
$expectedResponse = [
313333
'category' => [
@@ -324,14 +344,12 @@ public function testAnchorCategory()
324344
];
325345
$this->assertEquals($expectedResponse, $response);
326346
}
327-
328347
/**
329348
* @param ProductInterface $product
330349
* @param array $actualResponse
331350
*/
332351
private function assertBaseFields($product, $actualResponse)
333352
{
334-
335353
$assertionMap = [
336354
['response_field' => 'attribute_set_id', 'expected_value' => $product->getAttributeSetId()],
337355
['response_field' => 'created_at', 'expected_value' => $product->getCreatedAt()],
@@ -365,10 +383,8 @@ private function assertBaseFields($product, $actualResponse)
365383
['response_field' => 'type_id', 'expected_value' => $product->getTypeId()],
366384
['response_field' => 'updated_at', 'expected_value' => $product->getUpdatedAt()],
367385
];
368-
369386
$this->assertResponseFields($actualResponse, $assertionMap);
370387
}
371-
372388
/**
373389
* @param ProductInterface $product
374390
* @param array $actualResponse
@@ -385,10 +401,8 @@ private function assertWebsites($product, $actualResponse)
385401
'is_default' => true,
386402
]
387403
];
388-
389404
$this->assertEquals($actualResponse, $assertionMap);
390405
}
391-
392406
/**
393407
* @param array $actualResponse
394408
*/
@@ -410,9 +424,8 @@ private function assertAttributes($actualResponse)
410424
'special_from_date',
411425
'special_to_date',
412426
];
413-
414427
foreach ($eavAttributes as $eavAttribute) {
415428
$this->assertArrayHasKey($eavAttribute, $actualResponse);
416429
}
417430
}
418-
}
431+
}

dev/tests/integration/testsuite/Magento/Catalog/_files/categories.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -178,7 +178,7 @@
178178
->setParentId(3)
179179
->setPath('1/2/3/13')
180180
->setLevel(3)
181-
->setDescription('Ololo')
181+
->setDescription('Its a description of Test Category 1.2')
182182
->setAvailableSortBy('name')
183183
->setDefaultSortBy('name')
184184
->setIsActive(true)

0 commit comments

Comments
 (0)