Failed Conditions
Pull Request — release-11.2.x (#3154)
by Markus
64:06 queued 19:01
created

getUpdateSubPagesRecursiveTriggerConfiguration()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 20
Code Lines 9

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 9
dl 0
loc 20
rs 9.9666
c 0
b 0
f 0
cc 1
nc 1
nop 0

2 Methods

Rating   Name   Duplication   Size   Complexity  
A GarbageCollector::processCmdmap_postProcess() 0 5 4
A GarbageCollector::collectGarbage() 0 3 1
1
<?php
2
namespace ApacheSolrForTypo3\Solr;
3
4
/***************************************************************
5
 *  Copyright notice
6
 *
7
 *  (c) 2010-2015 Ingo Renner <[email protected]>
8
 *  All rights reserved
9
 *
10
 *  This script is part of the TYPO3 project. The TYPO3 project is
11
 *  free software; you can redistribute it and/or modify
12
 *  it under the terms of the GNU General Public License as published by
13
 *  the Free Software Foundation; either version 3 of the License, or
14
 *  (at your option) any later version.
15
 *
16
 *  The GNU General Public License can be found at
17
 *  http://www.gnu.org/copyleft/gpl.html.
18
 *
19
 *  This script is distributed in the hope that it will be useful,
20
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
21
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
22
 *  GNU General Public License for more details.
23
 *
24
 *  This copyright notice MUST APPEAR in all copies of the script!
25
 ***************************************************************/
26
27
use Psr\EventDispatcher\EventDispatcherInterface;
28
use ApacheSolrForTypo3\Solr\System\TCA\TCAService;
29
use TYPO3\CMS\Core\DataHandling\DataHandler;
30
use TYPO3\CMS\Core\SingletonInterface;
31
use TYPO3\CMS\Core\Utility\GeneralUtility;
32
use ApacheSolrForTypo3\Solr\Domain\Index\Queue\UpdateHandler\GarbageHandler;
33
use ApacheSolrForTypo3\Solr\Domain\Index\Queue\UpdateHandler\Events\RecordDeletedEvent;
34
use ApacheSolrForTypo3\Solr\Domain\Index\Queue\UpdateHandler\Events\PageMovedEvent;
35
use ApacheSolrForTypo3\Solr\Domain\Index\Queue\UpdateHandler\Events\RecordGarbageCheckEvent;
36
37
/**
38
 * Garbage Collector, removes related documents from the index when a record is
39
 * set to hidden, is deleted or is otherwise made invisible to website visitors.
40
 *
41
 * Garbage collection will happen for online/LIVE workspaces only.
42
 *
43
 * @author Ingo Renner <[email protected]>
44
 * @author Timo Schmidt <[email protected]>
45
 */
46
class GarbageCollector implements SingletonInterface
47
{
48
    /**
49
     * @var array
50
     */
51
    protected $trackedRecords = [];
52
53
    /**
54
     * @var TCAService
55
     */
56
    protected $tcaService;
57
58
    /**
59
     * GarbageCollector constructor.
60
     *
61
     * @param TCAService|null $TCAService
62
     * @param EventDispatcherInterface|null $eventDispatcher
63
     */
64
    public function __construct(TCAService $TCAService = null, EventDispatcherInterface $eventDispatcher = null)
65
    {
66
        $this->tcaService = $TCAService ?? GeneralUtility::makeInstance(TCAService::class);
67
        $this->eventDispatcher = $eventDispatcher ?? GeneralUtility::makeInstance(EventDispatcherInterface::class);
0 ignored issues
show
Bug Best Practice introduced by
The property eventDispatcher does not exist. Although not strictly required by PHP, it is generally a best practice to declare properties explicitly.
Loading history...
68
    }
69
70
    /**
71
     * Hooks into TCE main and tracks record deletion commands.
72
     *
73
     * @param string $command The command.
74
     * @param string $table The table the record belongs to
75
     * @param int $uid The record's uid
76
     * @param string $value Not used
77
     * @param DataHandler $tceMain TYPO3 Core Engine parent object, not used
78
     */
79
    public function processCmdmap_preProcess($command, $table, $uid, $value, DataHandler $tceMain): void
0 ignored issues
show
Unused Code introduced by
The parameter $value is not used and could be removed. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unused  annotation

79
    public function processCmdmap_preProcess($command, $table, $uid, /** @scrutinizer ignore-unused */ $value, DataHandler $tceMain): void

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
Unused Code introduced by
The parameter $tceMain is not used and could be removed. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unused  annotation

79
    public function processCmdmap_preProcess($command, $table, $uid, $value, /** @scrutinizer ignore-unused */ DataHandler $tceMain): void

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
80
    {
81
        // workspaces: collect garbage only for LIVE workspace
82
        if ($command === 'delete' && $GLOBALS['BE_USER']->workspace == 0) {
83
            $this->eventDispatcher->dispatch(
84
                new RecordDeletedEvent((int)$uid, (string)$table)
85
            );
86
        }
87
    }
88
89
    /**
90
     * Tracks down index documents belonging to a particular record or page and
91
     * removes them from the index and the Index Queue.
92
     *
93
     * @param string $table The record's table name.
94
     * @param int $uid The record's uid.
95
     * @throws \UnexpectedValueException if a hook object does not implement interface \ApacheSolrForTypo3\Solr\GarbageCollectorPostProcessor
96
     */
97
    public function collectGarbage($table, $uid): void
98
    {
99
        $this->getGarbageHandler()->collectGarbage((string)$table, (int)$uid);
100
    }
101
102
    /**
103
     * Hooks into TCE main and tracks page move commands.
104
     *
105
     * @param string $command The command.
106
     * @param string $table The table the record belongs to
107
     * @param int $uid The record's uid
108
     * @param string $value Not used
109
     * @param DataHandler $tceMain TYPO3 Core Engine parent object, not used
110
     */
111
    public function processCmdmap_postProcess($command, $table, $uid, $value, DataHandler $tceMain) {
0 ignored issues
show
Unused Code introduced by
The parameter $tceMain is not used and could be removed. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unused  annotation

111
    public function processCmdmap_postProcess($command, $table, $uid, $value, /** @scrutinizer ignore-unused */ DataHandler $tceMain) {

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
Unused Code introduced by
The parameter $value is not used and could be removed. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unused  annotation

111
    public function processCmdmap_postProcess($command, $table, $uid, /** @scrutinizer ignore-unused */ $value, DataHandler $tceMain) {

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
112
        // workspaces: collect garbage only for LIVE workspace
113
        if ($command === 'move' && $table === 'pages' && $GLOBALS['BE_USER']->workspace == 0) {
114
            $this->eventDispatcher->dispatch(
115
                new PageMovedEvent((int)$uid, (string)$table)
0 ignored issues
show
Unused Code introduced by
The call to ApacheSolrForTypo3\Solr\...vedEvent::__construct() has too many arguments starting with (string)$table. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

115
                /** @scrutinizer ignore-call */ 
116
                new PageMovedEvent((int)$uid, (string)$table)

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress. Please note the @ignore annotation hint above.

Loading history...
116
            );
117
        }
118
    }
119
120
    /**
121
     * Hooks into TCE main and tracks changed records. In this case the current
122
     * record's values are stored to do a change comparison later on for fields
123
     * like fe_group.
124
     *
125
     * @param array $incomingFields An array of incoming fields, new or changed, not used
126
     * @param string $table The table the record belongs to
127
     * @param mixed $uid The record's uid, [integer] or [string] (like 'NEW...')
128
     * @param DataHandler $tceMain TYPO3 Core Engine parent object, not used
129
     */
130
    public function processDatamap_preProcessFieldArray($incomingFields, $table, $uid, DataHandler $tceMain): void
0 ignored issues
show
Unused Code introduced by
The parameter $incomingFields is not used and could be removed. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unused  annotation

130
    public function processDatamap_preProcessFieldArray(/** @scrutinizer ignore-unused */ $incomingFields, $table, $uid, DataHandler $tceMain): void

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
Unused Code introduced by
The parameter $tceMain is not used and could be removed. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unused  annotation

130
    public function processDatamap_preProcessFieldArray($incomingFields, $table, $uid, /** @scrutinizer ignore-unused */ DataHandler $tceMain): void

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
131
    {
132
        if (!is_int($uid)) {
133
            // a newly created record, skip
134
            return;
135
        }
136
137
        $uid = (int)$uid;
138
        $table = (string)$table;
139
        if (Util::isDraftRecord($table, $uid)) {
140
            // skip workspaces: collect garbage only for LIVE workspace
141
            return;
142
        }
143
144
        $hasConfiguredEnableColumnForFeGroup = $this->tcaService->isEnableColumn($table, 'fe_group');
145
        if (!$hasConfiguredEnableColumnForFeGroup) {
146
            return;
147
        }
148
149
        $record = $this->getGarbageHandler()->getRecordWithFieldRelevantForGarbageCollection($table, $uid);
150
        // If no record could be found skip further processing
151
        if (empty($record)) {
152
            return;
153
        }
154
155
        $record = $this->tcaService->normalizeFrontendGroupField($table, $record);
156
157
        // keep previous state of important fields for later comparison
158
        $this->trackedRecords[$table][$uid] = $record;
159
    }
160
161
    /**
162
     * Hooks into TCE Main and watches all record updates. If a change is
163
     * detected that would remove the record from the website, we try to find
164
     * related documents and remove them from the index.
165
     *
166
     * @param string $status Status of the current operation, 'new' or 'update'
167
     * @param string $table The table the record belongs to
168
     * @param mixed $uid The record's uid, [integer] or [string] (like 'NEW...')
169
     * @param array $fields The record's data, not used
170
     * @param DataHandler $tceMain TYPO3 Core Engine parent object, not used
171
     */
172
    public function processDatamap_afterDatabaseOperations($status, $table, $uid, array $fields, DataHandler $tceMain): void
0 ignored issues
show
Unused Code introduced by
The parameter $tceMain is not used and could be removed. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unused  annotation

172
    public function processDatamap_afterDatabaseOperations($status, $table, $uid, array $fields, /** @scrutinizer ignore-unused */ DataHandler $tceMain): void

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
173
    {
174
        if ($status === 'new') {
175
            // a newly created record, skip
176
            return;
177
        }
178
179
        $uid = (int)$uid;
180
        $table = (string)$table;
181
        if (Util::isDraftRecord($table, $uid)) {
182
            // skip workspaces: collect garbage only for LIVE workspace
183
            return;
184
        }
185
186
        $updatedRecord = $this->getGarbageHandler()->getRecordWithFieldRelevantForGarbageCollection($table, $uid);
187
        $this->eventDispatcher->dispatch(
188
            new RecordGarbageCheckEvent(
189
                $uid,
190
                $table,
191
                $fields,
192
                $this->hasFrontendGroupsRemoved($table, $updatedRecord)
193
            )
194
        );
195
    }
196
197
    /**
198
     * Checks whether the a frontend group field exists for the record and if so
199
     * whether groups have been removed from accessing the record thus making
200
     * the record invisible to at least some people.
201
     *
202
     * @param string $table The table name.
203
     * @param array $updatedRecord An array with fields of the updated record that may affect visibility.
204
     * @return bool TRUE if frontend groups have been removed from access to the record, FALSE otherwise.
205
     */
206
    protected function hasFrontendGroupsRemoved(string $table, array $updatedRecord): bool
207
    {
208
        if (!isset($GLOBALS['TCA'][$table]['ctrl']['enablecolumns']['fe_group'])) {
209
            return false;
210
        }
211
212
        $frontendGroupsField = $GLOBALS['TCA'][$table]['ctrl']['enablecolumns']['fe_group'];
213
214
        $previousGroups = explode(',', (string)$this->trackedRecords[$table][$updatedRecord['uid']][$frontendGroupsField]);
215
        $currentGroups = explode(',', (string)$updatedRecord[$frontendGroupsField]);
216
        $removedGroups = array_diff($previousGroups, $currentGroups);
217
218
        return !empty($removedGroups);
219
    }
220
221
    /**
222
     * Returns the GarbageHandler
223
     *
224
     * @return GarbageHandler
225
     */
226
    protected function getGarbageHandler(): GarbageHandler
227
    {
228
        return GeneralUtility::makeInstance(GarbageHandler::class);
229
    }
230
}
231