* All rights reserved * * This script is part of the TYPO3 project. The TYPO3 project is * free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. * * The GNU General Public License can be found at * http://www.gnu.org/copyleft/gpl.html. * * This script is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * This copyright notice MUST APPEAR in all copies of the script! ***************************************************************/ use WapplerSystems\Meilisearch\ConnectionManager; use WapplerSystems\Meilisearch\GarbageCollectorPostProcessor; use WapplerSystems\Meilisearch\IndexQueue\Queue; use WapplerSystems\Meilisearch\System\Meilisearch\MeilisearchConnection; use TYPO3\CMS\Core\Utility\GeneralUtility; /** * An implementation ob a garbage remover strategy is responsible to remove all garbage from the index queue and * the meilisearch server for a certain table and uid combination. */ abstract class AbstractStrategy { /** * @var Queue */ protected $queue; /** * @var ConnectionManager */ protected $connectionManager; /** * AbstractStrategy constructor. * @param Queue|null $queue * @param ConnectionManager|null $connectionManager */ public function __construct(Queue $queue = null, ConnectionManager $connectionManager = null) { $this->queue = $queue ?? GeneralUtility::makeInstance(Queue::class); $this->connectionManager = $connectionManager ?? GeneralUtility::makeInstance(ConnectionManager::class); } /** * Call's the removal of the strategy and afterwards the garbagecollector post processing hook. * * @param string $table * @param int $uid * @return mixed */ public function removeGarbageOf($table, $uid) { $this->removeGarbageOfByStrategy($table, $uid); $this->callPostProcessGarbageCollectorHook($table, $uid); } /** * A implementation of the GarbageCollection strategy is responsible to remove the garbage from * the indexqueue and from the meilisearch server. * * @param string $table * @param int $uid * @return mixed */ abstract protected function removeGarbageOfByStrategy($table, $uid); /** * Deletes a document from meilisearch and from the index queue. * * @param string $table * @param integer $uid */ protected function deleteInMeilisearchAndRemoveFromIndexQueue($table, $uid) { $this->deleteIndexDocuments($table, $uid); $this->queue->deleteItem($table, $uid); } /** * Deletes a document from meilisearch and updates the item in the index queue (e.g. on page content updates). * * @param string $table * @param integer $uid */ protected function deleteInMeilisearchAndUpdateIndexQueue($table, $uid) { $this->deleteIndexDocuments($table, $uid); $this->queue->updateItem($table, $uid); } /** * Deletes index documents for a given record identification. * * @param string $table The record's table name. * @param int $uid The record's uid. */ protected function deleteIndexDocuments($table, $uid, $language = 0) { // record can be indexed for multiple sites $indexQueueItems = $this->queue->getItems($table, $uid); foreach ($indexQueueItems as $indexQueueItem) { $site = $indexQueueItem->getSite(); $enableCommitsSetting = $site->getMeilisearchConfiguration()->getEnableCommits(); $siteHash = $site->getSiteHash(); // a site can have multiple connections (cores / languages) $meilisearchConnections = $this->connectionManager->getConnectionBySite($site); if ($language > 0) { $meilisearchConnections = [$language => $meilisearchConnections[$language]]; } $this->deleteRecordInAllMeilisearchConnections($table, $uid, $meilisearchConnections, $siteHash, $enableCommitsSetting); } } /** * Deletes the record in all meilisearch connections from that site. * * @param string $table * @param int $uid * @param MeilisearchConnection[] $meilisearchConnections * @param string $siteHash * @param boolean $enableCommitsSetting */ protected function deleteRecordInAllMeilisearchConnections($table, $uid, $meilisearchConnections, $siteHash, $enableCommitsSetting) { foreach ($meilisearchConnections as $meilisearch) { $meilisearch->getWriteService()->deleteByQuery('type:' . $table . ' AND uid:' . (int)$uid . ' AND siteHash:' . $siteHash); if ($enableCommitsSetting) { $meilisearch->getWriteService()->commit(false, false); } } } /** * Calls the registered post processing hooks after the garbageCollection. * * @param string $table * @param int $uid */ protected function callPostProcessGarbageCollectorHook($table, $uid) { if (!is_array($GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['meilisearch']['postProcessGarbageCollector'])) { return; } foreach ($GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['meilisearch']['postProcessGarbageCollector'] as $classReference) { $garbageCollectorPostProcessor = GeneralUtility::makeInstance($classReference); if ($garbageCollectorPostProcessor instanceof GarbageCollectorPostProcessor) { $garbageCollectorPostProcessor->postProcessGarbageCollector($table, $uid); } else { $message = get_class($garbageCollectorPostProcessor) . ' must implement interface ' . GarbageCollectorPostProcessor::class; throw new \UnexpectedValueException($message, 1345807460); } } } }