Passed
Pull Request — master (#123)
by
unknown
05:01
created

ToolboxController::getPageLink()   B

Complexity

Conditions 10
Paths 32

Size

Total Lines 38
Code Lines 25

Duplication

Lines 0
Ratio 0 %

Importance

Changes 5
Bugs 2 Features 0
Metric Value
cc 10
eloc 25
c 5
b 2
f 0
nc 32
nop 0
dl 0
loc 38
rs 7.6666

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 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_pdfdownloadtool':
94
                    case 'pdfdownloadtool':
95
                        $this->renderToolByName('renderPdfDownloadTool');
96
                        break;
97
                    case 'tx_dlf_searchindocumenttool':
98
                    case 'searchindocumenttool':
99
                        $this->renderToolByName('renderSearchInDocumentTool');
100
                        break;
101
                    case 'scoretool':
102
                        $this->renderToolByName('renderScoreTool');
103
                        break;
104
                    default:
105
                        $this->logger->warning('Incorrect tool configuration: "' . $this->settings['tools'] . '". Tool "' . $tool . '" does not exist.');
0 ignored issues
show
Bug introduced by
The method warning() 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

105
                        $this->logger->/** @scrutinizer ignore-call */ 
106
                                       warning('Incorrect tool configuration: "' . $this->settings['tools'] . '". Tool "' . $tool . '" does not exist.');

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...
106
                }
107
            }
108
        }
109
    }
110
111
    /**
112
     * Renders tool by the name in the toolbox.
113
     *
114
     * @access private
115
     *
116
     * @param string $tool name
117
     *
118
     * @return void
119
     */
120
    private function renderToolByName(string $tool): void
121
    {
122
        $this->$tool();
123
        $this->view->assign($tool, true);
124
    }
125
126
    /**
127
     * Renders the annotation tool (used in template)
128
     * @SuppressWarnings(PHPMD.UnusedPrivateMethod)
129
     *
130
     * @access private
131
     *
132
     * @return void
133
     */
134
    private function renderAnnotationTool(): void
135
    {
136
        if ($this->isDocMissingOrEmpty()) {
137
            // Quit without doing anything if required variables are not set.
138
            return;
139
        }
140
141
        $this->setPage();
142
143
        $annotationContainers = $this->currentDocument->physicalStructureInfo[$this->currentDocument->physicalStructure[$this->requestData['page']]]['annotationContainers'];
144
        if (
145
            $annotationContainers != null
146
            && count($annotationContainers) > 0
147
        ) {
148
            $this->view->assign('annotationTool', true);
149
        } else {
150
            $this->view->assign('annotationTool', false);
151
        }
152
    }
153
154
    /**
155
     * Renders the fulltext download tool (used in template)
156
     * @SuppressWarnings(PHPMD.UnusedPrivateMethod)
157
     *
158
     * @access private
159
     *
160
     * @return void
161
     */
162
    private function renderFulltextDownloadTool(): void
163
    {
164
        if (
165
            $this->isDocMissingOrEmpty()
166
            || empty($this->extConf['files']['fileGrpFulltext'])
167
        ) {
168
            // Quit without doing anything if required variables are not set.
169
            return;
170
        }
171
172
        $this->setPage();
173
174
        // Get text download.
175
        $this->view->assign('fulltextDownload', !$this->isFullTextEmpty());
176
    }
177
178
    /**
179
     * Renders the fulltext tool (used in template)
180
     * @SuppressWarnings(PHPMD.UnusedPrivateMethod)
181
     *
182
     * @access private
183
     *
184
     * @return void
185
     */
186
    private function renderFulltextTool(): void
187
    {
188
        if (
189
            $this->isDocMissingOrEmpty()
190
            || empty($this->extConf['files']['fileGrpFulltext'])
191
        ) {
192
            // Quit without doing anything if required variables are not set.
193
            return;
194
        }
195
196
        $this->setPage();
197
198
        if (!$this->isFullTextEmpty()) {
199
            $this->view->assign('fulltext', true);
200
            $this->view->assign('activateFullTextInitially', MathUtility::forceIntegerInRange($this->settings['activateFullTextInitially'], 0, 1, 0));
201
        } else {
202
            $this->view->assign('fulltext', false);
203
        }
204
    }
205
206
    /**
207
     * Renders the score tool
208
     *
209
     * @return void
210
     */
211
    public function renderScoreTool()
212
    {
213
        if (
214
            $this->isDocMissingOrEmpty()
215
            || empty($this->extConf['files']['fileGrpScore'])
216
        ) {
217
            // Quit without doing anything if required variables are not set.
218
            return;
219
        }
220
221
        if ($this->requestData['page']) {
222
            $currentPhysPage = $this->document->getCurrentDocument()->physicalStructure[$this->requestData['page']];
223
        } else {
224
            $currentPhysPage = $this->document->getCurrentDocument()->physicalStructure[1];
225
        }
226
227
        $fileGrpsScores = GeneralUtility::trimExplode(',', $this->extConf['files']['fileGrpScore']);
228
        foreach ($fileGrpsScores as $fileGrpScore) {
229
            if ($this->document->getCurrentDocument()->physicalStructureInfo[$currentPhysPage]['files'][$fileGrpScore]) {
230
                $scoreFile = $this->document->getCurrentDocument()->physicalStructureInfo[$currentPhysPage]['files'][$fileGrpScore];
231
            }
232
        }
233
        if (!empty($scoreFile)) {
234
            $this->view->assign('score', true);
235
            $this->view->assign('activateScoreInitially', MathUtility::forceIntegerInRange($this->settings['activateScoreInitially'], 0, 1, 0));
236
        } else {
237
            $this->view->assign('score', false);
238
        }
239
    }
240
241
    /**
242
     * Renders the image download tool
243
     * Renders the image download tool (used in template)
244
     * @SuppressWarnings(PHPMD.UnusedPrivateMethod)
245
     *
246
     * @access private
247
     *
248
     * @return void
249
     */
250
    private function renderImageDownloadTool(): void
251
    {
252
        if (
253
            $this->isDocMissingOrEmpty()
254
            || empty($this->settings['fileGrpsImageDownload'])
255
        ) {
256
            // Quit without doing anything if required variables are not set.
257
            return;
258
        }
259
260
        $this->setPage();
261
262
        $imageArray = [];
263
        // Get left or single page download.
264
        $imageArray[0] = $this->getImage($this->requestData['page']);
265
        if ($this->requestData['double'] == 1) {
266
            $imageArray[1] = $this->getImage($this->requestData['page'] + 1);
267
        }
268
        $this->view->assign('imageDownload', $imageArray);
269
    }
270
271
    /**
272
     * Get image's URL and MIME type
273
     *
274
     * @access private
275
     *
276
     * @param int $page Page number
277
     *
278
     * @return array Array of image links and image format information
279
     */
280
    private function getImage(int $page): array
281
    {
282
        $image = [];
283
        // Get @USE value of METS fileGrp.
284
        $fileGrps = GeneralUtility::trimExplode(',', $this->settings['fileGrpsImageDownload']);
285
        while ($fileGrp = @array_pop($fileGrps)) {
286
            // Get image link.
287
            $physicalStructureInfo = $this->currentDocument->physicalStructureInfo[$this->currentDocument->physicalStructure[$page]];
288
            $fileId = $physicalStructureInfo['files'][$fileGrp];
289
            if (!empty($fileId)) {
290
                $image['url'] = $this->currentDocument->getDownloadLocation($fileId);
291
                $image['mimetype'] = $this->currentDocument->getFileMimeType($fileId);
292
                switch ($image['mimetype']) {
293
                    case 'image/jpeg':
294
                        $image['mimetypeLabel']  = ' (JPG)';
295
                        break;
296
                    case 'image/tiff':
297
                        $image['mimetypeLabel']  = ' (TIFF)';
298
                        break;
299
                    default:
300
                        $image['mimetypeLabel']  = '';
301
                }
302
                break;
303
            } else {
304
                $this->logger->warning('File not found in fileGrp "' . $fileGrp . '"');
305
            }
306
        }
307
        return $image;
308
    }
309
310
    /**
311
     * Renders the image manipulation tool (used in template)
312
     * @SuppressWarnings(PHPMD.UnusedPrivateMethod)
313
     *
314
     * @access private
315
     *
316
     * @return void
317
     */
318
    private function renderImageManipulationTool(): void
319
    {
320
        // Set parent element for initialization.
321
        $parentContainer = !empty($this->settings['parentContainer']) ? $this->settings['parentContainer'] : '.tx-dlf-imagemanipulationtool';
322
323
        $this->view->assign('imageManipulation', true);
324
        $this->view->assign('parentContainer', $parentContainer);
325
    }
326
327
    /**
328
     * Renders the PDF download tool (used in template)
329
     * @SuppressWarnings(PHPMD.UnusedPrivateMethod)
330
     *
331
     * @access private
332
     *
333
     * @return void
334
     */
335
    private function renderPdfDownloadTool(): void
336
    {
337
        if (
338
            $this->isDocMissingOrEmpty()
339
            || empty($this->extConf['files']['fileGrpDownload'])
340
        ) {
341
            // Quit without doing anything if required variables are not set.
342
            return;
343
        }
344
345
        $this->setPage();
346
347
        // Get single page downloads.
348
        $this->view->assign('pageLinks', $this->getPageLink());
349
        // Get work download.
350
        $this->view->assign('workLink', $this->getWorkLink());
351
    }
352
353
    /**
354
     * Get page's download link
355
     *
356
     * @access private
357
     *
358
     * @return array Link to downloadable page
359
     */
360
    private function getPageLink(): array
361
    {
362
        $firstPageLink = '';
363
        $secondPageLink = '';
364
        $pageLinkArray = [];
365
        $pageNumber = $this->requestData['page'];
366
        $fileGrpsDownload = GeneralUtility::trimExplode(',', $this->extConf['files']['fileGrpDownload']);
367
        // Get image link.
368
        while ($fileGrpDownload = array_shift($fileGrpsDownload)) {
369
            $firstFileGroupDownload = $this->currentDocument->physicalStructureInfo[$this->currentDocument->physicalStructure[$pageNumber]]['files'][$fileGrpDownload];
370
            if (!empty($firstFileGroupDownload)) {
371
                $firstPageLink = $this->currentDocument->getFileLocation($firstFileGroupDownload);
372
                // Get second page, too, if double page view is activated.
373
                $secondFileGroupDownload = $this->currentDocument->physicalStructureInfo[$this->currentDocument->physicalStructure[$pageNumber + 1]]['files'][$fileGrpDownload];
374
                if (
375
                    $this->requestData['double']
376
                    && $pageNumber < $this->currentDocument->numPages
377
                    && !empty($secondFileGroupDownload)
378
                ) {
379
                    $secondPageLink = $this->currentDocument->getFileLocation($secondFileGroupDownload);
380
                }
381
                break;
382
            }
383
        }
384
        if (
385
            empty($firstPageLink)
386
            && empty($secondPageLink)
387
        ) {
388
            $this->logger->warning('File not found in fileGrps "' . $this->extConf['files']['fileGrpDownload'] . '"');
389
        }
390
391
        if (!empty($firstPageLink)) {
392
            $pageLinkArray[0] = $firstPageLink;
393
        }
394
        if (!empty($secondPageLink)) {
395
            $pageLinkArray[1] = $secondPageLink;
396
        }
397
        return $pageLinkArray;
398
    }
399
400
    /**
401
     * Get work's download link
402
     *
403
     * @access private
404
     *
405
     * @return string Link to downloadable work
406
     */
407
    private function getWorkLink(): string
408
    {
409
        $workLink = '';
410
        $fileGrpsDownload = GeneralUtility::trimExplode(',', $this->extConf['files']['fileGrpDownload']);
411
        // Get work link.
412
        while ($fileGrpDownload = array_shift($fileGrpsDownload)) {
413
            $fileGroupDownload = $this->currentDocument->physicalStructureInfo[$this->currentDocument->physicalStructure[0]]['files'][$fileGrpDownload];
414
            if (!empty($fileGroupDownload)) {
415
                $workLink = $this->currentDocument->getFileLocation($fileGroupDownload);
416
                break;
417
            } else {
418
                $details = $this->currentDocument->getLogicalStructure($this->currentDocument->toplevelId);
419
                if (!empty($details['files'][$fileGrpDownload])) {
420
                    $workLink = $this->currentDocument->getFileLocation($details['files'][$fileGrpDownload]);
421
                    break;
422
                }
423
            }
424
        }
425
        if (empty($workLink)) {
426
            $this->logger->warning('File not found in fileGrps "' . $this->extConf['files']['fileGrpDownload'] . '"');
427
        }
428
        return $workLink;
429
    }
