Skip to content
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
use Magento\Framework\DB\Query\Generator as QueryGenerator;
use Magento\Framework\DB\Select;
use Magento\Framework\EntityManager\MetadataPool;
use Magento\Store\Api\Data\StoreInterface;
use Magento\Store\Model\Store;

// phpcs:disable Magento2.Classes.AbstractApi
Expand Down Expand Up @@ -126,9 +127,9 @@ abstract class AbstractAction
private $queryGenerator;

/**
* @var int
* @var StoreInterface
*/
private $currentStoreId = 0;
private $currentStore;

/**
* @param ResourceConnection $resource
Expand Down Expand Up @@ -171,14 +172,36 @@ protected function reindex()
{
foreach ($this->storeManager->getStores() as $store) {
if ($this->getPathFromCategoryId($store->getRootCategoryId())) {
$this->currentStoreId = $store->getId();
$this->setCurrentStore($store);
$this->reindexRootCategory($store);
$this->reindexAnchorCategories($store);
$this->reindexNonAnchorCategories($store);
}
}
}

/**
* Set current store
*
* @param StoreInterface $store
* @return $this
*/
private function setCurrentStore(StoreInterface $store): self
{
$this->currentStore = $store;
return $this;
}

/**
* Get current store
*
* @return StoreInterface
*/
private function getCurrentStore(): StoreInterface
{
return $this->currentStore;
}

