Skip to content

Instantly share code, notes, and snippets.

@h3nn3s
Created April 3, 2023 04:21
Show Gist options
  • Save h3nn3s/b829b9dada68b84fefbd3a0ac2f42786 to your computer and use it in GitHub Desktop.
Save h3nn3s/b829b9dada68b84fefbd3a0ac2f42786 to your computer and use it in GitHub Desktop.
Hook into Tcemain to clear custom cachetags
<?php
namespace Vendor\Extension\Hooks;
use TYPO3\CMS\Backend\Utility\BackendUtility;
use TYPO3\CMS\Core\Cache\CacheManager;
use TYPO3\CMS\Core\Cache\Exception\NoSuchCacheGroupException;
use TYPO3\CMS\Core\Database\ReferenceIndex;
use TYPO3\CMS\Core\SingletonInterface;
use TYPO3\CMS\Core\Utility\ExtensionManagementUtility;
use TYPO3\CMS\Core\Utility\GeneralUtility;
/**
* Hook into tcemain to clear the cachetags
*/
class DataHandler implements SingletonInterface
{
protected array $cacheTagsToFlush = [];
/**
* [$tablename][$uid] = number of references to this record
*
* @var int[][]
*/
protected array $referenceCount = [];
/**
* Flushes the cache if a tt_content record was edited, when it has references set by shortcut CE
* This happens on two levels: by UID and by PID.
*
* @param array $params
*
* @return void
* @throws NoSuchCacheGroupException
*/
public function clearCachePostProc(array $params): void
{
$table = $params['table'];
$uid = $params['uid'];
$cacheManager = GeneralUtility::makeInstance(CacheManager::class);
if (isset($table, $uid) && $table === 'tt_content') {
if ($this->getReferenceCount($table, $uid) > 0) {
$this->cacheTagsToFlush[] = 'shortcut_' . $table . '_' . $uid;
}
$emUtility = GeneralUtility::makeInstance(ExtensionManagementUtility::class);
// If EXT:flux is loaded, we need to check if the current element is a child record
// In flux we can guess this by cutting off the last two digits from `colPos` value and check is this
// new colPos value equals an uid in tt_content table
if ($emUtility::isLoaded('flux')) {
$element = BackendUtility::getRecord(
$table,
$uid
);
$uidOfParent = substr($element['colPos'], 0, -2);
$parentElement = BackendUtility::getRecord(
$table,
$uidOfParent
);
if (isset($parentElement) && $this->getReferenceCount($table, $uidOfParent) > 0) {
$this->cacheTagsToFlush[] = 'shortcut_' . $table . '_' . $uidOfParent;
}
}
// If EXT:gridelements is loaded, we need to check if the current element is a child record
// @todo
#if ($emUtility::isLoaded('gridelements')) {
#}
// If EXT:gridelements is loaded, we need to check if the current element is a child record
// @todo
#if ($emUtility::isLoaded('container')) {
#}
}
if (!empty($this->cacheTagsToFlush)) {
foreach (array_unique($this->cacheTagsToFlush) as $cacheTag) {
$cacheManager->flushCachesInGroupByTag('pages', $cacheTag);
}
}
}
/**
* Gets the number of records referencing the record with the UID $uid in
* the table $tableName.
*
* @param string $tableName
* @param int $uid
* @return int The number of references to record $uid in table
*/
protected function getReferenceCount($tableName, $uid)
{
if (!isset($this->referenceCount[$tableName][$uid])) {
$referenceIndex = GeneralUtility::makeInstance(ReferenceIndex::class);
$numberOfReferences = $referenceIndex->getNumberOfReferencedRecords($tableName, $uid);
$this->referenceCount[$tableName][$uid] = $numberOfReferences;
}
return $this->referenceCount[$tableName][$uid];
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment