Skip to content

Commit 8c33bbd

Browse files
MAGETWO-94565: Catalog product collection filters produce errors and cause inconsistent behaviour
- Replace using category collection to using db.
1 parent fc328d9 commit 8c33bbd

File tree

2 files changed

+63
-18
lines changed

2 files changed

+63
-18
lines changed

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

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,14 @@
99
*
1010
* @author Magento Core Team <[email protected]>
1111
*/
12+
declare(strict_types=1);
13+
1214
namespace Magento\Catalog\Model\ResourceModel;
1315

1416
use Magento\Catalog\Model\Indexer\Category\Product\Processor;
1517
use Magento\Framework\DataObject;
1618
use Magento\Framework\EntityManager\EntityManager;
19+
use Magento\Catalog\Setup\CategorySetup;
1720

1821
/**
1922
* Resource model for category entity
@@ -1132,4 +1135,41 @@ private function getAggregateCount()
11321135
}
11331136
return $this->aggregateCount;
11341137
}
1138+
1139+
/**
1140+
* Get category with children.
1141+
*
1142+
* @param int $categoryId
1143+
* @return array
1144+
*/
1145+
public function getCategoryWithChildren(int $categoryId): array
1146+
{
1147+
$connection = $this->getConnection();
1148+
1149+
$select = $connection->select()
1150+
->from(
1151+
['eav_attribute' => $this->getTable('eav_attribute')],
1152+
['attribute_id']
1153+
)->where('entity_type_id = ?', CategorySetup::CATEGORY_ENTITY_TYPE_ID)
1154+
->where('attribute_code = ?', 'is_anchor')
1155+
->limit(1);
1156+
$attributeId = $connection->fetchRow($select);
1157+
1158+
$select = $connection->select()
1159+
->from(
1160+
['cce' => $this->getTable('catalog_category_entity')],
1161+
['entity_id', 'parent_id', 'path']
1162+
)->join(
1163+
['cce_int' => $this->getTable('catalog_category_entity_int')],
1164+
'cce.entity_id = cce_int.entity_id',
1165+
['is_anchor' => 'cce_int.value']
1166+
)->where(
1167+
'cce_int.attribute_id = ?',
1168+
$attributeId['attribute_id']
1169+
)->where(
1170+
"cce.path LIKE '%/{$categoryId}' OR cce.path LIKE '%/{$categoryId}/%'"
1171+
)->order('path');
1172+
1173+
return $connection->fetchAll($select);
1174+
}
11351175
}

app/code/Magento/Catalog/Model/ResourceModel/Product/Collection.php

Lines changed: 23 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@
2323
use Magento\Framework\Indexer\DimensionFactory;
2424
use Magento\Store\Model\Indexer\WebsiteDimensionProvider;
2525
use Magento\Store\Model\Store;
26-
use Magento\Catalog\Model\ResourceModel\Category\CollectionFactory;
26+
use Magento\Catalog\Model\ResourceModel\Category;
2727

2828
/**
2929
* Product collection
@@ -305,9 +305,9 @@ class Collection extends \Magento\Catalog\Model\ResourceModel\Collection\Abstrac
305305
private $urlFinder;
306306

307307
/**
308-
* @var CollectionFactory
308+
* @var Category
309309
*/
310-
private $categoryCollectionFactory;
310+
private $categoryResourceModel;
311311

312312
/**
313313
* Collection constructor
@@ -337,7 +337,7 @@ class Collection extends \Magento\Catalog\Model\ResourceModel\Collection\Abstrac
337337
* @param TableMaintainer|null $tableMaintainer
338338
* @param PriceTableResolver|null $priceTableResolver
339339
* @param DimensionFactory|null $dimensionFactory
340-
* @param CollectionFactory|null $categoryCollectionFactory
340+
* @param Category|null $categoryResourceModel
341341
*
342342
* @SuppressWarnings(PHPMD.ExcessiveParameterList)
343343
*/
@@ -367,7 +367,7 @@ public function __construct(
367367
TableMaintainer $tableMaintainer = null,
368368
PriceTableResolver $priceTableResolver = null,
369369
DimensionFactory $dimensionFactory = null,
370-
CollectionFactory $categoryCollectionFactory = null
370+
Category $categoryResourceModel = null
371371
) {
372372
$this->moduleManager = $moduleManager;
373373
$this->_catalogProductFlatState = $catalogProductFlatState;
@@ -401,8 +401,8 @@ public function __construct(
401401
$this->priceTableResolver = $priceTableResolver ?: ObjectManager::getInstance()->get(PriceTableResolver::class);
402402
$this->dimensionFactory = $dimensionFactory
403403
?: ObjectManager::getInstance()->get(DimensionFactory::class);
404-
$this->categoryCollectionFactory = $categoryCollectionFactory ?: ObjectManager::getInstance()
405-
->get(CollectionFactory::class);
404+
$this->categoryResourceModel = $categoryResourceModel ?: ObjectManager::getInstance()
405+
->get(Category::class);
406406
}
407407

408408
/**
@@ -2104,18 +2104,23 @@ protected function _applyZeroStoreProductLimitations()
21042104
private function getChildrenCategories(int $categoryId): array
21052105
{
21062106
$categoryIds[] = $categoryId;
2107-
2108-
/** @var \Magento\Catalog\Model\ResourceModel\Category\Collection $categoryCollection */
2109-
$categoryCollection = $this->categoryCollectionFactory->create();
2110-
$categories = $categoryCollection
2111-
->addAttributeToFilter(
2112-
['is_anchor', 'path'],
2113-
[1, ['like' => $categoryId . '/%']]
2114-
)->getItems();
2115-
foreach ($categories as $category) {
2116-
$categoryChildren = $category->getChildren();
2117-
$categoryIds = array_merge($categoryIds, explode(',', $categoryChildren));
2107+
$anchorCategory = [];
2108+
2109+
$categories = $this->categoryResourceModel->getCategoryWithChildren($categoryId);
2110+
$firstCategory = array_shift($categories);
2111+
if ($firstCategory['is_anchor'] == 1) {
2112+
$anchorCategory[] = (int)$firstCategory['entity_id'];
2113+
foreach ($categories as $category) {
2114+
if (in_array($category['parent_id'], $categoryIds)
2115+
&& in_array($category['parent_id'], $anchorCategory)) {
2116+
$categoryIds[] = (int)$category['entity_id'];
2117+
if ($category['is_anchor'] == 1) {
2118+
$anchorCategory[] = (int)$category['entity_id'];
2119+
}
2120+
}
2121+
}
21182122
}
2123+
21192124
return $categoryIds;
21202125
}
21212126

0 commit comments

Comments
 (0)