diff --git a/src/HtmlCache.php b/src/HtmlCache.php index 7bf2200..997e52c 100644 --- a/src/HtmlCache.php +++ b/src/HtmlCache.php @@ -19,12 +19,15 @@ use craft\services\Plugins; use craft\events\PluginEvent; use craft\services\Elements; +use craft\services\Utilities; use craft\web\UrlManager; use craft\helpers\FileHelper; use craft\helpers\UrlHelper; use craft\events\RegisterUrlRulesEvent; use bolden\htmlcache\services\HtmlcacheService; use bolden\htmlcache\models\Settings; +use bolden\htmlcache\utilities\CacheUtility; + use yii\base\Event; use craft\elements\db\ElementQuery; @@ -35,6 +38,7 @@ use bolden\htmlcache\records\HtmlCacheElement; use craft\elements\User; use craft\elements\GlobalSet; +use craft\events\RegisterComponentTypesEvent; /** * Craft plugins are very much like little applications in and of themselves. We’ve made @@ -117,7 +121,7 @@ public function init() self::$plugin = $this; // ignore console requests - if ($this->isInstalled && !\Craft::$app->request->getIsConsoleRequest()) { + if ($this->isInstalled && !\Craft::$app->getRequest()->getIsConsoleRequest()) { $this->setComponents( [ 'htmlcacheService' => HtmlcacheService::class, @@ -142,10 +146,14 @@ public function init() if ($this->htmlcacheService->canCreateCacheFile()) { $elementClass = get_class($event->element); if (!in_array($elementClass, [User::class, GlobalSet::class])) { - $uri = \Craft::$app->request->getParam('p', ''); + $uri = \Craft::$app->getRequest()->getPathInfo() ?: $event->element->uri; $siteId = \Craft::$app->getSites()->getCurrentSite()->id; $elementId = $event->element->id; - + + if (!$uri || strlen($uri) === 0) { + return; + } + // check if cache entry already exits otherwise create it $cacheEntry = HtmlCacheCache::findOne(['uri' => $uri, 'siteId' => $siteId]); if (!$cacheEntry) { @@ -217,6 +225,17 @@ function (PluginEvent $event) { } } ); + + if (Craft::$app->getRequest()->getIsCpRequest()) { + Event::on( + Utilities::class, + Utilities::EVENT_REGISTER_UTILITY_TYPES, + function(RegisterComponentTypesEvent $event) { + $event->types[] = CacheUtility::class; + } + ); + } + parent::init(); } diff --git a/src/controllers/CacheController.php b/src/controllers/CacheController.php new file mode 100644 index 0000000..ecd6e04 --- /dev/null +++ b/src/controllers/CacheController.php @@ -0,0 +1,35 @@ +requireLogin(); + $this->requirePostRequest(); + try { + Plugin::$plugin->htmlcacheService->clearCacheFiles(); + Craft::$app->getSession()->setNotice(Craft::t('html-cache', 'Caches Cleared')); + } catch (\Throwable $th) { + Craft::$app->getSession()->setNotice(Craft::t('html-cache', 'Unable to Clear Caches')); + } + return; + } + +} diff --git a/src/icon-mask.svg b/src/icon-mask.svg new file mode 100644 index 0000000..b55d4a9 --- /dev/null +++ b/src/icon-mask.svg @@ -0,0 +1 @@ +Artboard 1 \ No newline at end of file diff --git a/src/models/Settings.php b/src/models/Settings.php index 804197b..3d383fb 100644 --- a/src/models/Settings.php +++ b/src/models/Settings.php @@ -19,11 +19,13 @@ class Settings extends \craft\base\Model public $optimizeContent = 0; public $cacheDuration = 3600; public $purgeCache = 0; + public $disablePreviewCache = 1; public $excludedUrlPaths = []; + public $queryStringCaching = false; public function rules() { return [ - [ ['enableGeneral', 'forceOn', 'optimizeContent', 'purgeCache' ], 'boolean' ], + [ ['enableGeneral', 'forceOn', 'optimizeContent', 'purgeCache', 'disablePreviewCache' ], 'boolean' ], [ ['cacheDuration' ], 'integer' ], ]; } diff --git a/src/records/HtmlCacheCachesRecord.php b/src/records/HtmlCacheCache.php similarity index 100% rename from src/records/HtmlCacheCachesRecord.php rename to src/records/HtmlCacheCache.php diff --git a/src/records/HtmlCacheElementRecord.php b/src/records/HtmlCacheElement.php similarity index 100% rename from src/records/HtmlCacheElementRecord.php rename to src/records/HtmlCacheElement.php diff --git a/src/services/HtmlcacheService.php b/src/services/HtmlcacheService.php index 6133219..24c7692 100755 --- a/src/services/HtmlcacheService.php +++ b/src/services/HtmlcacheService.php @@ -38,7 +38,7 @@ class HtmlcacheService extends Component */ public function __construct() { - $this->uri = \Craft::$app->request->getParam('p', ''); + $this->uri = \Craft::$app->getRequest()->getPathInfo() ?: '__HOME__'; $this->siteId = \Craft::$app->getSites()->getCurrentSite()->id; $this->settings = HtmlCache::getInstance()->getSettings(); } @@ -77,6 +77,16 @@ public function checkForCacheFile() */ public function canCreateCacheFile() { + // Skip if it's a preview url + if ($this->settings->disablePreviewCache && Craft::$app->getRequest()->getIsPreview()) { + return false; + } + + // Skip if it has a query string and plugin is set to ignore urls with query strings + if (!$this->settings->queryStringCaching && Craft::$app->getRequest()->getQueryString()) { + return false; + } + // Skip if we're running in devMode and not in force mode if (\Craft::$app->config->general->devMode === true && $this->settings->forceOn == false) { return false; @@ -93,25 +103,25 @@ public function canCreateCacheFile() } // Skip if it's a CP Request - if (\Craft::$app->request->getIsCpRequest()) { + if (\Craft::$app->getRequest()->getIsCpRequest()) { return false; } // Skip if it's an action Request - if (\Craft::$app->request->getIsActionRequest()) { + if (\Craft::$app->getRequest()->getIsActionRequest()) { return false; } // Skip if it's a preview request - if (\Craft::$app->request->getIsLivePreview()) { + if (\Craft::$app->getRequest()->getIsLivePreview()) { return false; } // Skip if it's a post request - if (!\Craft::$app->request->getIsGet()) { + if (!\Craft::$app->getRequest()->getIsGet()) { return false; } // Skip if it's an ajax request - if (\Craft::$app->request->getIsAjax()) { + if (\Craft::$app->getRequest()->getIsAjax()) { return false; } // Skip if route from element api @@ -157,7 +167,7 @@ private function isElementApiRoute() private function isPathExcluded() { // determine currently requested URL path and the multi-site ID - $requestedPath = \Craft::$app->request->getFullPath(); + $requestedPath = \Craft::$app->getRequest()->getFullPath(); $requestedSiteId = \Craft::$app->getSites()->getCurrentSite()->id; // compare with excluded paths and sites from the settings @@ -291,13 +301,23 @@ private function loadCache($file) } elseif (!empty($this->settings->cacheDuration)) { $settings = ['cacheDuration' => $this->settings->cacheDuration]; } else { - $settings = ['cacheDuration' => 3600]; + $settings = ['cacheDuration' => 0]; } - if (time() - ($fmt = filemtime($file)) >= $settings['cacheDuration']) { + if ($settings['cacheDuration'] > 0 && time() - ($fmt = filemtime($file)) >= $settings['cacheDuration']) { unlink($file); return false; } - \Craft::$app->response->data = file_get_contents($file); + + $page = file_get_contents($file); + + if (Craft::$app->config->general->devMode) { + $filename = array_slice(explode('/',$file),-1)[0]; + $uri = Craft::$app->getRequest()->getFullUri(); + $date = date("F d Y H:i:s",filemtime($file)); + $page .= "\n\n"; + } + + \Craft::$app->response->data = $page; return true; } diff --git a/src/templates/_settings.twig b/src/templates/_settings.twig index 165f0bb..54e2197 100755 --- a/src/templates/_settings.twig +++ b/src/templates/_settings.twig @@ -45,6 +45,24 @@ errors: settings.getErrors('honeypotField') }) }} +{{ forms.lightswitchField({ + label: "Enable Query String Caching" | t, + id: 'queryStringCaching', + name: 'queryStringCaching', + instructions: "Enable the caching of a urls with query strings" | t, + errors: settings.getErrors('queryStringCaching'), + on: settings.queryStringCaching +}) }} + +{{ forms.lightswitchField({ + label: "Disable Preview Cache" | t, + id: 'disablePreviewCache', + name: 'disablePreviewCache', + instructions: "Disable the caching of a preview url, this prevents a draft from being publicly accessible" | t, + errors: settings.getErrors('disablePreviewCache'), + on: settings.disablePreviewCache +}) }} + {{ forms.lightswitchField({ label: "Purge Cache now?" | t, id: 'purgeCache', @@ -72,7 +90,7 @@ cols: [ { heading: 'Excluded paths' | t, - info: 'Enter precise URL paths or regular expressions without the siteURL part as they are returned by \Craft::$app->request->getFullPath(), like "any/page" insteadof "https://example.com/site-specific/path/any/page".' | t, + info: 'Enter precise URL paths or regular expressions without the siteURL part as they are returned by \Craft::$app->getRequest()->getFullPath(), like "any/page" insteadof "https://example.com/site-specific/path/any/page".' | t, type: 'singleline', placeholder: 'path/to/excluded/page OR regex like path/.*/excluded/.*', }, diff --git a/src/templates/_utility.twig b/src/templates/_utility.twig new file mode 100644 index 0000000..e3d5e67 --- /dev/null +++ b/src/templates/_utility.twig @@ -0,0 +1,12 @@ +{% import "_includes/forms" as forms %} + +

{{ "Clear Caches"|t('html-cache') }}

+ +
+ {{ actionInput('html-cache/cache/clear-caches') }} + {{ csrfInput() }} +
+ +
+
+
diff --git a/src/utilities/CacheUtility.php b/src/utilities/CacheUtility.php new file mode 100644 index 0000000..e7eceda --- /dev/null +++ b/src/utilities/CacheUtility.php @@ -0,0 +1,52 @@ +getView()->renderTemplate('html-cache/_utility'); + } +} +