Skip to content

Commit 8acc379

Browse files
committed
ACP2E-3063: [Cloud] Cache is not getting invalidated.
- with test
1 parent 388be5d commit 8acc379

File tree

10 files changed

+524
-34
lines changed

10 files changed

+524
-34
lines changed
Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
<?php
2+
/************************************************************************
3+
*
4+
* Copyright 2024 Adobe
5+
* All Rights Reserved.
6+
*
7+
* NOTICE: All information contained herein is, and remains
8+
* the property of Adobe and its suppliers, if any. The intellectual
9+
* and technical concepts contained herein are proprietary to Adobe
10+
* and its suppliers and are protected by all applicable intellectual
11+
* property laws, including trade secret and copyright laws.
12+
* Dissemination of this information or reproduction of this material
13+
* is strictly forbidden unless prior written permission is obtained
14+
* from Adobe.
15+
* ************************************************************************
16+
*/
17+
declare(strict_types=1);
18+
19+
namespace Magento\Catalog\Model\Category;
20+
21+
use Magento\Catalog\Model\Category;
22+
use Magento\Framework\App\Cache\Tag\StrategyInterface;
23+
use Magento\Framework\Model\AbstractModel;
24+
use Magento\Widget\Model\Widget\Instance;
25+
26+
/**
27+
* Get additional layout cache tag for category layout.
28+
*/
29+
class CategoryLayoutTagCacheResolver implements StrategyInterface
30+
{
31+
/**
32+
* @inheritDoc
33+
*/
34+
public function getTags($object)
35+
{
36+
if ($this->isExistingCategoryLayoutChange($object)) {
37+
return [
38+
sprintf(
39+
'%s',
40+
str_replace('{{ID}}', $object->getId(), Instance::SINGLE_CATEGORY_LAYOUT_HANDLE))
41+
];
42+
}
43+
44+
return [];
45+
}
46+
47+
/**
48+
* Check if existing category page layout change
49+
*
50+
* @param AbstractModel $object
51+
* @return bool
52+
*/
53+
private function isExistingCategoryLayoutChange(AbstractModel $object): bool
54+
{
55+
return !$object instanceof Category || $this->isObjectChanged($object) ||
56+
$object->isObjectNew();
57+
}
58+
59+
/**
60+
* Check if the page layout of the given category is changed
61+
*
62+
* @param AbstractModel $object
63+
* @return bool
64+
*/
65+
private function isObjectChanged(AbstractModel $object): bool
66+
{
67+
$isChanged = false;
68+
if ($object->isDeleted() || $object->hasDataChanges()) {
69+
$isChanged = true;
70+
} else {
71+
$objectNewPageLayout = $object->getData('page_layout');
72+
$objectOldPageLayout = $object->getOrigData('page_layout');
73+
74+
if ($objectNewPageLayout !== $objectOldPageLayout) {
75+
$isChanged = true;
76+
}
77+
}
78+
return $isChanged;
79+
}
80+
}
Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
<?php
2+
/************************************************************************
3+
*
4+
* Copyright 2024 Adobe
5+
* All Rights Reserved.
6+
*
7+
* NOTICE: All information contained herein is, and remains
8+
* the property of Adobe and its suppliers, if any. The intellectual
9+
* and technical concepts contained herein are proprietary to Adobe
10+
* and its suppliers and are protected by all applicable intellectual
11+
* property laws, including trade secret and copyright laws.
12+
* Dissemination of this information or reproduction of this material
13+
* is strictly forbidden unless prior written permission is obtained
14+
* from Adobe.
15+
* ************************************************************************
16+
*/
17+
declare(strict_types=1);
18+
19+
namespace Magento\Catalog\Model\Product;
20+
21+
use Magento\Catalog\Model\Product;
22+
use Magento\Framework\App\Cache\Tag\StrategyInterface;
23+
use Magento\Framework\Model\AbstractModel;
24+
use Magento\Widget\Model\Widget\Instance;
25+
26+
/**
27+
* Get additional layout cache tag for product layout.
28+
*/
29+
class ProductLayoutTagCacheResolver implements StrategyInterface
30+
{
31+
/**
32+
* @inheritDoc
33+
*/
34+
public function getTags($object)
35+
{
36+
if ($this->isExistingProductLayoutChange($object)) {
37+
return [
38+
sprintf(
39+
'%s',
40+
str_replace('{{ID}}', $object->getId(), Instance::SINGLE_PRODUCT_LAYOUT_HANDLE))
41+
];
42+
}
43+
44+
return [];
45+
}
46+
47+
/**
48+
* Check if existing Product page layout change
49+
*
50+
* @param AbstractModel $object
51+
* @return bool
52+
*/
53+
private function isExistingProductLayoutChange(AbstractModel $object): bool
54+
{
55+
return !$object instanceof Product || $this->isObjectChanged($object) ||
56+
$object->isObjectNew();
57+
}
58+
59+
/**
60+
* Check if the page layout of the given product is changed
61+
*
62+
* @param AbstractModel $object
63+
* @return bool
64+
*/
65+
private function isObjectChanged(AbstractModel $object): bool
66+
{
67+
$isChanged = false;
68+
if ($object->isDeleted() || $object->hasDataChanges()) {
69+
$isChanged = true;
70+
} else {
71+
$objectNewPageLayout = $object->getData('page_layout');
72+
$objectOldPageLayout = $object->getOrigData('page_layout');
73+
74+
if ($objectNewPageLayout !== $objectOldPageLayout) {
75+
$isChanged = true;
76+
}
77+
}
78+
return $isChanged;
79+
}
80+
}

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

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1359,4 +1359,16 @@
13591359
</argument>
13601360
</arguments>
13611361
</type>
1362+
<type name="Magento\Theme\Model\LayoutTagCacheFactory">
1363+
<arguments>
1364+
<argument name="customLayoutTagCache" xsi:type="array">
1365+
<item name="Magento\Catalog\Model\Product" xsi:type="object">
1366+
Magento\Catalog\Model\Product\ProductLayoutTagCacheResolver
1367+
</item>
1368+
<item name="Magento\Catalog\Model\Category" xsi:type="object">
1369+
Magento\Catalog\Model\Category\CategoryLayoutTagCacheResolver
1370+
</item>
1371+
</argument>
1372+
</arguments>
1373+
</type>
13621374
</config>
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
<?php
2+
/************************************************************************
3+
*
4+
* Copyright 2024 Adobe
5+
* All Rights Reserved.
6+
*
7+
* NOTICE: All information contained herein is, and remains
8+
* the property of Adobe and its suppliers, if any. The intellectual
9+
* and technical concepts contained herein are proprietary to Adobe
10+
* and its suppliers and are protected by all applicable intellectual
11+
* property laws, including trade secret and copyright laws.
12+
* Dissemination of this information or reproduction of this material
13+
* is strictly forbidden unless prior written permission is obtained
14+
* from Adobe.
15+
* ************************************************************************
16+
*/
17+
declare(strict_types=1);
18+
19+
namespace Magento\Cms\Model\Page;
20+
21+
use Magento\Framework\App\Cache\Tag\StrategyInterface;
22+
use Magento\Framework\Model\AbstractModel;
23+
24+
/**
25+
* Get additional layout cache tag for CMS layout.
26+
*/
27+
class CmsLayoutTagCacheResolver implements StrategyInterface
28+
{
29+
/**
30+
* @inheritDoc
31+
*/
32+
public function getTags($object)
33+
{
34+
if ($this->isExistingPageLayoutChange($object)) {
35+
return [
36+
sprintf(
37+
'%s_%s',
38+
'CMS_PAGE_VIEW_ID',
39+
str_replace('-', '_', strtoupper($object->getIdentifier())))
40+
];
41+
}
42+
43+
return [];
44+
}
45+
46+
/**
47+
* Check if existing CMS page layout change
48+
*
49+
* @param AbstractModel $object
50+
* @return bool
51+
*/
52+
private function isExistingPageLayoutChange(AbstractModel $object): bool
53+
{
54+
return !$object instanceof Page ||
55+
!$object->dataHasChangedFor(Page::PAGE_LAYOUT) ||
56+
$object->isObjectNew();
57+
}
58+
}

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

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -316,4 +316,13 @@
316316
</argument>
317317
</arguments>
318318
</virtualType>
319+
<type name="Magento\Theme\Model\LayoutTagCacheFactory">
320+
<arguments>
321+
<argument name="customLayoutTagCache" xsi:type="array">
322+
<item name="Magento\Cms\Model\Page" xsi:type="object">
323+
Magento\Cms\Model\Page\CmsLayoutTagCacheResolver
324+
</item>
325+
</argument>
326+
</arguments>
327+
</type>
319328
</config>

app/code/Magento/Cms/etc/events.xml

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,4 @@
3939
<event name="cms_page_prepare_save">
4040
<observer name="validate_cms_page" instance="Magento\Cms\Observer\PageValidatorObserver" />
4141
</event>
42-
<event name="clean_cache_by_tags">
43-
<observer name="invalidate_layout_cache" instance="Magento\Cms\Observer\InvalidateLayoutCacheObserver"/>
44-
</event>
4542
</config>
Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
<?php
2+
/************************************************************************
3+
*
4+
* Copyright 2024 Adobe
5+
* All Rights Reserved.
6+
*
7+
* NOTICE: All information contained herein is, and remains
8+
* the property of Adobe and its suppliers, if any. The intellectual
9+
* and technical concepts contained herein are proprietary to Adobe
10+
* and its suppliers and are protected by all applicable intellectual
11+
* property laws, including trade secret and copyright laws.
12+
* Dissemination of this information or reproduction of this material
13+
* is strictly forbidden unless prior written permission is obtained
14+
* from Adobe.
15+
* ************************************************************************
16+
*/
17+
declare(strict_types=1);
18+
19+
namespace Magento\Theme\Model;
20+
21+
use InvalidArgumentException;
22+
use Magento\Framework\App\Cache\Tag\StrategyInterface;
23+
24+
/**
25+
* Creates strategies for layout cache
26+
*/
27+
class LayoutTagCacheFactory
28+
{
29+
/**
30+
* @var array
31+
*/
32+
private array $customLayoutTagCache= [];
33+
34+
/**
35+
* Factory constructor.
36+
*
37+
* @param array $customLayoutTagCache
38+
*/
39+
public function __construct(
40+
array $customLayoutTagCache = []
41+
) {
42+
$this->customLayoutTagCache = $customLayoutTagCache ;
43+
}
44+
45+
/**
46+
* Return tag strategy for specified object
47+
*
48+
* @param object $object
49+
* @return StrategyInterface|null
50+
*/
51+
public function getStrategy(object $object): ?StrategyInterface
52+
{
53+
if (!is_object($object)) {
54+
throw new InvalidArgumentException('Provided argument is not an object');
55+
}
56+
57+
$classHierarchy = array_merge(
58+
[get_class($object) => get_class($object)],
59+
class_parents($object),
60+
class_implements($object)
61+
);
62+
63+
$result = array_intersect(array_keys($this->customLayoutTagCache), $classHierarchy);
64+
if ($result) {
65+
return $this->customLayoutTagCache [array_shift($result)];
66+
}
67+
return null;
68+
}
69+
}

0 commit comments

Comments
 (0)