430
431
    /**
432
     * Renders the searchInDocument tool (used in template)
433
     * @SuppressWarnings(PHPMD.UnusedPrivateMethod)
434
     *
435
     * @access private
436
     *
437
     * @return void
438
     */
439
    private function renderSearchInDocumentTool(): void
440
    {
441
        if (
442
            $this->isDocMissingOrEmpty()
443
            || empty($this->extConf['files']['fileGrpFulltext'])
444
            || empty($this->settings['solrcore'])
445
        ) {
446
            // Quit without doing anything if required variables are not set.
447
            return;
448
        }
449
450
        $this->setPage();
451
452
        // Quit if no fulltext file is present
453
        if ($this->isFullTextEmpty()) {
454
            return;
455
        }
456
457
        $viewArray = [
458
            'labelQueryUrl' => $this->settings['queryInputName'],
459
            'labelStart' => $this->settings['startInputName'],
460
            'labelId' => $this->settings['idInputName'],
461
            'labelPid' => $this->settings['pidInputName'],
462
            'labelPageUrl' => $this->settings['pageInputName'],
463
            'labelHighlightWord' => $this->settings['highlightWordInputName'],
464
            'labelEncrypted' => $this->settings['encryptedInputName'],
465
            'documentId' => $this->getCurrentDocumentId(),
466
            'documentPageId' => $this->document->getPid(),
467
            'solrEncrypted' => $this->getEncryptedCoreName() ? : ''
468
        ];
469
470
        $this->view->assign('searchInDocument', $viewArray);
471
    }
472
473
    /**
474
     * Get current document id. As default the uid will be used.
475
     * In case there is defined documentIdUrlSchema then the id will
476
     * extracted from this URL.
477
     *
478
     * @access private
479
     *
480
     * @return string with current document id
481
     */
482
    private function getCurrentDocumentId(): string
483
    {
484
        $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

484
        /** @scrutinizer ignore-call */ 
485
        $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...
485
486
        if ($id !== null && $id > 0) {
487
            // we found the document uid
488
            return (string) $id;
489
        } else {
490
            $id = $this->requestData['id'];
491
            if (!GeneralUtility::isValidUrl($id)) {
492
                // we found no valid URI --> something unexpected we cannot search within.
493
                return '';
494
            }
495
        }
496
497
        // example: https://host.de/items/*id*/record
498
        if (!empty($this->settings['documentIdUrlSchema'])) {
499
            $arr = explode('*', $this->settings['documentIdUrlSchema']);
500
501
            if (count($arr) == 2) {
502
                $id = explode($arr[0], $id)[0];
503
            } else if (count($arr) == 3) {
504
                $sub = substr($id, strpos($id, $arr[0]) + strlen($arr[0]), strlen($id));
505
                $id = substr($sub, 0, strpos($sub, $arr[2]));
506
            }
507
        }
508
        return $id;
509
    }
510
511
    /**
512
     * Get the encrypted Solr core name
513
     *
514
     * @access private
515
     *
516
     * @return string with encrypted core name
517
     */
518
    private function getEncryptedCoreName(): string
519
    {
520
        // Get core name.
521
        $name = Helper::getIndexNameFromUid($this->settings['solrcore'], 'tx_dlf_solrcores');
522
        // Encrypt core name.
523
        if (!empty($name)) {
524
            $name = Helper::encrypt($name);
525
        }
526
        return $name;
527
    }
528
529
    /**
530
     * Check if the full text is empty.
531
     *
532
     * @access private
533
     *
534
     * @return bool true if empty, false otherwise
535
     */
536
    private function isFullTextEmpty(): bool
537
    {
538
        $fileGrpsFulltext = GeneralUtility::trimExplode(',', $this->extConf['files']['fileGrpFulltext']);
539
        while ($fileGrpFulltext = array_shift($fileGrpsFulltext)) {
540
            $files = $this->currentDocument->physicalStructureInfo[$this->currentDocument->physicalStructure[$this->requestData['page']]]['files'];
541
            if (!empty($files[$fileGrpFulltext])) {
542
                return false;
543
            }
544
        }
545
        return true;
546
    }
547
}
548