Passed
Pull Request — release-11.5.x (#3537)
by
unknown
33:52
created

AbstractStrategy   A

Complexity

Total Complexity 16

Size/Duplication

Total Lines 146
Duplicated Lines 0 %

Test Coverage

Coverage 90.48%

Importance

Changes 3
Bugs 0 Features 0
Metric Value
wmc 16
eloc 39
c 3
b 0
f 0
dl 0
loc 146
ccs 38
cts 42
cp 0.9048
rs 10

7 Methods

Rating   Name   Duplication   Size   Complexity  
A deleteRecordInAllSolrConnections() 0 13 3
A __construct() 0 6 1
A removeGarbageOf() 0 4 1
A deleteInSolrAndRemoveFromIndexQueue() 0 4 1
A deleteIndexDocuments() 0 20 5
A callPostProcessGarbageCollectorHook() 0 15 4
A deleteInSolrAndUpdateIndexQueue() 0 4 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 InvalidArgumentException;
23
use TYPO3\CMS\Core\Utility\GeneralUtility;
24
25
/**
26
 * An implementation ob a garbage remover strategy is responsible to remove all garbage from the index queue and
27
 * the solr server for a certain table and uid combination.
28
 */
29
abstract class AbstractStrategy
30
{
31
    /**
32
     * @var Queue
33
     */
34
    protected Queue $queue;
35
36
    /**
37
     * @var ConnectionManager
38
     */
39
    protected ConnectionManager $connectionManager;
40
41
    /**
42
     * AbstractStrategy constructor.
43
     * @param Queue|null $queue
44
     * @param ConnectionManager|null $connectionManager
45
     */
46 25
    public function __construct(
47
        Queue $queue = null,
48
        ConnectionManager $connectionManager = null
49
    ) {
50 25
        $this->queue = $queue ?? GeneralUtility::makeInstance(Queue::class);
51 25
        $this->connectionManager = $connectionManager ?? GeneralUtility::makeInstance(ConnectionManager::class);
52
    }
53
54
    /**
55
     * Call's the removal of the strategy and afterwards the garbage-collector post-processing hook.
56
     *
57
     * @param string $table
58
     * @param int $uid
59
     */
60 25
    public function removeGarbageOf(string $table, int $uid)
61
    {
62 25
        $this->removeGarbageOfByStrategy($table, $uid);
63 25
        $this->callPostProcessGarbageCollectorHook($table, $uid);
64
    }
65
66
    /**
67
     * An implementation of the GarbageCollection strategy is responsible to remove the garbage from
68
     * the indexqueue and from the solr server.
69
     *
70
     * @param string $table
71
     * @param int $uid
72
     */
73
    abstract protected function removeGarbageOfByStrategy(string $table, int $uid);
74
75
    /**
76
     * Deletes a document from solr and from the index queue.
77
     *
78
     * @param string $table
79
     * @param int $uid
80
     */
81 14
    protected function deleteInSolrAndRemoveFromIndexQueue(string $table, int $uid)
82
    {
83 14
        $this->deleteIndexDocuments($table, $uid);
84 14
        $this->queue->deleteItem($table, $uid);
85
    }
86
87
    /**
88
     * Deletes a document from solr and updates the item in the index queue (e.g. on page content updates).
89
     *
90
     * @param string $table
91
     * @param int $uid
92
     */
93 11
    protected function deleteInSolrAndUpdateIndexQueue(string $table, int $uid)
94
    {
95 11
        $this->deleteIndexDocuments($table, $uid);
96 11
        $this->queue->updateItem($table, $uid);
97
    }
98
99
    /**
100
     * Deletes index documents for a given record identification.
101
     *
102
     * @param string $table The record's table name.
103
     * @param int $uid The record's uid.
104
     */
105 25
    protected function deleteIndexDocuments(string $table, int $uid, int $language = 0)
106
    {
107
        // record can be indexed for multiple sites
108 25
        $indexQueueItems = $this->queue->getItems($table, $uid);
109 25
        foreach ($indexQueueItems as $indexQueueItem) {
110
            try {
111 21
                $site = $indexQueueItem->getSite();
112 1
            } catch (InvalidArgumentException $e) {
113 1
                $this->queue->deleteItem($indexQueueItem->getType(), $indexQueueItem->getIndexQueueUid());
114 1
                continue;
115
            }
116
117 20
            $enableCommitsSetting = $site->getSolrConfiguration()->getEnableCommits();
118 20
            $siteHash = $site->getSiteHash();
119
            // a site can have multiple connections (cores / languages)
120 20
            $solrConnections = $this->connectionManager->getConnectionsBySite($site);
121 20
            if ($language > 0 && isset($solrConnections[$language])) {
122
                $solrConnections = [$language => $solrConnections[$language]];
123
            }
124 20
            $this->deleteRecordInAllSolrConnections($table, $uid, $solrConnections, $siteHash, $enableCommitsSetting);
125
        }
126
    }
127
128
    /**
129
     * Deletes the record in all solr connections from that site.
130
     *
131
     * @param string $table
132
     * @param int $uid
133
     * @param SolrConnection[] $solrConnections
134
     * @param string $siteHash
135
     * @param bool $enableCommitsSetting
136
     */
137 20
    protected function deleteRecordInAllSolrConnections(
138
        string $table,
139
        int $uid,
140
        array $solrConnections,
141
        string $siteHash,
142
        bool $enableCommitsSetting
143
    ) {
144 20
        foreach ($solrConnections as $solr) {
145 20
            $solr->getWriteService()->deleteByQuery(
146 20
                'type:' . $table . ' AND uid:' . $uid . ' AND siteHash:' . $siteHash
147 20
            );
148 20
            if ($enableCommitsSetting) {
149 20
                $solr->getWriteService()->commit(false, false);
150
            }
151
        }
152
    }
153
154
    /**
155
     * Calls the registered post-processing hooks after the garbageCollection.
156
     *
157
     * @param string $table
158
     * @param int $uid
159
     */
160 25
    protected function callPostProcessGarbageCollectorHook(string $table, int $uid)
161
    {
162 25
        if (!is_array($GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['solr']['postProcessGarbageCollector'] ?? null)) {
163 23
            return;
164
        }
165
166 2
        foreach ($GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['solr']['postProcessGarbageCollector'] as $classReference) {
167 2
            $garbageCollectorPostProcessor = GeneralUtility::makeInstance($classReference);
168
169 2
            if ($garbageCollectorPostProcessor instanceof GarbageCollectorPostProcessor) {
170 2
                $garbageCollectorPostProcessor->postProcessGarbageCollector($table, $uid);
171
            } else {
172
                $message = get_class($garbageCollectorPostProcessor) . ' must implement interface ' .
173
                    GarbageCollectorPostProcessor::class;
174
                throw new \UnexpectedValueException($message, 1345807460);
175
            }
176
        }
177
    }
178
}
179