Completed
Pull Request — master (#6)
by Chetan
04:02
created

RefIndex::getConnectionPool()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 7
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 4
CRAP Score 2

Importance

Changes 0
Metric Value
cc 2
eloc 3
nc 2
nop 0
dl 0
loc 7
ccs 4
cts 4
cp 1
crap 2
rs 10
c 0
b 0
f 0
1
<?php
2
namespace Aoe\UpdateRefindex\Typo3;
3
4
/***************************************************************
5
 *  Copyright notice
6
 *
7
 *  (c) 2020 AOE GmbH <[email protected]>
8
 *
9
 *  All rights reserved
10
 *
11
 *  This script is part of the TYPO3 project. The TYPO3 project is
12
 *  free software; you can redistribute it and/or modify
13
 *  it under the terms of the GNU General Public License as published by
14
 *  the Free Software Foundation; either version 2 of the License, or
15
 *  (at your option) any later version.
16
 *
17
 *  The GNU General Public License can be found at
18
 *  http://www.gnu.org/copyleft/gpl.html.
19
 *
20
 *  This script is distributed in the hope that it will be useful,
21
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
22
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
23
 *  GNU General Public License for more details.
24
 *
25
 *  This copyright notice MUST APPEAR in all copies of the script!
26
 ***************************************************************/
27
28
use PDO;
29
use TYPO3\CMS\Core\Database\Connection;
0 ignored issues
show
Bug introduced by
The type TYPO3\CMS\Core\Database\Connection was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
30
use TYPO3\CMS\Core\Database\ConnectionPool;
0 ignored issues
show
Bug introduced by
The type TYPO3\CMS\Core\Database\ConnectionPool was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
31
use TYPO3\CMS\Core\Database\Query\QueryBuilder;
0 ignored issues
show
Bug introduced by
The type TYPO3\CMS\Core\Database\Query\QueryBuilder was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
32
use TYPO3\CMS\Core\Database\ReferenceIndex;
33
use TYPO3\CMS\Core\Utility\GeneralUtility;
34
35
/**
36
 * scheduler-task to update refindex of TYPO3
37
 *
38
 * @package update_refindex
39
 * @subpackage Typo3
40
 */
41
class RefIndex
42
{
43
    /**
44
     * @var ConnectionPool
45
     */
46
    private $connectionPool;
47
48
    /**
49
     * @var array
50
     */
51
    private $existingTables;
52
53
    /**
54
     * @var array
55
     */
56
    private $selectedTables = [];
57
58
    /**
59
     * @param array $selectedTables
60
     * @return RefIndex
61
     */
62 2
    public function setSelectedTables(array $selectedTables)
63
    {
64 2
        $this->selectedTables = $selectedTables;
65
66 2
        return $this;
67
    }
68
69
    /**
70
     * @return array
71
     */
72 2
    public function getSelectedTables()
73
    {
74 2
        return $this->selectedTables;
75
    }
76
77
    /**
78
     * @return array
79
     */
80 1
    public function getExistingTables()
81
    {
82 1
        if ($this->existingTables === null) {
83 1
            $this->existingTables = array_keys($GLOBALS['TCA']);
84 1
            sort($this->existingTables);
85
        }
86
87 1
        return $this->existingTables;
88
    }
89
90
    /**
91
     * update refIndex of selected tables
92
     */
93 2
    public function update()
94
    {
95
        // update index of selected tables
96 2
        foreach ($this->getSelectedTables() as $selectedTable) {
97 2
            if (array_search($selectedTable, $this->getExistingTables()) !== false) {
98 1
                $this->updateTable($selectedTable);
99
            }
100
        }
101
102
        // delete lost indexes ONLY if index of ALL tables where updated
103 2
        if (count($this->getExistingTables()) === count($this->getSelectedTables())) {
104 1
            $this->deleteLostIndexes();
105
        }
106 2
    }
107
108
    /**
109
     * @return ReferenceIndex
110
     */
111 1
    protected function getReferenceIndex()
112
    {
113 1
        return GeneralUtility::makeInstance(ReferenceIndex::class);
114
    }
115
116
    /**
117
     * Searching lost indexes for non-existing tables
118
     * this code is inspired by the code of method 'updateIndex' in class '\TYPO3\CMS\Core\Database\ReferenceIndex'
119
     */
120 1
    protected function deleteLostIndexes()
121
    {
122 1
        $queryBuilder = $this->getQueryBuilderForTable('sys_refindex');
123
        $queryBuilder
124 1
            ->delete('sys_refindex')
125 1
            ->where(
126 1
                $queryBuilder->expr()->notIn(
127 1
                    'tablename',
128 1
                    $queryBuilder->createNamedParameter($this->getExistingTables(), Connection::PARAM_STR_ARRAY)
129
                )
130
            )
131 1
            ->execute();
132 1
    }
133
134
    /**
135
     * update table
136
     * this code is inspired by the code of method 'updateIndex' in class '\TYPO3\CMS\Core\Database\ReferenceIndex'
137
     *
138
     * @param string $tableName
139
     */
140 1
    protected function updateTable($tableName)
141
    {
142
        // Traverse all records in table, including deleted records:
143 1
        $queryBuilder = $this->getQueryBuilderForTable($tableName);
144
        $allRecs = $queryBuilder
145 1
            ->select('uid')
146 1
            ->from($tableName)
147 1
            ->execute()
148 1
            ->fetchAll(PDO::FETCH_ASSOC);
149
150 1
        $uidList = [0];
151 1
        foreach ($allRecs as $recdat) {
152 1
            $this->getReferenceIndex()->updateRefIndexTable($tableName, $recdat['uid']);
153 1
            $uidList[] = (int) $recdat['uid'];
154
        }
155
156
        // Searching lost indexes for this table:
157 1
        $queryBuilder = $this->getQueryBuilderForTable('sys_refindex');
158
        $queryBuilder
159 1
            ->delete('sys_refindex')
160 1
            ->where(
161 1
                $queryBuilder->expr()->eq(
162 1
                    'tablename',
163 1
                    $queryBuilder->createNamedParameter($tableName, PDO::PARAM_STR)
164
                )
165
            )
166 1
            ->andWhere(
167 1
                $queryBuilder->expr()->notIn(
168 1
                    'recuid',
169 1
                    $queryBuilder->createNamedParameter($uidList, Connection::PARAM_INT_ARRAY)
170
                )
171
            )
172 1
            ->execute();
173 1
    }
174
175
    /**
176
     * @param string $table
177
     * @param bool   $useEnableFields
178
     * @return QueryBuilder
179
     */
180 2
    private function getQueryBuilderForTable(string $table, bool $useEnableFields = false): QueryBuilder
181
    {
182 2
        $connectionPool = $this->getConnectionPool();
183 2
        $queryBuilder = $connectionPool->getQueryBuilderForTable($table);
184
185 2
        if (false === $useEnableFields) {
186 2
            $queryBuilder->getRestrictions()->removeAll();
187
        }
188
189 2
        return $queryBuilder;
190
    }
191
192
    /**
193
     * @return ConnectionPool
194
     */
195 2
    private function getConnectionPool(): ConnectionPool
196
    {
197 2
        if (null === $this->connectionPool) {
198 2
            $this->connectionPool = GeneralUtility::makeInstance(ConnectionPool::class);
199
        }
200
201 2
        return $this->connectionPool;
202
    }
203
}
204