Skip to content

Instantly share code, notes, and snippets.

@kinglozzer
Created March 24, 2021 14:20
Show Gist options
  • Save kinglozzer/f71506c54adddb0e192d3aac14069ebc to your computer and use it in GitHub Desktop.
Save kinglozzer/f71506c54adddb0e192d3aac14069ebc to your computer and use it in GitHub Desktop.
Elemental + cacheinclude example
---
After: 'cacheinclude'
---
SilverStripe\ORM\DataObject:
extensions:
- 'Heyday\CacheInclude\SilverStripe\InvalidationExtension'
SilverStripe\Core\Injector\Injector:
SilverStripe\View\SSTemplateParser:
properties:
closedBlocks:
cache: 'App\Cache\TemplateParserBlockProvider::cacheTemplate'
PerDataObjectCacheKeyCreator:
class: 'App\Cache\PerDataObjectCacheKeyCreator'
CacheIncludeConfig:
class: 'Heyday\CacheInclude\Configs\ArrayConfig'
properties:
Config:
ElementFeatureBoxes:
context: no
contains:
- 'App\Model\Elements\Components\FeatureBox'
- 'App\Model\Elements\ElementFeatureBoxes'
- 'SilverStripe\Assets\Image'
- 'SilverStripe\CMS\Model\SiteTree'
<% cache 'ElementFeatureBoxes', 'PerDataObjectCacheKeyCreator', 'CacheInclude', $ClassName, $ID %>
loop elements etc
<% end_cache %>
<?php
namespace App\Cache;
use Heyday\CacheInclude\KeyCreators\KeyCreatorInterface;
use SilverStripe\Core\Injector\Injector;
class PerDataObjectCacheKeyCreator implements KeyCreatorInterface
{
/**
* @var KeyCreatorInterface
*/
protected $nestedKeyCreator;
/**
* @var string
*/
protected $className;
/**
* @var int
*/
protected $id;
/**
* PerDataObjectCacheKeyCreator constructor.
* @param string $className
* @param int $id
*/
public function __construct($className, $id)
{
$this->nestedKeyCreator = Injector::inst()->get('CacheIncludeKeyCreator');
$this->className = $className;
$this->id = $id;
}
public function getKey($name, $config)
{
$keyParts = $this->nestedKeyCreator->getKey($name, $config);
$keyParts[] = md5($this->className) . '_' . $this->id;
return $keyParts;
}
}
<?php
namespace App\Cache;
use InvalidArgumentException;
class TemplateParserBlockProvider
{
/**
* Allows the use of a <% cache 'ConfigName' %><% end_cache %> syntax in templates
*
* Also supports the optional specification of a key creator and a cache include instance
*
* Extended from cacheinclude default block provider to allow per-record cache keys
*
* <% cache 'ConfigName', 'PerDataObjectCacheKeyCreator', 'CacheInclude', $ClassName, $ID %><% end_cache %>
*
* @param $res
* @throws InvalidArgumentException
* @return string
*/
public static function cacheTemplate($res)
{
$arguments = $res['Arguments'] ?? [];
$configNameArg = array_shift($arguments);
if (!isset($res['Arguments']) || !isset($res['Arguments'][0])) {
throw new InvalidArgumentException('A config name must be passed into <% cache %>');
}
$keyCreatorArg = array_shift($arguments);
$cacheIncludeArg = array_shift($arguments);
$configName = $configNameArg['text'];
$keyCreator = $keyCreatorArg ? $keyCreatorArg['text'] : "'CacheIncludeKeyCreator'";
$cacheInclude = $cacheIncludeArg ? $cacheIncludeArg['text'] : "'CacheInclude'";
$additionalKeyCreatorArgs = [];
foreach ($arguments as $arg) {
$additionalKeyCreatorArgs[] = str_replace('$$FINAL', 'XML_val', $arg['php']);
}
$stringArgs = '[' . implode(', ', $additionalKeyCreatorArgs) . ']';
return <<<PHP
\$val .= \SilverStripe\Core\Injector\Injector::inst()->get({$cacheInclude})->process(
{$configName},
function () use (\$scope) {
\$val = '';
{$res['Template']['php']} return \$val;
},
\SilverStripe\Core\Injector\Injector::inst()->createWithArgs({$keyCreator}, {$stringArgs})
);
PHP;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment