Skip to content

Commit 7480cdc

Browse files
committed
MC-31497: Aggregations do not match ProductAttributeFilterInput
1 parent e71e92e commit 7480cdc

File tree

3 files changed

+117
-125
lines changed

3 files changed

+117
-125
lines changed

app/code/Magento/CatalogGraphQl/Model/Config/FilterAttributeReader.php

Lines changed: 19 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -10,16 +10,15 @@
1010
use Magento\Framework\Config\ReaderInterface;
1111
use Magento\Framework\GraphQl\Schema\Type\Entity\MapperInterface;
1212
use Magento\Catalog\Model\ResourceModel\Product\Attribute\CollectionFactory;
13-
use Magento\Catalog\Model\ResourceModel\Product\Attribute\Collection;
1413
use Magento\Catalog\Model\ResourceModel\Eav\Attribute;
1514

1615
/**
1716
* Adds custom/eav attributes to product filter type in the GraphQL config.
1817
*
1918
* Product Attribute should satisfy the following criteria:
20-
* - Attribute is searchable
21-
* - "Visible in Advanced Search" is set to "Yes"
22-
* - Attribute of type "Select" must have options
19+
* - (Attribute is searchable AND "Visible in Advanced Search" is set to "Yes")
20+
* - OR attribute is "Used in Layered Navigation"
21+
* - AND Attribute of type "Select" must have options
2322
*/
2423
class FilterAttributeReader implements ReaderInterface
2524
{
@@ -77,7 +76,7 @@ public function read($scope = null) : array
7776
$typeNames = $this->mapper->getMappedTypes(self::ENTITY_TYPE);
7877
$config = [];
7978

80-
foreach ($this->getAttributeCollection() as $attribute) {
79+
foreach ($this->getFilterAttributes() as $attribute) {
8180
$attributeCode = $attribute->getAttributeCode();
8281

8382
foreach ($typeNames as $typeName) {
@@ -120,15 +119,25 @@ private function getFilterType(Attribute $attribute): string
120119
}
121120

122121
/**
123-
* Create attribute collection
122+
* Get attributes to use in product filter input
124123
*
125-
* @return Collection|\Magento\Catalog\Model\ResourceModel\Eav\Attribute[]
124+
* @return array
126125
*/
127-
private function getAttributeCollection()
126+
private function getFilterAttributes(): array
128127
{
129-
return $this->collectionFactory->create()
128+
$filterableAttributes = $this->collectionFactory
129+
->create()
130+
->addHasOptionsFilter()
131+
->addIsFilterableFilter()
132+
->getItems();
133+
134+
$searchableAttributes = $this->collectionFactory
135+
->create()
130136
->addHasOptionsFilter()
131137
->addIsSearchableFilter()
132-
->addDisplayInAdvancedSearchFilter();
138+
->addDisplayInAdvancedSearchFilter()
139+
->getItems();
140+
141+
return $filterableAttributes + $searchableAttributes;
133142
}
134143
}

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

Lines changed: 81 additions & 100 deletions
Original file line numberDiff line numberDiff line change
@@ -5,127 +5,108 @@
55
*/
66
declare(strict_types=1);
77

8-
// phpcs:ignore Magento2.Security.IncludeFile
98
require __DIR__ . '/../../Catalog/_files/attribute_set_based_on_default_set.php';
10-
// phpcs:ignore Magento2.Security.IncludeFile
119
require __DIR__ . '/../../Catalog/_files/categories.php';
1210

11+
use Magento\Catalog\Api\ProductRepositoryInterface;
12+
use Magento\Catalog\Model\ResourceModel\Eav\Attribute;
13+
use Magento\Catalog\Setup\CategorySetup;
14+
use Magento\Eav\Model\Config;
15+
use Magento\Framework\Exception\NoSuchEntityException;
16+
use Magento\Indexer\Model\Indexer;
17+
use Magento\Indexer\Model\Indexer\Collection as IndexerCollection;
1318
use Magento\TestFramework\Helper\Bootstrap;
1419
use Magento\Eav\Api\AttributeRepositoryInterface;
1520

16-
$eavConfig = Bootstrap::getObjectManager()->get(\Magento\Eav\Model\Config::class);
17-
$attribute = $eavConfig->getAttribute('catalog_product', 'test_configurable');
18-
19-
$eavConfig->clear();
20-
21-
$attribute1 = $eavConfig->getAttribute('catalog_product', ' second_test_configurable');
21+
$objectManager = Bootstrap::getObjectManager();
22+
/** @var Config $eavConfig */
23+
$eavConfig = $objectManager->get(Config::class);
24+
/** @var AttributeRepositoryInterface $attributeRepository */
25+
$attributeRepository = $objectManager->create(AttributeRepositoryInterface::class);
26+
/** @var CategorySetup $installer */
27+
$installer = $objectManager->create(CategorySetup::class);
2228
$eavConfig->clear();
2329

24-
/** @var $installer \Magento\Catalog\Setup\CategorySetup */
25-
$installer = Bootstrap::getObjectManager()->create(\Magento\Catalog\Setup\CategorySetup::class);
26-
30+
$attribute = $eavConfig->getAttribute('catalog_product', 'test_configurable');
2731
if (!$attribute->getId()) {
28-
29-
/** @var $attribute \Magento\Catalog\Model\ResourceModel\Eav\Attribute */
30-
$attribute = Bootstrap::getObjectManager()->create(
31-
\Magento\Catalog\Model\ResourceModel\Eav\Attribute::class
32-
);
33-
34-
/** @var AttributeRepositoryInterface $attributeRepository */
35-
$attributeRepository = Bootstrap::getObjectManager()->create(AttributeRepositoryInterface::class);
36-
37-
$attribute->setData(
38-
[
39-
'attribute_code' => 'test_configurable',
40-
'entity_type_id' => $installer->getEntityTypeId('catalog_product'),
41-
'is_global' => 1,
42-
'is_user_defined' => 1,
43-
'frontend_input' => 'select',
44-
'is_unique' => 0,
45-
'is_required' => 0,
46-
'is_searchable' => 1,
47-
'is_visible_in_advanced_search' => 1,
48-
'is_comparable' => 1,
49-
'is_filterable' => 1,
50-
'is_filterable_in_search' => 1,
51-
'is_used_for_promo_rules' => 0,
52-
'is_html_allowed_on_front' => 1,
53-
'is_visible_on_front' => 1,
54-
'used_in_product_listing' => 1,
55-
'used_for_sort_by' => 1,
56-
'frontend_label' => ['Test Configurable'],
57-
'backend_type' => 'int',
58-
'option' => [
59-
'value' => ['option_0' => ['Option 1'], 'option_1' => ['Option 2']],
60-
'order' => ['option_0' => 1, 'option_1' => 2],
61-
],
62-
'default_value' => 'option_0'
63-
]
64-
);
65-
32+
/** @var $attribute Attribute */
33+
$attribute->setData([
34+
'attribute_code' => 'test_configurable',
35+
'entity_type_id' => $installer->getEntityTypeId('catalog_product'),
36+
'is_global' => 1,
37+
'is_user_defined' => 1,
38+
'frontend_input' => 'select',
39+
'is_unique' => 0,
40+
'is_required' => 0,
41+
'is_searchable' => 0,
42+
'is_visible_in_advanced_search' => 0,
43+
'is_comparable' => 1,
44+
'is_filterable' => 1,
45+
'is_filterable_in_search' => 1,
46+
'is_used_for_promo_rules' => 0,
47+
'is_html_allowed_on_front' => 1,
48+
'is_visible_on_front' => 1,
49+
'used_in_product_listing' => 1,
50+
'used_for_sort_by' => 1,
51+
'frontend_label' => ['Test Configurable'],
52+
'backend_type' => 'int',
53+
'option' => [
54+
'value' => ['option_0' => ['Option 1'], 'option_1' => ['Option 2']],
55+
'order' => ['option_0' => 1, 'option_1' => 2],
56+
],
57+
'default_value' => 'option_0'
58+
]);
6659
$attributeRepository->save($attribute);
6760

6861
/* Assign attribute to attribute set */
6962
$installer->addAttributeToGroup('catalog_product', 'Default', 'General', $attribute->getId());
7063
}
71-
// create a second attribute
72-
if (!$attribute1->getId()) {
73-
74-
/** @var $attribute1 \Magento\Catalog\Model\ResourceModel\Eav\Attribute */
75-
$attribute1 = Bootstrap::getObjectManager()->create(
76-
\Magento\Catalog\Model\ResourceModel\Eav\Attribute::class
77-
);
78-
79-
/** @var AttributeRepositoryInterface $attributeRepository */
80-
$attributeRepository = Bootstrap::getObjectManager()->create(AttributeRepositoryInterface::class);
8164

82-
$attribute1->setData(
83-
[
84-
'attribute_code' => 'second_test_configurable',
85-
'entity_type_id' => $installer->getEntityTypeId('catalog_product'),
86-
'is_global' => 1,
87-
'is_user_defined' => 1,
88-
'frontend_input' => 'select',
89-
'is_unique' => 0,
90-
'is_required' => 0,
91-
'is_searchable' => 1,
92-
'is_visible_in_advanced_search' => 1,
93-
'is_comparable' => 1,
94-
'is_filterable' => 1,
95-
'is_filterable_in_search' => 1,
96-
'is_used_for_promo_rules' => 0,
97-
'is_html_allowed_on_front' => 1,
98-
'is_visible_on_front' => 1,
99-
'used_in_product_listing' => 1,
100-
'used_for_sort_by' => 1,
101-
'frontend_label' => ['Second Test Configurable'],
102-
'backend_type' => 'int',
103-
'option' => [
104-
'value' => ['option_0' => ['Option 3'], 'option_1' => ['Option 4']],
105-
'order' => ['option_0' => 1, 'option_1' => 2],
106-
],
107-
'default' => ['option_0']
108-
]
109-
);
110-
111-
$attributeRepository->save($attribute1);
65+
// create a second attribute
66+
/** @var Attribute $secondAttribute */
67+
$secondAttribute = $eavConfig->getAttribute('catalog_product', ' second_test_configurable');
68+
if (!$secondAttribute->getId()) {
69+
$secondAttribute->setData([
70+
'attribute_code' => 'second_test_configurable',
71+
'entity_type_id' => $installer->getEntityTypeId('catalog_product'),
72+
'is_global' => 1,
73+
'is_user_defined' => 1,
74+
'frontend_input' => 'select',
75+
'is_unique' => 0,
76+
'is_required' => 0,
77+
'is_searchable' => 0,
78+
'is_visible_in_advanced_search' => 0,
79+
'is_comparable' => 1,
80+
'is_filterable' => 1,
81+
'is_filterable_in_search' => 1,
82+
'is_used_for_promo_rules' => 0,
83+
'is_html_allowed_on_front' => 1,
84+
'is_visible_on_front' => 1,
85+
'used_in_product_listing' => 1,
86+
'used_for_sort_by' => 1,
87+
'frontend_label' => ['Second Test Configurable'],
88+
'backend_type' => 'int',
89+
'option' => [
90+
'value' => ['option_0' => ['Option 3'], 'option_1' => ['Option 4']],
91+
'order' => ['option_0' => 1, 'option_1' => 2],
92+
],
93+
'default' => ['option_0']
94+
]);
95+
$attributeRepository->save($secondAttribute);
11296

11397
/* Assign attribute to attribute set */
11498
$installer->addAttributeToGroup(
11599
'catalog_product',
116100
$attributeSet->getId(),
117101
$attributeSet->getDefaultGroupId(),
118-
$attribute1->getId()
102+
$secondAttribute->getId()
119103
);
120104
}
121105

122106
$eavConfig->clear();
123107

124-
/** @var \Magento\Framework\ObjectManagerInterface $objectManager */
125-
$objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager();
126-
127-
/** @var $productRepository \Magento\Catalog\Api\ProductRepositoryInterface */
128-
$productRepository = $objectManager->get(\Magento\Catalog\Api\ProductRepositoryInterface::class);
108+
/** @var ProductRepositoryInterface $productRepository */
109+
$productRepository = $objectManager->get(ProductRepositoryInterface::class);
129110
$productsWithNewAttributeSet = ['simple', '12345', 'simple-4'];
130111

131112
foreach ($productsWithNewAttributeSet as $sku) {
@@ -139,14 +120,14 @@
139120
'is_in_stock' => 1]
140121
);
141122
$productRepository->save($product);
142-
} catch (\Magento\Framework\Exception\NoSuchEntityException $e) {
123+
} catch (NoSuchEntityException $e) {
143124

144125
}
145126
}
146-
/** @var \Magento\Indexer\Model\Indexer\Collection $indexerCollection */
147-
$indexerCollection = Bootstrap::getObjectManager()->get(\Magento\Indexer\Model\Indexer\Collection::class);
148-
$indexerCollection->load();
149-
/** @var \Magento\Indexer\Model\Indexer $indexer */
127+
128+
/** @var IndexerCollection $indexerCollection */
129+
$indexerCollection = $objectManager->get(IndexerCollection::class)->load();
130+
/** @var Indexer $indexer */
150131
foreach ($indexerCollection->getItems() as $indexer) {
151132
$indexer->reindexAll();
152133
}

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

Lines changed: 17 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -5,42 +5,44 @@
55
*/
66
declare(strict_types=1);
77

8-
// phpcs:ignore Magento2.Security.IncludeFile
98
require __DIR__ . '/../../Eav/_files/empty_attribute_set_rollback.php';
10-
// phpcs:ignore Magento2.Security.IncludeFile
119
require __DIR__ . '/../../Catalog/_files/categories_rollback.php';
1210

11+
use Magento\Eav\Api\Data\AttributeInterface;
12+
use Magento\Eav\Model\Config;
13+
use Magento\Eav\Model\Entity\Attribute\Set as AttributeSet;
14+
use Magento\Eav\Model\Entity\Type;
15+
use Magento\Eav\Model\ResourceModel\Entity\Attribute\Set\Collection as AttributeSetCollection;
16+
use Magento\Framework\App\ObjectManager;
1317
use Magento\TestFramework\Helper\Bootstrap;
1418
use Magento\Eav\Api\AttributeRepositoryInterface;
15-
use Magento\TestFramework\Helper\CacheCleaner;
1619

17-
$eavConfig = Bootstrap::getObjectManager()->get(\Magento\Eav\Model\Config::class);
20+
/** @var ObjectManager $objectManager */
21+
$objectManager = Bootstrap::getObjectManager();
22+
23+
$eavConfig = $objectManager->get(Config::class);
1824
$attributesToDelete = ['test_configurable', 'second_test_configurable'];
1925
/** @var AttributeRepositoryInterface $attributeRepository */
20-
$attributeRepository = Bootstrap::getObjectManager()->get(AttributeRepositoryInterface::class);
26+
$attributeRepository = $objectManager->get(AttributeRepositoryInterface::class);
2127

