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 ( 70fd28...767599 )
by Sebastian
23s queued 11s
created

Indexer::processLogical()   F

Complexity

Conditions 21
Paths 171

Size

Total Lines 88
Code Lines 61

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 21
eloc 61
nc 171
nop 2
dl 0
loc 88
rs 3.575
c 0
b 0
f 0

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
namespace Kitodo\Dlf\Common;
3
4
/**
5
 * (c) Kitodo. Key to digital objects e.V. <[email protected]>
6
 *
7
 * This file is part of the Kitodo and TYPO3 projects.
8
 *
9
 * @license GNU General Public License version 3 or later.
10
 * For the full copyright and license information, please read the
11
 * LICENSE.txt file that was distributed with this source code.
12
 */
13
14
/**
15
 * Indexer class for the 'dlf' extension
16
 *
17
 * @author Sebastian Meyer <[email protected]>
18
 * @package TYPO3
19
 * @subpackage dlf
20
 * @access public
21
 */
22
class Indexer {
23
    /**
24
     * The extension key
25
     *
26
     * @var string
27
     * @access public
28
     */
29
    public static $extKey = 'dlf';
30
31
    /**
32
     * Array of metadata fields' configuration
33
     * @see loadIndexConf()
34
     *
35
     * @var array
36
     * @access protected
37
     */
38
    protected static $fields = [
39
        'autocomplete' => [],
40
        'facets' => [],
41
        'sortables' => [],
42
        'indexed' => [],
43
        'stored' => [],
44
        'tokenized' => [],
45
        'fieldboost' => []
46
    ];
47
48
    /**
49
     * Is the index configuration loaded?
50
     * @see $fields
51
     *
52
     * @var boolean
53
     * @access protected
54
     */
55
    protected static $fieldsLoaded = FALSE;
56
57
    /**
58
     * List of already processed documents
59
     *
60
     * @var array
61
     * @access protected
62
     */
63
    protected static $processedDocs = [];
64
65
    /**
66
     * Instance of \Kitodo\Dlf\Common\Solr class
67
     *
68
     * @var \Kitodo\Dlf\Common\Solr
69
     * @access protected
70
     */
71
    protected static $solr;
72
73
    /**
74
     * Insert given document into Solr index
75
     *
76
     * @access public
77
     *
78
     * @param \Kitodo\Dlf\Common\Document &$doc: The document to add
79
     * @param integer $core: UID of the Solr core to use
80
     *
81
     * @return integer 0 on success or 1 on failure
82
     */
83
    public static function add(Document &$doc, $core = 0) {
84
        if (in_array($doc->uid, self::$processedDocs)) {
0 ignored issues
show
Bug Best Practice introduced by
The property $uid is declared protected in Kitodo\Dlf\Common\Document. Since you implement __get, consider adding a @property or @property-read.
Loading history...
85
            return 0;
86
        } elseif (self::solrConnect($core, $doc->pid)) {
0 ignored issues
show
Bug Best Practice introduced by
The property $pid is declared protected in Kitodo\Dlf\Common\Document. Since you implement __get, consider adding a @property or @property-read.
Loading history...
87
            $errors = 0;
88
            // Handle multi-volume documents.
89
            if ($doc->parentId) {
0 ignored issues
show
Bug Best Practice introduced by
The property $parentId is declared protected in Kitodo\Dlf\Common\Document. Since you implement __get, consider adding a @property or @property-read.
Loading history...
90
                $parent = Document::getInstance($doc->parentId, 0, TRUE);
91
                if ($parent->ready) {
0 ignored issues
show
Bug Best Practice introduced by
The property $ready is declared protected in Kitodo\Dlf\Common\Document. Since you implement __get, consider adding a @property or @property-read.
Loading history...
92
                    $errors = self::add($parent, $core);
93
                } else {
94
                    Helper::devLog('Could not load parent document with UID '.$doc->parentId, DEVLOG_SEVERITY_ERROR);
95
                    return 1;
96
                }
97
            }
98
            try {
99
                // Add document to list of processed documents.
100
                self::$processedDocs[] = $doc->uid;
101
                // Delete old Solr documents.
102
                $updateQuery = self::$solr->service->createUpdate();
0 ignored issues
show
Bug Best Practice introduced by
The property $service is declared protected in Kitodo\Dlf\Common\Solr. Since you implement __get, consider adding a @property or @property-read.
Loading history...
103
                $updateQuery->addDeleteQuery('uid:'.$doc->uid);
104
                self::$solr->service->update($updateQuery);
105
                // Index every logical unit as separate Solr document.
106
                foreach ($doc->tableOfContents as $logicalUnit) {
0 ignored issues
show
Bug Best Practice introduced by
The property $tableOfContents is declared protected in Kitodo\Dlf\Common\Document. Since you implement __get, consider adding a @property or @property-read.
Loading history...
107
                    if (!$errors) {
108
                        $errors = self::processLogical($doc, $logicalUnit);
109
                    } else {
110
                        break;
111
                    }
112
                }
113
                // Index fulltext files if available.
114
                if ($doc->hasFulltext) {
115
                    foreach ($doc->physicalStructure as $pageNumber => $xmlId) {
116
                        if (!$errors) {
117
                            $errors = self::processPhysical($doc, $pageNumber, $doc->physicalStructureInfo[$xmlId]);
118
                        } else {
119
                            break;
120
                        }
121
                    }
122
                }
123
                // Commit all changes.
124
                $updateQuery = self::$solr->service->createUpdate();
125
                $updateQuery->addCommit();
126
                self::$solr->service->update($updateQuery);
127
                // Get document title from database.
128
                $result = $GLOBALS['TYPO3_DB']->exec_SELECTquery(
129
                    'tx_dlf_documents.title AS title',
130
                    'tx_dlf_documents',
131
                    'tx_dlf_documents.uid='.intval($doc->uid)
132
                        .Helper::whereClause('tx_dlf_documents'),
133
                    '',
134
                    '',
135
                    '1'
136
                );
137
                $resArray = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($result);
138
                if ((TYPO3_REQUESTTYPE & TYPO3_REQUESTTYPE_CLI) == FALSE) {
0 ignored issues
show
Bug Best Practice introduced by
It seems like you are loosely comparing Kitodo\Dlf\Common\TYPO3_...n\TYPO3_REQUESTTYPE_CLI of type integer to the boolean FALSE. If you are specifically checking for 0, consider using something more explicit like === 0 instead.
Loading history...
139
                    if (!$errors) {
140
                        Helper::addMessage(
141
                            htmlspecialchars(sprintf(Helper::getMessage('flash.documentIndexed'), $resArray['title'], $doc->uid)),
142
                            Helper::getMessage('flash.done', TRUE),
143
                            \TYPO3\CMS\Core\Messaging\FlashMessage::OK,
144
                            TRUE
145
                        );
146
                    } else {
147
                        Helper::addMessage(
148
                            htmlspecialchars(sprintf(Helper::getMessage('flash.documentNotIndexed'), $resArray['title'], $doc->uid)),
149
                            Helper::getMessage('flash.error', TRUE),
150
                            \TYPO3\CMS\Core\Messaging\FlashMessage::ERROR,
151
                            TRUE
152
                        );
153
                    }
154
                }
155
                return $errors;
156
            } catch (\Exception $e) {
157
                if ((TYPO3_REQUESTTYPE & TYPO3_REQUESTTYPE_CLI) == FALSE) {
0 ignored issues
show
Bug Best Practice introduced by
It seems like you are loosely comparing Kitodo\Dlf\Common\TYPO3_...n\TYPO3_REQUESTTYPE_CLI of type integer to the boolean FALSE. If you are specifically checking for 0, consider using something more explicit like === 0 instead.
Loading history...
158
                    Helper::addMessage(
159
                        Helper::getMessage('flash.solrException', TRUE).'<br />'.htmlspecialchars($e->getMessage()),
160
                        Helper::getMessage('flash.error', TRUE),
161
                        \TYPO3\CMS\Core\Messaging\FlashMessage::ERROR,
162
                        TRUE
163
                    );
164
                }
165
                Helper::devLog('Apache Solr threw exception: "'.$e->getMessage().'"', DEVLOG_SEVERITY_ERROR);
166
                return 1;
167
            }
168
        } else {
169
            if ((TYPO3_REQUESTTYPE & TYPO3_REQUESTTYPE_CLI) == FALSE) {
0 ignored issues
show
Bug Best Practice introduced by
It seems like you are loosely comparing Kitodo\Dlf\Common\TYPO3_...n\TYPO3_REQUESTTYPE_CLI of type integer to the boolean FALSE. If you are specifically checking for 0, consider using something more explicit like === 0 instead.
Loading history...
170
                Helper::addMessage(
171
                    Helper::getMessage('flash.solrNoConnection', TRUE),
172
                    Helper::getMessage('flash.warning', TRUE),
173
                    \TYPO3\CMS\Core\Messaging\FlashMessage::WARNING,
174
                    TRUE
175
                );
176
            }
177
            Helper::devLog('Could not connect to Apache Solr server', DEVLOG_SEVERITY_ERROR);
178
            return 1;
179
        }
180
    }
181
182
    /**
183
     * Delete document from Solr index
184
     *
185
     * @access public
186
     *
187
     * @param integer $uid: UID of the document to delete
188
     *
189
     * @return integer 0 on success or 1 on failure
190
     */
191
    public static function delete($uid) {
192
        // Sanitize input.
193
        $uid = max(intval($uid), 0);
194
        // Get Solr core for document.
195
        $result = $GLOBALS['TYPO3_DB']->exec_SELECTquery(
196
            'tx_dlf_solrcores.uid AS uid,tx_dlf_documents.title AS title',
197
            'tx_dlf_solrcores,tx_dlf_documents',
198
            'tx_dlf_solrcores.uid=tx_dlf_documents.solrcore'
199
                .' AND tx_dlf_documents.uid='.$uid
200
                .Helper::whereClause('tx_dlf_solrcores'),
201
            '',
202
            '',
203
            '1'
204
        );
205
        if ($GLOBALS['TYPO3_DB']->sql_num_rows($result)) {
206
            list ($core, $title) = $GLOBALS['TYPO3_DB']->sql_fetch_row($result);
207
            // Establish Solr connection.
208
            if (self::solrConnect($core)) {
209
                try {
210
                    // Delete Solr document.
211
                    $updateQuery = self::$solr->service->createUpdate();
0 ignored issues
show
Bug Best Practice introduced by
The property $service is declared protected in Kitodo\Dlf\Common\Solr. Since you implement __get, consider adding a @property or @property-read.
Loading history...
212
                    $updateQuery->addDeleteQuery('uid:'.$uid);
213
                    $updateQuery->addCommit();
214
                    self::$solr->service->update($updateQuery);
215
                } catch (\Exception $e) {
216
                    if ((TYPO3_REQUESTTYPE & TYPO3_REQUESTTYPE_CLI) == FALSE) {
0 ignored issues
show
Bug Best Practice introduced by
It seems like you are loosely comparing Kitodo\Dlf\Common\TYPO3_...n\TYPO3_REQUESTTYPE_CLI of type integer to the boolean FALSE. If you are specifically checking for 0, consider using something more explicit like === 0 instead.
Loading history...
217
                        Helper::addMessage(
218
                            Helper::getMessage('flash.solrException', TRUE).'<br />'.htmlspecialchars($e->getMessage()),
219
                            Helper::getMessage('flash.error', TRUE),
220
                            \TYPO3\CMS\Core\Messaging\FlashMessage::ERROR,
221
                            TRUE
222
                        );
223
                    }
224
                    Helper::devLog('Apache Solr threw exception: "'.$e->getMessage().'"', DEVLOG_SEVERITY_ERROR);
225
                    return 1;
226
                }
227
            } else {
228
                if ((TYPO3_REQUESTTYPE & TYPO3_REQUESTTYPE_CLI) == FALSE) {
0 ignored issues
show
Bug Best Practice introduced by
It seems like you are loosely comparing Kitodo\Dlf\Common\TYPO3_...n\TYPO3_REQUESTTYPE_CLI of type integer to the boolean FALSE. If you are specifically checking for 0, consider using something more explicit like === 0 instead.
Loading history...
229
                    Helper::addMessage(
230
                        Helper::getMessage('flash.solrNoConnection', TRUE),
231
                        Helper::getMessage('flash.error', TRUE),
232
                        \TYPO3\CMS\Core\Messaging\FlashMessage::ERROR,
233
                        TRUE
234
                    );
235
                }
236
                Helper::devLog('Could not connect to Apache Solr server', DEVLOG_SEVERITY_ERROR);
237
                return 1;
238
            }
239
            if ((TYPO3_REQUESTTYPE & TYPO3_REQUESTTYPE_CLI) == FALSE) {
0 ignored issues
show
Bug Best Practice introduced by
It seems like you are loosely comparing Kitodo\Dlf\Common\TYPO3_...n\TYPO3_REQUESTTYPE_CLI of type integer to the boolean FALSE. If you are specifically checking for 0, consider using something more explicit like === 0 instead.
Loading history...
240
                Helper::addMessage(
241
                    htmlspecialchars(sprintf(Helper::getMessage('flash.documentDeleted'), $title, $uid)),
242
                    Helper::getMessage('flash.done', TRUE),
243
                    \TYPO3\CMS\Core\Messaging\FlashMessage::OK,
244
                    TRUE
245
                );
246
            }
247
            return 0;
248
        } else {
249
            Helper::devLog('Invalid UID '.$uid.' for document deletion', DEVLOG_SEVERITY_ERROR);
250
            return 1;
251
        }
252
    }
253
254
    /**
255
     * Returns the dynamic index field name for the given metadata field.
256
     *
257
     * @access public
258
     *
259
     * @param string $index_name: The metadata field's name in database
260
     * @param integer $pid: UID of the configuration page
261
     *
262
     * @return string The field's dynamic index name
263
     */
264
    public static function getIndexFieldName($index_name, $pid = 0) {
265
        // Sanitize input.
266
        $pid = max(intval($pid), 0);
267
        if (!$pid) {
268
            Helper::devLog('Invalid PID '.$pid.' for metadata configuration', DEVLOG_SEVERITY_ERROR);
269
            return '';
270
        }
271
        // Load metadata configuration.
272
        self::loadIndexConf($pid);
273
        // Build field's suffix.
274
        $suffix = (in_array($index_name, self::$fields['tokenized']) ? 't' : 'u');
275
        $suffix .= (in_array($index_name, self::$fields['stored']) ? 's' : 'u');
276
        $suffix .= (in_array($index_name, self::$fields['indexed']) ? 'i' : 'u');
277
        $index_name .= '_'.$suffix;
278
        return $index_name;
279
    }
280
281
    /**
282
     * Load indexing configuration
283
     *
284
     * @access protected
285
     *
286
     * @param integer $pid: The configuration page's UID
287
     *
288
     * @return void
289
     */
290
    protected static function loadIndexConf($pid) {
291
        if (!self::$fieldsLoaded) {
292
            // Get the metadata indexing options.
293
            $result = $GLOBALS['TYPO3_DB']->exec_SELECTquery(
294
                'tx_dlf_metadata.index_name AS index_name,tx_dlf_metadata.index_tokenized AS index_tokenized,tx_dlf_metadata.index_stored AS index_stored,tx_dlf_metadata.index_indexed AS index_indexed,tx_dlf_metadata.is_sortable AS is_sortable,tx_dlf_metadata.is_facet AS is_facet,tx_dlf_metadata.is_listed AS is_listed,tx_dlf_metadata.index_autocomplete AS index_autocomplete,tx_dlf_metadata.index_boost AS index_boost',
295
                'tx_dlf_metadata',
296
                'tx_dlf_metadata.pid='.intval($pid)
297
                    .Helper::whereClause('tx_dlf_metadata'),
298
                '',
299
                '',
300
                ''
301
            );
302
            while ($indexing = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($result)) {
303
                if ($indexing['index_tokenized']) {
304
                    self::$fields['tokenized'][] = $indexing['index_name'];
305
                }
306
                if ($indexing['index_stored']
307
                    || $indexing['is_listed']) {
308
                    self::$fields['stored'][] = $indexing['index_name'];
309
                }
310
                if ($indexing['index_indexed']
311
                    || $indexing['index_autocomplete']) {
312
                    self::$fields['indexed'][] = $indexing['index_name'];
313
                }
314
                if ($indexing['is_sortable']) {
315
                    self::$fields['sortables'][] = $indexing['index_name'];
316
                }
317
                if ($indexing['is_facet']) {
318
                    self::$fields['facets'][] = $indexing['index_name'];
319
                }
320
                if ($indexing['index_autocomplete']) {
321
                    self::$fields['autocomplete'][] = $indexing['index_name'];
322
                }
323
                if ($indexing['index_boost'] > 0.0) {
324
                    self::$fields['fieldboost'][$indexing['index_name']] = floatval($indexing['index_boost']);
325
                } else {
326
                    self::$fields['fieldboost'][$indexing['index_name']] = FALSE;
327
                }
328
            }
329
            self::$fieldsLoaded = TRUE;
330
        }
331
    }
332
333
    /**
334
     * Processes a logical unit (and its children) for the Solr index
335
     *
336
     * @access protected
337
     *
338
     * @param \Kitodo\Dlf\Common\Document &$doc: The METS document
339
     * @param array $logicalUnit: Array of the logical unit to process
340
     *
341
     * @return integer 0 on success or 1 on failure
342
     */
343
    protected static function processLogical(Document &$doc, array $logicalUnit) {
344
        $errors = 0;
345
        // Get metadata for logical unit.
346
        $metadata = $doc->metadataArray[$logicalUnit['id']];
0 ignored issues
show
Bug Best Practice introduced by
The property $metadataArray is declared protected in Kitodo\Dlf\Common\Document. Since you implement __get, consider adding a @property or @property-read.
Loading history...
347
        if (!empty($metadata)) {
348
            // Create new Solr document.
349
            $updateQuery = self::$solr->service->createUpdate();
0 ignored issues
show
Bug Best Practice introduced by
The property $service is declared protected in Kitodo\Dlf\Common\Solr. Since you implement __get, consider adding a @property or @property-read.
Loading history...
350
            $solrDoc = $updateQuery->createDocument();
351
            // Create unique identifier from document's UID and unit's XML ID.
352
            $solrDoc->setField('id', $doc->uid.$logicalUnit['id']);
0 ignored issues
show
Bug Best Practice introduced by
The property $uid is declared protected in Kitodo\Dlf\Common\Document. Since you implement __get, consider adding a @property or @property-read.
Loading history...
353
            $solrDoc->setField('uid', $doc->uid);
354
            $solrDoc->setField('pid', $doc->pid);
0 ignored issues
show
Bug Best Practice introduced by
The property $pid is declared protected in Kitodo\Dlf\Common\Document. Since you implement __get, consider adding a @property or @property-read.
Loading history...
355
            if (\TYPO3\CMS\Core\Utility\MathUtility::canBeInterpretedAsInteger($logicalUnit['points'])) {
356
                $solrDoc->setField('page', $logicalUnit['points']);
357
            }
358
            if ($logicalUnit['id'] == $doc->toplevelId) {
0 ignored issues
show
Bug Best Practice introduced by
The property $toplevelId is declared protected in Kitodo\Dlf\Common\Document. Since you implement __get, consider adding a @property or @property-read.
Loading history...
359
                $solrDoc->setField('thumbnail', $doc->thumbnail);
0 ignored issues
show
Bug Best Practice introduced by
The property $thumbnail is declared protected in Kitodo\Dlf\Common\Document. Since you implement __get, consider adding a @property or @property-read.
Loading history...
360
            } elseif (!empty($logicalUnit['thumbnailId'])) {
361
                $solrDoc->setField('thumbnail', $doc->getFileLocation($logicalUnit['thumbnailId']));
362
            }
363
            $solrDoc->setField('partof', $doc->parentId);
0 ignored issues
show
Bug Best Practice introduced by
The property $parentId is declared protected in Kitodo\Dlf\Common\Document. Since you implement __get, consider adding a @property or @property-read.
Loading history...
364
            $solrDoc->setField('root', $doc->rootId);
0 ignored issues
show
Bug Best Practice introduced by
The property $rootId is declared protected in Kitodo\Dlf\Common\Document. Since you implement __get, consider adding a @property or @property-read.
Loading history...
365
            $solrDoc->setField('sid', $logicalUnit['id']);
366
            // There can be only one toplevel unit per UID, independently of backend configuration
367
            $solrDoc->setField('toplevel', $logicalUnit['id'] == $doc->toplevelId ? TRUE : FALSE);
368
            $solrDoc->setField('type', $logicalUnit['type'], self::$fields['fieldboost']['type']);
369
            $solrDoc->setField('title', $metadata['title'][0], self::$fields['fieldboost']['title']);
370
            $solrDoc->setField('volume', $metadata['volume'][0], self::$fields['fieldboost']['volume']);
371
            $solrDoc->setField('record_id', $metadata['record_id'][0]);
372
            $solrDoc->setField('purl', $metadata['purl'][0]);
373
            $solrDoc->setField('location', $doc->location);
0 ignored issues
show
Bug Best Practice introduced by
The property $location is declared protected in Kitodo\Dlf\Common\Document. Since you implement __get, consider adding a @property or @property-read.
Loading history...
374
            $solrDoc->setField('urn', $metadata['urn']);
375
            $solrDoc->setField('collection', $doc->metadataArray[$doc->toplevelId]['collection']);
376
            $autocomplete = [];
377
            foreach ($metadata as $index_name => $data) {
378
                if (!empty($data)
379
                    && substr($index_name, -8) !== '_sorting') {
380
                    $solrDoc->setField(self::getIndexFieldName($index_name, $doc->pid), $data, self::$fields['fieldboost'][$index_name]);
381
                    if (in_array($index_name, self::$fields['sortables'])) {
382
                        // Add sortable fields to index.
383
                        $solrDoc->setField($index_name.'_sorting', $metadata[$index_name.'_sorting'][0]);
384
                    }
385
                    if (in_array($index_name, self::$fields['facets'])) {
386
                        // Add facets to index.
387
                        $solrDoc->setField($index_name.'_faceting', $data);
388
                    }
389
                    if (in_array($index_name, self::$fields['autocomplete'])) {
390
                        $autocomplete = array_merge($autocomplete, $data);
391
                    }
392
                }
393
            }
394
            // Add autocomplete values to index.
395
            if (!empty($autocomplete)) {
396
                $solrDoc->setField('autocomplete', $autocomplete);
397
            }
398
            // Add collection information to logical sub-elements if applicable.
399
            if (in_array('collection', self::$fields['facets'])
400
                && empty($metadata['collection'])
401
                && !empty($doc->metadataArray[$doc->toplevelId]['collection'])) {
402
                $solrDoc->setField('collection_faceting', $doc->metadataArray[$doc->toplevelId]['collection']);
403
            }
404
            try {
405
                $updateQuery->addDocument($solrDoc);
406
                self::$solr->service->update($updateQuery);
407
            } catch (\Exception $e) {
408
                if ((TYPO3_REQUESTTYPE & TYPO3_REQUESTTYPE_CLI) == FALSE) {
0 ignored issues
show
Bug Best Practice introduced by
It seems like you are loosely comparing Kitodo\Dlf\Common\TYPO3_...n\TYPO3_REQUESTTYPE_CLI of type integer to the boolean FALSE. If you are specifically checking for 0, consider using something more explicit like === 0 instead.
Loading history...
409
                    Helper::addMessage(
410
                        Helper::getMessage('flash.solrException', TRUE).'<br />'.htmlspecialchars($e->getMessage()),
411
                        Helper::getMessage('flash.error', TRUE),
412
                        \TYPO3\CMS\Core\Messaging\FlashMessage::ERROR,
413
                        TRUE
414
                    );
415
                }
416
                return 1;
417
            }
418
        }
419
        // Check for child elements...
420
        if (!empty($logicalUnit['children'])) {
421
            foreach ($logicalUnit['children'] as $child) {
422
                if (!$errors) {
423
                    // ...and process them, too.
424
                    $errors = self::processLogical($doc, $child);
425
                } else {
426
                    break;
427
                }
428
            }
429
        }
430
        return $errors;
431
    }
432
433
    /**
434
     * Processes a physical unit for the Solr index
435
     *
436
     * @access protected
437
     *
438
     * @param \Kitodo\Dlf\Common\Document &$doc: The METS document
439
     * @param integer $page: The page number
440
     * @param array $physicalUnit: Array of the physical unit to process
441
     *
442
     * @return integer 0 on success or 1 on failure
443
     */
444
    protected static function processPhysical(Document &$doc, $page, array $physicalUnit) {
445
        $errors = 0;
446
        // Read extension configuration.
447
        $extConf = unserialize($GLOBALS['TYPO3_CONF_VARS']['EXT']['extConf'][self::$extKey]);
448
        if (!empty($physicalUnit['files'][$extConf['fileGrpFulltext']])) {
449
            $file = $doc->getFileLocation($physicalUnit['files'][$extConf['fileGrpFulltext']]);
450
            // Load XML file.
451
            if (\TYPO3\CMS\Core\Utility\GeneralUtility::isValidUrl($file)) {
452
                // Set user-agent to identify self when fetching XML data.
453
                if (!empty($extConf['useragent'])) {
454
                    @ini_set('user_agent', $extConf['useragent']);
1 ignored issue
show
Security Best Practice introduced by
It seems like you do not handle an error condition for ini_set(). This can introduce security issues, and is generally not recommended. ( Ignorable by Annotation )

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

454
                    /** @scrutinizer ignore-unhandled */ @ini_set('user_agent', $extConf['useragent']);

If you suppress an error, we recommend checking for the error condition explicitly:

// For example instead of
@mkdir($dir);

// Better use
if (@mkdir($dir) === false) {
    throw new \RuntimeException('The directory '.$dir.' could not be created.');
}
Loading history...
455
                }
456
                // Turn off libxml's error logging.
457
                $libxmlErrors = libxml_use_internal_errors(TRUE);
458
                // disable entity loading
459
                $previousValueOfEntityLoader = libxml_disable_entity_loader(TRUE);
460
                // Load XML from file.
461
                $xml = simplexml_load_string(\TYPO3\CMS\Core\Utility\GeneralUtility::getUrl($file));
0 ignored issues
show
Bug introduced by
It seems like TYPO3\CMS\Core\Utility\G...lUtility::getUrl($file) can also be of type false; however, parameter $data of simplexml_load_string() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

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

461
                $xml = simplexml_load_string(/** @scrutinizer ignore-type */ \TYPO3\CMS\Core\Utility\GeneralUtility::getUrl($file));
Loading history...
462
                // reset entity loader setting
463
                libxml_disable_entity_loader($previousValueOfEntityLoader);
464
                // Reset libxml's error logging.
465
                libxml_use_internal_errors($libxmlErrors);
466
                if ($xml === FALSE) {
467
                    return 1;
468
                }
469
            } else {
470
                return 1;
471
            }
472
            // Create new Solr document.
473
            $updateQuery = self::$solr->service->createUpdate();
0 ignored issues
show
Bug Best Practice introduced by
The property $service is declared protected in Kitodo\Dlf\Common\Solr. Since you implement __get, consider adding a @property or @property-read.
Loading history...
474
            $solrDoc = $updateQuery->createDocument();
475
            // Create unique identifier from document's UID and unit's XML ID.
476
            $solrDoc->setField('id', $doc->uid.$physicalUnit['id']);
0 ignored issues
show
Bug Best Practice introduced by
The property $uid is declared protected in Kitodo\Dlf\Common\Document. Since you implement __get, consider adding a @property or @property-read.
Loading history...
477
            $solrDoc->setField('uid', $doc->uid);
478
            $solrDoc->setField('pid', $doc->pid);
0 ignored issues
show
Bug Best Practice introduced by
The property $pid is declared protected in Kitodo\Dlf\Common\Document. Since you implement __get, consider adding a @property or @property-read.
Loading history...
479
            $solrDoc->setField('page', $page);
480
            if (!empty($physicalUnit['files'][$extConf['fileGrpThumbs']])) {
481
                $solrDoc->setField('thumbnail', $doc->getFileLocation($physicalUnit['files'][$extConf['fileGrpThumbs']]));
482
            }
483
            $solrDoc->setField('partof', $doc->parentId);
0 ignored issues
show
Bug Best Practice introduced by
The property $parentId is declared protected in Kitodo\Dlf\Common\Document. Since you implement __get, consider adding a @property or @property-read.
Loading history...
484
            $solrDoc->setField('root', $doc->rootId);
0 ignored issues
show
Bug Best Practice introduced by
The property $rootId is declared protected in Kitodo\Dlf\Common\Document. Since you implement __get, consider adding a @property or @property-read.
Loading history...
485
            $solrDoc->setField('sid', $physicalUnit['id']);
486
            $solrDoc->setField('toplevel', FALSE);
487
            $solrDoc->setField('type', $physicalUnit['type'], self::$fields['fieldboost']['type']);
488
            $solrDoc->setField('collection', $doc->metadataArray[$doc->toplevelId]['collection']);
0 ignored issues
show
Bug Best Practice introduced by
The property $metadataArray is declared protected in Kitodo\Dlf\Common\Document. Since you implement __get, consider adding a @property or @property-read.
Loading history...
Bug Best Practice introduced by
The property $toplevelId is declared protected in Kitodo\Dlf\Common\Document. Since you implement __get, consider adding a @property or @property-read.
Loading history...
489
            $solrDoc->setField('fulltext', $doc->getRawText($physicalUnit['id']));
490
            // Add faceting information to physical sub-elements if applicable.
491
            foreach ($doc->metadataArray[$doc->toplevelId] as $index_name => $data) {
492
                if (!empty($data)
493
                    && substr($index_name, -8) !== '_sorting') {
494
                    if (in_array($index_name, self::$fields['facets'])) {
495
                        // Add facets to index.
496
                        $solrDoc->setField($index_name.'_faceting', $data);
497
                    }
498
                }
499
            }
500
            // Add collection information to physical sub-elements if applicable.
501
            if (in_array('collection', self::$fields['facets'])
502
                && !empty($doc->metadataArray[$doc->toplevelId]['collection'])) {
503
                $solrDoc->setField('collection_faceting', $doc->metadataArray[$doc->toplevelId]['collection']);
504
            }
505
            try {
506
                $updateQuery->addDocument($solrDoc);
507
                self::$solr->service->update($updateQuery);
508
            } catch (\Exception $e) {
509
                if ((TYPO3_REQUESTTYPE & TYPO3_REQUESTTYPE_CLI) == FALSE) {
0 ignored issues
show
Bug Best Practice introduced by
It seems like you are loosely comparing Kitodo\Dlf\Common\TYPO3_...n\TYPO3_REQUESTTYPE_CLI of type integer to the boolean FALSE. If you are specifically checking for 0, consider using something more explicit like === 0 instead.
Loading history...
510
                    Helper::addMessage(
511
                        \TYPO3\CMS\Core\Messaging\FlashMessage::class,
512
                        Helper::getMessage('flash.solrException', TRUE).'<br />'.htmlspecialchars($e->getMessage()),
513
                        Helper::getMessage('flash.error', TRUE),
514
                        \TYPO3\CMS\Core\Messaging\FlashMessage::ERROR,
515
                        TRUE
516
                    );
517
                }
518
                return 1;
519
            }
520
        }
521
        return $errors;
522
    }
523
524
    /**
525
     * Connects to Solr server.
526
     *
527
     * @access protected
528
     *
529
     * @param integer $core: UID of the Solr core
530
     * @param integer $pid: UID of the configuration page
531
     *
532
     * @return boolean TRUE on success or FALSE on failure
533
     */
534
    protected static function solrConnect($core, $pid = 0) {
535
        // Get Solr instance.
536
        if (!self::$solr) {
537
            // Connect to Solr server.
538
            if (self::$solr = Solr::getInstance($core)) {
539
                // Load indexing configuration if needed.
540
                if ($pid) {
541
                    self::loadIndexConf($pid);
542
                }
543
            } else {
544
                return FALSE;
545
            }
546
        }
547
        return TRUE;
548
    }
549
550
    /**
551
     * This is a static class, thus no instances should be created
552
     *
553
     * @access private
554
     */
555
    private function __construct() {}
556
}
557