Skip to content

Commit 3159bac

Browse files
amolina-adobepdohogne-magento
authored andcommitted
PWA-1817: Generate X-Magento-Cache-Id header to use as the cache key for GraphQL requests
1 parent ab59159 commit 3159bac

File tree

35 files changed

+1539
-26
lines changed

35 files changed

+1539
-26
lines changed
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
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\CacheIdFactorProviders;
9+
10+
use Magento\Customer\Api\Data\GroupInterface;
11+
use Magento\GraphQl\Model\Query\ContextInterface;
12+
use Magento\GraphQlCache\Model\CacheId\CacheIdFactorProviderInterface;
13+
14+
/**
15+
* Provides customer group as a factor to use in the cache id
16+
*/
17+
class CustomerGroupProvider implements CacheIdFactorProviderInterface
18+
{
19+
const NAME = "CUSTOMER_GROUP";
20+
21+
/**
22+
* @inheritdoc
23+
*/
24+
public function getFactorName(): string
25+
{
26+
return static::NAME;
27+
}
28+
29+
/**
30+
* @inheritdoc
31+
*/
32+
public function getFactorValue(ContextInterface $context): string
33+
{
34+
$customerGroupId = $context->getExtensionAttributes()->getCustomerGroupId() ?? GroupInterface::NOT_LOGGED_IN_ID;
35+
return (string)$customerGroupId;
36+
}
37+
}
Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
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\CacheIdFactorProviders;
9+
10+
use Magento\Customer\Api\Data\GroupInterface;
11+
use Magento\Customer\Model\ResourceModel\GroupRepository as CustomerGroupRepository;
12+
use Magento\GraphQl\Model\Query\ContextInterface;
13+
use Magento\GraphQlCache\Model\CacheId\CacheIdFactorProviderInterface;
14+
use Magento\Tax\Model\Calculation as CalculationModel;
15+
use Magento\Tax\Model\ResourceModel\Calculation as CalculationResource;
16+
17+
/**
18+
* Provides the relevant parts of the address used for tax rate calculations as a factor to use in the cache id
19+
*/
20+
class CustomerTaxRateProvider implements CacheIdFactorProviderInterface
21+
{
22+
const NAME = 'CUSTOMER_TAX_RATE';
23+
24+
/**
25+
* @var CustomerGroupRepository
26+
*/
27+
private $groupRepository;
28+
29+
/**
30+
* @var CalculationModel
31+
*/
32+
private $calculationModel;
33+
34+
/**
35+
* @var CalculationResource
36+
*/
37+
private $calculationResource;
38+
39+
/**
40+
* @param CustomerGroupRepository $groupRepository
41+
* @param CalculationModel $calculationModel
42+
* @param CalculationResource $calculationResource
43+
*/
44+
public function __construct(
45+
CustomerGroupRepository $groupRepository,
46+
CalculationModel $calculationModel,
47+
CalculationResource $calculationResource
48+
) {
49+
$this->groupRepository = $groupRepository;
50+
$this->calculationModel = $calculationModel;
51+
$this->calculationResource = $calculationResource;
52+
}
53+
54+
/**
55+
* @inheritdoc
56+
*/
57+
public function getFactorName(): string
58+
{
59+
return static::NAME;
60+
}
61+
62+
/**
63+
* @inheritdoc
64+
*/
65+
public function getFactorValue(ContextInterface $context): string
66+
{
67+
$loggedIn = $context->getExtensionAttributes()->getIsCustomer();
68+
$customerId = $loggedIn ? (int)$context->getUserId() : 0;
69+
$customerGroupId = $context->getExtensionAttributes()->getCustomerGroupId() ?? GroupInterface::NOT_LOGGED_IN_ID;
70+
$customerTaxClassId = $this->groupRepository->getById((int)$customerGroupId)->getTaxClassId();
71+
$store = $context->getExtensionAttributes()->getStore();
72+
$rateRequest = $this->calculationModel->getRateRequest(null, null, $customerTaxClassId, $store, $customerId);
73+
$rateInfo = $this->calculationResource->getRateInfo($rateRequest);
74+
return (string)$rateInfo['value'];
75+
}
76+
}
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
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\CacheIdFactorProviders;
9+
10+
use Magento\GraphQl\Model\Query\ContextInterface;
11+
use Magento\GraphQlCache\Model\CacheId\CacheIdFactorProviderInterface;
12+
13+
/**
14+
* Provides logged-in status as a factor to use in the cache id
15+
*/
16+
class IsLoggedInProvider implements CacheIdFactorProviderInterface
17+
{
18+
const NAME = "IS_LOGGED_IN";
19+
20+
/**
21+
* @inheritdoc
22+
*/
23+
public function getFactorName(): string
24+
{
25+
return static::NAME;
26+
}
27+
28+
/**
29+
* @inheritdoc
30+
*/
31+
public function getFactorValue(ContextInterface $context): string
32+
{
33+
return $context->getExtensionAttributes()->getIsCustomer() ? "true" : "false";
34+
}
35+
}

app/code/Magento/CustomerGraphQl/Model/Context/AddUserInfoToContext.php

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,12 +11,12 @@
1111
use Magento\Customer\Model\ResourceModel\CustomerRepository;
1212
use Magento\Customer\Model\Session;
1313
use Magento\GraphQl\Model\Query\ContextParametersInterface;
14-
use Magento\GraphQl\Model\Query\ContextParametersProcessorInterface;
14+
use Magento\GraphQl\Model\Query\UserContextParametersProcessorInterface;
1515

1616
/**
1717
* @inheritdoc
1818
*/
19-
class AddUserInfoToContext implements ContextParametersProcessorInterface
19+
class AddUserInfoToContext implements UserContextParametersProcessorInterface
2020
{
2121
/**
2222
* @var UserContextInterface
@@ -48,6 +48,14 @@ public function __construct(
4848
$this->customerRepository = $customerRepository;
4949
}
5050

51+
/**
52+
* @inheritdoc
53+
*/
54+
public function setUserContext(UserContextInterface $userContext): void
55+
{
56+
$this->userContext = $userContext;
57+
}
58+
5159
/**
5260
* @inheritdoc
5361
*/

app/code/Magento/CustomerGraphQl/composer.json

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,9 @@
1212
"magento/module-integration": "*",
1313
"magento/module-store": "*",
1414
"magento/framework": "*",
15-
"magento/module-directory": "*"
15+
"magento/module-directory": "*",
16+
"magento/module-tax": "*",
17+
"magento/module-graph-ql-cache": "*"
1618
},
1719
"license": [
1820
"OSL-3.0",

app/code/Magento/CustomerGraphQl/etc/graphql/di.xml

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,4 +43,13 @@
4343
<type name="Magento\GraphQl\Controller\GraphQl">
4444
<plugin name="ClearCustomerSessionAfterRequest" type="Magento\CustomerGraphQl\Plugin\ClearCustomerSessionAfterRequest" sortOrder="1" disabled="false" />
4545
</type>
46+
<type name="Magento\GraphQlCache\Model\CacheId\CacheIdCalculator">
47+
<arguments>
48+
<argument name="idFactorProviders" xsi:type="array">
49+
<item name="customergroup" xsi:type="object">Magento\CustomerGraphQl\CacheIdFactorProviders\CustomerGroupProvider</item>
50+
<item name="customertaxrate" xsi:type="object">Magento\CustomerGraphQl\CacheIdFactorProviders\CustomerTaxRateProvider</item>
51+
<item name="isloggedin" xsi:type="object">Magento\CustomerGraphQl\CacheIdFactorProviders\IsLoggedInProvider</item>
52+
</argument>
53+
</arguments>
54+
</type>
4655
</config>

app/code/Magento/GraphQl/Model/Query/ContextFactory.php

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77

88
namespace Magento\GraphQl\Model\Query;
99

10+
use Magento\Authorization\Model\UserContextInterface;
1011
use Magento\Framework\Api\ExtensionAttributesFactory;
1112
use Magento\Framework\Exception\LocalizedException;
1213
use Magento\Framework\ObjectManagerInterface;
@@ -31,6 +32,11 @@ class ContextFactory implements ContextFactoryInterface
3132
*/
3233
private $contextParametersProcessors;
3334

35+
/**
36+
* @var ContextInterface
37+
*/
38+
private $context;
39+
3440
/**
3541
* @param ExtensionAttributesFactory $extensionAttributesFactory
3642
* @param ObjectManagerInterface $objectManager
@@ -49,7 +55,7 @@ public function __construct(
4955
/**
5056
* @inheritdoc
5157
*/
52-
public function create(): ContextInterface
58+
public function create(?UserContextInterface $userContext = null): ContextInterface
5359
{
5460
$contextParameters = $this->objectManager->create(ContextParametersInterface::class);
5561

@@ -59,6 +65,9 @@ public function create(): ContextInterface
5965
__('ContextParametersProcessors must implement %1', ContextParametersProcessorInterface::class)
6066
);
6167
}
68+
if ($userContext && $contextParametersProcessor instanceof UserContextParametersProcessorInterface) {
69+
$contextParametersProcessor->setUserContext($userContext);
70+
}
6271
$contextParameters = $contextParametersProcessor->execute($contextParameters);
6372
}
6473

@@ -77,6 +86,18 @@ public function create(): ContextInterface
7786
'extensionAttributes' => $extensionAttributes,
7887
]
7988
);
89+
$this->context = $context;
8090
return $context;
8191
}
92+
93+
/**
94+
* @inheritdoc
95+
*/
96+
public function get(): ContextInterface
97+
{
98+
if (!$this->context) {
99+
$this->create();
100+
}
101+
return $this->context;
102+
}
82103
}

app/code/Magento/GraphQl/Model/Query/ContextFactoryInterface.php

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@
77

88
namespace Magento\GraphQl\Model\Query;
99

10+
use Magento\Authorization\Model\UserContextInterface;
11+
1012
/**
1113
* Context factory
1214
*/
@@ -15,7 +17,15 @@ interface ContextFactoryInterface
1517
/**
1618
* Create Context object
1719
*
20+
* @param UserContextInterface|null $userContext
21+
* @return ContextInterface
22+
*/
23+
public function create(?UserContextInterface $userContext = null): ContextInterface;
24+
25+
/**
26+
* Retrieve cached Context object
27+
*
1828
* @return ContextInterface
1929
*/
20-
public function create(): ContextInterface;
30+
public function get(): ContextInterface;
2131
}

app/code/Magento/GraphQl/Model/Query/ContextParametersProcessorInterface.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
* - Class must extend ContextParametersProcessorInterface.
1515
* - Implement execute method which adds additional data to the context though extension attributes.
1616
* - This data will be present in each resolver.
17+
* - If the processor needs to access the top-level user context, implement UserContextParametersProcessorInterface.
1718
*/
1819
interface ContextParametersProcessorInterface
1920
{
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
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\GraphQl\Model\Query;
9+
10+
use Magento\Authorization\Model\UserContextInterface;
11+
12+
/**
13+
* Adding custom parameters to GraphQL context object using the top-level user context even if it has been updated
14+
*/
15+
interface UserContextParametersProcessorInterface extends ContextParametersProcessorInterface
16+
{
17+
/**
18+
* Override the dependency-injected user context
19+
*
20+
* @param UserContextInterface $userContext
21+
*/
22+
public function setUserContext(UserContextInterface $userContext): void;
23+
}

0 commit comments

Comments
 (0)