Skip to content

Commit c1204a8

Browse files
authored
Merge branch '2.4-develop' into B2B-2257
2 parents c34d42f + c7464fe commit c1204a8

File tree

9 files changed

+556
-33
lines changed

9 files changed

+556
-33
lines changed
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
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\Eav\Model\Entity\Attribute as EavAttribute;
11+
use Magento\Framework\GraphQl\Query\Resolver\IdentityInterface;
12+
13+
/**
14+
* Cache identity provider for custom attribute metadata query results.
15+
*/
16+
class CustomAttributeMetadataIdentity implements IdentityInterface
17+
{
18+
/**
19+
* @inheritDoc
20+
*/
21+
public function getIdentities(array $resolvedData): array
22+
{
23+
$identities = [];
24+
if (isset($resolvedData['items']) && !empty($resolvedData['items'])) {
25+
foreach ($resolvedData['items'] as $item) {
26+
if (is_array($item)) {
27+
$identities[] = sprintf(
28+
"%s_%s_%s",
29+
EavAttribute::CACHE_TAG,
30+
$item['entity_type'],
31+
$item['attribute_code']
32+
);
33+
}
34+
}
35+
} else {
36+
return [];
37+
}
38+
return $identities;
39+
}
40+
}
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
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\Plugin\Eav;
9+
10+
use Magento\Eav\Model\Entity\Attribute;
11+
use Magento\Framework\Api\AttributeInterface;
12+
13+
/**
14+
* EAV plugin runs page cache clean and provides proper EAV identities.
15+
*/
16+
class AttributePlugin
17+
{
18+
/**
19+
* Clean cache by relevant tags after entity save.
20+
*
21+
* @param Attribute $subject
22+
* @param array $result
23+
*
24+
* @return string[]
25+
*/
26+
public function afterGetIdentities(Attribute $subject, array $result): array
27+
{
28+
return array_merge(
29+
$result,
30+
[
31+
sprintf(
32+
"%s_%s_%s",
33+
Attribute::CACHE_TAG,
34+
$subject->getEntityType()->getEntityTypeCode(),
35+
$subject->getOrigData(AttributeInterface::ATTRIBUTE_CODE)
36+
?? $subject->getData(AttributeInterface::ATTRIBUTE_CODE)
37+
)
38+
]
39+
);
40+
}
41+
}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
<?xml version="1.0"?>
2+
<!--
3+
/**
4+
* Copyright © Magento, Inc. All rights reserved.
5+
* See COPYING.txt for license details.
6+
*/
7+
-->
8+
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
9+
<type name="Magento\Eav\Model\Entity\Attribute">
10+
<plugin name="entityAttributeChangePlugin" type="Magento\EavGraphQl\Plugin\Eav\AttributePlugin" />
11+
</type>
12+
</config>

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
# See COPYING.txt for license details.
33

44
type Query {
5-
customAttributeMetadata(attributes: [AttributeInput!]! @doc(description: "An input object that specifies the attribute code and entity type to search.")): CustomAttributeMetadata @resolver(class: "Magento\\EavGraphQl\\Model\\Resolver\\CustomAttributeMetadata") @doc(description: "Return the attribute type, given an attribute code and entity type.") @cache(cacheable: false)
5+
customAttributeMetadata(attributes: [AttributeInput!]! @doc(description: "An input object that specifies the attribute code and entity type to search.")): CustomAttributeMetadata @resolver(class: "Magento\\EavGraphQl\\Model\\Resolver\\CustomAttributeMetadata") @doc(description: "Return the attribute type, given an attribute code and entity type.") @cache(cacheIdentity: "Magento\\EavGraphQl\\Model\\Resolver\\Cache\\CustomAttributeMetadataIdentity")
66
}
77

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

dev/tests/api-functional/framework/Magento/TestFramework/TestCase/GraphQl/Client.php

Lines changed: 18 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -101,13 +101,15 @@ public function get(string $query, array $variables = [], string $operationName
101101
}
102102

103103
/**
104-
* Process response from GraphQl server
104+
* Process response from GraphQL server.
105105
*
106106
* @param string $response
107+
* @param array $responseHeaders
108+
* @param array $responseCookies
107109
* @return mixed
108110
* @throws \Exception
109111
*/
110-
private function processResponse(string $response)
112+
private function processResponse(string $response, array $responseHeaders = [], array $responseCookies = [])
111113
{
112114
$responseArray = $this->json->jsonDecode($response);
113115

@@ -116,7 +118,7 @@ private function processResponse(string $response)
116118
throw new \Exception('Unknown GraphQL response body: ' . $response);
117119
}
118120

119-
$this->processErrors($responseArray);
121+
$this->processErrors($responseArray, $responseHeaders, $responseCookies);
120122

121123
if (!isset($responseArray['data'])) {
122124
//phpcs:ignore Magento2.Exceptions.DirectThrow
@@ -153,9 +155,9 @@ public function getWithResponseHeaders(
153155
array_filter($requestArray);
154156

155157
$response = $this->curlClient->getWithFullResponse($url, $requestArray, $headers, $flushCookies);
156-
$responseBody = $this->processResponse($response['body']);
157158
$responseHeaders = !empty($response['header']) ? $this->processResponseHeaders($response['header']) : [];
158159
$responseCookies = !empty($response['header']) ? $this->processResponseCookies($response['header']) : [];
160+
$responseBody = $this->processResponse($response['body'], $responseHeaders, $responseCookies);
159161

160162
return ['headers' => $responseHeaders, 'body' => $responseBody, 'cookies' => $responseCookies];
161163
}
@@ -188,20 +190,23 @@ public function postWithResponseHeaders(
188190
$postData = $this->json->jsonEncode($requestArray);
189191

190192
$response = $this->curlClient->postWithFullResponse($url, $postData, $headers, $flushCookies);
191-
$responseBody = $this->processResponse($response['body']);
192193
$responseHeaders = !empty($response['header']) ? $this->processResponseHeaders($response['header']) : [];
193194
$responseCookies = !empty($response['header']) ? $this->processResponseCookies($response['header']) : [];
195+
$responseBody = $this->processResponse($response['body'], $responseHeaders, $responseCookies);
194196

195197
return ['headers' => $responseHeaders, 'body' => $responseBody, 'cookies' => $responseCookies];
196198
}
197199

198200
/**
199-
* Process errors
201+
* Process errors.
200202
*
201203
* @param array $responseBodyArray
202-
* @throws \Exception
204+
* @param array $responseHeaders
205+
* @param array $responseCookies
206+
* @return void
207+
* @throws ResponseContainsErrorsException
203208
*/
204-
private function processErrors($responseBodyArray)
209+
private function processErrors($responseBodyArray, array $responseHeaders = [], array $responseCookies = [])
205210
{
206211
if (isset($responseBodyArray['errors'])) {
207212
$errorMessage = '';
@@ -221,7 +226,11 @@ private function processErrors($responseBodyArray)
221226

222227
throw new ResponseContainsErrorsException(
223228
'GraphQL response contains errors: ' . $errorMessage,
224-
$responseBodyArray
229+
$responseBodyArray,
230+
null,
231+
0,
232+
$responseHeaders,
233+
$responseCookies
225234
);
226235
}
227236
//phpcs:ignore Magento2.Exceptions.DirectThrow

dev/tests/api-functional/framework/Magento/TestFramework/TestCase/GraphQl/ResponseContainsErrorsException.php

Lines changed: 43 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
namespace Magento\TestFramework\TestCase\GraphQl;
99

1010
/**
11-
* Response contains errors exception
11+
* Exception thrown when GraphQL response contains errors.
1212
*/
1313
class ResponseContainsErrorsException extends \Exception
1414
{
@@ -17,16 +17,36 @@ class ResponseContainsErrorsException extends \Exception
1717
*/
1818
private $responseData;
1919

20+
/**
21+
* @var array
22+
*/
23+
private $responseHeaders;
24+
25+
/**
26+
* @var array
27+
*/
28+
private $responseCookies;
29+
2030
/**
2131
* @param string $message
2232
* @param array $responseData
2333
* @param \Exception|null $cause
2434
* @param int $code
35+
* @param array $responseHeaders
36+
* @param array $responseCookies
2537
*/
26-
public function __construct(string $message, array $responseData, \Exception $cause = null, int $code = 0)
27-
{
38+
public function __construct(
39+
string $message,
40+
array $responseData,
41+
\Exception $cause = null,
42+
int $code = 0,
43+
array $responseHeaders = [],
44+
array $responseCookies = []
45+
) {
2846
parent::__construct($message, $code, $cause);
2947
$this->responseData = $responseData;
48+
$this->responseHeaders = $responseHeaders;
49+
$this->responseCookies = $responseCookies;
3050
}
3151

3252
/**
@@ -38,4 +58,24 @@ public function getResponseData(): array
3858
{
3959
return $this->responseData;
4060
}
61+
62+
/**
63+
* Get response headers
64+
*
65+
* @return array
66+
*/
67+
public function getResponseHeaders(): array
68+
{
69+
return $this->responseHeaders;
70+
}
71+
72+
/**
73+
* Get response cookies
74+
*
75+
* @return array
76+
*/
77+
public function getResponseCookies(): array
78+
{
79+
return $this->responseCookies;
80+
}
4181
}

dev/tests/api-functional/testsuite/Magento/Customer/Api/AddressMetadataTest.php

Lines changed: 3 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,9 @@
1818
*/
1919
class AddressMetadataTest extends WebapiAbstract
2020
{
21-
const SERVICE_NAME = "customerAddressMetadataV1";
22-
const SERVICE_VERSION = "V1";
23-
const RESOURCE_PATH = "/V1/attributeMetadata/customerAddress";
21+
private const SERVICE_NAME = "customerAddressMetadataV1";
22+
private const SERVICE_VERSION = "V1";
23+
private const RESOURCE_PATH = "/V1/attributeMetadata/customerAddress";
2424

2525
/**
2626
* @var Config $config
@@ -372,22 +372,6 @@ public function checkMultipleAttributesValidationRules($expectedResult, $actualR
372372
return [$expectedResult, $actualResultSet];
373373
}
374374

375-
/**
376-
* Remove test attribute
377-
*/
378-
public static function tearDownAfterClass(): void
379-
{
380-
parent::tearDownAfterClass();
381-
/** @var \Magento\Customer\Model\Attribute $attribute */
382-
$attribute = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create(
383-
\Magento\Customer\Model\Attribute::class
384-
);
385-
foreach (['custom_attribute1', 'custom_attribute2'] as $attributeCode) {
386-
$attribute->loadByCode('customer_address', $attributeCode);
387-
$attribute->delete();
388-
}
389-
}
390-
391375
/**
392376
* Set core config data.
393377
*

0 commit comments

Comments
 (0)