/**
* Return validated table name
*
Expand Down Expand Up @@ -484,6 +507,7 @@ protected function hasAnchorSelect(Store $store)
*/
protected function createAnchorSelect(Store $store)
{
$this->setCurrentStore($store);
$isAnchorAttributeId = $this->config->getAttribute(
\Magento\Catalog\Model\Category::ENTITY,
'is_anchor'
Expand Down Expand Up @@ -690,7 +714,7 @@ protected function fillTempCategoryTreeIndex($temporaryName)
['ccacs' => $this->getTable('catalog_category_entity_int')],
'ccacs.' . $categoryLinkField . ' = c.' . $categoryLinkField
. ' AND ccacs.attribute_id = ccacd.attribute_id AND ccacs.store_id = ' .
$this->currentStoreId,
$this->getCurrentStore()->getId(),
[]
)->where(
$this->connection->getIfNullSql('ccacs.value', 'ccacd.value') . ' = ?',
Expand All @@ -702,8 +726,14 @@ protected function fillTempCategoryTreeIndex($temporaryName)
foreach ($selects as $select) {
$values = [];

foreach ($this->connection->fetchAll($select) as $category) {
foreach (explode('/', $category['path']) as $parentId) {
$categories = $this->connection->fetchAll($select);
foreach ($categories as $category) {
$categoriesTree = explode('/', $category['path']);
foreach ($categoriesTree as $parentId) {
if (!in_array($this->getCurrentStore()->getRootCategoryId(), $categoriesTree, true)) {
break;
}

if ($parentId !== $category['entity_id']) {
$values[] = [$parentId, $category['entity_id']];
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
<?php
/**
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/

declare(strict_types=1);

namespace Magento\GraphQl\Catalog\Product;

use Magento\TestFramework\TestCase\GraphQlAbstract;

/**
* Test for product categories
*/
class ProductCategoriesTest extends GraphQlAbstract
{
/**
* @magentoApiDataFixture Magento/Catalog/_files/product_in_two_root_categories.php
*/
public function testProductCategoriesInDefaultStore(): void
{
$response = $this->graphQlQuery(
$this->getQuery('in-stock-product'),
[],
'',
['Store' => 'default']
);

$product = current($response['products']['items']);
$categories = $product['categories'];

self::assertCount(1, $categories);
self::assertEquals('Category 1', $categories[0]['name']);
self::assertEquals('category-1', $categories[0]['url_path']);
self::assertEquals('category-1', $categories[0]['url_path']);
self::assertNull($categories[0]['breadcrumbs']);
}

/**
* @magentoApiDataFixture Magento/Catalog/_files/product_in_two_root_categories.php
*/
public function testProductCategoriesInNonDefaultStore(): void
{
$response = $this->graphQlQuery(
$this->getQuery('in-stock-product'),
[],
'',
['Store' => 'test_store_1']
);

$product = current($response['products']['items']);
$categories = $product['categories'];

self::assertCount(2, $categories);
self::assertEquals('Second Root Subcategory', $categories[0]['name']);
self::assertEquals('second-root-subcategory', $categories[0]['url_path']);
self::assertNull($categories[0]['breadcrumbs']);
self::assertEquals('Second Root Subsubcategory', $categories[1]['name']);
self::assertEquals('second-root-subcategory/second-root-subsubcategory', $categories[1]['url_path']);
self::assertCount(1, $categories[1]['breadcrumbs']);
self::assertEquals('Second Root Subcategory', $categories[1]['breadcrumbs'][0]['category_name']);
self::assertEquals(2, $categories[1]['breadcrumbs'][0]['category_level']);
}

/**
* @magentoApiDataFixture Magento/Catalog/_files/product_in_two_root_categories.php
* @magentoApiDataFixture Magento/Store/_files/second_store.php
*/
public function testProductCategoriesInNotRelevantStore(): void
{
$response = $this->graphQlQuery(
$this->getQuery('in-stock-product'),
[],
'',
['Store' => 'fixture_second_store']
);

self::assertEmpty($response['products']['items']);
}

/**
* Get query
*
* @param string $sku
* @return string
*/
private function getQuery(string $sku): string
{
return <<<QUERY
{
products(filter: { sku: { eq: "{$sku}"} }){
items {
categories {
name
id
url_path
breadcrumbs {
category_id
category_name
category_level
}
}
}
}
}
QUERY;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
<?php
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

/**
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/

declare(strict_types=1);

use Magento\Catalog\Api\CategoryRepositoryInterface;
use Magento\Catalog\Api\Data\ProductInterface;
use Magento\Catalog\Api\ProductRepositoryInterface;
use Magento\Catalog\Model\CategoryFactory;
use Magento\Catalog\Model\ResourceModel\Category\Collection;
use Magento\Catalog\Model\ResourceModel\Category\CollectionFactory;
use Magento\Store\Api\WebsiteRepositoryInterface;
use Magento\TestFramework\Helper\Bootstrap;
use Magento\TestFramework\Workaround\Override\Fixture\Resolver;

Resolver::getInstance()->requireDataFixture('Magento/Store/_files/store_with_second_root_category.php');
Resolver::getInstance()->requireDataFixture('Magento/Catalog/_files/product_with_category.php');

$objectManager = Bootstrap::getObjectManager();
$productRepository = $objectManager->get(ProductRepositoryInterface::class);
$websiteRepository = $objectManager->get(WebsiteRepositoryInterface::class);
$categoryRepository = $objectManager->get(CategoryRepositoryInterface::class);
$categoryCollectionFactory = $objectManager->get(CollectionFactory::class);
$categoryFactory = $objectManager->get(CategoryFactory::class);

$defaultWebsiteId = $websiteRepository->get('base')->getId();
$secondWebsiteId = $websiteRepository->get('test')->getId();

/** @var $categoryCollection Collection */
$categoryCollection = $categoryCollectionFactory->create();
$categoryCollection->addFieldToFilter('name', ['eq' => 'Second Root Category']);
$secondRootCategory = $categoryCollection->getFirstItem();

$subCategory = $categoryFactory->create();
$subCategory
->setName('Second Root Subcategory')
->setParentId($secondRootCategory->getEntityId())
->setLevel(2)
->setAvailableSortBy(['position', 'name'])
->setDefaultSortBy('name')
->setIsActive(true)
->setPosition(1);
$subCategory = $categoryRepository->save($subCategory);

$subSubCategory = $categoryFactory->create();
$subSubCategory
->setName('Second Root Subsubcategory')
->setParentId($subCategory->getEntityId())
->setLevel(2)
->setAvailableSortBy(['position', 'name'])
->setDefaultSortBy('name')
->setIsActive(true)
->setPosition(1);
$subSubCategory = $categoryRepository->save($subSubCategory);

/** @var $product ProductInterface */
$product = $productRepository->get('in-stock-product');
$product
->setUrlKey('in-stock-product')
->setWebsiteIds([$defaultWebsiteId, $secondWebsiteId])
->setCategoryIds(
[2, 333, $secondRootCategory->getEntityId(), $subCategory->getEntityId(), $subSubCategory->getEntityId()]
);
$productRepository->save($product);
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<?php
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

/**
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/

declare(strict_types=1);

use Magento\TestFramework\Workaround\Override\Fixture\Resolver;

Resolver::getInstance()->requireDataFixture('Magento/Store/_files/store_with_second_root_category_rollback.php');
Resolver::getInstance()->requireDataFixture('Magento/Catalog/_files/product_with_category_rollback.php');