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.
Completed
Push — master ( c20ef5...82f16d )
by Sebastian
16s queued 13s
created

ext_update::access()   A

Complexity

Conditions 6
Paths 6

Size

Total Lines 14
Code Lines 11

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 11
c 0
b 0
f 0
dl 0
loc 14
rs 9.2222
cc 6
nc 6
nop 0
1
<?php
2
3
/**
4
 * (c) Kitodo. Key to digital objects e.V. <[email protected]>
5
 *
6
 * This file is part of the Kitodo and TYPO3 projects.
7
 *
8
 * @license GNU General Public License version 3 or later.
9
 * For the full copyright and license information, please read the
10
 * LICENSE.txt file that was distributed with this source code.
11
 */
12
13
use Kitodo\Dlf\Common\Helper;
14
use Kitodo\Dlf\Common\Solr;
15
16
/**
17
 * Update class 'ext_update' for the 'dlf' extension
18
 *
19
 * @author Sebastian Meyer <[email protected]>
20
 * @package TYPO3
21
 * @subpackage dlf
22
 * @access public
23
 */
24
class ext_update
25
{
26
    /**
27
     * This holds the output ready to return
28
     *
29
     * @var string
30
     * @access protected
31
     */
32
    protected $content = '';
33
34
    /**
35
     * Triggers the update option in the extension manager
36
     *
37
     * @access public
38
     *
39
     * @return bool Should the update option be shown?
40
     */
41
    public function access()
42
    {
43
        if (count($this->getMetadataConfig())) {
44
            return true;
45
        } elseif ($this->oldIndexRelatedTableNames()) {
46
            return true;
47
        } elseif ($this->solariumSolrUpdateRequired()) {
48
            return true;
49
        } elseif (count($this->oldFormatClasses())) {
50
            return true;
51
        } elseif ($this->hasNoFormatForDocument()) {
52
            return true;
53
        }
54
        return false;
55
    }
56
57
    /**
58
     * Get all outdated metadata configuration records
59
     *
60
     * @access protected
61
     *
62
     * @return array Array of UIDs of outdated records
63
     */
64
    protected function getMetadataConfig()
65
    {
66
        $uids = [];
67
        // check if tx_dlf_metadata.xpath exists anyhow
68
        $fieldsInDatabase = $GLOBALS['TYPO3_DB']->admin_get_fields('tx_dlf_metadata');
69
        if (!in_array('xpath', array_keys($fieldsInDatabase))) {
70
            return $uids;
71
        }
72
        // Get all records with outdated configuration.
73
        $result = $GLOBALS['TYPO3_DB']->exec_SELECTquery(
74
            'tx_dlf_metadata.uid AS uid',
75
            'tx_dlf_metadata',
76
            'tx_dlf_metadata.format=0'
77
                . ' AND NOT tx_dlf_metadata.xpath=""'
78
                . Helper::whereClause('tx_dlf_metadata')
79
        );
80
        if ($GLOBALS['TYPO3_DB']->sql_num_rows($result)) {
81
            while ($resArray = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($result)) {
82
                $uids[] = intval($resArray['uid']);
83
            }
84
        }
85
        return $uids;
86
    }
87
88
    /**
89
     * The main method of the class
90
     *
91
     * @access public
92
     *
93
     * @return string The content that is displayed on the website
94
     */
95
    public function main()
96
    {
97
        // Load localization file.
98
        $GLOBALS['LANG']->includeLLFile('EXT:dlf/Resources/Private/Language/FlashMessages.xml');
99
        // Update the metadata configuration.
100
        if (count($this->getMetadataConfig())) {
101
            $this->updateMetadataConfig();
102
        }
103
        if ($this->oldIndexRelatedTableNames()) {
104
            $this->renameIndexRelatedColumns();
105
        }
106
        if ($this->solariumSolrUpdateRequired()) {
107
            $this->doSolariumSolrUpdate();
108
        }
109
        if (count($this->oldFormatClasses())) {
110
            $this->updateFormatClasses();
111
        }
112
        // Set tx_dlf_documents.document_format to distinguish between METS and IIIF.
113
        if ($this->hasNoFormatForDocument()) {
114
            $this->updateDocumentAddFormat();
115
        }
116
        return $this->content;
117
    }
118
119
    /**
120
     * Check for old format classes
121
     *
122
     * @access protected
123
     *
124
     * @return array containing old format classes
125
     */
126
    protected function oldFormatClasses()
127
    {
128
        $oldRecords = [];
129
        // Get all records with outdated configuration.
130
        $result = $GLOBALS['TYPO3_DB']->exec_SELECTquery(
131
            'tx_dlf_formats.uid AS uid,tx_dlf_formats.type AS type',
132
            'tx_dlf_formats',
133
            'tx_dlf_formats.class IS NOT NULL AND tx_dlf_formats.class != "" AND tx_dlf_formats.class NOT LIKE "%\\\\\\\\%"' // We are looking for a single backslash...
134
                . Helper::whereClause('tx_dlf_formats')
135
        );
136
        while ($resArray = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($result)) {
137
            $oldRecords[$resArray['uid']] = $resArray['type'];
138
        }
139
        return $oldRecords;
140
    }
141
142
    /**
143
     * Check for old index related columns
144
     *
145
     * @access protected
146
     *
147
     * @return bool true if old index related columns exist
148
     */
149
    protected function oldIndexRelatedTableNames()
150
    {
151
        $result = $GLOBALS['TYPO3_DB']->exec_SELECTquery(
152
            'column_name',
153
            'INFORMATION_SCHEMA.COLUMNS',
154
            'TABLE_NAME = "tx_dlf_metadata"'
155
        );
156
        while ($resArray = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($result)) {
157
            if (
158
                $resArray['column_name'] == 'tokenized'
159
                || $resArray['column_name'] == 'stored'
160
                || $resArray['column_name'] == 'indexed'
161
                || $resArray['column_name'] == 'boost'
162
                || $resArray['column_name'] == 'autocomplete'
163
            ) {
164
                return true;
165
            }
166
        }
167
    }
168
169
    /**
170
     * Copy the data of the old index related columns to the new columns
171
     *
172
     * @access protected
173
     *
174
     * @return void
175
     */
176
    protected function renameIndexRelatedColumns()
177
    {
178
        $sqlQuery = 'UPDATE tx_dlf_metadata'
179
            . ' SET `index_tokenized` = `tokenized`'
180
            . ', `index_stored` = `stored`'
181
            . ', `index_indexed` = `indexed`'
182
            . ', `index_boost` = `boost`'
183
            . ', `index_autocomplete` = `autocomplete`';
184
        // Copy the content of the old tables to the new ones
185
        $result = $GLOBALS['TYPO3_DB']->sql_query($sqlQuery);
186
        if ($result) {
187
            Helper::addMessage(
188
                $GLOBALS['LANG']->getLL('update.copyIndexRelatedColumnsOkay', true),
189
                $GLOBALS['LANG']->getLL('update.copyIndexRelatedColumns', true),
190
                \TYPO3\CMS\Core\Messaging\FlashMessage::OK
191
            );
192
        } else {
193
            Helper::addMessage(
194
                $GLOBALS['LANG']->getLL('update.copyIndexRelatedColumnsNotOkay', true),
195
                $GLOBALS['LANG']->getLL('update.copyIndexRelatedColumns', true),
196
                \TYPO3\CMS\Core\Messaging\FlashMessage::WARNING
197
            );
198
        }
199
        $this->content .= Helper::renderFlashMessages();
200
    }
201
202
    /**
203
     * Update all outdated format records
204
     *
205
     * @access protected
206
     *
207
     * @return void
208
     */
209
    protected function updateFormatClasses()
210
    {
211
        $oldRecords = $this->oldFormatClasses();
212
        $newValues = [
213
            'ALTO' => 'Kitodo\\\\Dlf\\\\Format\\\\Alto', // Those are effectively single backslashes
214
            'MODS' => 'Kitodo\\\\Dlf\\\\Format\\\\Mods',
215
            'TEIHDR' => 'Kitodo\\\\Dlf\\\\Format\\\\TeiHeader'
216
        ];
217
        foreach ($oldRecords as $uid => $type) {
218
            $sqlQuery = 'UPDATE tx_dlf_formats SET class="' . $newValues[$type] . '" WHERE uid=' . $uid;
219
            $GLOBALS['TYPO3_DB']->sql_query($sqlQuery);
220
        }
221
        Helper::addMessage(
222
            $GLOBALS['LANG']->getLL('update.FormatClassesOkay', true),
223
            $GLOBALS['LANG']->getLL('update.FormatClasses', true),
224
            \TYPO3\CMS\Core\Messaging\FlashMessage::OK
225
        );
226
        $this->content .= Helper::renderFlashMessages();
227
    }
228
229
    /**
230
     * Update all outdated metadata configuration records
231
     *
232
     * @access protected
233
     *
234
     * @return void
235
     */
236
    protected function updateMetadataConfig()
237
    {
238
        $metadataUids = $this->getMetadataConfig();
239
        if (!empty($metadataUids)) {
240
            $data = [];
241
            // Get all old metadata configuration records.
242
            $result = $GLOBALS['TYPO3_DB']->exec_SELECTquery(
243
                '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',
244
                'tx_dlf_metadata',
245
                'tx_dlf_metadata.uid IN (' . implode(',', $metadataUids) . ')'
246
                    . Helper::whereClause('tx_dlf_metadata')
247
            );
248
            while ($resArray = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($result)) {
249
                $newId = uniqid('NEW');
250
                // Copy record to new table.
251
                $data['tx_dlf_metadataformat'][$newId] = [
252
                    'pid' => $resArray['pid'],
253
                    'cruser_id' => $resArray['cruser_id'],
254
                    'parent_id' => $resArray['uid'],
255
                    'encoded' => $resArray['encoded'],
256
                    'xpath' => $resArray['xpath'],
257
                    'xpath_sorting' => $resArray['xpath_sorting']
258
                ];
259
                // Add reference to old table.
260
                $data['tx_dlf_metadata'][$resArray['uid']]['format'] = $newId;
261
            }
262
            if (!empty($data)) {
263
                // Process datamap.
264
                $substUids = Helper::processDBasAdmin($data);
265
                unset($data);
266
                if (!empty($substUids)) {
267
                    Helper::addMessage(
268
                        $GLOBALS['LANG']->getLL('update.metadataConfigOkay', true),
269
                        $GLOBALS['LANG']->getLL('update.metadataConfig', true),
270
                        \TYPO3\CMS\Core\Messaging\FlashMessage::OK
271
                    );
272
                } else {
273
                    Helper::addMessage(
274
                        $GLOBALS['LANG']->getLL('update.metadataConfigNotOkay', true),
275
                        $GLOBALS['LANG']->getLL('update.metadataConfig', true),
276
                        \TYPO3\CMS\Core\Messaging\FlashMessage::WARNING
277
                    );
278
                }
279
                $this->content .= Helper::renderFlashMessages();
280
            }
281
        }
282
    }
283
284
    /**
285
     * Check all configured Solr cores
286
     *
287
     * @access protected
288
     *
289
     * @return bool
290
     */
291
    protected function solariumSolrUpdateRequired()
292
    {
293
        // Get all Solr cores that were not deleted.
294
        $result = $GLOBALS['TYPO3_DB']->exec_SELECTquery(
295
            'index_name',
296
            'tx_dlf_solrcores',
297
            '1=1'
298
                . Helper::whereClause('tx_dlf_solrcores')
299
        );
300
        while ($resArray = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($result)) {
301
            // Instantiate search object.
302
            $solr = Solr::getInstance($resArray['index_name']);
303
            if (!$solr->ready) {
304
                return true;
305
            }
306
        }
307
        return false;
308
    }
309
310
    /**
311
     * Create all configured Solr cores
312
     *
313
     * @access protected
314
     *
315
     * @return void
316
     */
317
    protected function doSolariumSolrUpdate()
318
    {
319
        // Get all Solr cores that were not deleted.
320
        $result = $GLOBALS['TYPO3_DB']->exec_SELECTquery(
321
            'index_name',
322
            'tx_dlf_solrcores',
323
            '1=1'
324
                . Helper::whereClause('tx_dlf_solrcores')
325
        );
326
        while ($resArray = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($result)) {
327
            // Instantiate search object.
328
            $solr = Solr::getInstance($resArray['index_name']);
329
            if (!$solr->ready) {
330
                $conf = unserialize($GLOBALS['TYPO3_CONF_VARS']['EXT']['extConf']['dlf']);
331
                $solrInfo = Solr::getSolrConnectionInfo();
332
                // Prepend username and password to hostname.
333
                if (
334
                    $solrInfo['username']
335
                    && $solrInfo['password']
336
                ) {
337
                    $host = $solrInfo['username'] . ':' . $solrInfo['password'] . '@' . $solrInfo['host'];
338
                } else {
339
                    $host = $solrInfo['host'];
340
                }
341
                $context = stream_context_create([
342
                    'http' => [
343
                        'method' => 'GET',
344
                        'user_agent' => ($conf['useragent'] ? $conf['useragent'] : ini_get('user_agent'))
345
                    ]
346
                ]);
347
                // Build request for adding new Solr core.
348
                // @see http://wiki.apache.org/solr/CoreAdmin
349
                $url = $solrInfo['scheme'] . '://' . $host . ':' . $solrInfo['port'] . '/' . $solrInfo['path'] . '/admin/cores?wt=xml&action=CREATE&name=' . $resArray['index_name'] . '&instanceDir=' . $resArray['index_name'] . '&dataDir=data&configSet=dlf';
350
                $response = @simplexml_load_string(file_get_contents($url, false, $context));
351
                // Process response.
352
                if ($response) {
353
                    $status = $response->xpath('//lst[@name="responseHeader"]/int[@name="status"]');
354
                    if (
355
                        $status !== false
356
                        && $status[0] == 0
357
                    ) {
358
                        continue;
359
                    }
360
                }
361
                Helper::addMessage(
362
                    $GLOBALS['LANG']->getLL('update.solariumSolrUpdateNotOkay', true),
363
                    sprintf($GLOBALS['LANG']->getLL('update.solariumSolrUpdate', true), $resArray['index_name']),
364
                    \TYPO3\CMS\Core\Messaging\FlashMessage::ERROR
365
                );
366
                $this->content .= Helper::renderFlashMessages();
367
                return;
368
            }
369
        }
370
        Helper::addMessage(
371
            $GLOBALS['LANG']->getLL('update.solariumSolrUpdateOkay', true),
372
            $GLOBALS['LANG']->getLL('update.solariumSolrUpdate', true),
373
            \TYPO3\CMS\Core\Messaging\FlashMessage::OK
374
        );
375
        $this->content .= Helper::renderFlashMessages();
376
    }
377
378
    protected function hasNoFormatForDocument($checkStructureOnly = false)
379
    {
380
        // Check if column "document_format" exists.
381
        $database = $GLOBALS['TYPO3_CONF_VARS']['DB']['Connections']['Default']['dbname'];
382
        $result = $GLOBALS['TYPO3_DB']->exec_SELECTquery(
383
            'COLUMN_NAME',
384
            'INFORMATION_SCHEMA.COLUMNS',
385
            'TABLE_NAME="tx_dlf_documents" AND TABLE_SCHEMA="' . $database . '" AND COLUMN_NAME="document_format"'
386
        );
387
        while ($resArray = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($result)) {
388
            if ($resArray['COLUMN_NAME'] == 'document_format') {
389
                if ($checkStructureOnly) {
390
                    return false;
391
                }
392
                // Check if column has empty fields.
393
                $result2 = $GLOBALS['TYPO3_DB']->exec_SELECTquery(
394
                    'uid',
395
                    'tx_dlf_documents',
396
                    'document_format="" OR document_format IS NULL'
397
                );
398
                if ($GLOBALS['TYPO3_DB']->sql_num_rows($result2) == 0) {
399
                    return false;
400
                }
401
            }
402
        }
403
        return true;
404
    }
405
406
    protected function updateDocumentAddFormat()
407
    {
408
        if ($this->hasNoFormatForDocument(true)) {
409
            $sqlQuery = 'ALTER TABLE tx_dlf_documents ADD COLUMN document_format varchar(100) DEFAULT "" NOT NULL;';
410
            $result = $GLOBALS['TYPO3_DB']->sql_query($sqlQuery);
411
            if ($result) {
412
                Helper::addMessage(
413
                    $GLOBALS['LANG']->getLL('update.documentAddFormatOkay', true),
414
                    $GLOBALS['LANG']->getLL('update.documentAddFormat', true),
415
                    \TYPO3\CMS\Core\Messaging\FlashMessage::OK
416
                );
417
                $this->content .= Helper::renderFlashMessages();
418
            } else {
419
                Helper::addMessage(
420
                    $GLOBALS['LANG']->getLL('update.documentAddFormatNotOkay', true),
421
                    $GLOBALS['LANG']->getLL('update.documentAddFormat', true),
422
                    \TYPO3\CMS\Core\Messaging\FlashMessage::WARNING
423
                );
424
                $this->content .= Helper::renderFlashMessages();
425
                return;
426
            }
427
        }
428
        $sqlQuery = 'UPDATE `tx_dlf_documents` SET `document_format`="METS" WHERE `document_format` IS NULL OR `document_format`="";';
429
        $result = $GLOBALS['TYPO3_DB']->sql_query($sqlQuery);
430
        if ($result) {
431
            Helper::addMessage(
432
                $GLOBALS['LANG']->getLL('update.documentSetFormatForOldEntriesOkay', true),
433
                $GLOBALS['LANG']->getLL('update.documentSetFormatForOldEntries', true),
434
                \TYPO3\CMS\Core\Messaging\FlashMessage::OK
435
            );
436
        } else {
437
            Helper::addMessage(
438
                $GLOBALS['LANG']->getLL('update.documentSetFormatForOldEntriesNotOkay', true),
439
                $GLOBALS['LANG']->getLL('update.documentSetFormatForOldEntries', true),
440
                \TYPO3\CMS\Core\Messaging\FlashMessage::WARNING
441
            );
442
        }
443
        $this->content .= Helper::renderFlashMessages();
444
    }
445
}
446