Skip to content

Commit fd5b8d0

Browse files
authored
Merge pull request #8187 from magento-arcticfoxes/B2B-2257
B2B-2257: availableStores GraphQl query has no cache identity
2 parents c7464fe + c1204a8 commit fd5b8d0

File tree

7 files changed

+2920
-8
lines changed

7 files changed

+2920
-8
lines changed
Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
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\StoreGraphQl\Model\Resolver\Stores;
9+
10+
use Magento\Framework\Exception\NoSuchEntityException;
11+
use Magento\Framework\GraphQl\Query\Resolver\IdentityInterface;
12+
use Magento\Store\Model\StoreManagerInterface;
13+
use Magento\StoreGraphQl\Model\Resolver\Store\ConfigIdentity as StoreConfigIdentity;
14+
15+
class ConfigIdentity implements IdentityInterface
16+
{
17+
/**
18+
* @var StoreManagerInterface
19+
*/
20+
private $storeManager;
21+
22+
/**
23+
* @param StoreManagerInterface $storeManager
24+
*/
25+
public function __construct(StoreManagerInterface $storeManager)
26+
{
27+
$this->storeManager = $storeManager;
28+
}
29+
30+
/**
31+
* @inheritDoc
32+
*/
33+
public function getIdentities(array $resolvedData): array
34+
{
35+
$ids = [];
36+
foreach ($resolvedData as $storeConfig) {
37+
$ids[] = sprintf('%s_%s', StoreConfigIdentity::CACHE_TAG, $storeConfig['id']);
38+
}
39+
if (!empty($resolvedData)) {
40+
$websiteId = $resolvedData[0]['website_id'];
41+
$currentStoreGroupId = $this->getCurrentStoreGroupId($resolvedData);
42+
$groupTag = $currentStoreGroupId ? 'group_' . $currentStoreGroupId : '';
43+
$ids[] = sprintf('%s_%s', StoreConfigIdentity::CACHE_TAG, 'website_' . $websiteId . $groupTag);
44+
}
45+
46+
return empty($ids) ? [] : array_merge([StoreConfigIdentity::CACHE_TAG], $ids);
47+
}
48+
49+
/**
50+
* Return current store group id if it is certain that useCurrentGroup is true in the query
51+
*
52+
* @param array $resolvedData
53+
* @return string|int|null
54+
*/
55+
private function getCurrentStoreGroupId(array $resolvedData)
56+
{
57+
$storeGroupCodes = array_unique(array_column($resolvedData, 'store_group_code'));
58+
if (count($storeGroupCodes) == 1) {
59+
try {
60+
$store = $this->storeManager->getStore($resolvedData[0]['id']);
61+
if ($store->getWebsite()->getGroupCollection()->count() != 1) {
62+
// There are multiple store groups in the website while there is only one store group
63+
// in the resolved data. Therefore useCurrentGroup must be true in the query
64+
return $store->getStoreGroupId();
65+
}
66+
} catch (NoSuchEntityException $e) {
67+
// Do nothing
68+
;
69+
}
70+
}
71+
return null;
72+
}
73+
}

app/code/Magento/StoreGraphQl/Plugin/Group.php

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
use Magento\StoreGraphQl\Model\Resolver\Store\ConfigIdentity;
1111

1212
/**
13-
* Store group plugin
13+
* Store group plugin to provide identities for cache invalidation
1414
*/
1515
class Group
1616
{
@@ -24,9 +24,17 @@ class Group
2424
public function afterGetIdentities(\Magento\Store\Model\Group $subject, array $result): array
2525
{
2626
$storeIds = $subject->getStoreIds();
27-
foreach ($storeIds as $storeId) {
28-
$result[] = sprintf('%s_%s', ConfigIdentity::CACHE_TAG, $storeId);
27+
if (count($storeIds) > 0) {
28+
foreach ($storeIds as $storeId) {
29+
$result[] = sprintf('%s_%s', ConfigIdentity::CACHE_TAG, $storeId);
30+
}
31+
$origWebsiteId = $subject->getOrigData('website_id');
32+
$websiteId = $subject->getWebsiteId();
33+
if ($origWebsiteId != $websiteId) { // Add or switch to a new website
34+
$result[] = sprintf('%s_%s', ConfigIdentity::CACHE_TAG, 'website_' . $websiteId);
35+
}
2936
}
37+
3038
return $result;
3139
}
3240
}

app/code/Magento/StoreGraphQl/Plugin/Store.php

Lines changed: 36 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
use Magento\StoreGraphQl\Model\Resolver\Store\ConfigIdentity;
1111

1212
/**
13-
* Store plugin
13+
* Store plugin to provide identities for cache invalidation
1414
*/
1515
class Store
1616
{
@@ -23,6 +23,40 @@ class Store
2323
*/
2424
public function afterGetIdentities(\Magento\Store\Model\Store $subject, array $result): array
2525
{
26-
return array_merge($result, [sprintf('%s_%s', ConfigIdentity::CACHE_TAG, $subject->getId())]);
26+
$result[] = sprintf('%s_%s', ConfigIdentity::CACHE_TAG, $subject->getId());
27+
28+
$isActive = $subject->getIsActive();
29+
// New active store or newly activated store or an active store switched store group
30+
if ($isActive
31+
&& ($subject->getOrigData('is_active') !== $isActive || $this->isStoreGroupSwitched($subject))
32+
) {
33+
$websiteId = $subject->getWebsiteId();
34+
if ($websiteId !== null) {
35+
$result[] = sprintf('%s_%s', ConfigIdentity::CACHE_TAG, 'website_' . $websiteId);
36+
$storeGroupId = $subject->getStoreGroupId();
37+
if ($storeGroupId !== null) {
38+
$result[] = sprintf(
39+
'%s_%s',
40+
ConfigIdentity::CACHE_TAG,
41+
'website_' . $websiteId . 'group_' . $storeGroupId
42+
);
43+
}
44+
}
45+
}
46+
47+
return $result;
48+
}
49+
50+
/**
51+
* Check whether the store group of the store is switched
52+
*
53+
* @param \Magento\Store\Model\Store $store
54+
* @return bool
55+
*/
56+
private function isStoreGroupSwitched(\Magento\Store\Model\Store $store): bool
57+
{
58+
$origStoreGroupId = $store->getOrigData('group_id');
59+
$storeGroupId = $store->getStoreGroupId();
60+
return $origStoreGroupId != null && $origStoreGroupId != $storeGroupId;
2761
}
2862
}

app/code/Magento/StoreGraphQl/Plugin/Website.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
use Magento\StoreGraphQl\Model\Resolver\Store\ConfigIdentity;
1111

1212
/**
13-
* Website plugin
13+
* Website plugin to provide identities for cache invalidation
1414
*/
1515
class Website
1616
{

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ type Query {
44
storeConfig : StoreConfig @resolver(class: "Magento\\StoreGraphQl\\Model\\Resolver\\StoreConfigResolver") @doc(description: "Return details about the store's configuration.") @cache(cacheIdentity: "Magento\\StoreGraphQl\\Model\\Resolver\\Store\\ConfigIdentity")
55
availableStores(
66
useCurrentGroup: Boolean @doc(description: "Filter store views by the current store group.")
7-
): [StoreConfig] @resolver(class: "Magento\\StoreGraphQl\\Model\\Resolver\\AvailableStoresResolver") @doc(description: "Get a list of available store views and their config information.")
7+
): [StoreConfig] @resolver(class: "Magento\\StoreGraphQl\\Model\\Resolver\\AvailableStoresResolver") @doc(description: "Get a list of available store views and their config information.") @cache(cacheIdentity: "Magento\\StoreGraphQl\\Model\\Resolver\\Stores\\ConfigIdentity")
88
}
99

1010
type Website @doc(description: "Deprecated. It should not be used on the storefront. Contains information about a website.") {

0 commit comments

Comments
 (0)