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 (#382)
by
unknown
58:25
created

Collection::showCollectionList()   F

Complexity

Conditions 28
Paths > 20000

Size

Total Lines 164
Code Lines 112

Duplication

Lines 0
Ratio 0 %

Importance

Changes 3
Bugs 0 Features 0
Metric Value
eloc 112
c 3
b 0
f 0
dl 0
loc 164
rs 0
cc 28
nc 112320
nop 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\Plugin;
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
use Kitodo\Dlf\Common\DocumentList;
15
use Kitodo\Dlf\Common\Helper;
16
use Kitodo\Dlf\Common\Solr;
17
use TYPO3\CMS\Core\Database\ConnectionPool;
18
use TYPO3\CMS\Core\Database\Query\QueryBuilder;
19
use TYPO3\CMS\Core\Utility\GeneralUtility;
20
21
/**
22
 * Plugin 'Collection' for the 'dlf' extension
23
 *
24
 * @author Sebastian Meyer <[email protected]>
25
 * @package TYPO3
26
 * @subpackage dlf
27
 * @access public
28
 */
29
class Collection extends \Kitodo\Dlf\Common\AbstractPlugin {
30
    public $scriptRelPath = 'Classes/Plugin/Collection.php';
31
32
    /**
33
     * This holds the hook objects
34
     *
35
     * @var array
36
     * @access protected
37
     */
38
    protected $hookObjects = [];
39
40
    /**
41
     * The main method of the PlugIn
42
     *
43
     * @access public
44
     *
45
     * @param string $content: The PlugIn content
46
     * @param array $conf: The PlugIn configuration
47
     *
48
     * @return string The content that is displayed on the website
49
     */
50
    public function main($content, $conf) {
51
        $this->init($conf);
52
        // Turn cache on.
53
        $this->setCache(TRUE);
54
        // Quit without doing anything if required configuration variables are not set.
55
        if (empty($this->conf['pages'])) {
56
            Helper::devLog('Incomplete plugin configuration', DEVLOG_SEVERITY_WARNING);
57
            return $content;
58
        }
59
        // Load template file.
60
        $this->getTemplate();
61
        // Get hook objects.
62
        $this->hookObjects = Helper::getHookObjects($this->scriptRelPath);
63
        if (!empty($this->piVars['collection'])) {
64
            $this->showSingleCollection(intval($this->piVars['collection']));
65
        } else {
66
            $content .= $this->showCollectionList();
67
        }
68
        return $this->pi_wrapInBaseClass($content);
69
    }
70
71
    /**
72
     * Builds a collection list
73
     *
74
     * @access protected
75
     *
76
     * @return string The list of collections ready to output
77
     */
78
    protected function showCollectionList() {
79
        /** @var QueryBuilder $queryBuilder */
80
        $queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)
81
            ->getQueryBuilderForTable('tx_dlf_collections');
82
83
        $selectedCollections = $queryBuilder->expr()->neq('tx_dlf_collections.uid', 0);
84
        $orderBy = 'tx_dlf_collections.label';
85
        $showUserDefinedColls = '';
86
        // Handle collections set by configuration.
87
        if ($this->conf['collections']) {
88
            if (count(explode(',', $this->conf['collections'])) == 1
89
                && empty($this->conf['dont_show_single'])) {
90
                $this->showSingleCollection(intval(trim($this->conf['collections'], ' ,')));
91
            }
92
            $selectedCollections = $queryBuilder->expr()->in('tx_dlf_collections.uid', implode(',', GeneralUtility::intExplode(',', $this->conf['collections'])));
93
        }
94
        // Should user-defined collections be shown?
95
        if (empty($this->conf['show_userdefined'])) {
96
            $showUserDefinedColls = $queryBuilder->expr()->eq('tx_dlf_collections.fe_cruser_id', 0);
97
        } elseif ($this->conf['show_userdefined'] > 0) {
98
            if (!empty($GLOBALS['TSFE']->fe_user->user['uid'])) {
99
                $showUserDefinedColls = $queryBuilder->expr()->eq('tx_dlf_collections.fe_cruser_id', intval($GLOBALS['TSFE']->fe_user->user['uid']));
100
            } else {
101
                $showUserDefinedColls = $queryBuilder->expr()->neq('tx_dlf_collections.fe_cruser_id', 0);
102
            }
103
        }
104
105
        // Get collections.
106
        $queryBuilder
107
            ->select(
108
                'tx_dlf_collections.index_name AS index_name',
109
                'tx_dlf_collections.index_search as index_query',
110
                'tx_dlf_collections.uid AS uid',
111
                'tx_dlf_collections.sys_language_uid AS sys_language_uid',
112
                'tx_dlf_collections.label AS label',
113
                'tx_dlf_collections.thumbnail AS thumbnail',
114
                'tx_dlf_collections.description AS description',
115
                'tx_dlf_collections.priority AS priority'
116
            )
117
            ->from('tx_dlf_collections')
118
            ->where(
119
                $selectedCollections,
120
                $showUserDefinedColls,
121
                $queryBuilder->expr()->eq('tx_dlf_collections.pid', intval($this->conf['pages'])),
122
                $queryBuilder->expr()->andX(
123
                    $queryBuilder->expr()->orX(
124
                        $queryBuilder->expr()->in('tx_dlf_collections.sys_language_uid', array(-1, 0)),
125
                        $queryBuilder->expr()->eq('tx_dlf_collections.sys_language_uid', $GLOBALS['TSFE']->sys_language_uid)
126
                    ),
127
                    $queryBuilder->expr()->eq('tx_dlf_collections.l18n_parent', 0)
128
                ),
129
                Helper::whereExpression('tx_dlf_collections')
130
            )
131
            ->orderBy($orderBy);
132
133
        $result = $queryBuilder->execute();
134
        $count = $queryBuilder->count('uid')->execute()->fetchColumn(0);
135
        $content = '';
136
        if ($count == 1 && empty($this->conf['dont_show_single'])) {
137
            $resArray = $result->fetch();
138
            $this->showSingleCollection(intval($resArray['uid']));
139
        }
140
        $solr = Solr::getInstance($this->conf['solrcore']);
141
        // We only care about the UID and partOf in the results and want them sorted
142
        $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...
143
        $params['sort'] = ['uid' => 'asc'];
144
        $collections = [];
145
        while ($collectionData = $result->fetch()) {
146
            if ($collectionData['sys_language_uid'] != $GLOBALS['TSFE']->sys_language_content && $GLOBALS['TSFE']->sys_language_contentOL) {
147
                $collections[$collectionData['uid']] = $GLOBALS['TSFE']->sys_page->getRecordOverlay('tx_dlf_collections', $collectionData, $GLOBALS['TSFE']->sys_language_content, $GLOBALS['TSFE']->sys_language_contentOL);
148
            } else {
149
                $collections[$collectionData['uid']] = $collectionData;
150
            }
151
        }
152
        // Sort collections according to flexform configuration
153
        if ($this->conf['collections']) {
154
            $sortedCollections = [];
155
            foreach (GeneralUtility::intExplode(',', $this->conf['collections']) as $uid) {
156
                $sortedCollections[$uid] = $collections[$uid];
157
            }
158
            $collections = $sortedCollections;
159
        }
160
        $markerArray = [];
161
        // Process results.
162
        foreach ($collections as $collection) {
163
            $solr_query = '';
164
            if ($collection['index_query'] != '') {
165
                $solr_query .= '('.$collection['index_query'].')';
166
            } else {
167
                $solr_query .= 'collection:("'.$collection['index_name'].'")';
168
            }
169
            $partOfNothing = $solr->search_raw($solr_query.' AND partof:0', $params);
170
            $partOfSomething = $solr->search_raw($solr_query.' AND NOT partof:0', $params);
171
            // Titles are all documents that are "root" elements i.e. partof == 0
172
            $collection['titles'] = [];
173
            foreach ($partOfNothing as $doc) {
174
                $collection['titles'][$doc->uid] = $doc->uid;
175
            }
176
            // Volumes are documents that are both
177
            // a) "leaf" elements i.e. partof != 0
178
            // b) "root" elements that are not referenced by other documents ("root" elements that have no descendants)
179
            $collection['volumes'] = $collection['titles'];
180
            foreach ($partOfSomething as $doc) {
181
                $collection['volumes'][$doc->uid] = $doc->uid;
182
                // If a document is referenced via partof, it’s not a volume anymore.
183
                unset($collection['volumes'][$doc->partof]);
184
            }
185
            // Generate random but unique array key taking priority into account.
186
            do {
187
                $_key = ($collection['priority'] * 1000) + mt_rand(0, 1000);
188
            } while (!empty($markerArray[$_key]));
189
            // Merge plugin variables with new set of values.
190
            $additionalParams = ['collection' => $collection['uid']];
191
            if (is_array($this->piVars)) {
192
                $piVars = $this->piVars;
193
                unset($piVars['DATA']);
194
                $additionalParams = Helper::mergeRecursiveWithOverrule($piVars, $additionalParams);
195
            }
196
            // Build typolink configuration array.
197
            $conf = [
198
                'useCacheHash' => 1,
199
                'parameter' => $GLOBALS['TSFE']->id,
200
                'additionalParams' => \TYPO3\CMS\Core\Utility\GeneralUtility::implodeArrayForUrl($this->prefixId, $additionalParams, '', TRUE, FALSE)
201
            ];
202
            // Link collection's title to list view.
203
            $markerArray[$_key]['###TITLE###'] = $this->cObj->typoLink(htmlspecialchars($collection['label']), $conf);
204
            // Add feed link if applicable.
205
            if (!empty($this->conf['targetFeed'])) {
206
                $img = '<img src="'.\TYPO3\CMS\Core\Utility\ExtensionManagementUtility::siteRelPath($this->extKey).'Resources/Public/Icons/txdlffeeds.png" alt="'.$this->pi_getLL('feedAlt', '', TRUE).'" title="'.$this->pi_getLL('feedTitle', '', TRUE).'" />';
207
                $markerArray[$_key]['###FEED###'] = $this->pi_linkTP($img, [$this->prefixId => ['collection' => $collection['uid']]], FALSE, $this->conf['targetFeed']);
208
            } else {
209
                $markerArray[$_key]['###FEED###'] = '';
210
            }
211
            // Add thumbnail.
212
            if (!empty($collection['thumbnail'])) {
213
                $markerArray[$_key]['###THUMBNAIL###'] = '<img alt="" title="'.htmlspecialchars($collection['label']).'" src="'.$collection['thumbnail'].'" />';
214
            } else {
215
                $markerArray[$_key]['###THUMBNAIL###'] = '';
216
            }
217
            // Add description.
218
            $markerArray[$_key]['###DESCRIPTION###'] = $this->pi_RTEcssText($collection['description']);
219
            // Build statistic's output.
220
            $labelTitles = $this->pi_getLL((count($collection['titles']) > 1 ? 'titles' : 'title'), '', FALSE);
221
            $markerArray[$_key]['###COUNT_TITLES###'] = htmlspecialchars(count($collection['titles']).$labelTitles);
222
            $labelVolumes = $this->pi_getLL((count($collection['volumes']) > 1 ? 'volumes' : 'volume'), '', FALSE);
223
            $markerArray[$_key]['###COUNT_VOLUMES###'] = htmlspecialchars(count($collection['volumes']).$labelVolumes);
224
        }
225
        // Randomize sorting?
226
        if (!empty($this->conf['randomize'])) {
227
            ksort($markerArray, SORT_NUMERIC);
228
            // Don't cache the output.
229
            $this->setCache(FALSE);
230
        }
231
        $entry = $this->templateService->getSubpart($this->template, '###ENTRY###');
232
        foreach ($markerArray as $marker) {
233
            $content .= $this->templateService->substituteMarkerArray($entry, $marker);
234
        }
235
        // Hook for getting custom collection hierarchies/subentries (requested by SBB).
236
        foreach ($this->hookObjects as $hookObj) {
237
            if (method_exists($hookObj, 'showCollectionList_getCustomCollectionList')) {
238
                $hookObj->showCollectionList_getCustomCollectionList($this, $this->conf['templateFile'], $content, $markerArray);
239
            }
240
        }
241
        return $this->templateService->substituteSubpart($this->template, '###ENTRY###', $content, TRUE);
242
    }
243
244
    /**
245
     * Builds a collection's list
246
     *
247
     * @access protected
248
     *
249
     * @param integer $id: The collection's UID
250
     *
251
     * @return void
252
     */
253
    protected function showSingleCollection($id) {
254
        /** @var QueryBuilder $queryBuilder */
255
        $queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)
256
            ->getQueryBuilderForTable('tx_dlf_collections');
257
258
        $additionalWhere = '';
259
        // Should user-defined collections be shown?
260
        if (empty($this->conf['show_userdefined'])) {
261
            $additionalWhere = $queryBuilder->expr()->eq('tx_dlf_collections.fe_cruser_id', 0);
262
        } elseif ($this->conf['show_userdefined'] > 0) {
263
            $additionalWhere = $queryBuilder->expr()->neq('tx_dlf_collections.fe_cruser_id', 0);
264
        }
265
266
        // Get collection information from DB
267
        $collection = $queryBuilder
268
            ->select(
269
                'tx_dlf_collections.index_name AS index_name',
270
                'tx_dlf_collections.index_search as index_search',
271
                'tx_dlf_collections.label AS collLabel',
272
                'tx_dlf_collections.description AS collDesc',
273
                'tx_dlf_collections.thumbnail AS collThumb',
274
                'tx_dlf_collections.fe_cruser_id'
275
            )
276
            ->from('tx_dlf_collections')
277
            ->where(
278
                $queryBuilder->expr()->eq('tx_dlf_collections.pid', intval($this->conf['pages'])),
279
                $queryBuilder->expr()->eq('tx_dlf_collections.uid', intval($id)),
280
                $additionalWhere,
281
                $queryBuilder->expr()->eq('tx_dlf_collections.l18n_parent', 0),
282
                Helper::whereExpression('tx_dlf_collections')
283
            )
284
            ->setMaxResults(1)
285
            ->execute();
286
287
        // Fetch corresponding document UIDs from Solr.
288
        if ($resArray = $collection->fetch()) {
289
            $collectionData = $resArray;
290
        } else {
291
            Helper::devLog('No collection with UID '.$id.' found.', DEVLOG_SEVERITY_WARNING);
292
            return;
293
        }
294
        if ($collectionData['index_search'] != '') {
295
            $solr_query = '('.$collectionData['index_search'].')';
296
        } else {
297
            $solr_query = 'collection:("'.$collectionData['index_name'].'")';
298
        }
299
        $solr = Solr::getInstance($this->conf['solrcore']);
300
        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...
301
            Helper::devLog('Apache Solr not available', DEVLOG_SEVERITY_ERROR);
302
            return;
303
        }
