Voraussetzung hierfür ist zumindest ein Basis-Wissen über den TYPO3-Cache, gute Informationen hierüber findet man zBsp. hier, hier oder hier. Damit man sich das Problem am besten vorstellen kann, gehen wir das anhand der News-Erweiterung durch. Es gibt News-Objekte und diese werden über ein News-Detail-Plugin auf einer einzelnen Seite ausgegeben. Ändert sich nun ein News-Beitrag, möchte ich nicht den Cache aller News-Einträge leeren, sondern nur für dieses eine Objekt, standardmäßig bietet hierfür TYPO3 keine Funktion.
Prinzipiell wird anhand der URL ein cHash generiert und anhand diesen dann in der cf_cache_pages die fertige Seite abgelegt. Ruft ein Benutzer nun nochmals diese Seite auf, wird zuerst überprüft ob für diesen cHash ein Eintrag besteht, wenn ja wird dieser gerendert (und nicht nochmals alle Berechnungen durchgeführt). Dies bringt einen erheblichen Performance-Boost.
Ich habe hierfür einen kleinen Trick verwendet: Ich verwende den createHashBase-Hook. Dieser Hook wird immer aufgerufen wenn der identifier für eine Seite berechnet wird. Hier überprüfe ich ob hier in den Argumenten das Plugin aufscheint, welches ich suche, und falls ja speichere ich mir die Zuweisung identifier Objekt-Uid in einer Tabelle zwischen. Will ich nun bei der Aktualisierung den Cache eines einzelnen Objektes leeren, muss ich nur noch die identifiers für dieses Objekt suchen und anhand deeren alle Einträge aus der cf_cache_pages-Tabelle entfernen.
1. Hook registrieren
$GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['tslib/class.tslib_fe.php']['createHashBase'][] =
'Varioous\Hooks\HashHook->createHashBase';
2. Hook implementierung
public function createHashBase(&$params, $ref)
{
if(isset($params['hashParameters'])) {
//45 Ist die Page-Uid auf welcher das Plugin sitzt
if(!is_null($params['hashParameters']['id']) && intval($params['hashParameters']['id']) == 45) {
//Es handelt sich um diese Seite -> check ob das Plugin vorhanden ist
if(isset($params['hashParameters']['staticRouteArguments']['tx_vatest_detail']['test'])) {
//Die id des objektes holen
$propertyId = intval($params['hashParameters']['staticRouteArguments']['tx_vatest_detail']['test']);
$objectManager =
\TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance(\TYPO3\CMS\Extbase\Object\ObjectManager::class);
$propertycacheRepository = $objectManager->get(\Varioous\Domain\Repository\PropertycacheRepository::class);
$persistenceManager = $objectManager->get(\TYPO3\CMS\Extbase\Persistence\Generic\PersistenceManager::class);
//calculate identifier (same as in cf_cache_pages)
$hash = md5(serialize($params['hashParameters']));
//save data
$propertyCache = new \Varioous\Domain\Model\Propertycache();
$propertyCache->setIdentifier($hash);
$propertyCache->setProperty($propertyId);
$propertycacheRepository->add($propertyCache);
$persistenceManager->persistAll();
}
}
}
}
3. Objekt aktualisieren
//update extbase object
$propertyObject = $propertyRepository->findByUid(5);
$propertyObject->setTitle("test");
$propertyRepository->update($propertyObject);
$persistenceManager->persistAll();
Normalerweise würde ich nun die Seite zBsp. „https://varioous.test/objekt/5″ aufrufen, wäre noch immer die gecachte Seite sichtbar (und nicht der neue Titel).
3. Cache leeren
//alle Objekte aus der Hilfstabelle für das objekt mit der id=5 holen
$propertyCaches = $propertycacheRepository->findByPropertyIdentifier(5);
foreach ($propertyCaches as $cacheEntry) {
//Einträge aus der cf_cache_pages Tabelle leeren
$queryBuilder =
GeneralUtility::makeInstance(ConnectionPool::class)->getQueryBuilderForTable('cf_cache_pages');
$queryBuilder->delete('cf_cache_pages')->where($queryBuilder->expr()
->like('identifier',
$queryBuilder->createNamedParameter('%' . $cacheEntry->getIdentifier() . '%')));
$queryBuilder->execute();
$persistenceManager->persistAll();
}
//Seite aufrufen, damit der cache mit dem neuen Titel wieder aufgebaut wird
self::crawlProperty($propertyObject->getSlug(), $baseUrl);
Wir entwickeln digitale Lösungen mit Leidenschaft
Warum wir das tun? Weil die Verwirklichung Ihrer Vision unser größter Anspruch und die schönste Anerkennung ist. Deshalb nehmen wir uns gerne ausreichend Zeit für die Realisierung Ihres digitalen Projekts.
Kontaktieren Sie uns, wir sind gerne für Ihre Fragen da: