Skip to content

Commit d9d3d9b

Browse files
authored
Merge pull request #8310 from magento-lynx/eav-graphql
2 parents 3bf511a + 3360dd7 commit d9d3d9b

20 files changed

+1194
-461
lines changed

app/code/Magento/CustomerGraphQl/Model/Customer/Address/ExtractCustomerAddressData.php

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -167,6 +167,11 @@ function (array $customAttribute) {
167167
},
168168
$attributes
169169
);
170+
usort($customAttributes['custom_attributesV2'], function (array $a, array $b) {
171+
$aPosition = $a['sort_order'];
172+
$bPosition = $b['sort_order'];
173+
return $aPosition <=> $bPosition;
174+
});
170175

171176
return $customAttributes;
172177
}

app/code/Magento/CustomerGraphQl/Model/Customer/ExtractCustomerData.php

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,11 @@ function (array $customAttribute) {
8888
},
8989
$customerData['custom_attributes']
9090
);
91+
usort($customerData['custom_attributes'], function (array $a, array $b) {
92+
$aPosition = $a['sort_order'];
93+
$bPosition = $b['sort_order'];
94+
return $aPosition <=> $bPosition;
95+
});
9196
} else {
9297
$customerData['custom_attributes'] = [];
9398
}

app/code/Magento/CustomerGraphQl/Model/Customer/GetCustomAttributes.php

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,8 @@ public function execute(string $entityType, array $customAttribute): ?array
7070
$entityType,
7171
$customAttribute['attribute_code']
7272
),
73-
'code' => $customAttribute['attribute_code']
73+
'code' => $customAttribute['attribute_code'],
74+
'sort_order' => $attr->getSortOrder() ?? ''
7475
];
7576

7677
if (in_array($attr->getFrontendInput(), $this->frontendInputs)) {
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
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\CustomerGraphQl\Model\Resolver;
9+
10+
use Magento\CustomerGraphQl\Model\Customer\ExtractCustomerData;
11+
use Magento\CustomerGraphQl\Model\Customer\GetCustomer;
12+
use Magento\Framework\Api\CustomAttributesDataInterface;
13+
use Magento\Framework\GraphQl\Config\Element\Field;
14+
use Magento\Framework\GraphQl\Query\ResolverInterface;
15+
use Magento\Framework\GraphQl\Schema\Type\ResolveInfo;
16+
17+
/**
18+
* Resolver Custom Attribute filter
19+
*/
20+
class CustomAttributeFilter implements ResolverInterface
21+
{
22+
/**
23+
* @var GetCustomer
24+
*/
25+
private GetCustomer $getCustomer;
26+
27+
/**
28+
* @var ExtractCustomerData
29+
*/
30+
private ExtractCustomerData $extractCustomerData;
31+
32+
/**
33+
* @param GetCustomer $getCustomer
34+
* @param ExtractCustomerData $extractCustomerData
35+
*/
36+
public function __construct(
37+
GetCustomer $getCustomer,
38+
ExtractCustomerData $extractCustomerData,
39+
) {
40+
$this->getCustomer = $getCustomer;
41+
$this->extractCustomerData = $extractCustomerData;
42+
}
43+
44+
/**
45+
* @inheritdoc
46+
*/
47+
public function resolve(
48+
Field $field,
49+
$context,
50+
ResolveInfo $info,
51+
array $value = null,
52+
array $args = null
53+
): array {
54+
$customAttributes = $value[CustomAttributesDataInterface::CUSTOM_ATTRIBUTES];
55+
if (isset($args['uids']) && !empty($args['uids'])) {
56+
$selectedUids = array_values($args['uids']);
57+
return array_filter($customAttributes, function ($attr) use ($selectedUids) {
58+
return in_array($attr['uid'], $selectedUids);
59+
});
60+
}
61+
62+
return $customAttributes;
63+
}
64+
}
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
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\CustomerGraphQl\Model\Resolver;
9+
10+
use Magento\CustomerGraphQl\Model\Customer\Address\ExtractCustomerAddressData;
11+
use Magento\CustomerGraphQl\Model\Customer\Address\GetCustomerAddress;
12+
use Magento\Framework\Api\CustomAttributesDataInterface;
13+
use Magento\Framework\GraphQl\Config\Element\Field;
14+
use Magento\Framework\GraphQl\Query\ResolverInterface;
15+
use Magento\Framework\GraphQl\Schema\Type\ResolveInfo;
16+
17+
/**
18+
* Resolver Customer Address Custom Attribute filter
19+
*/
20+
class CustomerAddressCustomAttributeFilter implements ResolverInterface
21+
{
22+
/**
23+
* @var GetCustomerAddress
24+
*/
25+
private GetCustomerAddress $getCustomerAddress;
26+
27+
/**
28+
* @var ExtractCustomerAddressData
29+
*/
30+
private ExtractCustomerAddressData $extractCustomerAddressData;
31+
32+
/**
33+
* @param GetCustomerAddress $getCustomerAddress
34+
* @param ExtractCustomerAddressData $extractCustomerAddressData
35+
*/
36+
public function __construct(
37+
GetCustomerAddress $getCustomerAddress,
38+
ExtractCustomerAddressData $extractCustomerAddressData,
39+
) {
40+
$this->getCustomerAddress = $getCustomerAddress;
41+
$this->extractCustomerAddressData = $extractCustomerAddressData;
42+
}
43+
44+
/**
45+
* @inheritdoc
46+
*/
47+
public function resolve(
48+
Field $field,
49+
$context,
50+
ResolveInfo $info,
51+
array $value = null,
52+
array $args = null
53+
): array {
54+
$customAttributes = $value[CustomAttributesDataInterface::CUSTOM_ATTRIBUTES . 'V2'];
55+
if (isset($args['uids']) && !empty($args['uids'])) {
56+
$selectedUids = array_values($args['uids']);
57+
return array_filter($customAttributes, function ($attr) use ($selectedUids) {
58+
return in_array($attr['uid'], $selectedUids);
59+
});
60+
}
61+
62+
return $customAttributes;
63+
}
64+
}

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -139,7 +139,7 @@ type Customer @doc(description: "Defines the customer name, addresses, and other
139139
is_subscribed: Boolean @doc(description: "Indicates whether the customer is subscribed to the company's newsletter.") @resolver(class: "\\Magento\\CustomerGraphQl\\Model\\Resolver\\IsSubscribed")
140140
addresses: [CustomerAddress] @doc(description: "An array containing the customer's shipping and billing addresses.") @resolver(class: "\\Magento\\CustomerGraphQl\\Model\\Resolver\\CustomerAddresses")
141141
gender: Int @doc(description: "The customer's gender (Male - 1, Female - 2).")
142-
custom_attributes: [AttributeValueInterface] @doc(description: "Customer's custom attributes.")
142+
custom_attributes(uids: [ID!]): [AttributeValueInterface] @doc(description: "Customer's custom attributes.") @resolver(class: "Magento\\CustomerGraphQl\\Model\\Resolver\\CustomAttributeFilter")
143143
}
144144

145145
type CustomerAddress @doc(description: "Contains detailed information about a customer's billing or shipping address."){
@@ -164,7 +164,7 @@ type CustomerAddress @doc(description: "Contains detailed information about a cu
164164
default_shipping: Boolean @doc(description: "Indicates whether the address is the customer's default shipping address.")
165165
default_billing: Boolean @doc(description: "Indicates whether the address is the customer's default billing address.")
166166
custom_attributes: [CustomerAddressAttribute] @deprecated(reason: "Use custom_attributesV2 instead.")
167-
custom_attributesV2: [AttributeValueInterface!]! @doc(description: "Custom attributes assigned to the customer address.")
167+
custom_attributesV2(uids: [ID!]): [AttributeValueInterface!]! @doc(description: "Custom attributes assigned to the customer address.") @resolver(class: "Magento\\CustomerGraphQl\\Model\\Resolver\\CustomerAddressCustomAttributeFilter")
168168
extension_attributes: [CustomerAddressAttribute] @doc(description: "Contains any extension attributes for the address.")
169169
}
170170

app/code/Magento/EavGraphQl/Model/GetAttributeValueComposite.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ public function __construct(array $providers = [])
3434
* @param string $entityType
3535
* @param array $customAttribute
3636
* @return array|null
37-
* @throws RuntimeException
37+
* @throws RuntimeException|LocalizedException
3838
*/
3939
public function execute(string $entityType, array $customAttribute): ?array
4040
{

app/code/Magento/EavGraphQl/Model/Output/Value/GetCustomAttributes.php

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,8 @@ public function execute(string $entity, string $code, string $value): ?array
6363

6464
$result = [
6565
'uid' => $this->uid->encode($entity, $code),
66-
'code' => $code
66+
'code' => $code,
67+
'sort_order' => $attr->getSortOrder() ?? ''
6768
];
6869

6970
if (in_array($attr->getFrontendInput(), $this->frontendInputs)) {

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

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,16 +7,16 @@
77

88
namespace Magento\EavGraphQl\Model\Resolver;
99

10-
use Magento\Eav\Model\AttributeRepository;
1110
use Magento\Eav\Api\Data\AttributeInterface;
12-
use Magento\Framework\GraphQl\Query\EnumLookup;
11+
use Magento\Eav\Model\AttributeRepository;
12+
use Magento\EavGraphQl\Model\Output\GetAttributeDataInterface;
1313
use Magento\Framework\Api\SearchCriteriaBuilder;
14+
use Magento\Framework\Exception\RuntimeException;
1415
use Magento\Framework\GraphQl\Config\Element\Field;
1516
use Magento\Framework\GraphQl\Exception\GraphQlInputException;
17+
use Magento\Framework\GraphQl\Query\EnumLookup;
1618
use Magento\Framework\GraphQl\Query\ResolverInterface;
1719
use Magento\Framework\GraphQl\Schema\Type\ResolveInfo;
18-
use Magento\Framework\Exception\RuntimeException;
19-
use Magento\EavGraphQl\Model\Output\GetAttributeDataInterface;
2020

2121
/**
2222
* Returns a list of attributes metadata for a given entity type.
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
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\EavGraphQl\Model\Resolver\Cache;
9+
10+
use Magento\Framework\GraphQl\Query\Resolver\IdentityInterface;
11+
12+
/**
13+
* Cache identity provider for attributes list query results.
14+
*/
15+
class AttributesListIdentity implements IdentityInterface
16+
{
17+
public const CACHE_TAG = 'ATTRIBUTES_LIST';
18+
19+
/**
20+
* @inheritDoc
21+
*/
22+
public function getIdentities(array $resolvedData): array
23+
{
24+
if (empty($resolvedData['items'])) {
25+
return [];
26+
}
27+
28+
if (!is_array($resolvedData['items'][0])) {
29+
return [];
30+
}
31+
32+
return [sprintf(
33+
"%s_%s",
34+
self::CACHE_TAG,
35+
$resolvedData['items'][0]['entity_type']
36+
)];
37+
}
38+
}

app/code/Magento/EavGraphQl/Plugin/Eav/AttributePlugin.php

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
namespace Magento\EavGraphQl\Plugin\Eav;
99

1010
use Magento\Eav\Model\Entity\Attribute;
11+
use Magento\EavGraphQl\Model\Resolver\Cache\AttributesListIdentity;
1112
use Magento\Framework\Api\AttributeInterface;
1213

1314
/**
@@ -35,7 +36,8 @@ public function afterGetIdentities(Attribute $subject, array $result): array
3536
$subject->getOrigData(AttributeInterface::ATTRIBUTE_CODE)
3637
?? $subject->getData(AttributeInterface::ATTRIBUTE_CODE)
3738
)
38-
]
39+
],
40+
[AttributesListIdentity::CACHE_TAG.'_'.strtoupper($subject->getEntityType()->getEntityTypeCode())]
3941
);
4042
}
4143
}

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

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,11 @@ type Query {
1010
@deprecated(reason: "Use `customAttributeMetadataV2` query instead.")
1111
customAttributeMetadataV2(attributes: [AttributeInput!]): AttributesMetadataOutput! @resolver(class: "Magento\\EavGraphQl\\Model\\Resolver\\AttributesMetadata") @doc(description: "Retrieve EAV attributes metadata.") @cache(cacheIdentity: "Magento\\EavGraphQl\\Model\\Resolver\\Cache\\CustomAttributeMetadataV2Identity")
1212
attributesForm(formCode: String! @doc(description: "Form code.")): AttributesFormOutput! @resolver(class: "Magento\\EavGraphQl\\Model\\Resolver\\AttributesForm") @doc(description: "Retrieve EAV attributes associated to a frontend form.")
13-
attributesList(entityType: AttributeEntityTypeEnum! @doc(description: "Entity type.")): AttributesMetadataOutput @resolver(class: "Magento\\EavGraphQl\\Model\\Resolver\\AttributesList") @doc(description: "Returns a list of attributes metadata for a given entity type.") @cache(cacheable: false)
13+
attributesList(entityType: AttributeEntityTypeEnum! @doc(description: "Entity type.")):
14+
AttributesMetadataOutput
15+
@resolver(class: "Magento\\EavGraphQl\\Model\\Resolver\\AttributesList")
16+
@doc(description: "Returns a list of attributes metadata for a given entity type.")
17+
@cache(cacheIdentity: "Magento\\EavGraphQl\\Model\\Resolver\\Cache\\AttributesListIdentity")
1418
}
1519

1620
type CustomAttributeMetadata @doc(description: "Defines an array of custom attributes.") {

dev/tests/api-functional/testsuite/Magento/GraphQl/Customer/CreateCustomerAddressWithCustomAttributesV2Test.php

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@
3636
'attribute_set_id' => AddressMetadataInterface::ATTRIBUTE_SET_ID_ADDRESS,
3737
'attribute_group_id' => 1,
3838
'attribute_code' => 'simple_attribute',
39-
'sort_order' => 1
39+
'sort_order' => 2
4040
],
4141
'simple_attribute',
4242
),
@@ -50,7 +50,7 @@
5050
'backend_model' => ArrayBackend::class,
5151
'attribute_code' => 'multiselect_attribute',
5252
'frontend_input' => 'multiselect',
53-
'sort_order' => 2
53+
'sort_order' => 1
5454
],
5555
'multiselect_attribute',
5656
),
@@ -60,7 +60,7 @@
6060
'entity_type' => AddressMetadataInterface::ATTRIBUTE_SET_ID_ADDRESS,
6161
'attribute_code' => '$multiselect_attribute.attribute_code$',
6262
'label' => 'line 1',
63-
'sort_order' => 10
63+
'sort_order' => 20
6464
],
6565
'multiselect_attribute_option1'
6666
),
@@ -70,7 +70,7 @@
7070
'entity_type' => AddressMetadataInterface::ATTRIBUTE_SET_ID_ADDRESS,
7171
'attribute_code' => '$multiselect_attribute.attribute_code$',
7272
'label' => 'line 2',
73-
'sort_order' => 20
73+
'sort_order' => 30
7474
],
7575
'multiselect_attribute_option2'
7676
),
@@ -80,7 +80,7 @@
8080
'entity_type' => AddressMetadataInterface::ATTRIBUTE_SET_ID_ADDRESS,
8181
'attribute_code' => '$multiselect_attribute.attribute_code$',
8282
'label' => 'line 3',
83-
'sort_order' => 30
83+
'sort_order' => 10
8484
],
8585
'multiselect_attribute_option3'
8686
),
@@ -242,24 +242,24 @@ public function testCreateCustomerAddressWithCustomAttributesV2()
242242
'custom_attributesV2' =>
243243
[
244244
0 =>
245-
[
246-
'code' => $this->simple_attribute->getAttributeCode(),
247-
'value' => 'brand new customer address value'
248-
],
249-
1 =>
250245
[
251246
'code' => $this->multiselect_attribute->getAttributeCode(),
252247
'selected_options' => [
253-
[
254-
'label' => $this->option2->getLabel(),
255-
'value' => $this->option2->getValue()
256-
],
257248
[
258249
'label' => $this->option3->getLabel(),
259250
'value' => $this->option3->getValue()
251+
],
252+
[
253+
'label' => $this->option2->getLabel(),
254+
'value' => $this->option2->getValue()
260255
]
261256
]
262257
],
258+
1 =>
259+
[
260+
'code' => $this->simple_attribute->getAttributeCode(),
261+
'value' => 'brand new customer address value'
262+
]
263263
],
264264
],
265265
],

0 commit comments

Comments
 (0)