Skip to content

Instantly share code, notes, and snippets.

@jonom
Last active May 21, 2024 06:59
Show Gist options
  • Save jonom/0c60830c5326922dd308de6573edd938 to your computer and use it in GitHub Desktop.
Save jonom/0c60830c5326922dd308de6573edd938 to your computer and use it in GitHub Desktop.
Silverstripe partial caching methods
<?php
use SilverStripe\CMS\Controllers\ContentController;
use SilverStripe\Control\Director;
use SilverStripe\Core\Environment;
/**
* Below are some methods that can be added to PageController for use in partial caching blocks.
* Example: <% cached $EnvCacheKey, $ClassCacheKey('SilverStripe\CMS\Model\SiteTree') unless $DontCache %>
*/
class PageController extends ContentController
{
/**
* Generate a cache key for the current environment.
*
* @return string
*/
public function EnvCacheKey()
{
return __FUNCTION__ . md5(serialize([
// Dev mode can affect output
Director::get_environment_type(),
// Split cache by protocol to prevent accidental mixed-content issues
Director::protocolAndHost(),
]));
}
public function TodayCacheKey()
{
// Reset cache every day to ensure date based content is accurate
return __FUNCTION__ . date('Y-m-d');
}
/**
* Get a cache key which represents the approximate state of a page
*
* @param string $class
* @return string
*/
public function PageCacheKey()
{
return __FUNCTION__ . md5(serialize([
static::class,
// Identify by ID, or URL as a fallback. Note that Security pages (and maybe others?)
// generate a random ID so the fallback may be redundant
$this->ID ? $this->ID : $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'],
$this->request->params(),
$this->LastEdited,
]));
}
/**
* Get a cache key which get the approximate state of a class.
* Will not capture things like sort order if changes bypass the ORM.
*
* @param string $class
* @return string
*/
public function ClassCacheKey($class)
{
return __FUNCTION__ . md5(serialize([
$class,
$class::get()->max('LastEdited'), // Catch created / edited
$class::get()->count(), // Catch deleted
]));
}
/**
* Use on a ManyManyList or potentially a DataList HasManyList.
*
* Generate a cache key that covers:
* - Which items are in this list
* - The sort order of these items
* - The most recent LastEdited value
*
* Note that for a DataList or HasManyList ClassCacheKey() should generally
* be sufficient to invalidate when something changes.
*
* @param mixed $dataList
* @return void
*/
public function ListCacheKey($dataList)
{
return md5(serialize([
// Namespace for this cacheblock
$dataList->dataClass(),
// This covers which objects are linked and their sort order
$dataList->column('ID'),
// This catches edits
$dataList->max('LastEdited'),
]));
}
/**
* Caching can be temporarily disabled by setting environmental
* variable SS_DISABLE_PARTIAL_CACHING to true.
* Add any other logical tests here that should prevent caching.
*/
public function DontCache()
{
return Environment::getEnv('SS_DISABLE_PARTIAL_CACHING');
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment