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
Push — master ( 1cbe0a...d27b89 )
by
unknown
03:45
created

ToolboxController::filterImageFiles()   A

Complexity

Conditions 3
Paths 2

Size

Total Lines 6
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 3
eloc 3
c 0
b 0
f 0
nc 2
nop 1
dl 0
loc 6
rs 10
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 TYPO3\CMS\Core\Utility\GeneralUtility;
17
use TYPO3\CMS\Core\Utility\MathUtility;
18
19
/**
20
 * Controller class for plugin 'Toolbox'.
21
 *
22
 * @package TYPO3
23
 * @subpackage dlf
24
 *
25
 * @access public
26
 */
27
class ToolboxController extends AbstractController
28
{
29
30
    /**
31
     * @access private
32
     * @var AbstractDocument This holds the current document
33
     */
34
    private AbstractDocument $currentDocument;
35
36
    /**
37
     * The main method of the plugin
38
     *
39
     * @access public
40
     *
41
     * @return void
42
     */
43
    public function mainAction(): void
44
    {
45
        // Load current document.
46
        $this->loadDocument();
47
48
        $this->view->assign('double', $this->requestData['double']);
49
50
        if (!$this->isDocMissingOrEmpty()) {
51
            $this->currentDocument = $this->document->getCurrentDocument();
52
        }
53
54
        $this->renderTools();
55
        $this->view->assign('viewData', $this->viewData);
56
    }
57
58
    /**
59
     * Renders tool in the toolbox.
60
     *
61
     * @access private
62
     *
63
     * @return void
64
     */
65
    private function renderTools(): void
66
    {
67
        if (!empty($this->settings['tools'])) {
68
69
            $tools = explode(',', $this->settings['tools']);
70
71
            foreach ($tools as $tool) {
72
                switch ($tool) {
73
                    case 'tx_dlf_annotationtool':
74
                    case 'annotationtool':
75
                        $this->renderToolByName('renderAnnotationTool');
76
                        break;
77
                    case 'tx_dlf_fulltextdownloadtool':
78
                    case 'fulltextdownloadtool':
79
                        $this->renderToolByName('renderFulltextDownloadTool');
80
                        break;
81
                    case 'tx_dlf_fulltexttool':
82
                    case 'fulltexttool':
83
                        $this->renderToolByName('renderFulltextTool');
84
                        break;
85
                    case 'tx_dlf_imagedownloadtool':
86
                    case 'imagedownloadtool':
87
                        $this->renderToolByName('renderImageDownloadTool');
88
                        break;
89
                    case 'tx_dlf_imagemanipulationtool':
90
                    case 'imagemanipulationtool':
91
                        $this->renderToolByName('renderImageManipulationTool');
92
                        break;
93
                    case 'tx_dlf_modeldownloadtool':
94
                    case 'modeldownloadtool':
95
                        $this->renderToolByName('renderModelDownloadTool');
96
                        break;
97
                    case 'tx_dlf_pdfdownloadtool':
98
                    case 'pdfdownloadtool':
99
                        $this->renderToolByName('renderPdfDownloadTool');
100
                        break;
101
                    case 'tx_dlf_searchindocumenttool':
102
                    case 'searchindocumenttool':
103
                        $this->renderToolByName('renderSearchInDocumentTool');
104
                        break;
105
                    case 'scoretool':
106
                        $this->renderToolByName('renderScoreTool');
107
                        break;
108
                    default:
109
                        $this->logger->warning('Incorrect tool configuration: "' . $this->settings['tools'] . '". Tool "' . $tool . '" does not exist.');
110
                }
111
            }
112
        }
113
    }
114
115
    /**
116
     * Renders tool by the name in the toolbox.
117
     *
118
     * @access private
119
     *
120
     * @param string $tool name
121
     *
122
     * @return void
123
     */
124
    private function renderToolByName(string $tool): void
125
    {
126
        $this->$tool();
127
        $this->view->assign($tool, true);
128
    }
129
130
    /**
131
     * Get image's URL and MIME type information's.
132
     *
133
     * @access private
134
     *
135
     * @param int $page Page number
136
     *
137
     * @return array Array of image information's.
138
     */
139
    public function getImage(int $page): array
140
    {
141
        // Get @USE value of METS fileGroup.
142
        $image = $this->getFile($page, GeneralUtility::trimExplode(',', $this->settings['fileGrpsImageDownload']));
143
        switch ($image['mimetype']) {
144
            case 'image/jpeg':
145
                $image['mimetypeLabel'] = ' (JPG)';
146
                break;
147
            case 'image/tiff':
148
                $image['mimetypeLabel'] = ' (TIFF)';
149
                break;
150
            default:
151
                $image['mimetypeLabel'] = '';
152
        }
153
        return $image;
154
    }
155
156
    /**
157
     * Renders the annotation tool (used in template)
158
     * @SuppressWarnings(PHPMD.UnusedPrivateMethod)
159
     *
160
     * @access private
161
     *
162
     * @return void
163
     */
164
    private function renderAnnotationTool(): void
165
    {
166
        if ($this->isDocMissingOrEmpty()) {
167
            // Quit without doing anything if required variables are not set.
168
            return;
169
        }
170
171
        $this->setPage();
172
173
        $annotationContainers = $this->currentDocument->physicalStructureInfo[$this->currentDocument->physicalStructure[$this->requestData['page']]]['annotationContainers'];
174
        if (
175
            $annotationContainers != null
176
            && count($annotationContainers) > 0
177
        ) {
178
            $this->view->assign('annotationTool', true);
179
        } else {
180
            $this->view->assign('annotationTool', false);
181
        }
182
    }
183
184
    /**
185
     * Renders the fulltext download tool (used in template)
186
     * @SuppressWarnings(PHPMD.UnusedPrivateMethod)
187
     *
188
     * @access private
189
     *
190
     * @return void
191
     */
192
    private function renderFulltextDownloadTool(): void
193
    {
194
        if (
195
            $this->isDocMissingOrEmpty()
196
            || empty($this->extConf['files']['fileGrpFulltext'])
197
        ) {
198
            // Quit without doing anything if required variables are not set.
199
            return;
200
        }
201
202
        $this->setPage();
203
204
        // Get text download.
205
        $this->view->assign('fulltextDownload', !$this->isFullTextEmpty());
206
    }
207
208
    /**
209
     * Renders the fulltext tool (used in template)
210
     * @SuppressWarnings(PHPMD.UnusedPrivateMethod)
211
     *
212
     * @access private
213
     *
214
     * @return void
215
     */
216
    private function renderFulltextTool(): void
217
    {
218
        if (
219
            $this->isDocMissingOrEmpty()
220
            || empty($this->extConf['files']['fileGrpFulltext'])
221
        ) {
222
            // Quit without doing anything if required variables are not set.
223
            return;
224
        }
225
226
        $this->setPage();
227
228
        if (!$this->isFullTextEmpty()) {
229
            $this->view->assign('fulltext', true);
230
            $this->view->assign('activateFullTextInitially', MathUtility::forceIntegerInRange($this->settings['activateFullTextInitially'], 0, 1, 0));
231
        } else {
232
            $this->view->assign('fulltext', false);
233
        }
234
    }
235
236
    /**
237
     * Renders the score tool
238
     *
239
     * @return void
240
     */
241
    public function renderScoreTool()
242
    {
243
        if (
244
            $this->isDocMissingOrEmpty()
245
            || empty($this->extConf['files']['fileGrpScore'])
246
        ) {
247
            // Quit without doing anything if required variables are not set.
248
            return;
249
        }
250
251
        if ($this->requestData['page']) {
252
            $currentPhysPage = $this->document->getCurrentDocument()->physicalStructure[$this->requestData['page']];
253
        } else {
254
            $currentPhysPage = $this->document->getCurrentDocument()->physicalStructure[1];
255
        }
256
257
        $fileGrpsScores = GeneralUtility::trimExplode(',', $this->extConf['files']['fileGrpScore']);
258
        foreach ($fileGrpsScores as $fileGrpScore) {
259
            if ($this->document->getCurrentDocument()->physicalStructureInfo[$currentPhysPage]['files'][$fileGrpScore]) {
260
                $scoreFile = $this->document->getCurrentDocument()->physicalStructureInfo[$currentPhysPage]['files'][$fileGrpScore];
261
            }
262
        }
263
        if (!empty($scoreFile)) {
264
            $this->view->assign('score', true);
265
            $this->view->assign('activateScoreInitially', MathUtility::forceIntegerInRange($this->settings['activateScoreInitially'], 0, 1, 0));
266
        } else {
267
            $this->view->assign('score', false);
268
        }
269
    }
270
271
    /**
272
     * List of common web image mimetypes
273
     * The MIMETYPE attribute must specify the media type of the digital representation. All web-compatible formats as per RFC2046 are allowed.
274
     */
275
    private const IMAGE_MIMETYPES = [
276
        "image/jpeg",
277
        "image/jpg",
278
        "image/png",
279
        "image/gif",
280
        "image/bmp",
281
        "image/tiff",
282
        "image/x-tiff",
283
        "image/webp",
284
        "image/svg+xml",
285
        "image/vnd.microsoft.icon",
286
        "image/x-icon",
287
        "image/heif",
288
        "image/heic",
289
        "image/vnd.adobe.photoshop",
290
        "image/x-xbitmap",
291
        "image/x-xpixmap",
292
        "image/jp2",
293
        "image/jpx",
294
        "image/jpm",
295
        "image/mj2",
296
        "image/x-portable-anymap",
297
        "image/x-portable-bitmap",
298
        "image/x-portable-graymap",
299
        "image/x-portable-pixmap"
300
    ];
301
302
    /**
303
     * Renders the image download tool
304
     * Renders the image download tool (used in template)
305
     * @SuppressWarnings(PHPMD.UnusedPrivateMethod)
306
     *
307
     * @access private
308
     *
309
     * @return void
310
     */
311
    private function renderImageDownloadTool(): void
312
    {
313
        if (
314
            $this->isDocMissingOrEmpty()
315
            || empty($this->settings['fileGrpsImageDownload'])
316
        ) {
317
            // Quit without doing anything if required variables are not set.
318
            return;
319
        }
320
321
        $this->setPage();
322
323
        $imageArray = [];
324
        // Get left or single page download.
325
        $image = $this->getImage($this->requestData['page']);
326
        if ($this->filterImageFiles($image)) {
327
            $imageArray[0] = $image;
328
        }
329
330
        if ($this->requestData['double'] == 1) {
331
            $image = $this->getImage($this->requestData['page'] + 1);
332
            if ($this->filterImageFiles($image)) {
333
                $imageArray[1] = $image;
334
            }
335
        }
336
337
        $this->view->assign('imageDownload', $imageArray);
338
    }
339
340
    /**
341
     * Filters an image file based on its mimetype.
342
     *
343
     * This method checks if the provided image array contains a 'mimetype' key and
344
     * verifies if the mimetype is one of the supported image types defined in the class constant IMAGE_MIMETYPES.
345
     *
346
     * @param mixed $image The image array to filter
347
     *
348
     * @return bool True if the image mimetype is supported, false otherwise
349
     */
350
    private function filterImageFiles($image): bool
351
    {
352
        if (is_array($image) && isset($image['mimetype'])) {
353
            return in_array($image['mimetype'], self::IMAGE_MIMETYPES);
354
        }
355
        return false;
356
    }
357
358
    /**
359
     * Get file's URL and MIME type
360
     *
361
     * @access private
362
     *
363
     * @param int $page Page number
364
     *
365
     * @return array Array of file information
366
     */
367
    private function getFile(int $page, array $fileGrps): array
368
    {
369
        $file = [];
370
        while ($fileGrp = @array_pop($fileGrps)) {
371
            $physicalStructureInfo = $this->currentDocument->physicalStructureInfo[$this->currentDocument->physicalStructure[$page]];
372
            $fileId = $physicalStructureInfo['files'][$fileGrp];
373
            if (!empty($fileId)) {
374
                $file['url'] = $this->currentDocument->getDownloadLocation($fileId);
375
                $file['mimetype'] = $this->currentDocument->getFileMimeType($fileId);
376
            } else {
377
                $this->logger->warning('File not found in fileGrp "' . $fileGrp . '"');
378
            }
379
        }
380
        return $file;
381
    }
382
383
    /**
384
     * Renders the image manipulation tool (used in template)
385
     * @SuppressWarnings(PHPMD.UnusedPrivateMethod)
386
     *
387
     * @access private
388
     *
389
     * @return void
390
     */
391
    private function renderImageManipulationTool(): void
392
    {
393
        // Set parent element for initialization.
394
        $parentContainer = !empty($this->settings['parentContainer']) ? $this->settings['parentContainer'] : '.tx-dlf-imagemanipulationtool';
395
396
        $this->view->assign('imageManipulation', true);
397
        $this->view->assign('parentContainer', $parentContainer);
398
    }
399
400
    /**
401
     * Renders the model download tool
402
     * Renders the model download tool (used in template)
403
     * @SuppressWarnings(PHPMD.UnusedPrivateMethod)
404
     *
405
     * @access private
406
     *
407
     * @return void
408
     */
409
    private function renderModelDownloadTool(): void
410
    {
411
        if (
412
            $this->isDocMissingOrEmpty()
413
            || empty($this->settings['fileGrpsModelDownload'])
414
        ) {
415
            // Quit without doing anything if required variables are not set.
416
            return;
417
        }
418
419
        $this->setPage();
420
421
        $this->view->assign('modelDownload', $this->getFile($this->requestData['page'], GeneralUtility::trimExplode(',', $this->settings['fileGrpsModelDownload'])));
422
    }
423
424
    /**
425
     * Renders the PDF download tool (used in template)
426
     * @SuppressWarnings(PHPMD.UnusedPrivateMethod)
427
     *
428
     * @access private
429
     *
430
     * @return void
431
     */
432
    private function renderPdfDownloadTool(): void
433
    {
434
        if (
435
            $this->isDocMissingOrEmpty()
436
            || empty($this->extConf['files']['fileGrpDownload'])
437
        ) {
438
            // Quit without doing anything if required variables are not set.
439
            return;
440
        }
441
442
        $this->setPage();
443
444
        // Get single page downloads.
445
        $this->view->assign('pageLinks', $this->getPageLink());
446
        // Get work download.
447
        $this->view->assign('workLink', $this->getWorkLink());
448
    }
449
450
    /**
451
     * Get page's download link
452
     *
453
     * @access private
454
     *
455
     * @return array Link to downloadable page
456
     */
457
    private function getPageLink(): array
458
    {
459
        $firstPageLink = '';
460
        $secondPageLink = '';
461
        $pageLinkArray = [];
462
        $pageNumber = $this->requestData['page'];
463
        $fileGrpsDownload = GeneralUtility::trimExplode(',', $this->extConf['files']['fileGrpDownload']);
464
        // Get image link.
465
        while ($fileGrpDownload = array_shift($fileGrpsDownload)) {
466
            $firstFileGroupDownload = $this->currentDocument->physicalStructureInfo[$this->currentDocument->physicalStructure[$pageNumber]]['files'][$fileGrpDownload];
467
            if (!empty($firstFileGroupDownload)) {
468
                $firstPageLink = $this->currentDocument->getFileLocation($firstFileGroupDownload);
469
                // Get second page, too, if double page view is activated.
470
                $secondFileGroupDownload = $this->currentDocument->physicalStructureInfo[$this->currentDocument->physicalStructure[$pageNumber + 1]]['files'][$fileGrpDownload];
471
                if (
472
                    $this->requestData['double']
473
                    && $pageNumber < $this->currentDocument->numPages
474
                    && !empty($secondFileGroupDownload)
475
                ) {
476
                    $secondPageLink = $this->currentDocument->getFileLocation($secondFileGroupDownload);
477
                }
478
                break;
479
            }
480
        }
481
        if (
482
            empty($firstPageLink)
483
            && empty($secondPageLink)
484
        ) {
485
            $this->logger->warning('File not found in fileGrps "' . $this->extConf['files']['fileGrpDownload'] . '"');
486
        }
487
488
        if (!empty($firstPageLink)) {
489
            $pageLinkArray[0] = $firstPageLink;
490
        }
491
        if (!empty($secondPageLink)) {
492
            $pageLinkArray[1] = $secondPageLink;
493
        }
494
        return $pageLinkArray;
495
    }
496
497
    /**
498
     * Get work's download link
499
     *
500
     * @access private
501
     *
502
     * @return string Link to downloadable work
503
     */
504
    private function getWorkLink(): string
505
    {
506
        $workLink = '';
507
        $fileGrpsDownload = GeneralUtility::trimExplode(',', $this->extConf['files']['fileGrpDownload']);
508
        // Get work link.
509
        while ($fileGrpDownload = array_shift($fileGrpsDownload)) {
510
            $fileGroupDownload = $this->currentDocument->physicalStructureInfo[$this->currentDocument->physicalStructure[0]]['files'][$fileGrpDownload];
511
            if (!empty($fileGroupDownload)) {
512
                $workLink = $this->currentDocument->getFileLocation($fileGroupDownload);
513
                break;
514
            } else {
515
                $details = $this->currentDocument->getLogicalStructure($this->currentDocument->toplevelId);
516
                if (!empty($details['files'][$fileGrpDownload])) {
517
                    $workLink = $this->currentDocument->getFileLocation($details['files'][$fileGrpDownload]);
518
                    break;
519
                }
520
            }
521
        }
522
        if (empty($workLink)) {
523
            $this->logger->warning('File not found in fileGrps "' . $this->extConf['files']['fileGrpDownload'] . '"');
524
        }
525
        return $workLink;
526
    }
527
528
    /**
529
     * Renders the searchInDocument tool (used in template)
530
     * @SuppressWarnings(PHPMD.UnusedPrivateMethod)
531
     *
532
     * @access private
533
     *
534
     * @return void
535
     */
536
    private function renderSearchInDocumentTool(): void
537
    {
538
        if (
539
            $this->isDocMissingOrEmpty()
540
            || empty($this->extConf['files']['fileGrpFulltext'])
541
            || empty($this->settings['solrcore'])
542
        ) {
543
            // Quit without doing anything if required variables are not set.
544
            return;
545
        }
546
547
        $this->setPage();
548
549
        // Quit if no fulltext file is present
550
        if ($this->isFullTextEmpty()) {
551
            return;
552
        }
553
554
        $viewArray = [
555
            'labelQueryUrl' => $this->settings['queryInputName'],
556
            'labelStart' => $this->settings['startInputName'],
557
            'labelId' => $this->settings['idInputName'],
558
            'labelPid' => $this->settings['pidInputName'],
559
            'labelPageUrl' => $this->settings['pageInputName'],
560
            'labelHighlightWord' => $this->settings['highlightWordInputName'],
561
            'labelEncrypted' => $this->settings['encryptedInputName'],
562
            'documentId' => $this->getCurrentDocumentId(),
563
            'documentPageId' => $this->document->getPid(),
564
            'solrEncrypted' => $this->getEncryptedCoreName() ? : ''
565
        ];
566
567
        $this->view->assign('searchInDocument', $viewArray);
568
    }
569
570
    /**
571
     * Get current document id. As default the uid will be used.
572
     * In case there is defined documentIdUrlSchema then the id will
573
     * extracted from this URL.
574
     *
575
     * @access private
576
     *
577
     * @return string with current document id
578
     */
579
    private function getCurrentDocumentId(): string
580
    {
581
        $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

581
        /** @scrutinizer ignore-call */ 
582
        $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...
582
583
        if ($id !== null && $id > 0) {
584
            // we found the document uid
585
            return (string) $id;
586
        } else {
587
            $id = $this->requestData['id'];
588
            if (!GeneralUtility::isValidUrl($id)) {
589
                // we found no valid URI --> something unexpected we cannot search within.
590
                return '';
591
            }
592
        }
593
594
        // example: https://host.de/items/*id*/record
595
        if (!empty($this->settings['documentIdUrlSchema'])) {
596
            $arr = explode('*', $this->settings['documentIdUrlSchema']);
597
598
            if (count($arr) == 2) {
599
                $id = explode($arr[0], $id)[0];
600
            } else if (count($arr) == 3) {
601
                $sub = substr($id, strpos($id, $arr[0]) + strlen($arr[0]), strlen($id));
602
                $id = substr($sub, 0, strpos($sub, $arr[2]));
603
            }
604
        }
605
        return $id;
606
    }
607
608
    /**
609
     * Get the encrypted Solr core name
610
     *
611
     * @access private
612
     *
613
     * @return string with encrypted core name
614
     */
615
    private function getEncryptedCoreName(): string
616
    {
617
        // Get core name.
618
        $name = Helper::getIndexNameFromUid($this->settings['solrcore'], 'tx_dlf_solrcores');
619
        // Encrypt core name.
620
        if (!empty($name)) {
621
            $name = Helper::encrypt($name);
622
        }
623
        return $name;
624
    }
625
626
    /**
627
     * Check if the full text is empty.
628
     *
629
     * @access private
630
     *
631
     * @return bool true if empty, false otherwise
632
     */
633
    private function isFullTextEmpty(): bool
634
    {
635
        $fileGrpsFulltext = GeneralUtility::trimExplode(',', $this->extConf['files']['fileGrpFulltext']);
636
        while ($fileGrpFulltext = array_shift($fileGrpsFulltext)) {
637
            $files = $this->currentDocument->physicalStructureInfo[$this->currentDocument->physicalStructure[$this->requestData['page']]]['files'];
638
            if (!empty($files[$fileGrpFulltext])) {
639
                return false;
640
            }
641
        }
642
        return true;
643
    }
644
}
645