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 (#715)
by Alexander
03:51
created

ListViewController   F

Complexity

Total Complexity 74

Size/Duplication

Total Lines 406
Duplicated Lines 0 %

Importance

Changes 4
Bugs 0 Features 0
Metric Value
eloc 185
c 4
b 0
f 0
dl 0
loc 406
rs 2.48
wmc 74

7 Methods

Rating   Name   Duplication   Size   Complexity  
A injectMetadataRepository() 0 3 1
A getFieldWrap() 0 6 2
A loadConfig() 0 14 4
F getEntry() 0 73 20
F mainAction() 0 119 25
D getSubEntries() 0 69 21
A parseTS() 0 5 1

How to fix   Complexity   

Complex Class

Complex classes like ListViewController 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 ListViewController, 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
namespace Kitodo\Dlf\Controller;
13
14
use Kitodo\Dlf\Domain\Model\Metadata;
15
use TYPO3\CMS\Core\Configuration\ExtensionConfiguration;
16
use TYPO3\CMS\Core\TypoScript\Parser\TypoScriptParser;
17
use Kitodo\Dlf\Common\Document;
18
use Kitodo\Dlf\Common\DocumentList;
19
use Kitodo\Dlf\Common\Helper;
20
use Kitodo\Dlf\Common\Solr;
21
use TYPO3\CMS\Core\Utility\GeneralUtility;
22
use TYPO3\CMS\Extbase\Utility\LocalizationUtility;
23
use Kitodo\Dlf\Domain\Repository\MetadataRepository;
24
25
/**
26
 * Plugin 'List View' for the 'dlf' extension
27
 *
28
 * @author Sebastian Meyer <[email protected]>
29
 * @author Henrik Lochmann <[email protected]>
30
 * @author Frank Ulrich Weber <[email protected]>
31
 * @package TYPO3
32
 * @subpackage dlf
33
 * @access public
34
 */
35
class ListViewController extends AbstractController
36
{
37
    /**
38
     * This holds the field wrap of the metadata
39
     *
40
     * @var array
41
     * @access private
42
     */
43
    private $fieldwrap = [];
44
45
    /**
46
     * This holds the list
47
     *
48
     * @var \Kitodo\Dlf\Common\DocumentList
49
     * @access protected
50
     */
51
    protected $list;
52
53
    /**
54
     * Array of sorted metadata
55
     *
56
     * @var array
57
     * @access protected
58
     */
59
    protected $metadata = [];
60
61
    /**
62
     * Array of sortable metadata
63
     *
64
     * @var array
65
     * @access protected
66
     */
67
    protected $sortables = [];
68
69
    /**
70
     * Enriched documentList data for the view.
71
     *
72
     * @var array
73
     */
74
    protected $metadataList = [];
75
76
    /**
77
     * @var MetadataRepository
78
     */
79
    protected $metadataRepository;
80
81
    /**
82
     * @param MetadataRepository $metadataRepository
83
     */
84
    public function injectMetadataRepository(MetadataRepository $metadataRepository)
85
    {
86
        $this->metadataRepository = $metadataRepository;
87
    }
88
89
    /**
90
     * Renders one entry of the list
91
     *
92
     * @access protected
93
     *
94
     * @param int $number: The number of the entry
95
     *
96
     * @return string The rendered entry ready for output
97
     */
98
    protected function getEntry($number)
99
    {
100
        $imgAlt = '';
101
        $metadata = $this->list[$number]['metadata'];
102
        foreach ($this->metadata as $index_name => $metaConf) {
103
            if (!empty($metadata[$index_name])) {
104
                $parsedValues = [];
105
                $fieldwrap = $this->getFieldWrap($index_name, $metaConf['wrap']);
106
107
                do {
108
                    $value = @array_shift($metadata[$index_name]);
109
                    // Link title to pageview.
110
                    if ($index_name == 'title') {
111
                        // Get title of parent document if needed.
112
                        if (empty($value) && $this->settings['getTitle']) {
113
                            $superiorTitle = Document::getTitle($this->list[$number]['uid'], true);
114
                            if (!empty($superiorTitle)) {
115
                                $value = '[' . $superiorTitle . ']';
116
                            }
117
                        }
118
                        // Set fake title if still not present.
119
                        if (empty($value)) {
120
                            $value = LocalizationUtility::translate('noTitle', 'dlf');
121
                        }
122
                        $imgAlt = htmlspecialchars($value);
123
                        $value = htmlspecialchars($value);
124
125
                    } elseif ($index_name == 'owner' && !empty($value)) {
126
                        // Translate name of holding library.
127
                        $value = htmlspecialchars(Helper::translate($value, 'tx_dlf_libraries', $this->settings['pages']));
128
                    } elseif ($index_name == 'type' && !empty($value)) {
129
                        // Translate document type.
130
                        $value = htmlspecialchars(Helper::translate($value, 'tx_dlf_structures', $this->settings['pages']));
131
                    } elseif ($index_name == 'language' && !empty($value)) {
132
                        // Translate ISO 639 language code.
133
                        $value = htmlspecialchars(Helper::getLanguageName($value));
134
                    } elseif (!empty($value)) {
135
                        $value = htmlspecialchars($value);
136
                    }
137
138
                    if (!empty($value)) {
139
                        $parsedValues[] = [
140
                            'value' => $value,
141
                            'wrap' => $fieldwrap['value.']
142
                        ];
143
                    }
144
                } while (count($metadata[$index_name]));
145
146
                if (!empty($parsedValues)) {
147
                    $field[$index_name] = [
148
                        'label' => [
149
                            'value' => htmlspecialchars($metaConf['label']),
150
                            'wrap' => $fieldwrap['key.'],
151
                        ],
152
                        'values' => $parsedValues,
153
                        'wrap' => $fieldwrap['all.']
154
                    ];
155
156
                    $this->metadataList[$number]['metadata'] = $field;
157
                }
158
            }
159
        }
160
161
        // Add thumbnail.
162
        if (!empty($this->list[$number]['thumbnail'])) {
163
            $this->metadataList[$number]['thumbnail'] = [
164
                'alt' => $imgAlt,
165
                'src' => $this->list[$number]['thumbnail']
166
            ];
167
        }
168
169
        if (!empty($this->list[$number]['subparts'])) {
170
            $this->getSubEntries($number);
171
        }
172
    }
173
174
    /**
175
     * Returns the parsed fieldwrap of a metadata
176
     *
177
     * @access private
178
     *
179
     * @param string $index_name: The index name of a metadata
180
     * @param string $wrap: The configured metadata wrap
181
     *
182
     * @return array The parsed fieldwrap
183
     */
184
    private function getFieldWrap($index_name, $wrap)
185
    {
186
        if (isset($this->fieldwrap[$index_name])) {
187
            return $this->fieldwrap[$index_name];
188
        } else {
189
            return $this->fieldwrap[$index_name] = $this->parseTS($wrap);
190
        }
191
    }
192
193
    /**
194
     * Parses a string into a Typoscript array
195
     *
196
     * @access protected
197
     *
198
     * @param string $string: The string to parse
199
     *
200
     * @return array The resulting typoscript array
201
     */
202
    protected function parseTS($string = '')
203
    {
204
        $parser = GeneralUtility::makeInstance(TypoScriptParser::class);
205
        $parser->parse($string);
206
        return $parser->setup;
207
    }
208
209
    /**
210
     * Renders all sub-entries of one entry
211
     *
212
     * @access protected
213
     *
214
     * @param int $number: The number of the entry
215
     *
216
     * @return string The rendered entries ready for output
217
     */
218
    protected function getSubEntries($number)
219
    {
220
        foreach ($this->list[$number]['subparts'] as $subpartKey => $subpart) {
221
            $imgAlt = '';
222
            foreach ($this->metadata as $index_name => $metaConf) {
223
                $parsedValues = [];
224
                $fieldwrap = $this->getFieldWrap($index_name, $metaConf['wrap']);
225
                do {
226
                    $value = @array_shift($subpart['metadata'][$index_name]);
227
                    // Link title to pageview.
228
                    if ($index_name == 'title') {
229
                        // Get title of parent document if needed.
230
                        if (empty($value) && $this->settings['getTitle']) {
231
                            $superiorTitle = Document::getTitle($subpart['uid'], true);
232
                            if (!empty($superiorTitle)) {
233
                                $value = '[' . $superiorTitle . ']';
234
                            }
235
                        }
236
                        // Set fake title if still not present.
237
                        if (empty($value)) {
238
                            $value = LocalizationUtility::translate('noTitle', 'dlf');
239
                        }
240
                        $imgAlt = htmlspecialchars($value);
241
                        $value = htmlspecialchars($value);
242
                    } elseif ($index_name == 'owner' && !empty($value)) {
243
                        // Translate name of holding library.
244
                        $value = htmlspecialchars(Helper::translate($value, 'tx_dlf_libraries', $this->settings['pages']));
245
                    } elseif ($index_name == 'type' && !empty($value)) {
246
                        // Translate document type.
247
                        $_value = $value;
248
                        $value = htmlspecialchars(Helper::translate($value, 'tx_dlf_structures', $this->settings['pages']));
249
                        // Add page number for single pages.
250
                        if ($_value == 'page') {
251
                            $value .= ' ' . intval($subpart['page']);
252
                        }
253
                    } elseif ($index_name == 'language' && !empty($value)) {
254
                        // Translate ISO 639 language code.
255
                        $value = htmlspecialchars(Helper::getLanguageName($value));
256
                    } elseif (!empty($value)) {
257
                        $value = htmlspecialchars($value);
258
                    }
259
260
                    if (!empty($value)) {
261
                        $parsedValues[] = [
262
                            'value' => $value,
263
                            'wrap' => $fieldwrap['value.']
264
                        ];
265
                    }
266
267
                } while (is_array($subpart['metadata'][$index_name]) && count($subpart['metadata'][$index_name]) > 0);
268
                if (!empty($parsedValues)) {
269
                    $field[$index_name] = [
270
                        'label' => [
271
                            'value' => htmlspecialchars($metaConf['label']),
272
                            'wrap' => $fieldwrap['key.'],
273
                        ],
274
                        'values' => $parsedValues,
275
                        'wrap' => $fieldwrap['all.']
276
                    ];
277
278
                    $this->metadataList[$number]['subparts'][$subpartKey]['metadata'] = $field;
279
                }
280
            }
281
282
            // Add thumbnail.
283
            if (!empty($subpart['thumbnail'])) {
284
                $this->metadataList[$number]['subparts'][$subpartKey]['thumbnail'] = [
285
                    'alt' => $imgAlt,
286
                    'src' => $subpart['thumbnail']
287
                ];
288
            }
289
        }
290
    }
291
292
    /**
293
     * Get metadata configuration from database
294
     *
295
     * @access protected
296
     *
297
     * @return void
298
     */
299
    protected function loadConfig()
300
    {
301
        $metadataResult = $this->metadataRepository->findBySettings(['is_listed' => 1, 'is_sortable' => 1]);
302
303
        /** @var Metadata $metadata */
304
        foreach ($metadataResult as $metadata) {
305
            if ($metadata->getIsListed()) {
306
                $this->metadata[$metadata->getIndexName()] = [
307
                    'wrap' => $metadata->getWrap(),
308
                    'label' => Helper::translate($metadata->getIndexName(), 'tx_dlf_metadata', $this->settings['pages'])
309
                ];
310
            }
311
            if ($metadata->getIsSortable()) {
312
                $this->sortables[$metadata->getIndexName()] = Helper::translate($metadata->getIndexName(), 'tx_dlf_metadata', $this->settings['pages']);
313
            }
314
        }
315
    }
316
317
    /**
318
     * The main method of the plugin
319
     *
320
     * @return void
321
     */
322
    public function mainAction()
323
    {
324
        $requestData = GeneralUtility::_GPmerged('tx_dlf');
325
326
        $sort = $requestData['sort'];
327
        $pointer = $requestData['pointer'];
328
        $logicalPage = $requestData['logicalPage'];
329
330
        $this->extConf = GeneralUtility::makeInstance(ExtensionConfiguration::class)->get('dlf');
331
332
        // Load the list.
333
        $this->list = GeneralUtility::makeInstance(DocumentList::class);
334
        $currentEntry = $pointer * $this->settings['limit'];
335
        $lastEntry = ($pointer + 1) * $this->settings['limit'];
336
337
        // Check if it's a list of database records or Solr documents.
338
        if (
339
            !empty($this->list->metadata['options']['source'])
340
            && $this->list->metadata['options']['source'] == 'collection'
341
            && ((!empty($sort['order']) && $sort['order'] != $this->list->metadata['options']['order'])
342
                || (isset($sort['orderBy']) && $sort['orderBy'] != $this->list->metadata['options']['orderBy']))
343
        ) {
344
            // Order list by given field.
345
            $this->list->sort($sort['order'], $sort['orderBy'] == 'asc' ? true : false);
346
            // Update list's metadata.
347
            $listMetadata = $this->list->metadata;
348
            $listMetadata['options']['order'] = $sort['order'];
349
            $listMetadata['options']['orderBy'] = $sort['orderBy'];
350
            $this->list->metadata = $listMetadata;
351
            // Save updated list.
352
            $this->list->save();
353
            // Reset pointer.
354
            $pointer = 0;
355
        } elseif (!empty($this->list->metadata['options']['source']) && $this->list->metadata['options']['source'] == 'search') {
356
            // Update list's metadata
357
            $listMetadata = $this->list->metadata;
358
            // Sort the list if applicable.
359
            if ((!empty($sort['order']) && $sort['order'] != $listMetadata['options']['order'])
360
                || (isset($sort['orderBy']) && $sort['orderBy'] != $listMetadata['options']['orderBy'])
361
            ) {
362
                // Update list's metadata.
363
                $listMetadata['options']['params']['sort'] = [$sort['order'] . "_sorting" => (bool) $sort['asc'] ? 'asc' : 'desc'];
364
                $listMetadata['options']['order'] = $sort['order'];
365
                $listMetadata['options']['orderBy'] = $sort['orderBy'];
366
                // Reset pointer.
367
                $pointer = 0;
368
            }
369
            // Set some query parameters
370
            $listMetadata['options']['params']['start'] = $currentEntry;
371
            $listMetadata['options']['params']['rows'] = $this->settings['limit'];
372
            // Search only if the query params have changed.
373
            if ($listMetadata['options']['params'] != $this->list->metadata['options']['params']) {
374
                // Instantiate search object.
375
                $solr = Solr::getInstance($this->list->metadata['options']['core']);
376
                if (!$solr->ready) {
377
                    $this->logger->error('Apache Solr not available');
1 ignored issue
show
Bug introduced by
The method error() does not exist on null. ( Ignorable by Annotation )

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

377
                    $this->logger->/** @scrutinizer ignore-call */ 
378
                                   error('Apache Solr not available');

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
378
                }
379
                // Set search parameters.
380
                $solr->cPid = $listMetadata['options']['pid'];
381
                $solr->params = $listMetadata['options']['params'];
382
                // Perform search.
383
                $this->list = $solr->search();
384
            }
385
            $this->list->metadata = $listMetadata;
386
            // Save updated list.
387
            $this->list->save();
388
            $currentEntry = 0;
389
            $lastEntry = $this->settings['limit'];
390
        }
391
392
        // Set some variable defaults.
393
        if (!empty($pointer) && (($pointer * $this->settings['limit']) + 1) <= $this->list->metadata['options']['numberOfToplevelHits']) {
394
            $pointer = max(intval($pointer), 0);
395
        } else {
396
            $pointer = 0;
397
        }
398
399
        // Load metadata configuration.
400
        $this->loadConfig();
401
        for ($currentEntry, $lastEntry; $currentEntry < $lastEntry; $currentEntry++) {
402
            if (empty($this->list[$currentEntry])) {
403
                break;
404
            } else {
405
                $this->getEntry($currentEntry);
406
            }
407
        }
408
409
        if ($currentEntry) {
410
            $currentEntry = ($pointer * $this->settings['limit']) + 1;
411
            $lastEntry = ($pointer * $this->settings['limit']) + $this->settings['limit'];
412
        }
413
414
        // Pagination of Results
415
        // pass the currentPage to the fluid template to calculate current index of search result
416
        if (empty($requestData['@widget_0'])) {
417
            $widgetPage = ['currentPage' => 1];
418
        } else {
419
            $widgetPage = $requestData['@widget_0'];
420
        }
421
422
        // convert documentList to array --> use widget.pagination viewhelper
423
        $documentList = [];
424
        foreach ($this->list as $listElement) {
425
            $documentList[] = $listElement;
426
        }
427
        $this->view->assign('widgetPage', $widgetPage);
428
        $this->view->assign('documentList', $this->list);
429
        $this->view->assign('documentListArray', $documentList);
430
        $this->view->assign('metadataList', $this->metadataList);
431
        $this->view->assign('metadataConfig', $this->metadata);
432
        $this->view->assign('currentEntry', $currentEntry);
433
        $this->view->assign('lastEntry', $lastEntry);
434
        $this->view->assign('sortables', $this->sortables);
435
        $this->view->assign('logicalPage', $logicalPage);
436
        $this->view->assign(
437
            'maxPages',
438
            intval(ceil($this->list->metadata['options']['numberOfToplevelHits'] / $this->settings['limit']))
439
        );
440
        $this->view->assign('forceAbsoluteUrl', !empty($this->extConf['forceAbsoluteUrl']) ? 1 : 0);
441
    }
442
}
443