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 — dev-extbase-fluid (#737)
by Alexander
02:59
created

ListViewController   F

Complexity

Total Complexity 74

Size/Duplication

Total Lines 403
Duplicated Lines 0 %

Importance

Changes 4
Bugs 0 Features 0
Metric Value
eloc 185
dl 0
loc 403
rs 2.48
c 4
b 0
f 0
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
    protected $metadataRepository;
77
78
    /**
79
     * @param MetadataRepository $metadataRepository
80
     */
81
    public function injectMetadataRepository(MetadataRepository $metadataRepository)
82
    {
83
        $this->metadataRepository = $metadataRepository;
84
    }
85
86
    /**
87
     * Renders one entry of the list
88
     *
89
     * @access protected
90
     *
91
     * @param int $number: The number of the entry
92
     *
93
     * @return string The rendered entry ready for output
94
     */
95
    protected function getEntry($number)
96
    {
97
        $imgAlt = '';
98
        $metadata = $this->list[$number]['metadata'];
99
        foreach ($this->metadata as $index_name => $metaConf) {
100
            if (!empty($metadata[$index_name])) {
101
                $parsedValues = [];
102
                $fieldwrap = $this->getFieldWrap($index_name, $metaConf['wrap']);
103
104
                do {
105
                    $value = @array_shift($metadata[$index_name]);
106
                    // Link title to pageview.
107
                    if ($index_name == 'title') {
108
                        // Get title of parent document if needed.
109
                        if (empty($value) && $this->settings['getTitle']) {
110
                            $superiorTitle = Document::getTitle($this->list[$number]['uid'], true);
111
                            if (!empty($superiorTitle)) {
112
                                $value = '[' . $superiorTitle . ']';
113
                            }
114
                        }
115
                        // Set fake title if still not present.
116
                        if (empty($value)) {
117
                            $value = LocalizationUtility::translate('noTitle', 'dlf');
118
                        }
119
                        $imgAlt = htmlspecialchars($value);
120
                        $value = htmlspecialchars($value);
121
122
                    } elseif ($index_name == 'owner' && !empty($value)) {
123
                        // Translate name of holding library.
124
                        $value = htmlspecialchars(Helper::translate($value, 'tx_dlf_libraries', $this->settings['pages']));
125
                    } elseif ($index_name == 'type' && !empty($value)) {
126
                        // Translate document type.
127
                        $value = htmlspecialchars(Helper::translate($value, 'tx_dlf_structures', $this->settings['pages']));
128
                    } elseif ($index_name == 'language' && !empty($value)) {
129
                        // Translate ISO 639 language code.
130
                        $value = htmlspecialchars(Helper::getLanguageName($value));
131
                    } elseif (!empty($value)) {
132
                        $value = htmlspecialchars($value);
133
                    }
134
135
                    if (!empty($value)) {
136
                        $parsedValues[] = [
137
                            'value' => $value,
138
                            'wrap' => $fieldwrap['value.']
139
                        ];
140
                    }
141
                } while (count($metadata[$index_name]));
142
143
                if (!empty($parsedValues)) {
144
                    $field[$index_name] = [
145
                        'label' => [
146
                            'value' => htmlspecialchars($metaConf['label']),
147
                            'wrap' => $fieldwrap['key.'],
148
                        ],
149
                        'values' => $parsedValues,
150
                        'wrap' => $fieldwrap['all.']
151
                    ];
152
153
                    $this->metadataList[$number]['metadata'] = $field;
154
                }
155
            }
156
        }
157
158
        // Add thumbnail.
159
        if (!empty($this->list[$number]['thumbnail'])) {
160
            $this->metadataList[$number]['thumbnail'] = [
161
                'alt' => $imgAlt,
162
                'src' => $this->list[$number]['thumbnail']
163
            ];
164
        }
165
166
        if (!empty($this->list[$number]['subparts'])) {
167
            $this->getSubEntries($number);
168
        }
169
    }
170
171
    /**
172
     * Returns the parsed fieldwrap of a metadata
173
     *
174
     * @access private
175
     *
176
     * @param string $index_name: The index name of a metadata
177
     * @param string $wrap: The configured metadata wrap
178
     *
179
     * @return array The parsed fieldwrap
180
     */
181
    private function getFieldWrap($index_name, $wrap)
182
    {
183
        if (isset($this->fieldwrap[$index_name])) {
184
            return $this->fieldwrap[$index_name];
185
        } else {
186
            return $this->fieldwrap[$index_name] = $this->parseTS($wrap);
187
        }
188
    }
189
190
    /**
191
     * Parses a string into a Typoscript array
192
     *
193
     * @access protected
194
     *
195
     * @param string $string: The string to parse
196
     *
197
     * @return array The resulting typoscript array
198
     */
199
    protected function parseTS($string = '')
200
    {
201
        $parser = GeneralUtility::makeInstance(TypoScriptParser::class);
202
        $parser->parse($string);
203
        return $parser->setup;
204
    }
205
206
    /**
207
     * Renders all sub-entries of one entry
208
     *
209
     * @access protected
210
     *
211
     * @param int $number: The number of the entry
212
     *
213
     * @return string The rendered entries ready for output
214
     */
215
    protected function getSubEntries($number)
216
    {
217
        foreach ($this->list[$number]['subparts'] as $subpartKey => $subpart) {
218
            $imgAlt = '';
219
            foreach ($this->metadata as $index_name => $metaConf) {
220
                $parsedValues = [];
221
                $fieldwrap = $this->getFieldWrap($index_name, $metaConf['wrap']);
222
                do {
223
                    $value = @array_shift($subpart['metadata'][$index_name]);
224
                    // Link title to pageview.
225
                    if ($index_name == 'title') {
226
                        // Get title of parent document if needed.
227
                        if (empty($value) && $this->settings['getTitle']) {
228
                            $superiorTitle = Document::getTitle($subpart['uid'], true);
229
                            if (!empty($superiorTitle)) {
230
                                $value = '[' . $superiorTitle . ']';
231
                            }
232
                        }
233
                        // Set fake title if still not present.
234
                        if (empty($value)) {
235
                            $value = LocalizationUtility::translate('noTitle', 'dlf');
236
                        }
237
                        $imgAlt = htmlspecialchars($value);
238
                        $value = htmlspecialchars($value);
239
                    } elseif ($index_name == 'owner' && !empty($value)) {
240
                        // Translate name of holding library.
241
                        $value = htmlspecialchars(Helper::translate($value, 'tx_dlf_libraries', $this->settings['pages']));
242
                    } elseif ($index_name == 'type' && !empty($value)) {
243
                        // Translate document type.
244
                        $_value = $value;
245
                        $value = htmlspecialchars(Helper::translate($value, 'tx_dlf_structures', $this->settings['pages']));
246
                        // Add page number for single pages.
247
                        if ($_value == 'page') {
248
                            $value .= ' ' . intval($subpart['page']);
249
                        }
250
                    } elseif ($index_name == 'language' && !empty($value)) {
251
                        // Translate ISO 639 language code.
252
                        $value = htmlspecialchars(Helper::getLanguageName($value));
253
                    } elseif (!empty($value)) {
254
                        $value = htmlspecialchars($value);
255
                    }
256
257
                    if (!empty($value)) {
258
                        $parsedValues[] = [
259
                            'value' => $value,
260
                            'wrap' => $fieldwrap['value.']
261
                        ];
262
                    }
263
264
                } while (is_array($subpart['metadata'][$index_name]) && count($subpart['metadata'][$index_name]) > 0);
265
                if (!empty($parsedValues)) {
266
                    $field[$index_name] = [
267
                        'label' => [
268
                            'value' => htmlspecialchars($metaConf['label']),
269
                            'wrap' => $fieldwrap['key.'],
270
                        ],
271
                        'values' => $parsedValues,
272
                        'wrap' => $fieldwrap['all.']
273
                    ];
274
275
                    $this->metadataList[$number]['subparts'][$subpartKey]['metadata'] = $field;
276
                }
277
            }
278
279
            // Add thumbnail.
280
            if (!empty($subpart['thumbnail'])) {
281
                $this->metadataList[$number]['subparts'][$subpartKey]['thumbnail'] = [
282
                    'alt' => $imgAlt,
283
                    'src' => $subpart['thumbnail']
284
                ];
285
            }
286
        }
287
    }
288
289
    /**
290
     * Get metadata configuration from database
291
     *
292
     * @access protected
293
     *
294
     * @return void
295
     */
296
    protected function loadConfig()
297
    {
298
        $metadataResult = $this->metadataRepository->getMetadataForListview($this->settings['pages']);
299
300
        /** @var Metadata $metadata */
301
        foreach ($metadataResult as $metadata) {
302
            if ($metadata->getIsListed()) {
303
                $this->metadata[$metadata->getIndexName()] = [
304
                    'wrap' => $metadata->getWrap(),
305
                    'label' => Helper::translate($metadata->getIndexName(), 'tx_dlf_metadata', $this->settings['pages'])
306
                ];
307
            }
308
            if ($metadata->getIsSortable()) {
309
                $this->sortables[$metadata->getIndexName()] = Helper::translate($metadata->getIndexName(), 'tx_dlf_metadata', $this->settings['pages']);
310
            }
311
        }
312
    }
313
314
    /**
315
     * The main method of the plugin
316
     *
317
     * @return void
318
     */
319
    public function mainAction()
320
    {
321
        $requestData = GeneralUtility::_GPmerged('tx_dlf');
322
323
        $sort = $requestData['sort'];
324
        $pointer = $requestData['pointer'];
325
        $logicalPage = $requestData['logicalPage'];
326
327
        $this->extConf = GeneralUtility::makeInstance(ExtensionConfiguration::class)->get('dlf');
328
329
        // Load the list.
330
        $this->list = GeneralUtility::makeInstance(DocumentList::class);
331
        $currentEntry = $pointer * $this->settings['limit'];
332
        $lastEntry = ($pointer + 1) * $this->settings['limit'];
333
334
        // Check if it's a list of database records or Solr documents.
335
        if (
336
            !empty($this->list->metadata['options']['source'])
337
            && $this->list->metadata['options']['source'] == 'collection'
338
            && ((!empty($sort['order']) && $sort['order'] != $this->list->metadata['options']['order'])
339
                || (isset($sort['orderBy']) && $sort['orderBy'] != $this->list->metadata['options']['orderBy']))
340
        ) {
341
            // Order list by given field.
342
            $this->list->sort($sort['order'], $sort['orderBy'] == 'asc' ? true : false);
343
            // Update list's metadata.
344
            $listMetadata = $this->list->metadata;
345
            $listMetadata['options']['order'] = $sort['order'];
346
            $listMetadata['options']['orderBy'] = $sort['orderBy'];
347
            $this->list->metadata = $listMetadata;
348
            // Save updated list.
349
            $this->list->save();
350
            // Reset pointer.
351
            $pointer = 0;
352
        } elseif (!empty($this->list->metadata['options']['source']) && $this->list->metadata['options']['source'] == 'search') {
353
            // Update list's metadata
354
            $listMetadata = $this->list->metadata;
355
            // Sort the list if applicable.
356
            if ((!empty($sort['order']) && $sort['order'] != $listMetadata['options']['order'])
357
                || (isset($sort['orderBy']) && $sort['orderBy'] != $listMetadata['options']['orderBy'])
358
            ) {
359
                // Update list's metadata.
360
                $listMetadata['options']['params']['sort'] = [$sort['order'] . "_sorting" => (bool) $sort['asc'] ? 'asc' : 'desc'];
361
                $listMetadata['options']['order'] = $sort['order'];
362
                $listMetadata['options']['orderBy'] = $sort['orderBy'];
363
                // Reset pointer.
364
                $pointer = 0;
365
            }
366
            // Set some query parameters
367
            $listMetadata['options']['params']['start'] = $currentEntry;
368
            $listMetadata['options']['params']['rows'] = $this->settings['limit'];
369
            // Search only if the query params have changed.
370
            if ($listMetadata['options']['params'] != $this->list->metadata['options']['params']) {
371
                // Instantiate search object.
372
                $solr = Solr::getInstance($this->list->metadata['options']['core']);
373
                if (!$solr->ready) {
374
                    $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

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