From 632ea7a2d948a77bb5f43a515fb3365c1834d45a Mon Sep 17 00:00:00 2001 From: bencroker Date: Wed, 3 Jul 2024 11:13:33 +0200 Subject: [PATCH 1/4] 4.18.4 --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index fcc5e790..f44f2cf1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,6 @@ # Release Notes for Blitz -## 4.18.4 - 2024-07-02 +## 4.18.4 - 2024-07-03 ### Fixed From 8fce3abcc615b07a64623237f32d7a936ea5517a Mon Sep 17 00:00:00 2001 From: bencroker Date: Wed, 3 Jul 2024 19:18:37 +0200 Subject: [PATCH 2/4] Ignore propogating elements --- CHANGELOG.md | 9 ++- composer.json | 4 +- src/Blitz.php | 4 +- src/behaviors/ElementChangedBehavior.php | 34 ++++++++++- src/services/RefreshCacheService.php | 73 +++++++++++++++--------- tests/TESTS.md | 1 + tests/pest/Feature/RefreshCacheTest.php | 11 ++++ tests/pest/Helpers.php | 2 + 8 files changed, 104 insertions(+), 34 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f44f2cf1..f01e3fe6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,12 @@ # Release Notes for Blitz +## 4.19.0 - Unreleased + +### Changed + +- Blitz now requires Craft CMS 4.4.7 or later. +- Elements that are propagating are now ignored from the cache refresh process unless their status has changed (https://github.com/putyourlightson/craft-blitz/issues/631) + ## 4.18.4 - 2024-07-03 ### Fixed @@ -142,7 +149,7 @@ ### Changed -- Campaign now requires Craft CMS 4.4.0 or later. +- Blitz now requires Craft CMS 4.4.0 or later. - The Local Generator now uses the `bootstrap.php` file in the project root, if it exists. - The Local Generator now sets the server port according to the HTTP protocol. - Changed the default timeout of the HTTP Generator to 60 seconds. diff --git a/composer.json b/composer.json index f14390ed..24e0ebc4 100644 --- a/composer.json +++ b/composer.json @@ -1,7 +1,7 @@ { "name": "putyourlightson/craft-blitz", "description": "Intelligent static page caching for creating lightning-fast sites.", - "version": "4.18.4", + "version": "4.19.0", "type": "craft-plugin", "homepage": "https://putyourlightson.com/plugins/blitz", "license": "proprietary", @@ -17,7 +17,7 @@ "php": "^8.0.2", "amphp/http-client": "^4.0", "amphp/parallel": "^1.0", - "craftcms/cms": "^4.4", + "craftcms/cms": "^4.4.7", "cypresslab/gitelephant": "^4.0", "putyourlightson/craft-blitz-hints": "^1.2.2", "putyourlightson/craft-sprig-core": "^2.7.3" diff --git a/src/Blitz.php b/src/Blitz.php index daeaabce..5c4963b4 100644 --- a/src/Blitz.php +++ b/src/Blitz.php @@ -385,7 +385,9 @@ function(DeleteElementEvent $event) { function(ElementEvent|BatchElementActionEvent $event) { /** @var Element $element */ $element = $event->element; - $element->attachBehavior(ElementChangedBehavior::BEHAVIOR_NAME, ElementChangedBehavior::class); + if ($this->refreshCache->isRefreshableElement($element)) { + $element->attachBehavior(ElementChangedBehavior::BEHAVIOR_NAME, ElementChangedBehavior::class); + } } ); } diff --git a/src/behaviors/ElementChangedBehavior.php b/src/behaviors/ElementChangedBehavior.php index 0e5a7252..892a143b 100644 --- a/src/behaviors/ElementChangedBehavior.php +++ b/src/behaviors/ElementChangedBehavior.php @@ -8,6 +8,7 @@ use Craft; use craft\base\Element; use craft\elements\Asset; +use craft\helpers\ElementHelper; use putyourlightson\blitz\helpers\ElementTypeHelper; use yii\base\Behavior; @@ -35,6 +36,11 @@ class ElementChangedBehavior extends Behavior */ public ?Element $originalElement = null; + /** + * @var array The original element’s site statuses. + */ + public array $originalElementSiteStatuses = []; + /** * @var string[] The attributes that changed. */ @@ -75,6 +81,10 @@ public function attach($owner): void } $this->originalElement = Craft::$app->getElements()->getElementById($element->id, $element::class, $element->siteId); + + if ($this->originalElement !== null) { + $this->originalElementSiteStatuses = ElementHelper::siteStatusesForElement($this->originalElement); + } } /** @@ -131,7 +141,7 @@ public function getHasBeenDeleted(): bool } /** - * Returns whether the element’s status has changed. + * Returns whether the element’s status or any site statuses have changed. */ public function getHasStatusChanged(): bool { @@ -141,7 +151,27 @@ public function getHasStatusChanged(): bool return false; } - return $element->getStatus() != $this->originalElement->getStatus(); + if ($element->getStatus() != $this->originalElement->getStatus()) { + return true; + } + + $supportedSites = ElementHelper::supportedSitesForElement($element); + + foreach ($supportedSites as $supportedSite) { + $siteId = $supportedSite['siteId']; + $siteStatus = $element->getEnabledForSite($siteId); + $originalSiteStatus = $this->originalElementSiteStatuses[$siteId] ?? null; + + if ( + $siteStatus !== null + && $originalSiteStatus !== null + && $siteStatus !== $originalSiteStatus + ) { + return true; + } + } + + return false; } /** diff --git a/src/services/RefreshCacheService.php b/src/services/RefreshCacheService.php index 24a6c3d5..4678612b 100755 --- a/src/services/RefreshCacheService.php +++ b/src/services/RefreshCacheService.php @@ -175,34 +175,7 @@ public function addElementIds(string $elementType, array $elementIds): void */ public function addElement(ElementInterface $element): void { - // Don’t proceed if not an actual element - if (!($element instanceof Element)) { - return; - } - - // Don’t proceed if the element is an asset that is being indexed - if ($element instanceof Asset && $element->getScenario() === Asset::SCENARIO_INDEX) { - return; - } - - // Refresh the entire cache if this is a global set since they are populated on every request - if ($element instanceof GlobalSet) { - if (Blitz::$plugin->settings->refreshCacheAutomaticallyForGlobals) { - $this->refreshAll(); - } - - return; - } - - $elementType = $element::class; - - // Don’t proceed if not a cacheable element type - if (!ElementTypeHelper::getIsCacheableElementType($elementType)) { - return; - } - - // Don’t proceed if element is a draft or revision - if (ElementHelper::isDraftOrRevision($element)) { + if (!$this->isRefreshableElement($element)) { return; } @@ -292,6 +265,50 @@ public function addElementExpiryDate(Element $element, DateTime $expiryDate): vo ->execute(); } + /** + * Returns whether an element is refreshable. + */ + public function isRefreshableElement(ElementInterface $element): bool + { + // Don’t proceed if not an actual element + if (!($element instanceof Element)) { + return false; + } + + // Don’t proceed if element is a draft or revision + if (ElementHelper::isDraftOrRevision($element)) { + return false; + } + + // Don’t proceed if propagating + if ($element->propagating) { + return false; + } + + // Don’t proceed if the element is an asset that is being indexed + if ($element instanceof Asset && $element->getScenario() === Asset::SCENARIO_INDEX) { + return false; + } + + // Refresh the entire cache if this is a global set since they are populated on every request + if ($element instanceof GlobalSet) { + if (Blitz::$plugin->settings->refreshCacheAutomaticallyForGlobals) { + $this->refreshAll(); + } + + return false; + } + + $elementType = $element::class; + + // Don’t proceed if not a cacheable element type + if (!ElementTypeHelper::getIsCacheableElementType($elementType)) { + return false; + } + + return true; + } + /** * Generates element expiry dates. */ diff --git a/tests/TESTS.md b/tests/TESTS.md index 1ce074fc..406805e3 100644 --- a/tests/TESTS.md +++ b/tests/TESTS.md @@ -150,6 +150,7 @@ _Tests the tracking of changes to elements and the resulting element cache IDs a ![Pass](https://raw.githubusercontent.com/putyourlightson/craft-generate-test-spec/main/icons/pass.svg) Element is not tracked when disabled and its attribute is changed. ![Pass](https://raw.githubusercontent.com/putyourlightson/craft-generate-test-spec/main/icons/pass.svg) Element is tracked when disabled and `refreshCacheWhenElementSavedNotLive` is `true` and its attribute is changed. ![Pass](https://raw.githubusercontent.com/putyourlightson/craft-generate-test-spec/main/icons/pass.svg) Element is tracked when its status is changed. +![Pass](https://raw.githubusercontent.com/putyourlightson/craft-generate-test-spec/main/icons/pass.svg) Element is tracked when its status for another site is changed. ![Pass](https://raw.githubusercontent.com/putyourlightson/craft-generate-test-spec/main/icons/pass.svg) Element is tracked when it expires. ![Pass](https://raw.githubusercontent.com/putyourlightson/craft-generate-test-spec/main/icons/pass.svg) Element is tracked when it is deleted. ![Pass](https://raw.githubusercontent.com/putyourlightson/craft-generate-test-spec/main/icons/pass.svg) Element is tracked when its attribute is changed. diff --git a/tests/pest/Feature/RefreshCacheTest.php b/tests/pest/Feature/RefreshCacheTest.php index 58becb5b..f2e87c4f 100644 --- a/tests/pest/Feature/RefreshCacheTest.php +++ b/tests/pest/Feature/RefreshCacheTest.php @@ -67,6 +67,17 @@ ->toBeTracked(); }); +test('Element is tracked when its status for another site is changed', function() { + $entry = createEntry(); + $entry->setEnabledForSite([ + 2 => false, + ]); + Blitz::$plugin->refreshCache->addElement($entry); + + expect($entry) + ->toBeTracked(); +}); + test('Element is tracked when it expires', function() { $entry = createEntry(); $entry->expiryDate = new DateTime('20010101'); diff --git a/tests/pest/Helpers.php b/tests/pest/Helpers.php index 537fd3d4..08d3e45b 100644 --- a/tests/pest/Helpers.php +++ b/tests/pest/Helpers.php @@ -67,6 +67,8 @@ function createEntry(bool $enabled = true, bool $batchMode = false): Entry ->enabled($enabled) ->create(); + $entry->setEnabledForSite($enabled); + $entry->attachBehavior(ElementChangedBehavior::BEHAVIOR_NAME, ElementChangedBehavior::class); Blitz::$plugin->generateCache->reset(); From 43a0d95c48c27aae7f0c519728d82c2236547014 Mon Sep 17 00:00:00 2001 From: bencroker Date: Thu, 4 Jul 2024 12:04:30 +0200 Subject: [PATCH 3/4] 4.19.0 --- CHANGELOG.md | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f01e3fe6..05939824 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,11 +1,14 @@ # Release Notes for Blitz -## 4.19.0 - Unreleased +## 4.19.0 - 2024-07-03 + +### Added + +- Added the ability for element site status changes to be tracked while not refreshing propagating elements ([#631](https://github.com/putyourlightson/craft-blitz/issues/631)). ### Changed - Blitz now requires Craft CMS 4.4.7 or later. -- Elements that are propagating are now ignored from the cache refresh process unless their status has changed (https://github.com/putyourlightson/craft-blitz/issues/631) ## 4.18.4 - 2024-07-03 From 3e3c9c241facae6c71bc9d7b3d70e8d63516f94a Mon Sep 17 00:00:00 2001 From: bencroker Date: Thu, 4 Jul 2024 12:07:37 +0200 Subject: [PATCH 4/4] Add @since --- src/services/RefreshCacheService.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/services/RefreshCacheService.php b/src/services/RefreshCacheService.php index 4678612b..2700af65 100755 --- a/src/services/RefreshCacheService.php +++ b/src/services/RefreshCacheService.php @@ -267,6 +267,8 @@ public function addElementExpiryDate(Element $element, DateTime $expiryDate): vo /** * Returns whether an element is refreshable. + * + * @since 4.19.0 */ public function isRefreshableElement(ElementInterface $element): bool {