2228
foreach ($attributesToDelete as $attributeCode) {
23-
/** @var \Magento\Eav\Api\Data\AttributeInterface $attribute */
29+
/** @var AttributeInterface $attribute */
2430
$attribute = $attributeRepository->get('catalog_product', $attributeCode);
2531
$attributeRepository->delete($attribute);
2632
}
27-
/** @var $product \Magento\Catalog\Model\Product */
28-
$objectManager = Bootstrap::getObjectManager();
29-
30-
$entityType = $objectManager->create(\Magento\Eav\Model\Entity\Type::class)->loadByCode('catalog_product');
3133

3234
// remove attribute set
33-
34-
/** @var \Magento\Eav\Model\ResourceModel\Entity\Attribute\Set\Collection $attributeSetCollection */
35+
$entityType = $objectManager->create(Type::class)->loadByCode('catalog_product');
36+
/** @var AttributeSetCollection $attributeSetCollection */
3537
$attributeSetCollection = $objectManager->create(
36-
\Magento\Eav\Model\ResourceModel\Entity\Attribute\Set\Collection::class
38+
AttributeSetCollection::class
3739
);
3840
$attributeSetCollection->addFilter('attribute_set_name', 'second_attribute_set');
3941
$attributeSetCollection->addFilter('entity_type_id', $entityType->getId());
40-
$attributeSetCollection->setOrder('attribute_set_id'); // descending is default value
42+
$attributeSetCollection->setOrder('attribute_set_id');
4143
$attributeSetCollection->setPageSize(1);
4244
$attributeSetCollection->load();
4345

44-
/** @var \Magento\Eav\Model\Entity\Attribute\Set $attributeSet */
46+
/** @var AttributeSet $attributeSet */
4547
$attributeSet = $attributeSetCollection->fetchItem();
4648
$attributeSet->delete();

0 commit comments

Comments
 (0)