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.

ToolboxController::renderTools()   D
last analyzed

Complexity

Conditions 20
Paths 20

Size

Total Lines 45
Code Lines 41

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 20
eloc 41
c 1
b 0
f 0
nc 20
nop 0
dl 0
loc 45
rs 4.1666

How to fix   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
/**
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\Common\AbstractDocument;
15
use Kitodo\Dlf\Common\Helper;
16
use Psr\Http\Message\ResponseInterface;
17
use TYPO3\CMS\Core\Utility\GeneralUtility;
18
use TYPO3\CMS\Core\Utility\MathUtility;
19
20
/**
21
 * Controller class for plugin 'Toolbox'.
22
 *
23
 * @package TYPO3
24
 * @subpackage dlf
25
 *
26
 * @access public
27
 */
28
class ToolboxController extends AbstractController
29
{
30
31
    /**
32
     * @access private
33
     * @var AbstractDocument This holds the current document
34
     */
35
    private AbstractDocument $currentDocument;
36
37
    /**
38
     * The main method of the plugin
39
     *
40
     * @access public
41
     *
42
     * @return ResponseInterface the response
43
     */
44
    public function mainAction(): ResponseInterface
45
    {
46
        // Load current document.
47
        $this->loadDocument();
48
49
        $this->view->assign('double', $this->requestData['double']);
50
51
        if (!$this->isDocMissingOrEmpty()) {
52
            $this->currentDocument = $this->document->getCurrentDocument();
53
        }
54
55
        $this->renderTools();
56
        $this->view->assign('viewData', $this->viewData);
57
58
        return $this->htmlResponse();
59
    }
60
61
    /**
62
     * Renders tool in the toolbox.
63
     *
64
     * @access private
65
     *
66
     * @return void
67
     */
68
    private function renderTools(): void
69
    {
70
        if (!empty($this->settings['tools'])) {
71
72
            $tools = explode(',', $this->settings['tools']);
73
74
            foreach ($tools as $tool) {
75
                switch ($tool) {
76
                    case 'tx_dlf_annotationtool':
77
                    case 'annotationtool':
78
                        $this->renderToolByName('renderAnnotationTool');
79
                        break;
80
                    case 'tx_dlf_fulltextdownloadtool':
81
                    case 'fulltextdownloadtool':
82
                        $this->renderToolByName('renderFulltextDownloadTool');
83
                        break;
84
                    case 'tx_dlf_fulltexttool':
85
                    case 'fulltexttool':
86
                        $this->renderToolByName('renderFulltextTool');
87
                        break;
88
                    case 'tx_dlf_imagedownloadtool':
89
                    case 'imagedownloadtool':
90
                        $this->renderToolByName('renderImageDownloadTool');
91
                        break;
92
                    case 'tx_dlf_imagemanipulationtool':
93
                    case 'imagemanipulationtool':
94
                        $this->renderToolByName('renderImageManipulationTool');
95
                        break;
96
                    case 'tx_dlf_modeldownloadtool':
97
                    case 'modeldownloadtool':
98
                        $this->renderToolByName('renderModelDownloadTool');
99
                        break;
100
                    case 'tx_dlf_pdfdownloadtool':
101
                    case 'pdfdownloadtool':
102
                        $this->renderToolByName('renderPdfDownloadTool');
103
                        break;
104
                    case 'tx_dlf_searchindocumenttool':
105
                    case 'searchindocumenttool':
106
                        $this->renderToolByName('renderSearchInDocumentTool');
107
                        break;
108
                    case 'scoretool':
109
                        $this->renderToolByName('renderScoreTool');
110
                        break;
111
                    default:
112
                        $this->logger->warning('Incorrect tool configuration: "' . $this->settings['tools'] . '". Tool "' . $tool . '" does not exist.');
113
                }
114
            }
115
        }
116
    }
117
118
    /**
119
     * Renders tool by the name in the toolbox.
120
     *
121
     * @access private
122
     *
123
     * @param string $tool name
124
     *
125
     * @return void
126
     */
127
    private function renderToolByName(string $tool): void
128
    {
129
        $this->$tool();
130
        $this->view->assign($tool, true);
131
    }
132
133
    /**
134
     * Get image's URL and MIME type information's.
135
     *
136
     * @access private
137
     *
138
     * @param int $page Page number
139
     *
140
     * @return array Array of image information's.
141
     */
142
    public function getImage(int $page): array
143
    {
144
        // Get @USE value of METS fileGroup.
145
        $image = $this->getFile($page, GeneralUtility::trimExplode(',', $this->settings['fileGrpsImageDownload']));
146
        switch ($image['mimetype']) {
147
            case 'image/jpeg':
148
                $image['mimetypeLabel'] = ' (JPG)';
149
                break;
150
            case 'image/tiff':
151
                $image['mimetypeLabel'] = ' (TIFF)';
152
                break;
153
            default:
154
                $image['mimetypeLabel'] = '';
155
        }
156
        return $image;
157
    }
158
159
    /**
160
     * Renders the annotation tool (used in template)
161
     * @SuppressWarnings(PHPMD.UnusedPrivateMethod)
162
     *
163
     * @access private
164
     *
165
     * @return void
166
     */
167
    private function renderAnnotationTool(): void
168
    {
169
        if ($this->isDocMissingOrEmpty()) {
170
            // Quit without doing anything if required variables are not set.
171
            return;
172
        }
173
174
        $this->setPage();
175
176
        $annotationContainers = $this->currentDocument->physicalStructureInfo[$this->currentDocument->physicalStructure[$this->requestData['page']]]['annotationContainers'];
177
        if (
178
            $annotationContainers != null
179
            && count($annotationContainers) > 0
180
        ) {
181
            $this->view->assign('annotationTool', true);
182
        } else {
183
            $this->view->assign('annotationTool', false);
184
        }
185
    }
186
187
    /**
188
     * Renders the fulltext download tool (used in template)
189
     * @SuppressWarnings(PHPMD.UnusedPrivateMethod)
190
     *
191
     * @access private
192
     *
193
     * @return void
194
     */
195
    private function renderFulltextDownloadTool(): void
196
    {
197
        if (
198
            $this->isDocMissingOrEmpty()
199
            || empty($this->extConf['files']['fileGrpFulltext'])
200
        ) {
201
            // Quit without doing anything if required variables are not set.
202
            return;
203
        }
204
205
        $this->setPage();
206
207
        // Get text download.
208
        $this->view->assign('fulltextDownload', !$this->isFullTextEmpty());
209
    }
210
211
    /**
212
     * Renders the fulltext tool (used in template)
213
     * @SuppressWarnings(PHPMD.UnusedPrivateMethod)
214
     *
215
     * @access private
216
     *
217
     * @return void
218
     */
219
    private function renderFulltextTool(): void
220
    {
221
        if (
222
            $this->isDocMissingOrEmpty()
223
            || empty($this->extConf['files']['fileGrpFulltext'])
224
        ) {
225
            // Quit without doing anything if required variables are not set.
226
            return;
227
        }
228
229
        $this->setPage();
230
231
        if (!$this->isFullTextEmpty()) {
232
            $this->view->assign('fulltext', true);
233
            $this->view->assign('activateFullTextInitially', MathUtility::forceIntegerInRange($this->settings['activateFullTextInitially'], 0, 1, 0));
234
        } else {
235
            $this->view->assign('fulltext', false);
236
        }
237
    }
238
239
    /**
240
     * Renders the score tool
241
     *
242
     * @return void
243
     */
244
    public function renderScoreTool()
245
    {
246
        if (
247
            $this->isDocMissingOrEmpty()
248
            || empty($this->extConf['files']['fileGrpScore'])
249
        ) {
250
            // Quit without doing anything if required variables are not set.
251
            return;
252
        }
253
254
        if ($this->requestData['page']) {
255
            $currentPhysPage = $this->document->getCurrentDocument()->physicalStructure[$this->requestData['page']];
256
        } else {
257
            $currentPhysPage = $this->document->getCurrentDocument()->physicalStructure[1];
258
        }
259
260
        $fileGrpsScores = GeneralUtility::trimExplode(',', $this->extConf['files']['fileGrpScore']);
261
        foreach ($fileGrpsScores as $fileGrpScore) {
262
            if ($this->document->getCurrentDocument()->physicalStructureInfo[$currentPhysPage]['files'][$fileGrpScore]) {
263
                $scoreFile = $this->document->getCurrentDocument()->physicalStructureInfo[$currentPhysPage]['files'][$fileGrpScore];
264
            }
265
        }
266
        if (!empty($scoreFile)) {
267
            $this->view->assign('score', true);
268
            $this->view->assign('activateScoreInitially', MathUtility::forceIntegerInRange($this->settings['activateScoreInitially'], 0, 1, 0));
269
        } else {
270
            $this->view->assign('score', false);
271
        }
272
    }
273
274
    /**
275
     * Renders the image download tool (used in template)
276
     * @SuppressWarnings(PHPMD.UnusedPrivateMethod)
277
     *
278
     * @access private
279
     *
280
     * @return void
281
     */
282
    private function renderImageDownloadTool(): void
283
    {
284
        if (
285
            $this->isDocMissingOrEmpty()
286
            || empty($this->settings['fileGrpsImageDownload'])
287
        ) {
288
            // Quit without doing anything if required variables are not set.
289
            return;
290
        }
291
292
        $this->setPage();
293
        $page = $this->requestData['page'] ?? 0;
294
295
        $imageArray = [];
296
        // Get left or single page download.
297
        $image = $this->getImage($page);
298
        if (Helper::filterFilesByMimeType($image, ['image'])) {
299
            $imageArray[0] = $image;
300
        }
301
302
        if ($this->requestData['double'] == 1) {
303
            $image = $this->getImage($page + 1);
304
            if (Helper::filterFilesByMimeType($image, ['image'])) {
305
                $imageArray[1] = $image;
306
            }
307
        }
308
309
        $this->view->assign('imageDownload', $imageArray);
310
    }
311
312
    /**
313
     * Get file's URL and MIME type
314
     *
315
     * @access private
316
     *
317
     * @param int $page Page number
318
     *
319
     * @return array Array of file information
320
     */
321
    private function getFile(int $page, array $fileGrps): array
322
    {
323
        $file = [];
324
        while ($fileGrp = @array_pop($fileGrps)) {
325
            $physicalStructureInfo = $this->currentDocument->physicalStructureInfo[$this->currentDocument->physicalStructure[$page]];
326
            $fileId = $physicalStructureInfo['files'][$fileGrp];
327
            if (!empty($fileId)) {
328
                $file['url'] = $this->currentDocument->getDownloadLocation($fileId);
329
                $file['mimetype'] = $this->currentDocument->getFileMimeType($fileId);
330
            } else {
331
                $this->logger->warning('File not found in fileGrp "' . $fileGrp . '"');
332
            }
333
        }
334
        return $file;
335
    }
336
337
    /**
338
     * Renders the image manipulation tool (used in template)
339
     * @SuppressWarnings(PHPMD.UnusedPrivateMethod)
340
     *
341
     * @access private
342
     *
343
     * @return void
344
     */
345
    private function renderImageManipulationTool(): void
346
    {
347
        // Set parent element for initialization.
348
        $parentContainer = !empty($this->settings['parentContainer']) ? $this->settings['parentContainer'] : '.tx-dlf-imagemanipulationtool';
349
350
        $this->view->assign('imageManipulation', true);
351
        $this->view->assign('parentContainer', $parentContainer);
352
    }
353
354
    /**
355
     * Renders the model download tool
356
     * Renders the model download tool (used in template)
357
     * @SuppressWarnings(PHPMD.UnusedPrivateMethod)
358
     *
359
     * @access private
360
     *
361
     * @return void
362
     */
363
    private function renderModelDownloadTool(): void
364
    {
365
        if (
366
            $this->isDocMissingOrEmpty()
367
            || empty($this->settings['fileGrpsModelDownload'])
368
        ) {
369
            // Quit without doing anything if required variables are not set.
370
            return;
371
        }
372
373
        $this->setPage();
374
375
        if (isset($this->requestData['page'])) {
376
            $this->view->assign('modelDownload', $this->getFile($this->requestData['page'], GeneralUtility::trimExplode(',', $this->settings['fileGrpsModelDownload'])));
377
        }
378
    }
379
380
    /**
381
     * Renders the PDF download tool (used in template)
382
     * @SuppressWarnings(PHPMD.UnusedPrivateMethod)
383
     *
384
     * @access private
385
     *
386
     * @return void
387
     */
388
    private function renderPdfDownloadTool(): void
389
    {
390
        if (
391
            $this->isDocMissingOrEmpty()
392
            || empty($this->extConf['files']['fileGrpDownload'])
393
        ) {
394
            // Quit without doing anything if required variables are not set.
395
            return;
396
        }
397
398
        $this->setPage();
399
400
        // Get single page downloads.
401
        $this->view->assign('pageLinks', $this->getPageLink());
402
        // Get work download.
403
        $this->view->assign('workLink', $this->getWorkLink());
404
    }
405
406
    /**
407
     * Get page's download link
408
     *
409
     * @access private
410
     *
411
     * @return array Link to downloadable page
412
     */
413
    private function getPageLink(): array
414
    {
415
        $firstPageLink = '';
416
        $secondPageLink = '';
417
        $pageLinkArray = [];
418
        $pageNumber = $this->requestData['page'] ?? 0;
419
        $fileGrpsDownload = GeneralUtility::trimExplode(',', $this->extConf['files']['fileGrpDownload']);
420
        // Get image link.
421
        while ($fileGrpDownload = array_shift($fileGrpsDownload)) {
422
            $firstFileGroupDownload = $this->currentDocument->physicalStructureInfo[$this->currentDocument->physicalStructure[$pageNumber]]['files'][$fileGrpDownload] ?? [];
423
            if (!empty($firstFileGroupDownload)) {
424
                $firstPageLink = $this->currentDocument->getFileLocation($firstFileGroupDownload);
0 ignored issues
show
Bug introduced by
It seems like $firstFileGroupDownload can also be of type array; however, parameter $id of Kitodo\Dlf\Common\Abstra...ment::getFileLocation() 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

424
                $firstPageLink = $this->currentDocument->getFileLocation(/** @scrutinizer ignore-type */ $firstFileGroupDownload);
Loading history...
425
                // Get second page, too, if double page view is activated.
426
                $secondFileGroupDownload = $this->currentDocument->physicalStructureInfo[$this->currentDocument->physicalStructure[$pageNumber + 1]]['files'][$fileGrpDownload];
427
                if (
428
                    $this->requestData['double']
429
                    && $pageNumber < $this->currentDocument->numPages
430
                    && !empty($secondFileGroupDownload)
431
                ) {
432
                    $secondPageLink = $this->currentDocument->getFileLocation($secondFileGroupDownload);
433
                }
434
                break;
435
            }
436
        }
437
        if (
438
            empty($firstPageLink)
439
            && empty($secondPageLink)
440
        ) {
441
            $this->logger->warning('File not found in fileGrps "' . $this->extConf['files']['fileGrpDownload'] . '"');
442
        }
443
444
        if (!empty($firstPageLink)) {
445
            $pageLinkArray[0] = $firstPageLink;
446
        }
447
        if (!empty($secondPageLink)) {
448
            $pageLinkArray[1] = $secondPageLink;
449
        }
450
        return $pageLinkArray;
451
    }
452
453
    /**
454
     * Get work's download link
455
     *
456
     * @access private
457
     *
458
     * @return string Link to downloadable work
459
     */
460
    private function getWorkLink(): string
461
    {
462
        $workLink = '';
463
        $fileGrpsDownload = GeneralUtility::trimExplode(',', $this->extConf['files']['fileGrpDownload']);
464
        // Get work link.
465
        while ($fileGrpDownload = array_shift($fileGrpsDownload)) {
466
            $fileGroupDownload = $this->currentDocument->physicalStructureInfo[$this->currentDocument->physicalStructure[0]]['files'][$fileGrpDownload] ?? [];
467
            if (!empty($fileGroupDownload)) {
468
                $workLink = $this->currentDocument->getFileLocation($fileGroupDownload);
0 ignored issues
show
Bug introduced by
It seems like $fileGroupDownload can also be of type array; however, parameter $id of Kitodo\Dlf\Common\Abstra...ment::getFileLocation() 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

468
                $workLink = $this->currentDocument->getFileLocation(/** @scrutinizer ignore-type */ $fileGroupDownload);
Loading history...
469
                break;
470
            } else {
471
                $details = $this->currentDocument->getLogicalStructure($this->currentDocument->toplevelId);
472
                if (!empty($details['files'][$fileGrpDownload])) {
473
                    $workLink = $this->currentDocument->getFileLocation($details['files'][$fileGrpDownload]);
474
                    break;
475
                }
476
            }
477
        }
478
        if (empty($workLink)) {
479
            $this->logger->warning('File not found in fileGrps "' . $this->extConf['files']['fileGrpDownload'] . '"');
480
        }
481
        return $workLink;
482
    }
483
484
    /**
485
     * Renders the searchInDocument tool (used in template)
486
     * @SuppressWarnings(PHPMD.UnusedPrivateMethod)
487
     *
488
     * @access private
489
     *
490
     * @return void
491
     */
492
    private function renderSearchInDocumentTool(): void
493
    {
494
        if (
495
            $this->isDocMissingOrEmpty()
496
            || empty($this->extConf['files']['fileGrpFulltext'])
497
            || empty($this->settings['solrcore'])
498
        ) {
499
            // Quit without doing anything if required variables are not set.
500
            return;
501
        }
502
503
        $this->setPage();
504
505
        // Quit if no fulltext file is present
506
        if ($this->isFullTextEmpty()) {
507
            return;
508
        }
509
510
        $viewArray = [
511
            'labelQueryUrl' => $this->settings['queryInputName'],
512
            'labelStart' => $this->settings['startInputName'],
513
            'labelId' => $this->settings['idInputName'],
514
            'labelPid' => $this->settings['pidInputName'],
515
            'labelPageUrl' => $this->settings['pageInputName'],
516
            'labelHighlightWord' => $this->settings['highlightWordInputName'],
517
            'labelEncrypted' => $this->settings['encryptedInputName'],
518
            'documentId' => $this->getCurrentDocumentId(),
519
            'pageId' => $this->request->getAttribute('routing')->getPageId(),
520
            'solrEncrypted' => $this->getEncryptedCoreName() ? : ''
521
        ];
522
523
        $this->view->assign('searchInDocument', $viewArray);
524
    }
525
526
    /**
527
     * Get current document id. As default the uid will be used.
528
     * In case there is defined documentIdUrlSchema then the id will
529
     * extracted from this URL.
530
     *
531
     * @access private
532
     *
533
     * @return string with current document id
534
     */
535
    private function getCurrentDocumentId(): string
536
    {
537
        $id = $this->document->getUid();
0 ignored issues
show
Bug introduced by
The method getUid() 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

537
        /** @scrutinizer ignore-call */ 
538
        $id = $this->document->getUid();

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...
538
539
        if ($id !== null && $id > 0) {
540
            // we found the document uid
541
            return (string) $id;
542
        } else {
543
            $id = $this->requestData['id'];
544
            if (!GeneralUtility::isValidUrl($id)) {
545
                // we found no valid URI --> something unexpected we cannot search within.
546
                return '';
547
            }
548
        }
549
550
        // example: https://host.de/items/*id*/record
551
        if (!empty($this->settings['documentIdUrlSchema'])) {
552
            $arr = explode('*', $this->settings['documentIdUrlSchema']);
553
554
            if (count($arr) == 2) {
555
                $id = explode($arr[0], $id)[0];
556
            } else if (count($arr) == 3) {
557
                $sub = substr($id, strpos($id, $arr[0]) + strlen($arr[0]), strlen($id));
558
                $id = substr($sub, 0, strpos($sub, $arr[2]));
559
            }
560
        }
561
        return $id;
562
    }
563
564
    /**
565
     * Get the encrypted Solr core name
566
     *
567
     * @access private
568
     *
569
     * @return string with encrypted core name
570
     */
571
    private function getEncryptedCoreName(): string
572
    {
573
        // Get core name.
574
        $name = Helper::getIndexNameFromUid($this->settings['solrcore'], 'tx_dlf_solrcores');
575
        // Encrypt core name.
576
        if (!empty($name)) {
577
            $name = Helper::encrypt($name);
578
        }
579
        return $name;
580
    }
581
582
    /**
583
     * Check if the full text is empty.
584
     *
585
     * @access private
586
     *
587
     * @return bool true if empty, false otherwise
588
     */
589
    private function isFullTextEmpty(): bool
590
    {
591
        $fileGrpsFulltext = GeneralUtility::trimExplode(',', $this->extConf['files']['fileGrpFulltext']);
592
        while ($fileGrpFulltext = array_shift($fileGrpsFulltext)) {
593
            if (isset($this->requestData['page'])) {
594
                $files = $this->currentDocument->physicalStructureInfo[$this->currentDocument->physicalStructure[$this->requestData['page']]]['files'];
595
                if (!empty($files[$fileGrpFulltext])) {
596
                    return false;
597
                }
598
            }
599
        }
600
        return true;
601
    }
602
}
603