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 ( 2c4c85...70fd28 )
by Sebastian
27s queued 10s
created

tx_dlf_collection   C

Complexity

Total Complexity 53

Size/Duplication

Total Lines 511
Duplicated Lines 0 %

Importance

Changes 19
Bugs 1 Features 1
Metric Value
eloc 195
c 19
b 1
f 1
dl 0
loc 511
rs 6.96
wmc 53

3 Methods

Rating   Name   Duplication   Size   Complexity  
A main() 0 45 5
F showSingleCollection() 0 194 22
F showCollectionList() 0 228 26

How to fix   Complexity   

Complex Class

Complex classes like tx_dlf_collection 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 tx_dlf_collection, 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
/**
13
 * Plugin 'DLF: Collection' for the 'dlf' extension.
14
 *
15
 * @author	Sebastian Meyer <[email protected]>
16
 * @package	TYPO3
17
 * @subpackage	tx_dlf
18
 * @access	public
19
 */
20
class tx_dlf_collection extends tx_dlf_plugin {
21
22
    public $scriptRelPath = 'plugins/collection/class.tx_dlf_collection.php';
23
24
    /**
25
     * This holds the hook objects
26
     *
27
     * @var	array
28
     * @access protected
29
     */
30
    protected $hookObjects = array ();
31
32
    /**
33
     * The main method of the PlugIn
34
     *
35
     * @access	public
36
     *
37
     * @param	string		$content: The PlugIn content
38
     * @param	array		$conf: The PlugIn configuration
39
     *
40
     * @return	string		The content that is displayed on the website
41
     */
42
    public function main($content, $conf) {
43
44
        $this->init($conf);
45
46
        // Turn cache on.
47
        $this->setCache(TRUE);
48
49
        // Quit without doing anything if required configuration variables are not set.
50
        if (empty($this->conf['pages'])) {
51
52
            if (TYPO3_DLOG) {
53
54
                \TYPO3\CMS\Core\Utility\GeneralUtility::devLog('[tx_dlf_collection->main('.$content.', [data])] Incomplete plugin configuration', $this->extKey, SYSLOG_SEVERITY_WARNING, $conf);
0 ignored issues
show
Bug introduced by
The constant SYSLOG_SEVERITY_WARNING was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
55
56
            }
57
58
            return $content;
59
60
        }
61
62
        // Load template file.
63
        if (!empty($this->conf['templateFile'])) {
64
65
            $this->template = $this->cObj->getSubpart($this->cObj->fileResource($this->conf['templateFile']), '###TEMPLATE###');
66
67
        } else {
68
69
            $this->template = $this->cObj->getSubpart($this->cObj->fileResource('EXT:dlf/plugins/collection/template.tmpl'), '###TEMPLATE###');
70
71
        }
72
73
        // Get hook objects.
74
        $this->hookObjects = tx_dlf_helper::getHookObjects($this->scriptRelPath);
75
76
        if (!empty($this->piVars['collection'])) {
77
78
            $this->showSingleCollection(intval($this->piVars['collection']));
79
80
        } else {
81
82
            $content .= $this->showCollectionList();
83
84
        }
85
86
        return $this->pi_wrapInBaseClass($content);
87
88
    }
89
90
    /**
91
     * Builds a collection list
92
     *
93
     * @access	protected
94
     *
95
     * @return	string		The list of collections ready to output
96
     */
97
    protected function showCollectionList() {
98
99
        $selectedCollections = 'tx_dlf_collections.uid != 0';
100
101
        $orderBy = 'tx_dlf_collections.label';
102
103
        $showUserDefinedColls = '';
104
105
        // Handle collections set by configuration.
106
        if ($this->conf['collections']) {
107
108
            if (count(explode(',', $this->conf['collections'])) == 1 && empty($this->conf['dont_show_single'])) {
109
110
                $this->showSingleCollection(intval(trim($this->conf['collections'], ' ,')));
111
112
            }
113
114
            $selectedCollections = 'tx_dlf_collections.uid IN ('.$GLOBALS['TYPO3_DB']->cleanIntList($this->conf['collections']).')';
115
116
            $orderBy = 'FIELD(tx_dlf_collections.uid,'.$GLOBALS['TYPO3_DB']->cleanIntList($this->conf['collections']).')';
117
118
        }
119
120
        // Should user-defined collections be shown?
121
        if (empty($this->conf['show_userdefined'])) {
122
123
            $showUserDefinedColls = ' AND tx_dlf_collections.fe_cruser_id=0';
124
125
        } elseif ($this->conf['show_userdefined'] > 0) {
126
127
            if (!empty($GLOBALS['TSFE']->fe_user->user['uid'])) {
128
129
                $showUserDefinedColls = ' AND tx_dlf_collections.fe_cruser_id='.intval($GLOBALS['TSFE']->fe_user->user['uid']);
130
131
            } else {
132
133
                $showUserDefinedColls = ' AND NOT tx_dlf_collections.fe_cruser_id=0';
134
135
            }
136
137
        }
138
139
        // Get collections.
140
        $result = $GLOBALS['TYPO3_DB']->exec_SELECTquery(
141
            'tx_dlf_collections.index_name AS index_name,tx_dlf_collections.index_search as index_query,tx_dlf_collections.uid AS uid,tx_dlf_collections.sys_language_uid AS sys_language_uid,tx_dlf_collections.label AS label,tx_dlf_collections.thumbnail AS thumbnail,tx_dlf_collections.description AS description,tx_dlf_collections.priority AS priority',
142
            'tx_dlf_collections',
143
            $selectedCollections.$showUserDefinedColls.' AND tx_dlf_collections.pid='.intval($this->conf['pages']).' AND (tx_dlf_collections.sys_language_uid IN (-1,0) OR (tx_dlf_collections.sys_language_uid = '.$GLOBALS['TSFE']->sys_language_uid.' AND tx_dlf_collections.l18n_parent = 0))'.tx_dlf_helper::whereClause('tx_dlf_collections'),
144
            '',
145
            $orderBy,
146
            ''
147
        );
148
149
        $count = $GLOBALS['TYPO3_DB']->sql_num_rows($result);
150
151
        $content = '';
152
153
        if ($count == 1 && empty($this->conf['dont_show_single'])) {
154
155
            $resArray = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($result);
156
157
            $this->showSingleCollection(intval($resArray['uid']));
158
159
        }
160
161
        $solr = tx_dlf_solr::getInstance($this->conf['solrcore']);
162
163
        // We only care about the UID and partOf in the results and want them sorted
164
        $params['fields'] = 'uid,partof';
1 ignored issue
show
Comprehensibility Best Practice introduced by
$params was never initialized. Although not strictly required by PHP, it is generally a good practice to add $params = array(); before regardless.
Loading history...
165
        $params['sort'] = array ('uid' => 'asc');
166
167
        $collections = array ();
168
169
        while ($collectionData = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($result)) {
170
171
            if ($collectionData['sys_language_uid'] != $GLOBALS['TSFE']->sys_language_content && $GLOBALS['TSFE']->sys_language_contentOL) {
172
173
                $collections[$collectionData['uid']] = $GLOBALS['TSFE']->sys_page->getRecordOverlay('tx_dlf_collections', $collectionData, $GLOBALS['TSFE']->sys_language_content, $GLOBALS['TSFE']->sys_language_contentOL);
174
175
            } else {
176
177
                $collections[$collectionData['uid']] = $collectionData;
178
179
            }
180
181
        }
182
183
        $markerArray = array ();
184
185
        // Process results.
186
        foreach ($collections as $collection) {
187
188
            $solr_query = '';
189
190
            if ($collection['index_query'] != '') {
191
192
                $solr_query .= '('.$collection['index_query'].')';
193
194
            } else {
195
196
                $solr_query .= 'collection:("'.$collection['index_name'].'")';
197
198
            }
199
200
            $partOfNothing = $solr->search_raw($solr_query.' AND partof:0', $params);
201
202
            $partOfSomething = $solr->search_raw($solr_query.' AND NOT partof:0', $params);
203
204
            // Titles are all documents that are "root" elements i.e. partof == 0
205
            $collection['titles'] = array ();
206
207
            foreach ($partOfNothing as $doc) {
208
209
                $collection['titles'][$doc->uid] = $doc->uid;
210
211
            }
212
213
            // Volumes are documents that are both
214
            // a) "leaf" elements i.e. partof != 0
215
            // b) "root" elements that are not referenced by other documents ("root" elements that have no descendants)
216
            $collection['volumes'] = $collection['titles'];
217
218
            foreach ($partOfSomething as $doc) {
219
220
                $collection['volumes'][$doc->uid] = $doc->uid;
221
222
                // If a document is referenced via partof, it’s not a volume anymore.
223
                unset($collection['volumes'][$doc->partof]);
224
225
            }
226
227
            // Generate random but unique array key taking priority into account.
228
            do {
229
230
                $_key = ($collection['priority'] * 1000) + mt_rand(0, 1000);
231
232
            } while (!empty($markerArray[$_key]));
233
234
            // Merge plugin variables with new set of values.
235
            $additionalParams = array ('collection' => $collection['uid']);
236
237
            if (is_array($this->piVars)) {
238
239
                $piVars = $this->piVars;
240
241
                unset($piVars['DATA']);
242
243
                $additionalParams = tx_dlf_helper::array_merge_recursive_overrule($piVars, $additionalParams);
244
245
            }
246
247
            // Build typolink configuration array.
248
            $conf = array (
249
                'useCacheHash' => 1,
250
                'parameter' => $GLOBALS['TSFE']->id,
251
                'additionalParams' => \TYPO3\CMS\Core\Utility\GeneralUtility::implodeArrayForUrl($this->prefixId, $additionalParams, '', TRUE, FALSE)
252
            );
253
254
            // Link collection's title to list view.
255
            $markerArray[$_key]['###TITLE###'] = $this->cObj->typoLink(htmlspecialchars($collection['label']), $conf);
256
257
            // Add feed link if applicable.
258
            if (!empty($this->conf['targetFeed'])) {
259
260
                $img = '<img src="'.\TYPO3\CMS\Core\Utility\ExtensionManagementUtility::siteRelPath($this->extKey).'res/icons/txdlffeeds.png" alt="'.$this->pi_getLL('feedAlt', '', TRUE).'" title="'.$this->pi_getLL('feedTitle', '', TRUE).'" />';
261
262
                $markerArray[$_key]['###FEED###'] = $this->pi_linkTP($img, array ($this->prefixId => array ('collection' => $collection['uid'])), FALSE, $this->conf['targetFeed']);
263
264
            } else {
265
266
                $markerArray[$_key]['###FEED###'] = '';
267
268
            }
269
270
            // Add thumbnail.
271
            if (!empty($collection['thumbnail'])) {
272
273
                $markerArray[$_key]['###THUMBNAIL###'] = '<img alt="" title="'.htmlspecialchars($collection['label']).'" src="'.$collection['thumbnail'].'" />';
274
275
            } else {
276
277
                $markerArray[$_key]['###THUMBNAIL###'] = '';
278
279
            }
280
281
            // Add description.
282
            $markerArray[$_key]['###DESCRIPTION###'] = $this->pi_RTEcssText($collection['description']);
283
284
            // Build statistic's output.
285
            $labelTitles = $this->pi_getLL((count($collection['titles']) > 1 ? 'titles' : 'title'), '', FALSE);
286
287
            $markerArray[$_key]['###COUNT_TITLES###'] = htmlspecialchars(count($collection['titles']).$labelTitles);
288
289
            $labelVolumes = $this->pi_getLL((count($collection['volumes']) > 1 ? 'volumes' : 'volume'), '', FALSE);
290
291
            $markerArray[$_key]['###COUNT_VOLUMES###'] = htmlspecialchars(count($collection['volumes']).$labelVolumes);
292
293
        }
294
295
        // Randomize sorting?
296
        if (!empty($this->conf['randomize'])) {
297
298
            ksort($markerArray, SORT_NUMERIC);
299
300
            // Don't cache the output.
301
            $this->setCache(FALSE);
302
303
        }
304
305
        $entry = $this->cObj->getSubpart($this->template, '###ENTRY###');
306
307
        foreach ($markerArray as $marker) {
308
309
            $content .= $this->cObj->substituteMarkerArray($entry, $marker);
310
311
        }
312
313
        // Hook for getting custom collection hierarchies/subentries (requested by SBB).
314
        foreach ($this->hookObjects as $hookObj) {
315
316
            if (method_exists($hookObj, 'showCollectionList_getCustomCollectionList')) {
317
318
                $hookObj->showCollectionList_getCustomCollectionList($this, $this->conf['templateFile'], $content, $markerArray);
319
320
            }
321
322
        }
323
324
        return $this->cObj->substituteSubpart($this->template, '###ENTRY###', $content, TRUE);
325
326
    }
327
328
    /**
329
     * Builds a collection's list
330
     *
331
     * @access	protected
332
     *
333
     * @param	integer		$id: The collection's UID
334
     *
335
     * @return	void
336
     */
337
    protected function showSingleCollection($id) {
338
339
        $additionalWhere = '';
340
341
        // Should user-defined collections be shown?
342
        if (empty($this->conf['show_userdefined'])) {
343
344
            $additionalWhere = ' AND tx_dlf_collections.fe_cruser_id=0';
345
346
        } elseif ($this->conf['show_userdefined'] > 0) {
347
348
            $additionalWhere = ' AND NOT tx_dlf_collections.fe_cruser_id=0';
349
350
        }
351
352
        // Get collection information from DB
353
        $collection = $GLOBALS['TYPO3_DB']->exec_SELECTquery(
354
            'tx_dlf_collections.index_name AS index_name, tx_dlf_collections.index_search as index_query, tx_dlf_collections.label AS collLabel, tx_dlf_collections.description AS collDesc, tx_dlf_collections.thumbnail AS collThumb, tx_dlf_collections.fe_cruser_id',
355
            'tx_dlf_collections',
356
            'tx_dlf_collections.pid='.intval($this->conf['pages']).' AND tx_dlf_collections.uid='.intval($id).$additionalWhere.tx_dlf_helper::whereClause('tx_dlf_collections'),
357
            '',
358
            '',
359
            '1'
360
        );
361
362
        // Fetch corresponding document UIDs from Solr.
363
        $solr_query = '';
364
365
        $collectionData = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($collection);
366
367
        if ($collectionData['index_query'] != '') {
368
369
            $solr_query .= '('.$collectionData['index_query'].')';
370
371
        } else {
372
373
            $solr_query .= 'collection:("'.$collectionData['index_name'].'")';
374
375
        }
376
377
        $solr = tx_dlf_solr::getInstance($this->conf['solrcore']);
378
379
        if (!$solr->ready) {
0 ignored issues
show
Bug Best Practice introduced by
The property $ready is declared protected in tx_dlf_solr. Since you implement __get, consider adding a @property or @property-read.
Loading history...
380
381
            if (TYPO3_DLOG) {
382
383
                \TYPO3\CMS\Core\Utility\GeneralUtility::devLog('[tx_dlf_collection->showSingleCollection('.intval($id).')] Apache Solr not available', $this->extKey, SYSLOG_SEVERITY_ERROR);
0 ignored issues
show
Bug introduced by
The constant SYSLOG_SEVERITY_ERROR was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
384
385
            }
386
387
            return;
388
389
        }
390
391
        $params['fields'] = 'uid';
1 ignored issue
show
Comprehensibility Best Practice introduced by
$params was never initialized. Although not strictly required by PHP, it is generally a good practice to add $params = array(); before regardless.
Loading history...
392
        $params['sort'] = array ('uid' => 'asc');
393
394
        $solrResult = $solr->search_raw($solr_query, $params);
395
396
        // initialize array
397
        $documentSet = [];
398
399
        foreach ($solrResult as $doc) {
400
401
            $documentSet[] = $doc->uid;
402
403
        }
404
405
        $documentSet = array_unique($documentSet);
406
407
        //Fetch document info for UIDs in $documentSet from DB
408
        $documents = $GLOBALS['TYPO3_DB']->exec_SELECTquery(
409
            'tx_dlf_documents.uid AS uid, tx_dlf_documents.metadata_sorting AS metadata_sorting, tx_dlf_documents.volume_sorting AS volume_sorting, tx_dlf_documents.partof AS partof',
410
            'tx_dlf_documents',
411
            'tx_dlf_documents.pid='.intval($this->conf['pages']).' AND tx_dlf_documents.uid IN ('.implode(',', $documentSet).')'.tx_dlf_helper::whereClause('tx_dlf_documents'),
412
            '',
413
            '',
414
            ''
415
        );
416
417
        $toplevel = array ();
418
419
        $subparts = array ();
420
421
        $listMetadata = array ();
422
423
        // Process results.
424
        while ($resArray = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($documents)) {
425
426
            if (empty($l10nOverlay)) {
427
428
                $l10nOverlay = $GLOBALS['TSFE']->sys_page->getRecordOverlay('tx_dlf_collections', $resArray, $GLOBALS['TSFE']->sys_language_content, $GLOBALS['TSFE']->sys_language_contentOL);
429
430
            }
431
432
            if (empty($listMetadata)) {
433
434
                $listMetadata = array (
435
                    'label' => !empty($l10nOverlay['label']) ? htmlspecialchars($l10nOverlay['label']) : htmlspecialchars($collectionData['collLabel']),
436
                    'description' => !empty($l10nOverlay['description']) ? $this->pi_RTEcssText($l10nOverlay['description']) : $this->pi_RTEcssText($collectionData['collDesc']),
437
                    'thumbnail' => htmlspecialchars($collectionData['collThumb']),
438
                    'options' => array (
439
                        'source' => 'collection',
440
                        'select' => $id,
441
                        'userid' => $collectionData['userid'],
442
                        'params' => array ('filterquery' => array (array ('query' => 'collection_faceting:("'.$collectionData['index_name'].'")'))),
443
                        'core' => '',
444
                        'pid' => $this->conf['pages'],
445
                        'order' => 'title',
446
                        'order.asc' => TRUE
447
                    )
448
                );
449
450
            }
451
452
            // Split toplevel documents from volumes.
453
            if ($resArray['partof'] == 0) {
454
455
                // Prepare document's metadata for sorting.
456
                $sorting = unserialize($resArray['metadata_sorting']);
457
458
                if (!empty($sorting['type']) && \TYPO3\CMS\Core\Utility\MathUtility::canBeInterpretedAsInteger($sorting['type'])) {
459
460
                    $sorting['type'] = tx_dlf_helper::getIndexName($sorting['type'], 'tx_dlf_structures', $this->conf['pages']);
461
462
                }
463
464
                if (!empty($sorting['owner']) && \TYPO3\CMS\Core\Utility\MathUtility::canBeInterpretedAsInteger($sorting['owner'])) {
465
466
                    $sorting['owner'] = tx_dlf_helper::getIndexName($sorting['owner'], 'tx_dlf_libraries', $this->conf['pages']);
467
468
                }
469
470
                if (!empty($sorting['collection']) && \TYPO3\CMS\Core\Utility\MathUtility::canBeInterpretedAsInteger($sorting['collection'])) {
471
472
                    $sorting['collection'] = tx_dlf_helper::getIndexName($sorting['collection'], 'tx_dlf_collections', $this->conf['pages']);
473
474
                }
475
476
                $toplevel[$resArray['uid']] = array (
477
                    'u' => $resArray['uid'],
478
                    'h' => '',
479
                    's' => $sorting,
480
                    'p' => array ()
481
                );
482
483
            } else {
484
485
                $subparts[$resArray['partof']][$resArray['volume_sorting']] = $resArray['uid'];
486
487
            }
488
489
        }
490
491
        // Add volumes to the corresponding toplevel documents.
492
        foreach ($subparts as $partof => $parts) {
493
494
            if (!empty($toplevel[$partof])) {
495
496
                ksort($parts);
497
498
                foreach ($parts as $part) {
499
500
                    $toplevel[$partof]['p'][] = array ('u' => $part);
501
502
                }
503
504
            }
505
506
        }
507
508
        // Save list of documents.
509
        $list = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance('tx_dlf_list');
510
511
        $list->reset();
512
513
        $list->add(array_values($toplevel));
514
515
        $listMetadata['options']['numberOfToplevelHits'] = count($list);
516
517
        $list->metadata = $listMetadata;
518
519
        $list->save();
520
521
        // Clean output buffer.
522
        \TYPO3\CMS\Core\Utility\GeneralUtility::cleanOutputBuffers();
0 ignored issues
show
Deprecated Code introduced by
The function TYPO3\CMS\Core\Utility\G...y::cleanOutputBuffers() has been deprecated: since TYPO3 CMS 7, will be removed in CMS 8, use ob_* functions directly or self::flushOutputBuffers ( Ignorable by Annotation )

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

522
        /** @scrutinizer ignore-deprecated */ \TYPO3\CMS\Core\Utility\GeneralUtility::cleanOutputBuffers();

This function has been deprecated. The supplier of the function has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the function will be removed and what other function to use instead.

Loading history...
523
524
        // Send headers.
525
        header('Location: '.\TYPO3\CMS\Core\Utility\GeneralUtility::locationHeaderUrl($this->cObj->typoLink_URL(array ('parameter' => $this->conf['targetPid']))));
526
527
        // Flush output buffer and end script processing.
528
        ob_end_flush();
529
530
        exit;
0 ignored issues
show
Best Practice introduced by
Using exit here is not recommended.

In general, usage of exit should be done with care and only when running in a scripting context like a CLI script.

Loading history...
531
532
    }
533
534
}
535