Skip to content

Commit 807f47a

Browse files
LYNX-183: Add filters to attributesList query (#128)
1 parent f7d0491 commit 807f47a

File tree

13 files changed

+602
-393
lines changed

13 files changed

+602
-393
lines changed

app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductCustomAttributes.php

Lines changed: 25 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,8 @@
1212
use Magento\Catalog\Model\Product;
1313
use Magento\CatalogGraphQl\Model\ProductDataProvider;
1414
use Magento\Eav\Api\Data\AttributeInterface;
15-
use Magento\Eav\Model\AttributeRepository;
1615
use Magento\EavGraphQl\Model\Output\Value\GetAttributeValueInterface;
17-
use Magento\EavGraphQl\Model\Resolver\AttributeFilter;
18-
use Magento\Framework\Api\SearchCriteriaBuilder;
16+
use Magento\EavGraphQl\Model\Resolver\GetFilteredAttributes;
1917
use Magento\GraphQl\Model\Query\ContextInterface;
2018
use Magento\Framework\GraphQl\Schema\Type\ResolveInfo;
2119
use Magento\Framework\GraphQl\Config\Element\Field;
@@ -27,16 +25,6 @@
2725
*/
2826
class ProductCustomAttributes implements ResolverInterface
2927
{
30-
/**
31-
* @var AttributeRepository
32-
*/
33-
private AttributeRepository $attributeRepository;
34-
35-
/**
36-
* @var SearchCriteriaBuilder
37-
*/
38-
private SearchCriteriaBuilder $searchCriteriaBuilder;
39-
4028
/**
4129
* @var GetAttributeValueInterface
4230
*/
@@ -48,36 +36,30 @@ class ProductCustomAttributes implements ResolverInterface
4836
private ProductDataProvider $productDataProvider;
4937

5038
/**
51-
* @var AttributeFilter
39+
* @var GetFilteredAttributes
5240
*/
53-
private AttributeFilter $attributeFilter;
41+
private GetFilteredAttributes $getFilteredAttributes;
5442

5543
/**
5644
* @var FilterProductCustomAttribute
5745
*/
5846
private FilterProductCustomAttribute $filterCustomAttribute;
5947

6048
/**
61-
* @param AttributeRepository $attributeRepository
62-
* @param SearchCriteriaBuilder $searchCriteriaBuilder
6349
* @param GetAttributeValueInterface $getAttributeValue
6450
* @param ProductDataProvider $productDataProvider
65-
* @param AttributeFilter $attributeFilter
51+
* @param GetFilteredAttributes $getFilteredAttributes
6652
* @param FilterProductCustomAttribute $filterCustomAttribute
6753
*/
6854
public function __construct(
69-
AttributeRepository $attributeRepository,
70-
SearchCriteriaBuilder $searchCriteriaBuilder,
7155
GetAttributeValueInterface $getAttributeValue,
7256
ProductDataProvider $productDataProvider,
73-
AttributeFilter $attributeFilter,
57+
GetFilteredAttributes $getFilteredAttributes,
7458
FilterProductCustomAttribute $filterCustomAttribute
7559
) {
76-
$this->attributeRepository = $attributeRepository;
77-
$this->searchCriteriaBuilder = $searchCriteriaBuilder;
7860
$this->getAttributeValue = $getAttributeValue;
7961
$this->productDataProvider = $productDataProvider;
80-
$this->attributeFilter = $attributeFilter;
62+
$this->getFilteredAttributes = $getFilteredAttributes;
8163
$this->filterCustomAttribute = $filterCustomAttribute;
8264
}
8365

@@ -99,25 +81,18 @@ public function resolve(
9981
array $value = null,
10082
array $args = null
10183
) {
102-
$filterArgs = $args['filter'] ?? [];
84+
$filtersArgs = $args['filters'] ?? [];
10385

104-
$searchCriteriaBuilder = $this->attributeFilter->execute($filterArgs, $this->searchCriteriaBuilder);
105-
106-
$searchCriteriaBuilder = $searchCriteriaBuilder
107-
->addFilter('is_visible', true)
108-
->addFilter('backend_type', 'static', 'neq')
109-
->create();
110-
111-
$productCustomAttributes = $this->attributeRepository->getList(
112-
ProductAttributeInterface::ENTITY_TYPE_CODE,
113-
$searchCriteriaBuilder
114-
)->getItems();
86+
$productCustomAttributes = $this->getFilteredAttributes->execute(
87+
$filtersArgs,
88+
ProductAttributeInterface::ENTITY_TYPE_CODE
89+
);
11590

11691
$attributeCodes = array_map(
11792
function (AttributeInterface $customAttribute) {
11893
return $customAttribute->getAttributeCode();
11994
},
120-
$productCustomAttributes
95+
$productCustomAttributes['items']
12196
);
12297

12398
$filteredAttributeCodes = $this->filterCustomAttribute->execute(array_flip($attributeCodes));
@@ -141,15 +116,18 @@ function (AttributeInterface $customAttribute) {
141116
];
142117
}
143118

144-
return array_map(
145-
function (array $customAttribute) {
146-
return $this->getAttributeValue->execute(
147-
ProductAttributeInterface::ENTITY_TYPE_CODE,
148-
$customAttribute['attribute_code'],
149-
$customAttribute['value']
150-
);
151-
},
152-
$customAttributes
153-
);
119+
return [
120+
'items' => array_map(
121+
function (array $customAttribute) {
122+
return $this->getAttributeValue->execute(
123+
ProductAttributeInterface::ENTITY_TYPE_CODE,
124+
$customAttribute['attribute_code'],
125+
$customAttribute['value']
126+
);
127+
},
128+
$customAttributes
129+
),
130+
'errors' => $productCustomAttributes['errors']
131+
];
154132
}
155133
}

app/code/Magento/CatalogGraphQl/etc/schema.graphqls

Lines changed: 4 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -125,7 +125,7 @@ interface ProductInterface @typeResolver(class: "Magento\\CatalogGraphQl\\Model\
125125
categories: [CategoryInterface] @doc(description: "The categories assigned to a product.") @resolver(class: "Magento\\CatalogGraphQl\\Model\\Resolver\\Categories") @cache(cacheIdentity: "Magento\\CatalogGraphQl\\Model\\Resolver\\Category\\CategoriesIdentity")
126126
canonical_url: String @doc(description: "The relative canonical URL. This value is returned only if the system setting 'Use Canonical Link Meta Tag For Products' is enabled.") @resolver(class: "Magento\\CatalogGraphQl\\Model\\Resolver\\Product\\CanonicalUrl")
127127
media_gallery: [MediaGalleryInterface] @doc(description: "An array of media gallery objects.") @resolver(class: "Magento\\CatalogGraphQl\\Model\\Resolver\\Product\\MediaGallery")
128-
custom_attributes(filter: AttributeFilterInput): [AttributeValueInterface] @doc(description: "Product custom attributes.") @resolver(class: "Magento\\CatalogGraphQl\\Model\\Resolver\\Product\\ProductCustomAttributes")
128+
custom_attributes(filters: AttributeFilterInput): ProductCustomAttributes @doc(description: "Product custom attributes.") @resolver(class: "Magento\\CatalogGraphQl\\Model\\Resolver\\Product\\ProductCustomAttributes")
129129
}
130130