304
        $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...
305
        $params['sort'] = ['uid' => 'asc'];
306
        $solrResult = $solr->search_raw($solr_query, $params);
307
        // Initialize array
308
        $documentSet = [];
309
        foreach ($solrResult as $doc) {
310
            $documentSet[] = $doc->uid;
311
        }
312
        $documentSet = array_unique($documentSet);
313
        // Fetch document info for UIDs in $documentSet from DB
314
        $documents = $queryBuilder
315
            ->select(
316
                'tx_dlf_documents.uid AS uid',
317
                'tx_dlf_documents.metadata_sorting AS metadata_sorting',
318
                'tx_dlf_documents.volume_sorting AS volume_sorting',
319
                'tx_dlf_documents.partof AS partof'
320
            )
321
            ->from('tx_dlf_documents')
322
            ->where(
323
                $queryBuilder->expr()->eq('tx_dlf_documents.pid', intval($this->conf['pages'])),
324
                $queryBuilder->expr()->in('tx_dlf_documents.uid', $documentSet),
325
                Helper::whereExpression('tx_dlf_documents')
326
            )
327
            ->execute();
328
329
        $toplevel = [];
330
        $subparts = [];
331
        $listMetadata = [];
332
        // Process results.
333
        while ($resArray = $documents->fetch()) {
334
            if (empty($l10nOverlay)) {
335
                $l10nOverlay = $GLOBALS['TSFE']->sys_page->getRecordOverlay('tx_dlf_collections', $resArray, $GLOBALS['TSFE']->sys_language_content, $GLOBALS['TSFE']->sys_language_contentOL);
336
            }
337
            if (empty($listMetadata)) {
338
                $listMetadata = [
339
                    'label' => !empty($l10nOverlay['label']) ? htmlspecialchars($l10nOverlay['label']) : htmlspecialchars($collectionData['collLabel']),
340
                    'description' => !empty($l10nOverlay['description']) ? $this->pi_RTEcssText($l10nOverlay['description']) : $this->pi_RTEcssText($collectionData['collDesc']),
341
                    'thumbnail' => htmlspecialchars($collectionData['collThumb']),
342
                    'options' => [
343
                        'source' => 'collection',
344
                        'select' => $id,
345
                        'userid' => $collectionData['userid'],
346
                        'params' => ['filterquery' => [['query' => 'collection_faceting:("'.$collectionData['index_name'].'")']]],
347
                        'core' => '',
348
                        'pid' => $this->conf['pages'],
349
                        'order' => 'title',
350
                        'order.asc' => TRUE
351
                    ]
352
                ];
353
            }
354
            // Split toplevel documents from volumes.
355
            if ($resArray['partof'] == 0) {
356
                // Prepare document's metadata for sorting.
357
                $sorting = unserialize($resArray['metadata_sorting']);
358
                if (!empty($sorting['type']) && \TYPO3\CMS\Core\Utility\MathUtility::canBeInterpretedAsInteger($sorting['type'])) {
359
                    $sorting['type'] = Helper::getIndexNameFromUid($sorting['type'], 'tx_dlf_structures', $this->conf['pages']);
360
                }
361
                if (!empty($sorting['owner']) && \TYPO3\CMS\Core\Utility\MathUtility::canBeInterpretedAsInteger($sorting['owner'])) {
362
                    $sorting['owner'] = Helper::getIndexNameFromUid($sorting['owner'], 'tx_dlf_libraries', $this->conf['pages']);
363
                }
364
                if (!empty($sorting['collection']) && \TYPO3\CMS\Core\Utility\MathUtility::canBeInterpretedAsInteger($sorting['collection'])) {
365
                    $sorting['collection'] = Helper::getIndexNameFromUid($sorting['collection'], 'tx_dlf_collections', $this->conf['pages']);
366
                }
367
                $toplevel[$resArray['uid']] = [
368
                    'u' => $resArray['uid'],
369
                    'h' => '',
370
                    's' => $sorting,
371
                    'p' => []
372
                ];
373
            } else {
374
                $subparts[$resArray['partof']][$resArray['volume_sorting']] = $resArray['uid'];
375
            }
376
        }
377
        // Add volumes to the corresponding toplevel documents.
378
        foreach ($subparts as $partof => $parts) {
379
            if (!empty($toplevel[$partof])) {
380
                ksort($parts);
381
                foreach ($parts as $part) {
382
                    $toplevel[$partof]['p'][] = ['u' => $part];
383
                }
384
            }
385
        }
386
        // Save list of documents.
387
        $list = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance(DocumentList::class);
388
        $list->reset();
389
        $list->add(array_values($toplevel));
390
        $listMetadata['options']['numberOfToplevelHits'] = count($list);
391
        $list->metadata = $listMetadata;
392
        $list->save();
393
        // Clean output buffer.
394
        ob_end_clean();
395
        // Send headers.
396
        header('Location: '.\TYPO3\CMS\Core\Utility\GeneralUtility::locationHeaderUrl($this->cObj->typoLink_URL(['parameter' => $this->conf['targetPid']])));
397
        exit;
398
    }
399
}
400