From 219a950672f4d108b5d483dae7a98ad9787b86d1 Mon Sep 17 00:00:00 2001 From: bencroker Date: Wed, 31 Jul 2024 10:59:25 +0200 Subject: [PATCH 01/15] Add sidebar panel to entries --- src/Blitz.php | 27 +++++++++++++++++++++++++++ src/templates/_sidebar-panel.twig | 11 +++++++++++ 2 files changed, 38 insertions(+) create mode 100644 src/templates/_sidebar-panel.twig diff --git a/src/Blitz.php b/src/Blitz.php index b2eb08a3..726b57bf 100644 --- a/src/Blitz.php +++ b/src/Blitz.php @@ -8,8 +8,10 @@ use Craft; use craft\base\Element; use craft\base\Plugin; +use craft\elements\Entry; use craft\elements\User; use craft\events\BatchElementActionEvent; +use craft\events\DefineHtmlEvent; use craft\events\DeleteElementEvent; use craft\events\ElementEvent; use craft\events\MoveElementEvent; @@ -42,6 +44,7 @@ use putyourlightson\blitz\drivers\storage\BaseCacheStorage; use putyourlightson\blitz\helpers\IntegrationHelper; use putyourlightson\blitz\helpers\RefreshCacheHelper; +use putyourlightson\blitz\helpers\SiteUriHelper; use putyourlightson\blitz\models\RefreshDataModel; use putyourlightson\blitz\models\SettingsModel; use putyourlightson\blitz\services\CacheRequestService; @@ -153,6 +156,7 @@ public function init(): void $this->registerCpUrlRules(); $this->registerUtilities(); $this->registerWidgets(); + $this->registerSidebarPanels(); $this->registerRedirectAfterInstall(); if (Craft::$app->getEdition() === Craft::Pro) { @@ -549,6 +553,29 @@ function(RegisterComponentTypesEvent $event) { ); } + /** + * Registers sidebar panels + * + * @since 4.22.0 + */ + private function registerSidebarPanels(): void + { + Event::on(Entry::class, Entry::EVENT_DEFINE_SIDEBAR_HTML, + function(DefineHtmlEvent $event) { + /** @var Entry $entry */ + $entry = $event->sender; + $url = $entry->getUrl(); + if ($url === null) { + return; + } + $cachedValue = $this->cacheStorage->get(SiteUriHelper::getSiteUriFromUrl($url)); + $event->html .= Craft::$app->getView()->renderTemplate('blitz/_sidebar-panel', [ + 'status' => !empty($cachedValue) ? 'cached' : 'uncached', + ]); + } + ); + } + /** * Registers redirect after install */ diff --git a/src/templates/_sidebar-panel.twig b/src/templates/_sidebar-panel.twig new file mode 100644 index 00000000..9abaf4a2 --- /dev/null +++ b/src/templates/_sidebar-panel.twig @@ -0,0 +1,11 @@ +{% import '_includes/forms' as forms %} + +
+ Blitz +
+
+
Status
+
{{ status|ucfirst }}
+
+
+
From ebbd79160e51a78b8e886904e6ad894d5058ac36 Mon Sep 17 00:00:00 2001 From: bencroker Date: Wed, 31 Jul 2024 12:16:22 +0200 Subject: [PATCH 02/15] Add refresh button and user permission --- src/Blitz.php | 16 +++----- src/controllers/CacheController.php | 4 +- src/helpers/SidebarPanelHelper.php | 37 ++++++++++++++++++ src/templates/_sidebar-panel.twig | 58 +++++++++++++++++++++++++++-- 4 files changed, 100 insertions(+), 15 deletions(-) create mode 100755 src/helpers/SidebarPanelHelper.php diff --git a/src/Blitz.php b/src/Blitz.php index 726b57bf..145b8482 100644 --- a/src/Blitz.php +++ b/src/Blitz.php @@ -44,7 +44,7 @@ use putyourlightson\blitz\drivers\storage\BaseCacheStorage; use putyourlightson\blitz\helpers\IntegrationHelper; use putyourlightson\blitz\helpers\RefreshCacheHelper; -use putyourlightson\blitz\helpers\SiteUriHelper; +use putyourlightson\blitz\helpers\SidebarPanelHelper; use putyourlightson\blitz\models\RefreshDataModel; use putyourlightson\blitz\models\SettingsModel; use putyourlightson\blitz\services\CacheRequestService; @@ -562,16 +562,7 @@ private function registerSidebarPanels(): void { Event::on(Entry::class, Entry::EVENT_DEFINE_SIDEBAR_HTML, function(DefineHtmlEvent $event) { - /** @var Entry $entry */ - $entry = $event->sender; - $url = $entry->getUrl(); - if ($url === null) { - return; - } - $cachedValue = $this->cacheStorage->get(SiteUriHelper::getSiteUriFromUrl($url)); - $event->html .= Craft::$app->getView()->renderTemplate('blitz/_sidebar-panel', [ - 'status' => !empty($cachedValue) ? 'cached' : 'uncached', - ]); + $event->html .= SidebarPanelHelper::getHtml($event->sender); } ); } @@ -635,6 +626,9 @@ function(RegisterUserPermissionsEvent $event) { 'blitz:refresh-tagged' => [ 'label' => Craft::t('blitz', 'Refresh tagged cache'), ], + 'blitz:view-sidebar-panel' => [ + 'label' => Craft::t('blitz', 'View sidebar panel'), + ], ], ]; } diff --git a/src/controllers/CacheController.php b/src/controllers/CacheController.php index 0f088657..c81c6489 100755 --- a/src/controllers/CacheController.php +++ b/src/controllers/CacheController.php @@ -42,9 +42,11 @@ public function beforeAction($action): bool $request = Craft::$app->getRequest(); - // Require permission if posted from utility + // Require permission if posted from utility or sidebar panel if ($request->getIsPost() && $request->getParam('utility')) { $this->requirePermission('blitz:' . $action->id); + } elseif ($request->getIsPost() && $request->getParam('sidebar-panel') && $action->id === 'refresh-urls') { + $this->requirePermission('blitz:view-sidebar-panel'); } else { // Verify API key $key = $request->getParam('key'); diff --git a/src/helpers/SidebarPanelHelper.php b/src/helpers/SidebarPanelHelper.php new file mode 100755 index 00000000..447c5a08 --- /dev/null +++ b/src/helpers/SidebarPanelHelper.php @@ -0,0 +1,37 @@ +getUrl(); + if ($url === null) { + return ''; + } + + $siteUri = SiteUriHelper::getSiteUriFromUrl($url); + $cachedValue = Blitz::$plugin->cacheStorage->get($siteUri); + $expired = CacheRecord::find() + ->where($siteUri->getAttributes()) + ->andWhere(['not', ['expiryDate' => null]]) + ->exists(); + + return Craft::$app->getView()->renderTemplate('blitz/_sidebar-panel', [ + 'cached' => !empty($cachedValue), + 'expired' => $expired, + 'url' => $url, + 'refreshActionUrl' => UrlHelper::actionUrl('blitz/cache/refresh-urls'), + ]); + } +} diff --git a/src/templates/_sidebar-panel.twig b/src/templates/_sidebar-panel.twig index 9abaf4a2..f6114a16 100644 --- a/src/templates/_sidebar-panel.twig +++ b/src/templates/_sidebar-panel.twig @@ -1,11 +1,63 @@ {% import '_includes/forms' as forms %}
- Blitz + + {{ 'Blitz Cache'|t('blitz') }} +
-
Status
-
{{ status|ucfirst }}
+
+ {{ 'Status'|t('blitz') }} +
+
+ {% if cached %} + {{ expired ? 'Expired'|t('blitz') : 'Cached'|t('blitz') }} + {{ tag('button', { + text: 'Refresh'|t('blitz'), + class: 'blitzRefreshUrl btn small', + data: { + action: refreshActionUrl, + url: url, + }, + }) }} + {% else %} + {{ 'Uncached'|t('blitz') }} + {% endif %} +
+ +{% js %} + $('.blitzRefreshUrl').click(function(event) { + event.preventDefault(); + + if ($(this).hasClass('disabled')) { + return; + } + + $(this).addClass('disabled'); + + const data = { + urls: $(this).data('url'), + 'sidebar-panel': 1 + }; + + Craft.sendActionRequest('POST', $(this).data('action'), {data}) + .then((response) => { + Craft.cp.displayNotice(response.data.message); + $('.blitzRefreshUrl').closest('.value').html('Refreshed'); + }) + .catch(({response}) => { + if (response.data.message) { + Craft.cp.displayError(response.data.message); + } + else { + Craft.cp.displayError(); + } + }) + .finally(() => { + $(this).removeClass('disabled'); + }); + }); +{% endjs %} From 91599ab01f39d85ef1a9a8f17190f0bd8143992a Mon Sep 17 00:00:00 2001 From: bencroker Date: Wed, 31 Jul 2024 12:28:54 +0200 Subject: [PATCH 03/15] Apply to all element types --- src/Blitz.php | 9 +++++---- src/helpers/SidebarPanelHelper.php | 6 +++--- 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/src/Blitz.php b/src/Blitz.php index 145b8482..9493f550 100644 --- a/src/Blitz.php +++ b/src/Blitz.php @@ -8,7 +8,6 @@ use Craft; use craft\base\Element; use craft\base\Plugin; -use craft\elements\Entry; use craft\elements\User; use craft\events\BatchElementActionEvent; use craft\events\DefineHtmlEvent; @@ -560,9 +559,11 @@ function(RegisterComponentTypesEvent $event) { */ private function registerSidebarPanels(): void { - Event::on(Entry::class, Entry::EVENT_DEFINE_SIDEBAR_HTML, + Event::on(Element::class, Element::EVENT_DEFINE_SIDEBAR_HTML, function(DefineHtmlEvent $event) { - $event->html .= SidebarPanelHelper::getHtml($event->sender); + /** @var Element $element */ + $element = $event->sender; + $event->html .= SidebarPanelHelper::getHtml($element); } ); } @@ -627,7 +628,7 @@ function(RegisterUserPermissionsEvent $event) { 'label' => Craft::t('blitz', 'Refresh tagged cache'), ], 'blitz:view-sidebar-panel' => [ - 'label' => Craft::t('blitz', 'View sidebar panel'), + 'label' => Craft::t('blitz', 'View sidebar panel on element edit pages'), ], ], ]; diff --git a/src/helpers/SidebarPanelHelper.php b/src/helpers/SidebarPanelHelper.php index 447c5a08..795078f9 100755 --- a/src/helpers/SidebarPanelHelper.php +++ b/src/helpers/SidebarPanelHelper.php @@ -6,16 +6,16 @@ namespace putyourlightson\blitz\helpers; use Craft; -use craft\elements\Entry; +use craft\base\Element; use craft\helpers\UrlHelper; use putyourlightson\blitz\Blitz; use putyourlightson\blitz\records\CacheRecord; class SidebarPanelHelper { - public static function getHtml(Entry $entry): string + public static function getHtml(Element $element): string { - $url = $entry->getUrl(); + $url = $element->getUrl(); if ($url === null) { return ''; } From 898c149f93c462d3a7c914b9b641f661bf4391f2 Mon Sep 17 00:00:00 2001 From: bencroker Date: Wed, 31 Jul 2024 18:30:54 +0200 Subject: [PATCH 04/15] Add date cached to record and display --- CHANGELOG.md | 11 ++++ composer.json | 4 +- src/Blitz.php | 2 +- src/controllers/CacheController.php | 23 +++++++- src/controllers/DiagnosticsController.php | 2 + src/helpers/DiagnosticsHelper.php | 4 +- src/helpers/SidebarPanelHelper.php | 28 +++++---- src/migrations/Install.php | 1 + .../m240731_120000_add_datecached_column.php | 31 ++++++++++ src/records/CacheRecord.php | 1 + src/services/GenerateCacheService.php | 1 + src/templates/_sidebar-panel.twig | 59 ++++++++++++++----- .../diagnostics/_components/pages.twig | 8 +++ 13 files changed, 144 insertions(+), 31 deletions(-) create mode 100644 src/migrations/m240731_120000_add_datecached_column.php diff --git a/CHANGELOG.md b/CHANGELOG.md index 886453be..f70ff36e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,16 @@ # Release Notes for Blitz +## 4.22.0 - Unreleased + +### Added + +- Added a sidebar panel to element edit pages ([#690](https://github.com/putyourlightson/craft-blitz/issues/690)). +- Added a `dateCached` column to cache records which is output in the sidebar panel and the Blitz Diagnostics utility. + +### Changed + +- Blitz now requires Craft CMS 4.5.0 or later. + ## 4.21.0 - 2024-07-24 ### Added diff --git a/composer.json b/composer.json index 37a51f89..253fb65a 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.21.0", + "version": "4.22.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.8", + "craftcms/cms": "^4.5.0", "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 9493f550..50c3517f 100644 --- a/src/Blitz.php +++ b/src/Blitz.php @@ -113,7 +113,7 @@ public static function config(): array /** * @inheritdoc */ - public string $schemaVersion = '4.13.0'; + public string $schemaVersion = '4.22.0'; /** * @inheritdoc diff --git a/src/controllers/CacheController.php b/src/controllers/CacheController.php index c81c6489..cdae9412 100755 --- a/src/controllers/CacheController.php +++ b/src/controllers/CacheController.php @@ -11,6 +11,8 @@ use craft\web\Controller; use craft\web\View; use putyourlightson\blitz\Blitz; +use putyourlightson\blitz\helpers\SidebarPanelHelper; +use putyourlightson\blitz\models\SiteUriModel; use yii\web\ForbiddenHttpException; use yii\web\Response; @@ -45,7 +47,7 @@ public function beforeAction($action): bool // Require permission if posted from utility or sidebar panel if ($request->getIsPost() && $request->getParam('utility')) { $this->requirePermission('blitz:' . $action->id); - } elseif ($request->getIsPost() && $request->getParam('sidebar-panel') && $action->id === 'refresh-urls') { + } elseif ($request->getIsPost() && $action->id === 'refresh-site-uri') { $this->requirePermission('blitz:view-sidebar-panel'); } else { // Verify API key @@ -211,6 +213,25 @@ public function actionRefreshTagged(): ?Response return $this->getSuccessResponse('Tagged cache successfully refreshed.'); } + /** + * Refreshes a cached site URI. + * + * @used-by SidebarPanelHelper::getHtml() + */ + public function actionRefreshSiteUri(): ?Response + { + $siteId = Craft::$app->getRequest()->getRequiredParam('siteId'); + $uri = Craft::$app->getRequest()->getRequiredParam('uri'); + $siteUri = new SiteUriModel([ + 'siteId' => $siteId, + 'uri' => $uri, + ]); + + Blitz::$plugin->refreshCache->refreshSiteUris([$siteUri]); + + return $this->getSuccessResponse('Cached page successfully refreshed.'); + } + /** * Returns a success response. */ diff --git a/src/controllers/DiagnosticsController.php b/src/controllers/DiagnosticsController.php index 27d01cd2..7da9b3de 100755 --- a/src/controllers/DiagnosticsController.php +++ b/src/controllers/DiagnosticsController.php @@ -76,6 +76,7 @@ public function actionExportPages(int $siteId, ?int $elementId = null, ?int $que 'elements' => $page['elementCount'] ?: 0, 'elementQueries' => $page['elementQueryCount'] ?: 0, 'tags' => $page['tagCount'] ?: 0, + 'dateCached' => $page['dateCached'], 'expiryDate' => $page['expiryDate'], ]; } @@ -104,6 +105,7 @@ public function actionExportIncludes(int $siteId): Response 'params' => $include['params'], 'elements' => $include['elementCount'] ?: 0, 'elementQueries' => $include['elementQueryCount'] ?: 0, + 'dateCached' => $include['dateCached'], 'expiryDate' => $include['expiryDate'], ]; } diff --git a/src/helpers/DiagnosticsHelper.php b/src/helpers/DiagnosticsHelper.php index 2c0103f3..bc1a7726 100644 --- a/src/helpers/DiagnosticsHelper.php +++ b/src/helpers/DiagnosticsHelper.php @@ -218,7 +218,7 @@ public static function getIncludesQuery(int $siteId): ActiveQuery $index = self::getIncludesIndexColumnForSelect(); return self::getBasePagesQuery($siteId) - ->select(['caches.id', 'uri', $index . ' AS index', 'template', 'params', 'elementCount', 'elementQueryCount', 'expiryDate']) + ->select(['caches.id', 'uri', $index . ' AS index', 'template', 'params', 'elementCount', 'elementQueryCount', 'dateCached', 'expiryDate']) ->innerJoin([ 'indexes' => IncludeRecord::find() ->where(['siteId' => $siteId]), @@ -642,7 +642,7 @@ private static function getBasePagesQuery(int $siteId, ?int $elementId = null, ? { $query = CacheRecord::find() ->from(['caches' => CacheRecord::tableName()]) - ->select(['id', 'uri', 'elementCount', 'elementQueryCount', 'tagCount', 'expiryDate']) + ->select(['id', 'uri', 'elementCount', 'elementQueryCount', 'tagCount', 'dateCached', 'expiryDate']) ->leftJoin([ 'elements' => ElementCacheRecord::find() ->select(['cacheId', 'count(*) as elementCount']) diff --git a/src/helpers/SidebarPanelHelper.php b/src/helpers/SidebarPanelHelper.php index 795078f9..7dc0c2af 100755 --- a/src/helpers/SidebarPanelHelper.php +++ b/src/helpers/SidebarPanelHelper.php @@ -8,30 +8,38 @@ use Craft; use craft\base\Element; use craft\helpers\UrlHelper; +use DateTime; use putyourlightson\blitz\Blitz; +use putyourlightson\blitz\models\SiteUriModel; use putyourlightson\blitz\records\CacheRecord; class SidebarPanelHelper { public static function getHtml(Element $element): string { - $url = $element->getUrl(); - if ($url === null) { + $uri = $element->uri; + if ($uri === null) { return ''; } - $siteUri = SiteUriHelper::getSiteUriFromUrl($url); + $siteUri = new SiteUriModel([ + 'siteId' => $element->siteId, + 'uri' => $uri, + ]); $cachedValue = Blitz::$plugin->cacheStorage->get($siteUri); - $expired = CacheRecord::find() - ->where($siteUri->getAttributes()) - ->andWhere(['not', ['expiryDate' => null]]) - ->exists(); + $cacheRecord = CacheRecord::find() + ->where($siteUri->toArray()) + ->one(); return Craft::$app->getView()->renderTemplate('blitz/_sidebar-panel', [ 'cached' => !empty($cachedValue), - 'expired' => $expired, - 'url' => $url, - 'refreshActionUrl' => UrlHelper::actionUrl('blitz/cache/refresh-urls'), + 'expired' => $cacheRecord && $cacheRecord->expiryDate && $cacheRecord->expiryDate <= (new DateTime()), + 'dateCached' => $cacheRecord->dateCached ?? null, + 'expiryDate' => $cacheRecord->expiryDate ?? null, + 'refreshActionUrl' => UrlHelper::actionUrl('blitz/cache/refresh-site-uri', [ + 'siteId' => $element->siteId, + 'uri' => $uri, + ]), ]); } } diff --git a/src/migrations/Install.php b/src/migrations/Install.php index c8d045dd..7a062c51 100644 --- a/src/migrations/Install.php +++ b/src/migrations/Install.php @@ -84,6 +84,7 @@ protected function createTables(): bool 'siteId' => $this->integer()->notNull(), 'uri' => $this->string(Blitz::$plugin->settings->maxUriLength)->notNull(), 'paginate' => $this->integer(), + 'dateCached' => $this->dateTime(), 'expiryDate' => $this->dateTime(), ]); } diff --git a/src/migrations/m240731_120000_add_datecached_column.php b/src/migrations/m240731_120000_add_datecached_column.php new file mode 100644 index 00000000..a1a03c5d --- /dev/null +++ b/src/migrations/m240731_120000_add_datecached_column.php @@ -0,0 +1,31 @@ +db->columnExists(CacheRecord::tableName(), 'dateCached')) { + $this->addColumn(CacheRecord::tableName(), 'dateCached', $this->dateTime()->after('paginate')); + } + + return true; + } + + /** + * @inheritdoc + */ + public function safeDown(): bool + { + echo self::class . " cannot be reverted.\n"; + + return true; + } +} diff --git a/src/records/CacheRecord.php b/src/records/CacheRecord.php index 61a66efd..ea79668f 100644 --- a/src/records/CacheRecord.php +++ b/src/records/CacheRecord.php @@ -14,6 +14,7 @@ * @property int $siteId * @property string $uri * @property int|null $paginate + * @property DateTime|null $dateCached * @property DateTime|null $expiryDate * @property-read ElementCacheRecord[] $elements */ diff --git a/src/services/GenerateCacheService.php b/src/services/GenerateCacheService.php index b417d32a..7f622e9e 100755 --- a/src/services/GenerateCacheService.php +++ b/src/services/GenerateCacheService.php @@ -527,6 +527,7 @@ public function save(string $content, SiteUriModel $siteUri): ?string $cacheValue = array_merge($cacheValue, [ 'paginate' => $paginate, + 'dateCached' => Db::prepareDateForDb('now'), 'expiryDate' => Db::prepareDateForDb($this->options->expiryDate), ]); diff --git a/src/templates/_sidebar-panel.twig b/src/templates/_sidebar-panel.twig index f6114a16..1eec7468 100644 --- a/src/templates/_sidebar-panel.twig +++ b/src/templates/_sidebar-panel.twig @@ -1,23 +1,22 @@ {% import '_includes/forms' as forms %} -
+
{{ 'Blitz Cache'|t('blitz') }}
-
+
{{ 'Status'|t('blitz') }} -
-
+
+
{% if cached %} {{ expired ? 'Expired'|t('blitz') : 'Cached'|t('blitz') }} {{ tag('button', { text: 'Refresh'|t('blitz'), - class: 'blitzRefreshUrl btn small', + class: 'refresh btn small', data: { action: refreshActionUrl, - url: url, }, }) }} {% else %} @@ -25,11 +24,45 @@ {% endif %}
+ {% if cached %} + {% if dateCached %} +
+
+ {{ 'Cached at'|t('blitz') }} +
+
+ {{ dateCached|datetime('short') }} +
+
+ {% endif %} + {% if expiryDate %} +
+
+ {{ 'Expiry Date'|t('blitz') }} +
+
+ {{ expiryDate|datetime('short') }} +
+
+ {% endif %} + {% endif %}
+{% css %} + .blitz-sidebar-panel .meta .data:first-of-type { + padding-top: 8px; + } + .blitz-sidebar-panel .meta .data:last-of-type { + padding-bottom: 8px; + } + .blitz-sidebar-panel .meta .data { + min-height: 0; + } +{% endcss %} + {% js %} - $('.blitzRefreshUrl').click(function(event) { + $('.blitz-sidebar-panel .refresh').click(function(event) { event.preventDefault(); if ($(this).hasClass('disabled')) { @@ -38,15 +71,11 @@ $(this).addClass('disabled'); - const data = { - urls: $(this).data('url'), - 'sidebar-panel': 1 - }; - - Craft.sendActionRequest('POST', $(this).data('action'), {data}) + Craft.sendActionRequest('POST', $(this).data('action')) .then((response) => { - Craft.cp.displayNotice(response.data.message); - $('.blitzRefreshUrl').closest('.value').html('Refreshed'); + Craft.cp.displaySuccess(response.data.message); + $('.blitz-sidebar-panel .cacheStatus').html(Craft.t('blitz', 'Refreshed')); + $('.blitz-sidebar-panel .date').html(''); }) .catch(({response}) => { if (response.data.message) { diff --git a/src/templates/_utilities/diagnostics/_components/pages.twig b/src/templates/_utilities/diagnostics/_components/pages.twig index a3f62099..292559c3 100644 --- a/src/templates/_utilities/diagnostics/_components/pages.twig +++ b/src/templates/_utilities/diagnostics/_components/pages.twig @@ -61,6 +61,11 @@ {{ 'Tags'|t('blitz') }} + + +