Skip to content

Commit cd41bc2

Browse files
authored
Merge pull request #8089 from magento-arcticfoxes/B2B-2258
B2B-2258: Add caching capability to the storeConfig GraphQl query
2 parents 647b34e + 4115913 commit cd41bc2

File tree

23 files changed

+2328
-11
lines changed

23 files changed

+2328
-11
lines changed
Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
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\DirectoryGraphQl\Model\Cache\Tag\Strategy\Config;
9+
10+
use Magento\DirectoryGraphQl\Model\Resolver\Currency\Identity;
11+
use Magento\Framework\App\Config\ValueInterface;
12+
use Magento\Store\Model\ScopeInterface;
13+
use Magento\Store\Model\StoreManagerInterface;
14+
use Magento\Store\Model\Config\Cache\Tag\Strategy\TagGeneratorInterface;
15+
16+
/**
17+
* Generator that generates cache tags for currency configuration
18+
*/
19+
class CurrencyTagGenerator implements TagGeneratorInterface
20+
{
21+
/**
22+
* @var string[]
23+
*/
24+
private $currencyConfigPaths = [
25+
'currency/options/base',
26+
'currency/options/default',
27+
'currency/options/allow',
28+
'currency/options/customsymbol'
29+
];
30+
31+
/**
32+
* @var StoreManagerInterface
33+
*/
34+
private $storeManager;
35+
36+
/**
37+
* @param StoreManagerInterface $storeManager
38+
*/
39+
public function __construct(
40+
StoreManagerInterface $storeManager
41+
) {
42+
$this->storeManager = $storeManager;
43+
}
44+
45+
/**
46+
* @inheritdoc
47+
*/
48+
public function generateTags(ValueInterface $config): array
49+
{
50+
if (in_array($config->getPath(), $this->currencyConfigPaths)) {
51+
if ($config->getScope() == ScopeInterface::SCOPE_WEBSITES) {
52+
$website = $this->storeManager->getWebsite($config->getScopeId());
53+
$storeIds = $website->getStoreIds();
54+
} elseif ($config->getScope() == ScopeInterface::SCOPE_STORES) {
55+
$storeIds = [$config->getScopeId()];
56+
} else {
57+
$storeIds = array_keys($this->storeManager->getStores());
58+
}
59+
$tags = [];
60+
foreach ($storeIds as $storeId) {
61+
$tags[] = sprintf('%s_%s', Identity::CACHE_TAG, $storeId);
62+
}
63+
return $tags;
64+
}
65+
return [];
66+
}
67+
}
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
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\DirectoryGraphQl\Model\Resolver\Currency;
9+
10+
use Magento\Framework\GraphQl\Query\Resolver\IdentityInterface;
11+
use Magento\Store\Model\StoreManagerInterface;
12+
13+
class Identity implements IdentityInterface
14+
{
15+
/**
16+
* @var string
17+
*/
18+
public const CACHE_TAG = 'gql_currency';
19+
20+
/**
21+
* @var StoreManagerInterface
22+
*/
23+
private $storeManager;
24+
25+
/**
26+
* @param StoreManagerInterface $storeManager
27+
*/
28+
public function __construct(StoreManagerInterface $storeManager)
29+
{
30+
$this->storeManager = $storeManager;
31+
}
32+
33+
/**
34+
* @inheritdoc
35+
*/
36+
public function getIdentities(array $resolvedData): array
37+
{
38+
if (empty($resolvedData)) {
39+
return [];
40+
}
41+
$storeId = $this->storeManager->getStore()->getId();
42+
return [self::CACHE_TAG, sprintf('%s_%s', self::CACHE_TAG, $storeId)];
43+
}
44+
}
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
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\DirectoryGraphQl\Plugin;
9+
10+
use Magento\DirectoryGraphQl\Model\Resolver\Currency\Identity;
11+
use Magento\Framework\DataObject\IdentityInterface;
12+
use Magento\Framework\Event\ManagerInterface;
13+
use Magento\Directory\Model\Currency as CurrencyModel;
14+
15+
/**
16+
* Currency plugin triggers clean page cache and provides currency cache identities
17+
*/
18+
class Currency implements IdentityInterface
19+
{
20+
/**
21+
* Application Event Dispatcher
22+
*
23+
* @var ManagerInterface
24+
*/
25+
private $eventManager;
26+
27+
/**
28+
* @param ManagerInterface $eventManager
29+
*/
30+
public function __construct(ManagerInterface $eventManager)
31+
{
32+
$this->eventManager = $eventManager;
33+
}
34+
35+
/**
36+
* Trigger clean cache by tags after save rates
37+
*
38+
* @param CurrencyModel $subject
39+
* @param CurrencyModel $result
40+
* @return CurrencyModel
41+
* @SuppressWarnings(PHPMD.UnusedFormalParameter)
42+
*/
43+
public function afterSaveRates(CurrencyModel $subject, CurrencyModel $result): CurrencyModel
44+
{
45+
$this->eventManager->dispatch('clean_cache_by_tags', ['object' => $this]);
46+
return $result;
47+
}
48+
49+
/**
50+
* @inheritdoc
51+
*/
52+
public function getIdentities()
53+
{
54+
return [Identity::CACHE_TAG];
55+
}
56+
}
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
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\Store\Model\Config\Cache\Tag\Strategy\CompositeTagGenerator">
10+
<arguments>
11+
<argument name="tagGenerators" xsi:type="array">
12+
<item name="currency_tag_generator" xsi:type="object">
13+
Magento\DirectoryGraphQl\Model\Cache\Tag\Strategy\Config\CurrencyTagGenerator
14+
</item>
15+
</argument>
16+
</arguments>
17+
</type>
18+
<type name="Magento\Directory\Model\Currency">
19+
<plugin name="afterSaveRate" type="Magento\DirectoryGraphQl\Plugin\Currency" />
20+
</type>
21+
</config>

app/code/Magento/DirectoryGraphQl/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-
currency: Currency @resolver(class: "Magento\\DirectoryGraphQl\\Model\\Resolver\\Currency") @doc(description: "Return information about the store's currency.") @cache(cacheable: false)
5+
currency: Currency @resolver(class: "Magento\\DirectoryGraphQl\\Model\\Resolver\\Currency") @doc(description: "Return information about the store's currency.") @cache(cacheIdentity: "Magento\\DirectoryGraphQl\\Model\\Resolver\\Currency\\Identity")
66
countries: [Country] @resolver(class: "Magento\\DirectoryGraphQl\\Model\\Resolver\\Countries") @doc(description: "The countries query provides information for all countries.") @cache(cacheable: false)
77
country (id: String): Country @resolver(class: "Magento\\DirectoryGraphQl\\Model\\Resolver\\Country") @doc(description: "The countries query provides information for a single country.") @cache(cacheable: false)
88
}
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
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\Store\Model\Config\Cache\Tag\Strategy;
9+
10+
use Magento\Framework\App\Config\ValueInterface;
11+
12+
/**
13+
* Composite tag generator that generates cache tags for store configurations.
14+
*/
15+
class CompositeTagGenerator implements TagGeneratorInterface
16+
{
17+
/**
18+
* @var TagGeneratorInterface[]
19+
*/
20+
private $tagGenerators;
21+
22+
/**
23+
* @param TagGeneratorInterface[] $tagGenerators
24+
*/
25+
public function __construct(
26+
array $tagGenerators
27+
) {
28+
$this->tagGenerators = $tagGenerators;
29+
}
30+
31+
/**
32+
* @inheritdoc
33+
*/
34+
public function generateTags(ValueInterface $config): array
35+
{
36+
$tagsArray = [];
37+
foreach ($this->tagGenerators as $tagGenerator) {
38+
$tagsArray[] = $tagGenerator->generateTags($config);
39+
}
40+
return array_merge(...$tagsArray);
41+
}
42+
}
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
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\Store\Model\Config\Cache\Tag\Strategy;
9+
10+
use Magento\Framework\App\Cache\Tag\StrategyInterface;
11+
use Magento\Framework\App\Config\ValueInterface;
12+
13+
/**
14+
* Produce cache tags for store config.
15+
*/
16+
class StoreConfig implements StrategyInterface
17+
{
18+
/**
19+
* @var TagGeneratorInterface
20+
*/
21+
private $tagGenerator;
22+
23+
/**
24+
* @param TagGeneratorInterface $tagGenerator
25+
*/
26+
public function __construct(
27+
TagGeneratorInterface $tagGenerator
28+
) {
29+
$this->tagGenerator = $tagGenerator;
30+
}
31+
32+
/**
33+
* @inheritdoc
34+
*/
35+
public function getTags($object): array
36+
{
37+
if (!is_object($object)) {
38+
throw new \InvalidArgumentException('Provided argument is not an object');
39+
}
40+
41+
if ($object instanceof ValueInterface && $object->isValueChanged()) {
42+
return $this->tagGenerator->generateTags($object);
43+
}
44+
45+
return [];
46+
}
47+
}
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
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\Store\Model\Config\Cache\Tag\Strategy;
9+
10+
use Magento\Framework\App\Config\ValueInterface;
11+
12+
/**
13+
* Store configuration cache tag generator interface
14+
*/
15+
interface TagGeneratorInterface
16+
{
17+
/**
18+
* Generate cache tags with given store configuration
19+
*
20+
* @param ValueInterface $config
21+
* @return array
22+
*/
23+
public function generateTags(ValueInterface $config): array;
24+
}

app/code/Magento/Store/etc/di.xml

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -457,4 +457,20 @@
457457
</argument>
458458
</arguments>
459459
</type>
460+
<type name="Magento\Framework\App\Cache\Tag\Strategy\Factory">
461+
<arguments>
462+
<argument name="customStrategies" xsi:type="array">
463+
<item name="Magento\Framework\App\Config\ValueInterface" xsi:type="object">
464+
Magento\Store\Model\Config\Cache\Tag\Strategy\StoreConfig
465+
</item>
466+
</argument>
467+
</arguments>
468+
</type>
469+
<type name="Magento\Store\Model\Config\Cache\Tag\Strategy\StoreConfig">
470+
<arguments>
471+
<argument name="tagGenerator" xsi:type="object">
472+
Magento\Store\Model\Config\Cache\Tag\Strategy\CompositeTagGenerator
473+
</argument>
474+
</arguments>
475+
</type>
460476
</config>
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
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\Cache\Tag\Strategy;
9+
10+
use Magento\Framework\App\Config\ValueInterface;
11+
use Magento\Store\Model\Config\Cache\Tag\Strategy\TagGeneratorInterface;
12+
use Magento\Store\Model\ScopeInterface;
13+
use Magento\Store\Model\StoreManagerInterface;
14+
use Magento\StoreGraphQl\Model\Resolver\Store\ConfigIdentity;
15+
16+
/**
17+
* Generator that generates cache tags for store configuration.
18+
*/
19+
class ConfigTagGenerator implements TagGeneratorInterface
20+
{
21+
/**
22+
* @var StoreManagerInterface
23+
*/
24+
private $storeManager;
25+
26+
/**
27+
* @param StoreManagerInterface $storeManager
28+
*/
29+
public function __construct(
30+
StoreManagerInterface $storeManager
31+
) {
32+
$this->storeManager = $storeManager;
33+
}
34+
35+
/**
36+
* @inheritdoc
37+
*/
38+
public function generateTags(ValueInterface $config): array
39+
{
40+
if ($config->getScope() == ScopeInterface::SCOPE_WEBSITES) {
41+
$website = $this->storeManager->getWebsite($config->getScopeId());
42+
$storeIds = $website->getStoreIds();
43+
} elseif ($config->getScope() == ScopeInterface::SCOPE_STORES) {
44+
$storeIds = [$config->getScopeId()];
45+
} else {
46+
$storeIds = array_keys($this->storeManager->getStores());
47+
}
48+
$tags = [];
49+
foreach ($storeIds as $storeId) {
50+
$tags[] = sprintf('%s_%s', ConfigIdentity::CACHE_TAG, $storeId);
51+
}
52+
return $tags;
53+
}
54+
}

0 commit comments

Comments
 (0)