Passed
Push — release-11.5.x ( eab588...506b54 )
by Rafael
49:07 queued 25:53
created

AbstractStrategy::removeGarbageOf()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 3
CRAP Score 1

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 2
c 1
b 0
f 0
dl 0
loc 4
ccs 3
cts 3
cp 1
rs 10
cc 1
nc 1
nop 2
crap 1
1
<?php
2
3
/*
4
 * This file is part of the TYPO3 CMS project.
5
 *
6
 * It is free software; you can redistribute it and/or modify it under
7
 * the terms of the GNU General Public License, either version 2
8
 * of the License, or any later version.
9
 *
10
 * For the full copyright and license information, please read the
11
 * LICENSE.txt file that was distributed with this source code.
12
 *
13
 * The TYPO3 project - inspiring people to share!
14
 */
15
16
namespace ApacheSolrForTypo3\Solr\Domain\Index\Queue\GarbageRemover;
17
18
use ApacheSolrForTypo3\Solr\ConnectionManager;
19
use ApacheSolrForTypo3\Solr\GarbageCollectorPostProcessor;
20
use ApacheSolrForTypo3\Solr\IndexQueue\Queue;
21
use ApacheSolrForTypo3\Solr\System\Solr\SolrConnection;
22
use TYPO3\CMS\Core\Utility\GeneralUtility;
23
24
/**
25
 * An implementation ob a garbage remover strategy is responsible to remove all garbage from the index queue and
26
 * the solr server for a certain table and uid combination.
27
 */
28
abstract class AbstractStrategy
29
{
30
    /**
31
     * @var Queue
32
     */
33
    protected Queue $queue;
34
35
    /**
36
     * @var ConnectionManager
37
     */
38
    protected ConnectionManager $connectionManager;
39
40
    /**
41
     * AbstractStrategy constructor.
42
     * @param Queue|null $queue
43
     * @param ConnectionManager|null $connectionManager
44
     */
45 22
    public function __construct(
46
        Queue $queue = null,
47
        ConnectionManager $connectionManager = null
48
    ) {
49 22
        $this->queue = $queue ?? GeneralUtility::makeInstance(Queue::class);
50 22
        $this->connectionManager = $connectionManager ?? GeneralUtility::makeInstance(ConnectionManager::class);
51
    }
52
53
    /**
54
     * Call's the removal of the strategy and afterwards the garbage-collector post-processing hook.
55
     *
56
     * @param string $table
57
     * @param int $uid
58
     */
59 22
    public function removeGarbageOf(string $table, int $uid)
60
    {
61 22
        $this->removeGarbageOfByStrategy($table, $uid);
62 22
        $this->callPostProcessGarbageCollectorHook($table, $uid);
63
    }
64
65
    /**
66
     * An implementation of the GarbageCollection strategy is responsible to remove the garbage from
67
     * the indexqueue and from the solr server.
68
     *
69
     * @param string $table
70
     * @param int $uid
71
     */
72
    abstract protected function removeGarbageOfByStrategy(string $table, int $uid);
73
74
    /**
75
     * Deletes a document from solr and from the index queue.
76
     *
77
     * @param string $table
78
     * @param int $uid
79
     */
80 14
    protected function deleteInSolrAndRemoveFromIndexQueue(string $table, int $uid)
81
    {
82 14
        $this->deleteIndexDocuments($table, $uid);
83 14
        $this->queue->deleteItem($table, $uid);
84
    }
85
86
    /**
87
     * Deletes a document from solr and updates the item in the index queue (e.g. on page content updates).
88
     *
89
     * @param string $table
90
     * @param int $uid
91
     */
92 8
    protected function deleteInSolrAndUpdateIndexQueue(string $table, int $uid)
93
    {
94 8
        $this->deleteIndexDocuments($table, $uid);
95 8
        $this->queue->updateItem($table, $uid);
96
    }
97
98
    /**
99
     * Deletes index documents for a given record identification.
100
     *
101
     * @param string $table The record's table name.
102
     * @param int $uid The record's uid.
103
     */
104 22
    protected function deleteIndexDocuments(string $table, int $uid, int $language = 0)
105
    {
106
        // record can be indexed for multiple sites
107 22
        $indexQueueItems = $this->queue->getItems($table, $uid);
108 22
        foreach ($indexQueueItems as $indexQueueItem) {
109 19
            $site = $indexQueueItem->getSite();
110 19
            $enableCommitsSetting = $site->getSolrConfiguration()->getEnableCommits();
111 19
            $siteHash = $site->getSiteHash();
112
            // a site can have multiple connections (cores / languages)
113 19
            $solrConnections = $this->connectionManager->getConnectionsBySite($site);
114 19
            if ($language > 0 && isset($solrConnections[$language])) {
115
                $solrConnections = [$language => $solrConnections[$language]];
116
            }
117 19
            $this->deleteRecordInAllSolrConnections($table, $uid, $solrConnections, $siteHash, $enableCommitsSetting);
118
        }
119
    }
120
121
    /**
122
     * Deletes the record in all solr connections from that site.
123
     *
124
     * @param string $table
125
     * @param int $uid
126
     * @param SolrConnection[] $solrConnections
127
     * @param string $siteHash
128
     * @param bool $enableCommitsSetting
129
     */
130 19
    protected function deleteRecordInAllSolrConnections(
131
        string $table,
132
        int $uid,
133
        array $solrConnections,
134
        string $siteHash,
135
        bool $enableCommitsSetting
136
    ) {
137 19
        foreach ($solrConnections as $solr) {
138 19
            $solr->getWriteService()->deleteByQuery(
139 19
                'type:' . $table . ' AND uid:' . $uid . ' AND siteHash:' . $siteHash
140
            );
141 19
            if ($enableCommitsSetting) {
142 19
                $solr->getWriteService()->commit(false, false);
143
            }
144
        }
145
    }
146
147
    /**
148
     * Calls the registered post-processing hooks after the garbageCollection.
149
     *
150
     * @param string $table
151
     * @param int $uid
152
     */
153 22
    protected function callPostProcessGarbageCollectorHook(string $table, int $uid)
154
    {
155 22
        if (!is_array($GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['solr']['postProcessGarbageCollector'] ?? null)) {
156 20
            return;
157
        }
158
159 2
        foreach ($GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['solr']['postProcessGarbageCollector'] as $classReference) {
160 2
            $garbageCollectorPostProcessor = GeneralUtility::makeInstance($classReference);
161
162 2
            if ($garbageCollectorPostProcessor instanceof GarbageCollectorPostProcessor) {
163 2
                $garbageCollectorPostProcessor->postProcessGarbageCollector($table, $uid);
164
            } else {
165
                $message = get_class($garbageCollectorPostProcessor) . ' must implement interface ' .
166
                    GarbageCollectorPostProcessor::class;
167
                throw new \UnexpectedValueException($message, 1345807460);
168
            }
169
        }
170
    }
171
}
172