Skip to content

Commit 13e95ea

Browse files
committed
Merge branch 'ACP2E-3063-2' of https://github.com/adobe-commerce-tier-4/magento2ce into PR-08-29-2024
2 parents ee74fcc + f69ffca commit 13e95ea

File tree

11 files changed

+660
-8
lines changed

11 files changed

+660
-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+
*
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 LayoutCacheTagResolver implements StrategyInterface
30+
{
31+
/**
32+
* @inheritDoc
33+
*/
34+
public function getTags($object)
35+
{
36+
if ($this->isExistingCategoryLayoutChange($object)) {
37+
return [
38+
str_replace('{{ID}}', (string) $object->getId(), Instance::SINGLE_CATEGORY_LAYOUT_HANDLE)
39+
];
40+
}
41+
return [];
42+
}
43+
44+
/**
45+
* Check if existing category page layout change
46+
*
47+
* @param Category $object
48+
* @return bool
49+
*/
50+
private function isExistingCategoryLayoutChange(Category $object): bool
51+
{
52+
return !$object->isObjectNew() && $this->isObjectChanged($object);
53+
}
54+
55+
/**
56+
* Check if the page layout of the given category is changed
57+
*
58+
* @param AbstractModel $object
59+
* @return bool
60+
*/
61+
private function isObjectChanged(AbstractModel $object): bool
62+
{
63+
$isChanged = false;
64+
$objectNewPageLayout = $object->getData('page_layout');
65+
$objectOldPageLayout = $object->getOrigData('page_layout');
66+
if ($objectNewPageLayout !== 'empty' &&
67+
$objectNewPageLayout !== $objectOldPageLayout
68+
) {
69+
$isChanged = true;
70+
}
71+
return $isChanged;
72+
}
73+
}
Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
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 LayoutCacheTagResolver implements StrategyInterface
30+
{
31+
/**
32+
* @inheritDoc
33+
*/
34+
public function getTags($object)
35+
{
36+
if ($this->isExistingProductLayoutChange($object)) {
37+
return [
38+
str_replace('{{ID}}', (string) $object->getId(), Instance::SINGLE_PRODUCT_LAYOUT_HANDLE)
39+
];
40+
}
41+
return [];
42+
}
43+
44+
/**
45+
* Check if existing Product page layout change
46+
*
47+
* @param Product $object
48+
* @return bool
49+
*/
50+
private function isExistingProductLayoutChange(Product $object): bool
51+
{
52+
return !$object->isObjectNew() && $this->isObjectChanged($object);
53+
}
54+
55+
/**
56+
* Check if the page layout of the given product is changed
57+
*
58+
* @param AbstractModel $object
59+
* @return bool
60+
*/
61+
private function isObjectChanged(AbstractModel $object): bool
62+
{
63+
$isChanged = false;
64+
$objectNewPageLayout = $object->getData('page_layout');
65+
$objectOldPageLayout = $object->getOrigData('page_layout');
66+
if ($objectNewPageLayout !== 'empty' &&
67+
$objectNewPageLayout !== $objectOldPageLayout
68+
) {
69+
$isChanged = true;
70+
}
71+
return $isChanged;
72+
}
73+
}

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\LayoutCacheTagResolverFactory">
1363+
<arguments>
1364+
<argument name="cacheTagsResolvers" xsi:type="array">
1365+
<item name="Magento\Catalog\Model\Product" xsi:type="object">
1366+
Magento\Catalog\Model\Product\LayoutCacheTagResolver
1367+
</item>
1368+
<item name="Magento\Catalog\Model\Category" xsi:type="object">
1369+
Magento\Catalog\Model\Category\LayoutCacheTagResolver
1370+
</item>
1371+
</argument>
1372+
</arguments>
1373+
</type>
13621374
</config>
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
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\Cms\Model\Page;
22+
use Magento\Framework\App\Cache\Tag\StrategyInterface;
23+
24+
/**
25+
* Get additional layout cache tag for CMS layout.
26+
*/
27+
class LayoutCacheTagResolver implements StrategyInterface
28+
{
29+
/**
30+
* @inheritDoc
31+
*/
32+
public function getTags($object)
33+
{
34+
if ($this->isExistingPageLayoutChange($object)) {
35+
return [
36+
'CMS_PAGE_VIEW_ID_'.
37+
str_replace('-', '_', strtoupper($object->getIdentifier()))
38+
];
39+
}
40+
return [];
41+
}
42+
43+
/**
44+
* Check if existing CMS page layout change
45+
*
46+
* @param Page $object
47+
* @return bool
48+
*/
49+
private function isExistingPageLayoutChange(Page $object): bool
50+
{
51+
return !$object->isObjectNew() &&
52+
$object->dataHasChangedFor(Page::PAGE_LAYOUT);
53+
}
54+
}

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\LayoutCacheTagResolverFactory">
320+
<arguments>
321+
<argument name="cacheTagsResolvers" xsi:type="array">
322+
<item name="Magento\Cms\Model\Page" xsi:type="object">
323+
Magento\Cms\Model\Page\LayoutCacheTagResolver
324+
</item>
325+
</argument>
326+
</arguments>
327+
</type>
319328
</config>
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
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 LayoutCacheTagResolverFactory
28+
{
29+
/**
30+
* Construct
31+
*
32+
* @param array $cacheTagsResolvers
33+
*/
34+
public function __construct(
35+
private readonly array $cacheTagsResolvers
36+
) {
37+
}
38+
39+
/**
40+
* Return tag resolver for specified object
41+
*
42+
* @param object $object
43+
* @return StrategyInterface|null
44+
*/
45+
public function getStrategy(object $object): ?StrategyInterface
46+
{
47+
if (!is_object($object)) {
48+
throw new InvalidArgumentException('Provided argument is not an object');
49+
}
50+
51+
$classHierarchy = array_merge(
52+
[get_class($object) => get_class($object)],
53+
class_parents($object),
54+
class_implements($object)
55+
);
56+
57+
$result = array_intersect(array_keys($this->cacheTagsResolvers), $classHierarchy);
58+
if ($result) {
59+
return $this->cacheTagsResolvers[array_shift($result)];
60+
}
61+
return null;
62+
}
63+
}
Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
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\Observer;
20+
21+
use Magento\Framework\App\Cache\Type\Layout as LayoutCache;
22+
use Magento\Framework\App\Cache\StateInterface as CacheState;
23+
use Magento\Framework\Event\Observer;
24+
use Magento\Framework\Event\ObserverInterface;
25+
use Magento\Theme\Model\LayoutCacheTagResolverFactory;
26+
27+
/**
28+
* Invalidates layout cache.
29+
*/
30+
class InvalidateLayoutCacheObserver implements ObserverInterface
31+
{
32+
/**
33+
* @var LayoutCache
34+
*/
35+
private $layoutCache;
36+
37+
/**
38+
* @var CacheState
39+
*/
40+
private $cacheState;
41+
42+
/**
43+
* @var LayoutCacheTagResolverFactory
44+
*/
45+
private $layoutCacheTagResolver;
46+
47+
/**
48+
* @param LayoutCache $layoutCache
49+
* @param CacheState $cacheState
50+
* @param LayoutCacheTagResolverFactory $layoutCacheTagResolver
51+
*/
52+
public function __construct(
53+
LayoutCache $layoutCache,
54+
CacheState $cacheState,
55+
LayoutCacheTagResolverFactory $layoutCacheTagResolver
56+
) {
57+
$this->layoutCache = $layoutCache;
58+
$this->cacheState = $cacheState;
59+
$this->layoutCacheTagResolver = $layoutCacheTagResolver;
60+
}
61+
62+
/**
63+
* Clean identities of event object from layout cache
64+
*
65+
* @param Observer $observer
66+
*
67+
* @return void
68+
*/
69+
public function execute(Observer $observer): void
70+
{
71+
$object = $observer->getEvent()->getObject();
72+
$tagResolver = $this->layoutCacheTagResolver->getStrategy($object);
73+
74+
if (!$tagResolver || !is_object($object)) {
75+
return;
76+
}
77+
78+
if (!$this->cacheState->isEnabled(LayoutCache::TYPE_IDENTIFIER)) {
79+
return;
80+
}
81+
82+
$tags = $tagResolver->getTags($object);
83+
84+
if (!empty($tags)) {
85+
$this->layoutCache->clean(\Zend_Cache::CLEANING_MODE_MATCHING_ANY_TAG, $tags);
86+
}
87+
}
88+
}

0 commit comments

Comments
 (0)