131131
interface PhysicalProductInterface @typeResolver(class: "Magento\\CatalogGraphQl\\Model\\ProductInterfaceTypeResolverComposite") @doc(description: "Contains attributes specific to tangible products.") {
@@ -562,21 +562,7 @@ enum CatalogAttributeApplyToEnum {
562562
CATEGORY
563563
}
564564

565-
input AttributeFilterInput @doc(description: "An input object that specifies the filters used for product.") {
566-
is_comparable: Boolean @doc(description: "Whether a product or category attribute can be compared against another or not.")
567-
is_filterable_in_search: Boolean @doc(description: "Whether a product or category attribute can be filtered in search or not.")
568-
is_searchable: Boolean @doc(description: "Whether a product or category attribute can be searched or not.")
569-
is_filterable: Boolean @doc(description: "Whether a product or category attribute can be filtered or not.")
570-
is_html_allowed_on_front: Boolean @doc(description: "Whether a product or category attribute can use HTML on front or not.")
571-
is_used_for_price_rules: Boolean @doc(description: "Whether a product or category attribute can be used for price rules or not.")
572-
is_visible_in_advanced_search: Boolean @doc(description: "Whether a product or category attribute is visible in advanced search or not.")
573-
is_wysiwyg_enabled: Boolean @doc(description: "Whether a product or category attribute has WYSIWYG enabled or not.")
574-
is_used_for_promo_rules: Boolean @doc(description: "Whether a product or category attribute is used for promo rules or not.")
575-
used_in_product_listing: Boolean @doc(description: "Whether a product or category attribute is used in product listing or not.")
576-
is_visible_on_front: Boolean @doc(description: "Whether a product or category attribute is visible on front or not.")
577-
used_for_sort_by: Boolean @doc(description: "Whether a product or category attribute is used for sort or not.")
578-
is_required_in_admin_store: Boolean @doc(description: "Whether a product or category attribute is required in admin store or not.")
579-
is_used_in_grid: Boolean @doc(description: "Whether a product or category attribute is used in grid or not.")
580-
is_visible_in_grid: Boolean @doc(description: "Whether a product or category attribute is visible in grid or not.")
581-
is_filterable_in_grid: Boolean @doc(description: "Whether a product or category attribute is filterable in grid or not.")
565+
type ProductCustomAttributes @doc(description: "Product custom attributes") {
566+
items: [AttributeValueInterface!]! @doc(description: "Requested custom attributes")
567+
errors: [AttributeMetadataError!]! @doc(description: "Errors when retrieving custom attributes metadata.")
582568
}

app/code/Magento/Customer/Test/Fixture/CustomerAttribute.php

Lines changed: 12 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -19,34 +19,6 @@
1919

2020
class CustomerAttribute implements RevertibleDataFixtureInterface
2121
{
22-
private const DEFAULT_DATA = [
23-
'entity_type_id' => null,
24-
'attribute_id' => null,
25-
'attribute_code' => 'attribute%uniqid%',
26-
'default_frontend_label' => 'Attribute%uniqid%',
27-
'frontend_labels' => [],
28-
'frontend_input' => 'text',
29-
'backend_type' => 'varchar',
30-
'is_required' => false,
31-
'is_user_defined' => true,
32-
'note' => null,
33-
'backend_model' => null,
34-
'source_model' => null,
35-
'default_value' => null,
36-
'is_unique' => '0',
37-
'frontend_class' => null,
38-
'used_in_forms' => [],
39-
'sort_order' => 0,
40-
'attribute_set_id' => null,
41-
'attribute_group_id' => null,
42-
'input_filter' => null,
43-
'multiline_count' => 0,
44-
'validate_rules' => null,
45-
'website_id' => null,
46-
'is_visible' => 1,
47-
'scope_is_visible' => 1,
48-
];
49-
5022
/**
5123
* @var DataMerger
5224
*/
@@ -72,32 +44,41 @@ class CustomerAttribute implements RevertibleDataFixtureInterface
7244
*/
7345
private AttributeRepositoryInterface $attributeRepository;
7446

47+
/**
48+
* @var CustomerAttributeDefaultData
49+
*/
50+
private CustomerAttributeDefaultData $customerAttributeDefaultData;
51+
7552
/**
7653
* @param DataMerger $dataMerger
7754
* @param ProcessorInterface $processor
7855
* @param AttributeRepositoryInterface $attributeRepository
7956
* @param AttributeFactory $attributeFactory
8057
* @param ResourceModelAttribute $resourceModelAttribute
58+
* @param CustomerAttributeDefaultData $customerAttributeDefaultData
8159
*/
8260
public function __construct(
8361
DataMerger $dataMerger,
8462
ProcessorInterface $processor,
8563
AttributeRepositoryInterface $attributeRepository,
8664
AttributeFactory $attributeFactory,
87-
ResourceModelAttribute $resourceModelAttribute
65+
ResourceModelAttribute $resourceModelAttribute,
66+
CustomerAttributeDefaultData $customerAttributeDefaultData
8867
) {
8968
$this->dataMerger = $dataMerger;
9069
$this->processor = $processor;
9170
$this->attributeFactory = $attributeFactory;
9271
$this->resourceModelAttribute = $resourceModelAttribute;
9372
$this->attributeRepository = $attributeRepository;
73+
$this->customerAttributeDefaultData = $customerAttributeDefaultData;
9474
}
9575

9676
/**
9777
* @inheritdoc
9878
*/
9979
public function apply(array $data = []): ?DataObject
10080
{
81+
$defaultData = $this->customerAttributeDefaultData->getData();
10182
if (empty($data['entity_type_id'])) {
10283
throw new InvalidArgumentException(
10384
__(
@@ -110,8 +91,8 @@ public function apply(array $data = []): ?DataObject
11091
}
11192

11293
/** @var Attribute $attr */
113-
$attr = $this->attributeFactory->createAttribute(Attribute::class, self::DEFAULT_DATA);
114-
$mergedData = $this->processor->process($this, $this->dataMerger->merge(self::DEFAULT_DATA, $data));
94+
$attr = $this->attributeFactory->createAttribute(Attribute::class, $defaultData);
95+
$mergedData = $this->processor->process($this, $this->dataMerger->merge($defaultData, $data));
11596
$attr->setData($mergedData);
11697
if (isset($data['website_id'])) {
11798
$attr->setWebsite($data['website_id']);
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
<?php
2+
/**
3+
* Copyright © Magento, Inc. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
declare(strict_types=1);
7+
8+
namespace Magento\Customer\Test\Fixture;
9+
10+
class CustomerAttributeDefaultData
11+
{
12+
private const DEFAULT_DATA = [
13+
'entity_type_id' => null,
14+
'attribute_id' => null,
15+
'attribute_code' => 'attribute%uniqid%',
16+
'default_frontend_label' => 'Attribute%uniqid%',
17+
'frontend_labels' => [],
18+
'frontend_input' => 'text',
19+
'backend_type' => 'varchar',
20+
'is_required' => false,
21+
'is_user_defined' => true,
22+
'note' => null,
23+
'backend_model' => null,
24+
'source_model' => null,
25+
'default_value' => null,
26+
'is_unique' => '0',
27+
'frontend_class' => null,
28+
'used_in_forms' => [],
29+
'sort_order' => 0,
30+
'attribute_set_id' => null,
31+
'attribute_group_id' => null,
32+
'input_filter' => null,
33+
'multiline_count' => 0,
34+
'validate_rules' => null,
35+
'website_id' => null,
36+
'is_visible' => 1,
37+
'scope_is_visible' => 1,
38+
];
39+
40+
/**
41+
* @var array
42+
*/
43+
private $defaultData;
44+
45+
/**
46+
* @param array $defaultData
47+
*/
48+
public function __construct(array $defaultData = [])
49+
{
50+
$this->defaultData = array_merge(self::DEFAULT_DATA, $defaultData);
51+
}
52+
53+
/**
54+
* Return default data
55+
*/
56+
public function getData(): array
57+
{
58+
return $this->defaultData;
59+
}
60+
}

app/code/Magento/EavGraphQl/Model/Resolver/AttributeFilter.php

Lines changed: 0 additions & 32 deletions
This file was deleted.

0 commit comments

Comments
 (0)