Skip to content

Commit 8bfeb98

Browse files
committed
Merge remote-tracking branch 'origin/BUG#AC2515' into Hammer_QaulityBacklog_GraphQL_24052022
2 parents 43b8abc + ec954a2 commit 8bfeb98

File tree

2 files changed

+207
-6
lines changed

2 files changed

+207
-6
lines changed

app/code/Magento/Catalog/Model/Indexer/Category/Product/AbstractAction.php

Lines changed: 36 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
use Magento\Framework\DB\Query\Generator as QueryGenerator;
1414
use Magento\Framework\DB\Select;
1515
use Magento\Framework\EntityManager\MetadataPool;
16+
use Magento\Store\Api\Data\StoreInterface;
1617
use Magento\Store\Model\Store;
1718

1819
// phpcs:disable Magento2.Classes.AbstractApi
@@ -126,9 +127,9 @@ abstract class AbstractAction
126127
private $queryGenerator;
127128

128129
/**
129-
* @var int
130+
* @var StoreInterface
130131
*/
131-
private $currentStoreId = 0;
132+
private $currentStore;
132133

133134
/**
134135
* @param ResourceConnection $resource
@@ -171,14 +172,36 @@ protected function reindex()
171172
{
172173
foreach ($this->storeManager->getStores() as $store) {
173174
if ($this->getPathFromCategoryId($store->getRootCategoryId())) {
174-
$this->currentStoreId = $store->getId();
175+
$this->setCurrentStore($store);
175176
$this->reindexRootCategory($store);
176177
$this->reindexAnchorCategories($store);
177178
$this->reindexNonAnchorCategories($store);
178179
}
179180
}
180181
}
181182

183+
/**
184+
* Set current store
185+
*
186+
* @param StoreInterface $store
187+
* @return $this
188+
*/
189+
private function setCurrentStore(StoreInterface $store): self
190+
{
191+
$this->currentStore = $store;
192+
return $this;
193+
}
194+
195+
/**
196+
* Get current store
197+
*
198+
* @return StoreInterface
199+
*/
200+
private function getCurrentStore(): StoreInterface
201+
{
202+
return $this->currentStore;
203+
}
204+
182205
/**
183206
* Return validated table name
184207
*
@@ -484,6 +507,7 @@ protected function hasAnchorSelect(Store $store)
484507
*/
485508
protected function createAnchorSelect(Store $store)
486509
{
510+
$this->setCurrentStore($store);
487511
$isAnchorAttributeId = $this->config->getAttribute(
488512
\Magento\Catalog\Model\Category::ENTITY,
489513
'is_anchor'
@@ -690,7 +714,7 @@ protected function fillTempCategoryTreeIndex($temporaryName)
690714
['ccacs' => $this->getTable('catalog_category_entity_int')],
691715
'ccacs.' . $categoryLinkField . ' = c.' . $categoryLinkField
692716
. ' AND ccacs.attribute_id = ccacd.attribute_id AND ccacs.store_id = ' .
693-
$this->currentStoreId,
717+
$this->getCurrentStore()->getId(),
694718
[]
695719
)->where(
696720
$this->connection->getIfNullSql('ccacs.value', 'ccacd.value') . ' = ?',
@@ -702,8 +726,14 @@ protected function fillTempCategoryTreeIndex($temporaryName)
702726
foreach ($selects as $select) {
703727
$values = [];
704728

705-
foreach ($this->connection->fetchAll($select) as $category) {
706-
foreach (explode('/', $category['path']) as $parentId) {
729+
$categories = $this->connection->fetchAll($select);
730+
foreach ($categories as $category) {
731+
$categoriesTree = explode('/', $category['path']);
732+
foreach ($categoriesTree as $parentId) {
733+
if (!in_array($this->getCurrentStore()->getRootCategoryId(), $categoriesTree, true)) {
734+
break;
735+
}
736+
707737
if ($parentId !== $category['entity_id']) {
708738
$values[] = [$parentId, $category['entity_id']];
709739
}
Lines changed: 171 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,171 @@
1+
<?php
2+
/**
3+
* Copyright © Magento, Inc. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
7+
declare(strict_types=1);
8+
9+
namespace Magento\GraphQl\Catalog\Product;
10+
11+
use Magento\Catalog\Api\Data\ProductInterface;
12+
use Magento\Catalog\Api\ProductRepositoryInterface;
13+
use Magento\Store\Api\WebsiteRepositoryInterface;
14+
use Magento\TestFramework\Helper\Bootstrap;
15+
use Magento\TestFramework\TestCase\GraphQlAbstract;
16+
17+
/**
18+
* Test for product categories
19+
*/
20+
class ProductCategoriesTest extends GraphQlAbstract
21+
{
22+
/**
23+
* phpcs:disable Generic.Files.LineLength.TooLong
24+
* @magentoDataFixture Magento/Catalog/_files/category.php
25+
* @magentoDataFixture Magento\Catalog\Test\Fixture\Category with:{"name":"Second Root Category","parent_id":"1","position":"2"} as:c1
26+
* @magentoDataFixture Magento\Catalog\Test\Fixture\Category with:{"name":"Second Root Subcategory","parent_id":"$c1.id$","level":"2"} as:c2
27+
* @magentoDataFixture Magento\Catalog\Test\Fixture\Category with:{"name":"Second Root Subsubcategory","parent_id":"$c2.id$","level":"2"} as:c3
28+
* @magentoDataFixture Magento\Catalog\Test\Fixture\Product with:{"name":"Simple Product In Stock","sku":"in-stock-product","category_ids":["2","333","$c1.id$","$c2.id$","$c3.id$"]}
29+
* @magentoDataFixture Magento\Store\Test\Fixture\Website with:{"code":"test","name":"Test Website","default_group_id":"1"} as:w2
30+
* @magentoDataFixture Magento\Store\Test\Fixture\Group with:{"code":"test_store_group_1","name":"Test Store Group","website_id":"$w2.id$","root_category_id":"$c1.id$"} as:s2
31+
* @magentoDataFixture Magento\Store\Test\Fixture\Store with:{"code":"test_store_1","name":"Test Store","website_id":"$w2.id$","store_group_id":"$s2.id$"}
32+
* @magentoDbIsolation disabled
33+
* @magentoAppArea adminhtml
34+
* phpcs:enable Generic.Files.LineLength.TooLong
35+
*/
36+
public function testProductCategoriesInDefaultStore(): void
37+
{
38+
$objectManager = Bootstrap::getObjectManager();
39+
$websiteRepository = $objectManager->get(WebsiteRepositoryInterface::class);
40+
$defaultWebsiteId = $websiteRepository->get('base')->getId();
41+
$secondWebsiteId = $websiteRepository->get('test')->getId();
42+
43+
$productRepository = $objectManager->get(ProductRepositoryInterface::class);
44+
/** @var $product ProductInterface */
45+
$product = $productRepository->get('in-stock-product');
46+
$product
47+
->setUrlKey('in-stock-product')
48+
->setWebsiteIds([$defaultWebsiteId, $secondWebsiteId]);
49+
$productRepository->save($product);
50+
51+
$response = $this->graphQlQuery(
52+
$this->getQuery('in-stock-product'),
53+
[],
54+
'',
55+
['Store' => 'default']
56+
);
57+
58+
$product = current($response['products']['items']);
59+
$categories = $product['categories'];
60+
61+
self::assertCount(1, $categories);
62+
self::assertEquals('Category 1', $categories[0]['name']);
63+
self::assertEquals('category-1', $categories[0]['url_path']);
64+
self::assertNull($categories[0]['breadcrumbs']);
65+
}
66+
67+
/**
68+
* phpcs:disable Generic.Files.LineLength.TooLong
69+
* @magentoDataFixture Magento/Catalog/_files/category.php
70+
* @magentoDataFixture Magento\Catalog\Test\Fixture\Category with:{"name":"Second Root Category","parent_id":"1","position":"2"} as:c1
71+
* @magentoDataFixture Magento\Catalog\Test\Fixture\Category with:{"name":"Second Root Subcategory","parent_id":"$c1.id$","level":"2"} as:c2
72+
* @magentoDataFixture Magento\Catalog\Test\Fixture\Category with:{"name":"Second Root Subsubcategory","parent_id":"$c2.id$","level":"2"} as:c3
73+
* @magentoDataFixture Magento\Catalog\Test\Fixture\Product with:{"name":"Simple Product In Stock","sku":"in-stock-product","category_ids":["2","333","$c1.id$","$c2.id$","$c3.id$"]}
74+
* @magentoDataFixture Magento\Store\Test\Fixture\Website with:{"code":"test","name":"Test Website","default_group_id":"1"} as:w2
75+
* @magentoDataFixture Magento\Store\Test\Fixture\Group with:{"code":"test_store_group_1","name":"Test Store Group","website_id":"$w2.id$","root_category_id":"$c1.id$"} as:s2
76+
* @magentoDataFixture Magento\Store\Test\Fixture\Store with:{"code":"test_store_1","name":"Test Store","website_id":"$w2.id$","store_group_id":"$s2.id$"}
77+
* @magentoDbIsolation disabled
78+
* @magentoAppArea adminhtml
79+
* phpcs:enable Generic.Files.LineLength.TooLong
80+
*/
81+
public function testProductCategoriesInNonDefaultStore(): void
82+
{
83+
$objectManager = Bootstrap::getObjectManager();
84+
$websiteRepository = $objectManager->get(WebsiteRepositoryInterface::class);
85+
$defaultWebsiteId = $websiteRepository->get('base')->getId();
86+
$secondWebsiteId = $websiteRepository->get('test')->getId();
87+
88+
$productRepository = $objectManager->get(ProductRepositoryInterface::class);
89+
/** @var $product ProductInterface */
90+
$product = $productRepository->get('in-stock-product');
91+
$product
92+
->setUrlKey('in-stock-product')
93+
->setWebsiteIds([$defaultWebsiteId, $secondWebsiteId]);
94+
$productRepository->save($product);
95+
96+
$response = $this->graphQlQuery(
97+
$this->getQuery('in-stock-product'),
98+
[],
99+
'',
100+
['Store' => 'test_store_1']
101+
);
102+
103+
$product = current($response['products']['items']);
104+
$categories = $product['categories'];
105+
106+
self::assertCount(2, $categories);
107+
self::assertEquals('Second Root Subcategory', $categories[0]['name']);
108+
self::assertEquals('second-root-subcategory', $categories[0]['url_path']);
109+
self::assertNull($categories[0]['breadcrumbs']);
110+
self::assertEquals('Second Root Subsubcategory', $categories[1]['name']);
111+
self::assertEquals('second-root-subcategory/second-root-subsubcategory', $categories[1]['url_path']);
112+
self::assertCount(1, $categories[1]['breadcrumbs']);
113+
self::assertEquals('Second Root Subcategory', $categories[1]['breadcrumbs'][0]['category_name']);
114+
self::assertEquals(2, $categories[1]['breadcrumbs'][0]['category_level']);
115+
}
116+
117+
/**
118+
* phpcs:disable Generic.Files.LineLength.TooLong
119+
* @magentoDataFixture Magento/Catalog/_files/category.php
120+
* @magentoDataFixture Magento\Catalog\Test\Fixture\Category with:{"name":"Second Root Category","parent_id":"1","position":"2"} as:c1
121+
* @magentoDataFixture Magento\Catalog\Test\Fixture\Category with:{"name":"Second Root Subcategory","parent_id":"$c1.id$","level":"2"} as:c2
122+
* @magentoDataFixture Magento\Catalog\Test\Fixture\Category with:{"name":"Second Root Subsubcategory","parent_id":"$c2.id$","level":"2"} as:c3
123+
* @magentoDataFixture Magento\Catalog\Test\Fixture\Product with:{"name":"Simple Product In Stock","sku":"in-stock-product","category_ids":["2","333","$c1.id$","$c2.id$","$c3.id$"]}
124+
* @magentoDataFixture Magento\Store\Test\Fixture\Website with:{"code":"test","name":"Test Website","default_group_id":"1"} as:w2
125+
* @magentoDataFixture Magento\Store\Test\Fixture\Group with:{"code":"test_store_group_1","name":"Test Store Group","website_id":"$w2.id$","root_category_id":"$c1.id$"} as:s2
126+
* @magentoDataFixture Magento\Store\Test\Fixture\Store with:{"code":"test_store_1","name":"Test Store","website_id":"$w2.id$","store_group_id":"$s2.id$"}
127+
* @magentoApiDataFixture Magento/Store/_files/second_store.php
128+
* @magentoDbIsolation disabled
129+
* @magentoAppArea adminhtml
130+
* phpcs:enable Generic.Files.LineLength.TooLong
131+
*/
132+
public function testProductCategoriesInNotRelevantStore(): void
133+
{
134+
$response = $this->graphQlQuery(
135+
$this->getQuery('in-stock-product'),
136+
[],
137+
'',
138+
['Store' => 'fixture_second_store']
139+
);
140+
141+
self::assertEmpty($response['products']['items']);
142+
}
143+
144+
/**
145+
* Get query
146+
*
147+
* @param string $sku
148+
* @return string
149+
*/
150+
private function getQuery(string $sku): string
151+
{
152+
return <<<QUERY
153+
{
154+
products(filter: { sku: { eq: "{$sku}"} }){
155+
items {
156+
categories {
157+
name
158+
id
159+
url_path
160+
breadcrumbs {
161+
category_id
162+
category_name
163+
category_level
164+
}
165+
}
166+
}
167+
}
168+
}
169+
QUERY;
170+
}
171+
}

0 commit comments

Comments
 (0)