Scrutinizer GitHub App not installed

We could not synchronize checks via GitHub's checks API since Scrutinizer's GitHub App is not installed for this repository.

Install GitHub App

GitHub Access Token became invalid

It seems like the GitHub access token used for retrieving details about this repository from GitHub became invalid. This might prevent certain types of inspections from being run (in particular, everything related to pull requests).
Please ask an admin of your repository to re-new the access token on this website.
Passed
Pull Request — master (#329)
by Sebastian
03:28
created

ext_update   B

Complexity

Total Complexity 44

Size/Duplication

Total Lines 345
Duplicated Lines 0 %

Importance

Changes 2
Bugs 0 Features 0
Metric Value
eloc 181
dl 0
loc 345
rs 8.8798
c 2
b 0
f 0
wmc 44

10 Methods

Rating   Name   Duplication   Size   Complexity  
A renameIndexRelatedColumns() 0 23 2
A access() 0 11 5
A main() 0 17 5
A oldFormatClasses() 0 16 2
A getMetadataConfig() 0 24 4
B oldIndexRelatedTableNames() 0 16 7
B doSolariumSolrUpdate() 0 56 9
A solariumSolrUpdateRequired() 0 18 3
A updateMetadataConfig() 0 46 5
A updateFormatClasses() 0 17 2

How to fix   Complexity   

Complex Class

Complex classes like ext_update often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use ext_update, and based on these observations, apply Extract Interface, too.

1
<?php
2
/**
3
 * (c) Kitodo. Key to digital objects e.V. <[email protected]>
4
 *
5
 * This file is part of the Kitodo and TYPO3 projects.
6
 *
7
 * @license GNU General Public License version 3 or later.
8
 * For the full copyright and license information, please read the
9
 * LICENSE.txt file that was distributed with this source code.
10
 */
11
12
use Kitodo\Dlf\Common\Helper;
13
use Kitodo\Dlf\Common\Solr;
14
15
/**
16
 * Update class 'ext_update' for the 'dlf' extension
17
 *
18
 * @author Sebastian Meyer <[email protected]>
19
 * @package TYPO3
20
 * @subpackage dlf
21
 * @access public
22
 */
23
class ext_update {
24
    /**
25
     * This holds the output ready to return
26
     *
27
     * @var string
28
     * @access protected
29
     */
30
    protected $content = '';
31
32
    /**
33
     * Triggers the update option in the extension manager
34
     *
35
     * @access public
36
     *
37
     * @return boolean Should the update option be shown?
38
     */
39
    public function access() {
40
        if (count($this->getMetadataConfig())) {
41
            return TRUE;
42
        } elseif ($this->oldIndexRelatedTableNames()) {
43
            return TRUE;
44
        } elseif ($this->solariumSolrUpdateRequired()) {
45
            return TRUE;
46
        } elseif (count($this->oldFormatClasses())) {
0 ignored issues
show
Bug introduced by
$this->oldFormatClasses() of type boolean is incompatible with the type Countable|array expected by parameter $var of count(). ( Ignorable by Annotation )

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

46
        } elseif (count(/** @scrutinizer ignore-type */ $this->oldFormatClasses())) {
Loading history...
47
            return TRUE;
48
        }
49
        return FALSE;
50
    }
51
52
    /**
53
     * Get all outdated metadata configuration records
54
     *
55
     * @access protected
56
     *
57
     * @return array Array of UIDs of outdated records
58
     */
59
    protected function getMetadataConfig() {
60
        $uids = [];
61
        // check if tx_dlf_metadata.xpath exists anyhow
62
        $fieldsInDatabase = $GLOBALS['TYPO3_DB']->admin_get_fields('tx_dlf_metadata');
63
        if (!in_array('xpath', array_keys($fieldsInDatabase))) {
64
            return $uids;
65
        }
66
        // Get all records with outdated configuration.
67
        $result = $GLOBALS['TYPO3_DB']->exec_SELECTquery(
68
            'tx_dlf_metadata.uid AS uid',
69
            'tx_dlf_metadata',
70
            'tx_dlf_metadata.format=0'
71
                .' AND NOT tx_dlf_metadata.xpath=""'
72
                .Helper::whereClause('tx_dlf_metadata'),
73
            '',
74
            '',
75
            ''
76
        );
77
        if ($GLOBALS['TYPO3_DB']->sql_num_rows($result)) {
78
            while ($resArray = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($result)) {
79
                $uids[] = intval($resArray['uid']);
80
            }
81
        }
82
        return $uids;
83
    }
84
85
    /**
86
     * The main method of the class
87
     *
88
     * @access public
89
     *
90
     * @return string The content that is displayed on the website
91
     */
92
    public function main() {
93
        // Load localization file.
94
        $GLOBALS['LANG']->includeLLFile('EXT:dlf/Resources/Private/Language/FlashMessages.xml');
95
        // Update the metadata configuration.
96
        if (count($this->getMetadataConfig())) {
97
            $this->updateMetadataConfig();
98
        }
99
        if ($this->oldIndexRelatedTableNames()) {
100
            $this->renameIndexRelatedColumns();
101
        }
102
        if ($this->solariumSolrUpdateRequired()) {
103
            $this->doSolariumSolrUpdate();
104
        }
105
        if (count($this->oldFormatClasses())) {
0 ignored issues
show
Bug introduced by
$this->oldFormatClasses() of type boolean is incompatible with the type Countable|array expected by parameter $var of count(). ( Ignorable by Annotation )

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

105
        if (count(/** @scrutinizer ignore-type */ $this->oldFormatClasses())) {
Loading history...
106
            $this->updateFormatClasses();
107
        }
108
        return $this->content;
109
    }
110
111
    /**
112
     * Check for old format classes
113
     *
114
     * @access protected
115
     *
116
     * @return boolean true if old format classes exist
117
     */
118
    protected function oldFormatClasses() {
119
        $oldRecords = [];
120
        // Get all records with outdated configuration.
121
        $result = $GLOBALS['TYPO3_DB']->exec_SELECTquery(
122
            'tx_dlf_formats.uid AS uid,tx_dlf_formats.type AS type',
123
            'tx_dlf_formats',
124
            'tx_dlf_formats.class NOT LIKE "%\\%"'
125
                .Helper::whereClause('tx_dlf_formats'),
126
            '',
127
            '',
128
            ''
129
        );
130
        while ($resArray = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($result)) {
131
            $oldRecords[$resArray['uid']] = $resArray['type'];
132
        }
133
        return $oldRecords;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $oldRecords returns the type array which is incompatible with the documented return type boolean.
Loading history...
134
    }
135
136
    /**
137
     * Check for old index related colums
138
     *
139
     * @access protected
140
     *
141
     * @return boolean TRUE if old index related columns exist
142
     */
143
    protected function oldIndexRelatedTableNames() {
144
        $result = $GLOBALS['TYPO3_DB']->exec_SELECTquery(
145
            'column_name',
146
            'INFORMATION_SCHEMA.COLUMNS',
147
            'TABLE_NAME = "tx_dlf_metadata"',
148
            '',
149
            '',
150
            ''
151
        );
152
        while ($resArray = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($result)) {
153
            if ($resArray['column_name'] == 'tokenized'
154
                || $resArray['column_name'] == 'stored'
155
                || $resArray['column_name'] == 'indexed'
156
                || $resArray['column_name'] == 'boost'
157
                || $resArray['column_name'] == 'autocomplete') {
158
                    return TRUE;
159
            }
160
        }
161
    }
162
163
    /**
164
     * Copy the data of the old index related columns to the new columns
165
     *
166
     * @access protected
167
     *
168
     * @return void
169
     */
170
    protected function renameIndexRelatedColumns() {
171
        $sqlQuery = 'UPDATE tx_dlf_metadata'
172
            .' SET `index_tokenized` = `tokenized`'
173
            .', `index_stored` = `stored`'
174
            .', `index_indexed` = `indexed`'
175
            .', `index_boost` = `boost`'
176
            .', `index_autocomplete` = `autocomplete`';
177
        // Copy the content of the old tables to the new ones
178
        $result = $GLOBALS['TYPO3_DB']->sql_query($sqlQuery);
179
        if ($result) {
180
            Helper::addMessage(
181
                $GLOBALS['LANG']->getLL('update.copyIndexRelatedColumnsOkay', TRUE),
182
                $GLOBALS['LANG']->getLL('update.copyIndexRelatedColumns', TRUE),
183
                \TYPO3\CMS\Core\Messaging\FlashMessage::OK
184
            );
185
        } else {
186
            Helper::addMessage(
187
                $GLOBALS['LANG']->getLL('update.copyIndexRelatedColumnsNotOkay', TRUE),
188
                $GLOBALS['LANG']->getLL('update.copyIndexRelatedColumns', TRUE),
189
                \TYPO3\CMS\Core\Messaging\FlashMessage::WARNING
190
            );
191
        }
192
        $this->content .= Helper::renderFlashMessages();
193
    }
194
195
    /**
196
     * Update all outdated format records
197
     *
198
     * @access protected
199
     *
200
     * @return void
201
     */
202
    protected function updateFormatClasses() {
203
        $oldRecords = $this->oldFormatClasses();
204
        $newValues = [
205
            'ALTO' => 'Kitodo\\Dlf\\Formats\\Alto',
206
            'MODS' => 'Kitodo\\Dlf\\Formats\\Mods',
207
            'TEIHDR' => 'Kitodo\\Dlf\\Formats\\TeiHeader'
208
        ];
209
        foreach ($oldRecords as $uid => $type) {
0 ignored issues
show
Bug introduced by
The expression $oldRecords of type boolean is not traversable.
Loading history...
210
            $sqlQuery = 'UPDATE tx_dlf_formats SET class="'.$newValues[$type].'" WHERE uid='.$uid;
211
            $GLOBALS['TYPO3_DB']->sql_query($sqlQuery);
212
        }
213
        Helper::addMessage(
214
            $GLOBALS['LANG']->getLL('update.FormatClassesOkay', TRUE),
215
            $GLOBALS['LANG']->getLL('update.FormatClasses', TRUE),
216
            \TYPO3\CMS\Core\Messaging\FlashMessage::OK
217
        );
218
        $this->content .= Helper::renderFlashMessages();
219
    }
220
221
    /**
222
     * Update all outdated metadata configuration records
223
     *
224
     * @access protected
225
     *
226
     * @return void
227
     */
228
    protected function updateMetadataConfig() {
229
        $metadataUids = $this->getMetadataConfig();
230
        if (!empty($metadataUids)) {
231
            $data = [];
232
            // Get all old metadata configuration records.
233
            $result = $GLOBALS['TYPO3_DB']->exec_SELECTquery(
234
                'tx_dlf_metadata.uid AS uid,tx_dlf_metadata.pid AS pid,tx_dlf_metadata.cruser_id AS cruser_id,tx_dlf_metadata.encoded AS encoded,tx_dlf_metadata.xpath AS xpath,tx_dlf_metadata.xpath_sorting AS xpath_sorting',
235
                'tx_dlf_metadata',
236
                'tx_dlf_metadata.uid IN ('.implode(',', $metadataUids).')'
237
                    .Helper::whereClause('tx_dlf_metadata'),
238
                '',
239
                '',
240
                ''
241
            );
242
            while ($resArray = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($result)) {
243
                $newId = uniqid('NEW');
244
                // Copy record to new table.
245
                $data['tx_dlf_metadataformat'][$newId] = [
246
                    'pid' => $resArray['pid'],
247
                    'cruser_id' => $resArray['cruser_id'],
248
                    'parent_id' => $resArray['uid'],
249
                    'encoded' => $resArray['encoded'],
250
                    'xpath' => $resArray['xpath'],
251
                    'xpath_sorting' => $resArray['xpath_sorting']
252
                ];
253
                // Add reference to old table.
254
                $data['tx_dlf_metadata'][$resArray['uid']]['format'] = $newId;
255
            }
256
            if (!empty($data)) {
257
                // Process datamap.
258
                $substUids = Helper::processDBasAdmin($data);
259
                unset ($data);
260
                if (!empty($substUids)) {
261
                    Helper::addMessage(
262
                        $GLOBALS['LANG']->getLL('update.metadataConfigOkay', TRUE),
263
                        $GLOBALS['LANG']->getLL('update.metadataConfig', TRUE),
264
                        \TYPO3\CMS\Core\Messaging\FlashMessage::OK
265
                    );
266
                } else {
267
                    Helper::addMessage(
268
                        $GLOBALS['LANG']->getLL('update.metadataConfigNotOkay', TRUE),
269
                        $GLOBALS['LANG']->getLL('update.metadataConfig', TRUE),
270
                        \TYPO3\CMS\Core\Messaging\FlashMessage::WARNING
271
                    );
272
                }
273
                $this->content .= Helper::renderFlashMessages();
274
            }
275
        }
276
    }
277
278
    /**
279
     * Check all configured Solr cores
280
     *
281
     * @access protected
282
     *
283
     * @return boolean
284
     */
285
    protected function solariumSolrUpdateRequired() {
286
        // Get all Solr cores that were not deleted.
287
        $result = $GLOBALS['TYPO3_DB']->exec_SELECTquery(
288
            'index_name',
289
            'tx_dlf_solrcores',
290
            'deleted=0',
291
            '',
292
            '',
293
            ''
294
        );
295
        while ($resArray = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($result)) {
296
            // Instantiate search object.
297
            $solr = Solr::getInstance($resArray['index_name']);
298
            if (!$solr->ready) {
0 ignored issues
show
Bug Best Practice introduced by
The property $ready is declared protected in Kitodo\Dlf\Common\Solr. Since you implement __get, consider adding a @property or @property-read.
Loading history...
299
                return TRUE;
300
            }
301
        }
302
        return FALSE;
303
    }
304
305
    /**
306
     * Create all configured Solr cores
307
     *
308
     * @access protected
309
     *
310
     * @return void
311
     */
312
    protected function doSolariumSolrUpdate() {
313
        // Get all Solr cores that were not deleted.
314
        $result = $GLOBALS['TYPO3_DB']->exec_SELECTquery(
315
            'index_name',
316
            'tx_dlf_solrcores',
317
            'deleted=0',
318
            '',
319
            '',
320
            ''
321
        );
322
        while ($resArray = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($result)) {
323
            // Instantiate search object.
324
            $solr = Solr::getInstance($resArray['index_name']);
325
            if (!$solr->ready) {
0 ignored issues
show
Bug Best Practice introduced by
The property $ready is declared protected in Kitodo\Dlf\Common\Solr. Since you implement __get, consider adding a @property or @property-read.
Loading history...
326
                $conf = unserialize($GLOBALS['TYPO3_CONF_VARS']['EXT']['extConf']['dlf']);
327
                $solrInfo = Solr::getSolrConnectionInfo();
328
                // Prepend username and password to hostname.
329
                if ($solrInfo['username']
330
                    && $solrInfo['password']) {
331
                    $host = $solrInfo['username'].':'.$solrInfo['password'].'@'.$solrInfo['host'];
332
                } else {
333
                    $host = $solrInfo['host'];
334
                }
335
                $context = stream_context_create([
336
                    'http' => [
337
                        'method' => 'GET',
338
                        'user_agent' => ($conf['useragent'] ? $conf['useragent'] : ini_get('user_agent'))
339
                    ]
340
                ]);
341
                // Build request for adding new Solr core.
342
                // @see http://wiki.apache.org/solr/CoreAdmin
343
                $url = $solrInfo['scheme'].'://'.$host.':'.$solrInfo['port'].'/'.$solrInfo['path'].'/admin/cores?wt=xml&action=CREATE&name='.$resArray['index_name'].'&instanceDir=dlfCore'.$resArray['index_name'].'&dataDir=data&configSet=dlf';
344
                $response = @simplexml_load_string(file_get_contents($url, FALSE, $context));
345
                // Process response.
346
                if ($response) {
347
                    $status = $response->xpath('//lst[@name="responseHeader"]/int[@name="status"]');
348
                    if ($status
0 ignored issues
show
Bug Best Practice introduced by
The expression $status of type SimpleXMLElement[] is implicitly converted to a boolean; are you sure this is intended? If so, consider using ! empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
349
                        && $status[0] == 0) {
350
                        continue;
351
                    }
352
                }
353
                Helper::addMessage(
354
                    $GLOBALS['LANG']->getLL('update.solariumSolrUpdateNotOkay', TRUE),
355
                    sprintf($GLOBALS['LANG']->getLL('update.solariumSolrUpdate', TRUE), $resArray['index_name']),
356
                    \TYPO3\CMS\Core\Messaging\FlashMessage::ERROR
357
                );
358
                $this->content .= Helper::renderFlashMessages();
359
                return;
360
            }
361
        }
362
        Helper::addMessage(
363
            $GLOBALS['LANG']->getLL('update.solariumSolrUpdateOkay', TRUE),
364
            $GLOBALS['LANG']->getLL('update.solariumSolrUpdate', TRUE),
365
            \TYPO3\CMS\Core\Messaging\FlashMessage::OK
366
        );
367
        $this->content .= Helper::renderFlashMessages();
368
    }
369
}
370