Created
November 13, 2013 11:43
-
-
Save bwaidelich/7447752 to your computer and use it in GitHub Desktop.
A simple TYPO3 Fluid ViewHelper that caches its content based on some variables
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Your_Package_ViewHelpers_CacheViewHelper_CacheFrontend: | |
| frontend: TYPO3\Flow\Cache\Frontend\StringFrontend | |
| backend: TYPO3\Flow\Cache\Backend\SimpleFileBackend |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?php | |
| namespace Your\Package\ViewHelpers; | |
| /* * | |
| * This script belongs to the TYPO3 Flow package "Your.Package". * | |
| * */ | |
| use TYPO3\Flow\Annotations as Flow; | |
| use TYPO3\Flow\Cache\Frontend\StringFrontend; | |
| use TYPO3\Flow\Persistence\PersistenceManagerInterface; | |
| use TYPO3\Flow\Utility\Arrays; | |
| use TYPO3\Fluid\Core\ViewHelper\AbstractViewHelper; | |
| use TYPO3\Fluid\Core\ViewHelper\Exception; | |
| use TYPO3\Fluid\Core\ViewHelper\Facets\ChildNodeAccessInterface; | |
| /** | |
| * View Helper that caches all its contents based on some (optional) variables | |
| * | |
| * = Examples = | |
| * | |
| * <code title="independent cache w/o variables"> | |
| * <x:cache>This is cached</x:cache> | |
| * </code> | |
| * <output> | |
| * This is cached | |
| * // will be cached until the caches are flushed manually | |
| * </output> | |
| * | |
| * <code title="Cache based on a variable"> | |
| * <x:cache variables="{user: user}">This is cached: {user.name}</x:cache> | |
| * </code> | |
| * <output> | |
| * This is cached: <bar> | |
| * // depending on the {user} identity but NOT depending on the users name! To achieve this see next example | |
| * </output> | |
| * | |
| * <code title="Cache based on multiple variables"> | |
| * <x:cache variables="{user: user, name: user.name}">This is cached: {user.name}</x:cache> | |
| * </code> | |
| * <output> | |
| * This is cached: <bar> | |
| * // depending on the {user} identity *and* it's name. If you only specify the name, all occurrences with the same name variable will create the same cache identifier | |
| * </output> | |
| * | |
| * <code title="Inline syntax"> | |
| * {user.name -> x:cache(variables: '{user: user}')} | |
| * </code> | |
| * <output> | |
| * John Doe | |
| * // depending on the {user} identity | |
| * </output> | |
| */ | |
| class CacheViewHelper extends AbstractViewHelper implements ChildNodeAccessInterface { | |
| /** | |
| * @Flow\Inject | |
| * @var PersistenceManagerInterface | |
| */ | |
| protected $persistenceManager; | |
| /** | |
| * @Flow\Inject | |
| * @var StringFrontend | |
| */ | |
| protected $cacheFrontend; | |
| /** | |
| * @var array<AbstractNode> | |
| */ | |
| private $childNodes = array(); | |
| /** | |
| * Renders the child nodes of this ViewHelper or fetches those from the cache, if found | |
| * | |
| * @param array $variables variables that affect the cache identifier | |
| * @param string $value optional content that will be used instead of child nodes if specified | |
| * @return string | |
| */ | |
| public function render(array $variables, $value = NULL) { | |
| $cacheIdentifier = $this->buildCacheIdentifier(); | |
| if (!$this->cacheFrontend->has($cacheIdentifier)) { | |
| if ($value === NULL) { | |
| $value = $this->renderChildren(); | |
| } | |
| $this->cacheFrontend->set($cacheIdentifier, $value); | |
| return $value; | |
| } | |
| return $this->cacheFrontend->get($cacheIdentifier); | |
| } | |
| /** | |
| * Sets the direct child nodes of the current syntax tree node. | |
| * | |
| * @param array<AbstractNode> $childNodes | |
| * @return void | |
| */ | |
| public function setChildNodes(array $childNodes) { | |
| $this->childNodes = $childNodes; | |
| } | |
| /** | |
| * @return string | |
| */ | |
| protected function buildCacheIdentifier() { | |
| $variables = $this->convertObjectsToHashes($this->arguments['variables']); | |
| Arrays::sortKeysRecursively($variables); | |
| return md5(http_build_query($variables)); | |
| } | |
| /** | |
| * Recursively converts objects in an array to their identifiers | |
| * | |
| * @param array $values the array to be processed | |
| * @return array the modified array | |
| * @throws Exception if $values contain an object and its identifier could not be determined | |
| */ | |
| protected function convertObjectsToHashes(array $values) { | |
| foreach ($values as &$value) { | |
| if (is_object($value)) { | |
| $identifier = $this->persistenceManager->getIdentifierByObject($value); | |
| if ($identifier === NULL) { | |
| throw new Exception(sprintf('The identifier of an object of type "%s" could not be determined', get_class($value)), 1384341157); | |
| } | |
| $value = $identifier; | |
| } elseif (is_array($value)) { | |
| $value = $this->convertObjectsToHashes($value); | |
| } | |
| } | |
| return $values; | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Your\Package\ViewHelpers\CacheViewHelper: | |
| properties: | |
| cacheFrontend: | |
| object: | |
| factoryObjectName: 'TYPO3\Flow\Cache\CacheManager' | |
| factoryMethodName: 'getCache' | |
| arguments: | |
| 1: | |
| value: 'Your_Package_ViewHelpers_CacheViewHelper_CacheFrontend' |
Author
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Usage:
Disclaimer: Only use this as preliminary to increase performance - it is error prone and to be replaced with proper caching mechanisms!