TYPO3 Tipps und Tricks:
Cache für einzelne Extbase-Objekte leeren

Kürzlich bin ich bei einem Projekt vor folgendem Problem gestanden: Per Plugin werden Extbase-Objekte auf einer Seite ausgegeben und diese auch gecached (cf_cache_pages) - ähnlich wie wir das zBsp. von der "news"-Extension kennen. Nun wird über eine Schnittstelle (API) eines dieser Objekte aktualisiert, und danach muss natürlich auch der Cache geleert werden, damit die Änderung im Frontend ersichtlich ist. Wie man den Cache von diesem einem Objekt leeren kann, und nicht von der ganzen Seite oder allen anderen Objekten (vom gleichen Typ), beschreibe ich in diesem Blogbeitrag.

Voraussetzung hierfür ist zumindest ein Basis-Wissen über den TYPO3-Cache, gute Informationen hierüber findet man zBsp. hierhier 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 wirdself::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:

Passend zu diesem Thema:

TYPO3 Indexed Search mit Segmentierung/Indexierung

TYPO3 Indexed Search mit Segmentierung/Indexierung

In diesem Blogbeitrag will ich Euch den Einsatz der Such-Erweiterung "indexed_search" zeigen und anhand eines Beispiels näher bringen. Wir werden uns …

TYPO3 Award 2019

TYPO3 Award 2019

Wir wurden dieses Jahr gleich dreimal für den TYPO3 Award in den Kategorien "Industry", "Non-governmental organization" und "Finance / Logistic" nomin…

TYPO3 9 Bild-Slider

TYPO3 9 Bild-Slider

Aus der Reihe "Custom Content Elements". Im heutigen Blog-Beitrag zeige ich euch kurz, wie man innerhalb kürzester Zeit einen einfachen Bild-Slider al…