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.
Completed
Push — master ( aedf9a...cd6bf0 )
by Erik
35s queued 10s
created

IiifManifest::establishRecordId()   A

Complexity

Conditions 6
Paths 5

Size

Total Lines 33
Code Lines 19

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 19
c 1
b 0
f 0
dl 0
loc 33
rs 9.0111
cc 6
nc 5
nop 1
1
<?php
2
namespace Kitodo\Dlf\Common;
3
4
/**
5
 * (c) Kitodo. Key to digital objects e.V. <[email protected]>
6
 *
7
 * This file is part of the Kitodo and TYPO3 projects.
8
 *
9
 * @license GNU General Public License version 3 or later.
10
 * For the full copyright and license information, please read the
11
 * LICENSE.txt file that was distributed with this source code.
12
 */
13
14
use Flow\JSONPath\JSONPath;
15
use TYPO3\CMS\Core\Utility\GeneralUtility;
16
use Ubl\Iiif\Presentation\Common\Model\Resources\AnnotationContainerInterface;
17
use Ubl\Iiif\Presentation\Common\Model\Resources\AnnotationInterface;
18
use Ubl\Iiif\Presentation\Common\Model\Resources\CanvasInterface;
19
use Ubl\Iiif\Presentation\Common\Model\Resources\ContentResourceInterface;
20
use Ubl\Iiif\Presentation\Common\Model\Resources\IiifResourceInterface;
21
use Ubl\Iiif\Presentation\Common\Model\Resources\ManifestInterface;
22
use Ubl\Iiif\Presentation\Common\Model\Resources\RangeInterface;
23
use Ubl\Iiif\Presentation\Common\Vocabulary\Motivation;
24
use Ubl\Iiif\Presentation\V1\Model\Resources\AbstractIiifResource1;
25
use Ubl\Iiif\Presentation\V2\Model\Resources\AbstractIiifResource2;
26
use Ubl\Iiif\Presentation\V3\Model\Resources\AbstractIiifResource3;
27
use Ubl\Iiif\Services\AbstractImageService;
28
use Ubl\Iiif\Services\Service;
29
use Ubl\Iiif\Tools\IiifHelper;
30
31
/**
32
 * IiifManifest class for the 'dlf' extension. This class
33
 * represents a IIIF manifest in the conext of this TYPO3 extension.
34
 *
35
 * @author Lutz Helm <[email protected]>
36
 * @package	TYPO3
37
 * @subpackage	tx_dlf
38
 * @access	public
39
 */
40
final class IiifManifest extends Document
41
{
42
    /**
43
     * This holds the manifest file as string for serialization purposes
44
     * @see __sleep() / __wakeup()
45
     *
46
     * @var string
47
     * @access protected
48
     */
49
    protected $asJson = '';
50
51
    /**
52
     * A PHP object representation of a IIIF manifest.
53
     * @var ManifestInterface
54
     * @access protected
55
     */
56
    protected $iiif;
57
58
    /**
59
     * 'IIIF1', 'IIIF2' or 'IIIF3', depending on the API $this->iiif confrms to:
60
     * IIIF Metadata API 1, IIIF Presentation API 2 or 3
61
     * @var string
62
     * @access protected
63
     */
64
    protected $iiifVersion;
65
66
    /**
67
     * Document has already been analyzed if it contains fulltext for the Solr index
68
     * @var boolean
69
     * @access protected
70
     */
71
    protected $hasFulltextSet = false;
72
73
    /**
74
     * This holds the original manifest's parsed metadata array with their corresponding
75
     * resource (Manifest / Sequence / Range) ID as array key
76
     *
77
     * @var array
78
     * @access protected
79
     */
80
    protected $originalMetadataArray = array ();
81
82
    /**
83
     * Holds the mime types of linked resources in the manifest (extreacted during parsing) for later use.
84
     * @var array
85
     * @access protected
86
     */
87
    protected $mimeTypes = [];
88
89
    /**
90
     * The extension key
91
     *
92
     * @var string
93
     * @static
94
     * @access public
95
     */
96
    public static $extKey = 'dlf';
97
98
    /**
99
     * {@inheritDoc}
100
     * @see Document::establishRecordId()
101
     */
102
    protected function establishRecordId($pid)
103
    {
104
        if ($this->iiif !== null) {
105
            /*
106
             *  FIXME This will not consistently work because we can not be sure to have the pid at hand. It may miss
107
             *  if the plugin that actually loads the manifest allows content from other pages.
108
             *  Up until now the cPid is only set after the document has been initialized. We need it before to
109
             *  check the configuration.
110
             *  TODO Saving / indexing should still work - check!
111
             */
112
            $result = $GLOBALS['TYPO3_DB']->exec_SELECTquery(
113
                'tx_dlf_metadataformat.xpath AS querypath',
114
                'tx_dlf_metadata,tx_dlf_metadataformat,tx_dlf_formats',
115
                'tx_dlf_metadata.pid='.intval($pid)
116
                    .' AND tx_dlf_metadataformat.pid='.intval($pid)
117
                    .' AND ((tx_dlf_metadata.uid=tx_dlf_metadataformat.parent_id AND tx_dlf_metadataformat.encoded=tx_dlf_formats.uid'
118
                    .' AND tx_dlf_metadata.index_name="record_id" AND tx_dlf_formats.type='.$GLOBALS['TYPO3_DB']->fullQuoteStr($this->getIiifVersion(), 'tx_dlf_formats').') OR tx_dlf_metadata.format=0)'
119
                    .Helper::whereClause('tx_dlf_metadata', TRUE)
120
                    .Helper::whereClause('tx_dlf_metadataformat')
121
                    .Helper::whereClause('tx_dlf_formats')
122
            );
123
            if ($GLOBALS['TYPO3_DB']->sql_num_rows($result) > 0) {
124
                for ($i = 0, $j = $GLOBALS['TYPO3_DB']->sql_num_rows($result); $i < $j; $i++) {
125
                    $resArray = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($result);
126
                    $recordIdPath = $resArray['querypath'];
127
                    if (!empty($recordIdPath)) {
128
                        $this->recordId = $this->iiif->jsonPath($recordIdPath);
0 ignored issues
show
Documentation Bug introduced by
It seems like $this->iiif->jsonPath($recordIdPath) can also be of type Ubl\Iiif\Presentation\Co...urces\ManifestInterface or Ubl\Iiif\Presentation\Co...s\AbstractIiifResource1 or Ubl\Iiif\Presentation\Co...s\AbstractIiifResource2 or Ubl\Iiif\Presentation\Co...s\AbstractIiifResource3. However, the property $recordId is declared as type string. Maybe add an additional type check?

Our type inference engine has found a suspicous assignment of a value to a property. This check raises an issue when a value that can be of a mixed type is assigned to a property that is type hinted more strictly.

For example, imagine you have a variable $accountId that can either hold an Id object or false (if there is no account id yet). Your code now assigns that value to the id property of an instance of the Account class. This class holds a proper account, so the id value must no longer be false.

Either this assignment is in error or a type check should be added for that assignment.

class Id
{
    public $id;

    public function __construct($id)
    {
        $this->id = $id;
    }

}

class Account
{
    /** @var  Id $id */
    public $id;
}

$account_id = false;

if (starsAreRight()) {
    $account_id = new Id(42);
}

$account = new Account();
if ($account instanceof Id)
{
    $account->id = $account_id;
}
Loading history...
129
                    }
130
                }
131
            }
132
            // For now, it's a hardcoded ID, not only as a fallback
133
            if (!isset($this->recordId)) {
134
                $this->recordId = $this->iiif->getId();
135
            }
136
        }
137
    }
138
139
    /**
140
     * {@inheritDoc}
141
     * @see Document::getDocument()
142
     */
143
    protected function getDocument()
144
    {
145
        return $this->iiif;
146
    }
147
148
    /**
149
     * Returns a string representing the Metadata / Presentation API version which the IIIF resource
150
     * conforms to. This is used for example to extract metadata according to configured patterns.
151
     *
152
     * @access public
153
     *
154
     * @return string 'IIIF1' if the resource is a Metadata API 1 resource, 'IIIF2' / 'IIIF3' if
155
     * the resource is a Presentation API 2 / 3 resource
156
     */
157
    public function getIiifVersion() {
158
        if (!isset($this->iiifVersion)) {
159
            if ($this->iiif instanceof AbstractIiifResource1) {
160
                $this->iiifVersion = 'IIIF1';
161
            } elseif ($this->iiif instanceof AbstractIiifResource2) {
162
                $this->iiifVersion = 'IIIF2';
163
            } elseif ($this->iiif instanceof AbstractIiifResource3) {
164
                $this->iiifVersion = 'IIIF3';
165
            }
166
        }
167
        return $this->iiifVersion;
168
    }
169
170
    /**
171
     * True if getUseGroups() has been called and $this-useGrps is loaded
172
     *
173
     * @var boolean
174
     * @access protected
175
     */
176
    protected $useGrpsLoaded;
177
178
    /**
179
     * Holds the configured useGrps as array.
180
     *
181
     * @var array
182
     * @access protected
183
     */
184
    protected $useGrps;
185
186
    /**
187
     * IiifManifest also populates the physical stucture array entries for matching
188
     * 'fileGrp's. To do that, the configuration has to be loaded; afterwards configured
189
     * 'fileGrp's for thumbnails, downloads, audio, fulltext and the 'fileGrp's for images
190
     * can be requested with this method.
191
     *
192
     * @access protected
193
     *
194
     * @param string $use
195
     *
196
     * @return array|string
197
     */
198
    protected function getUseGroups($use)
199
    {
200
        if (!$this->useGrpsLoaded) {
201
            // Get configured USE attributes.
202
            $extConf = unserialize($GLOBALS['TYPO3_CONF_VARS']['EXT']['extConf'][self::$extKey]);
203
            if (!empty($extConf['fileGrps'])) {
204
                $this->useGrps['fileGrps'] = \TYPO3\CMS\Core\Utility\GeneralUtility::trimExplode(',', $extConf['fileGrps']);
205
            }
206
            if (!empty($extConf['fileGrpThumbs'])) {
207
                $this->useGrps['fileGrpThumbs'] = $extConf['fileGrpThumbs'];
208
            }
209
            if (!empty($extConf['fileGrpDownload'])) {
210
                $this->useGrps['fileGrpDownload'] = $extConf['fileGrpDownload'];
211
            }
212
            if (!empty($extConf['fileGrpFulltext'])) {
213
                $this->useGrps['fileGrpFulltext'] = $extConf['fileGrpFulltext'];
214
            }
215
            if (!empty($extConf['fileGrpAudio'])) {
216
                $this->useGrps['fileGrpAudio'] = $extConf['fileGrpAudio'];
217
            }
218
        }
219
        return array_key_exists($use, $this->useGrps) ? $this->useGrps[$use] : [];
220
    }
221
222
    /**
223
     * {@inheritDoc}
224
     * @see Document::_getPhysicalStructure()
225
     */
226
    protected function _getPhysicalStructure()
227
    {
228
        // Is there no physical structure array yet?
229
        if (!$this->physicalStructureLoaded) {
230
            if ($this->iiif == null || !($this->iiif instanceof ManifestInterface)) {
231
                return null;
232
            }
233
            $extConf = unserialize($GLOBALS['TYPO3_CONF_VARS']['EXT']['extConf'][self::$extKey]);
234
            $iiifId = $this->iiif->getId();
235
            $physSeq[0] = $iiifId;
1 ignored issue
show
Comprehensibility Best Practice introduced by
$physSeq was never initialized. Although not strictly required by PHP, it is generally a good practice to add $physSeq = array(); before regardless.
Loading history...
236
            $this->physicalStructureInfo[$physSeq[0]]['id'] = $iiifId;
237
            $this->physicalStructureInfo[$physSeq[0]]['dmdId'] = $iiifId;
238
            $this->physicalStructureInfo[$physSeq[0]]['label'] = $this->iiif->getLabelForDisplay();
239
            $this->physicalStructureInfo[$physSeq[0]]['orderlabel'] = $this->iiif->getLabelForDisplay();
240
            $this->physicalStructureInfo[$physSeq[0]]['type'] = 'physSequence';
241
            $this->physicalStructureInfo[$physSeq[0]]['contentIds'] = null;
242
            $fileUseDownload = $this->getUseGroups('fileGrpDownload');
243
            $fileUseFulltext = $this->getUseGroups('fileGrpFulltext');
244
            $fileUseThumbs = $this->getUseGroups('fileGrpThumbs');
245
            $fileUses = $this->getUseGroups('fileGrps');
246
            if (isset($fileUseDownload)) {
247
                $docPdfRendering = $this->iiif->getRenderingUrlsForFormat('application/pdf');
248
                if (!empty($docPdfRendering)) {
249
                    $this->physicalStructureInfo[$physSeq[0]]['files'][$fileUseDownload] = $docPdfRendering[0];
250
                }
251
            }
252
            if (isset($fileUseFulltext)) {
253
                $iiifAlto = $this->iiif->getSeeAlsoUrlsForFormat("application/alto+xml");
254
                if (empty($iiifAlto)) {
255
                    $iiifAlto = $this->iiif->getSeeAlsoUrlsForProfile("http://www.loc.gov/standards/alto/", true);
256
                }
257
                if (!empty($iiifAlto)) {
258
                    // TODO use multiple possible alto files?
259
                    $this->mimeTypes[$iiifAlto[0]] = "application/alto+xml";
260
                    $this->physicalStructureInfo[$physSeq[0]]['files'][$fileUseFulltext] = $iiifAlto[0];
261
                    $this->hasFulltext = true;
262
                    $this->hasFulltextSet = true;
263
                }
264
            }
265
            if (!empty($this->iiif->getDefaultCanvases())) {
266
                // canvases have not order property, but the context defines canveses as @list with a specific order, so we can provide an alternative
267
                $canvasOrder = 0;
268
                foreach ($this->iiif->getDefaultCanvases() as $canvas) {
269
                    $canvasOrder++;
270
                    $thumbnailUrl = $canvas->getThumbnailUrl();
271
                    // put thumbnails in thumbnail filegroup
272
                    if (isset($thumbnailUrl)) {
273
                        $this->physicalStructureInfo[$physSeq[0]]['files'][$fileUseThumbs] = $thumbnailUrl;
274
                    }
275
                    $image = $canvas->getImageAnnotations()[0];
276
                    // put images in all non specific filegroups
277
                    if (isset($fileUses)) {
278
                        foreach ($fileUses as $fileUse) {
279
                            if ($image->getBody() != null && $image->getBody() instanceof ContentResourceInterface) {
280
                                $this->physicalStructureInfo[$physSeq[0]]['files'][$fileUse] = $image->getBody()->getId();
281
                            }
282
                        }
283
                    }
284
                    // populate structural metadata info
285
                    $elements[$canvasOrder] = $canvas->getId();
286
                    $this->physicalStructureInfo[$elements[$canvasOrder]]['id']=$canvas->getId();
287
                    $this->physicalStructureInfo[$elements[$canvasOrder]]['dmdId']=null;
288
                    $this->physicalStructureInfo[$elements[$canvasOrder]]['label']=$canvas->getLabelForDisplay();
289
                    $this->physicalStructureInfo[$elements[$canvasOrder]]['orderlabel']=$canvas->getLabelForDisplay();
290
                    // assume that a canvas always represents a page
291
                    $this->physicalStructureInfo[$elements[$canvasOrder]]['type']='page';
292
                    $this->physicalStructureInfo[$elements[$canvasOrder]]['contentIds']=null;
293
                    $this->physicalStructureInfo[$elements[$canvasOrder]]['annotationContainers'] = null;
294
                    if (!empty($canvas->getPossibleTextAnnotationContainers(Motivation::PAINTING))) {
0 ignored issues
show
Unused Code introduced by
The call to Ubl\Iiif\Presentation\Co...tAnnotationContainers() has too many arguments starting with Ubl\Iiif\Presentation\Co...ry\Motivation::PAINTING. ( Ignorable by Annotation )

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

294
                    if (!empty($canvas->/** @scrutinizer ignore-call */ getPossibleTextAnnotationContainers(Motivation::PAINTING))) {

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress. Please note the @ignore annotation hint above.

Loading history...
295
                        $this->physicalStructureInfo[$elements[$canvasOrder]]['annotationContainers'] = array();
296
                        $this->physicalStructureInfo[$physSeq[0]]['annotationContainers'] = array();
297
                        foreach ($canvas->getPossibleTextAnnotationContainers(Motivation::PAINTING) as $annotationContainer) {
298
                            $this->physicalStructureInfo[$elements[$canvasOrder]]['annotationContainers'][] = $annotationContainer->getId();
299
                            if ($extConf['indexAnnotations']) {
300
                                $this->hasFulltext = true;
301
                                $this->hasFulltextSet = true;
302
                            }
303
                        }
304
                    }
305
                    if (isset($fileUseFulltext)) {
306
                        $alto = $canvas->getSeeAlsoUrlsForFormat("application/alto+xml");
307
                        if (empty($alto)) {
308
                            $alto = $canvas->getSeeAlsoUrlsForProfile("http://www.loc.gov/standards/alto/", true);
309
                        }
310
                        if (!empty($alto)) {
311
                            // TODO use all possible alto files?
312
                            $this->mimeTypes[$alto[0]] = "application/alto+xml";
313
                            $this->physicalStructureInfo[$elements[$canvasOrder]]['files'][$fileUseFulltext] = $alto[0];
314
                            $this->hasFulltext = true;
315
                            $this->hasFulltextSet = true;
316
                        }
317
                    }
318
                    if (isset($fileUses)) {
319
                        foreach ($fileUses as $fileUse) {
320
                            if ($image->getBody() != null && $image->getBody() instanceof ContentResourceInterface) {
321
                                $this->physicalStructureInfo[$elements[$canvasOrder]]['files'][$fileUse] = $image->getBody()->getId();
322
                            }
323
                        }
324
                    }
325
                    if (isset($thumbnailUrl)) {
326
                        $this->physicalStructureInfo[$elements[$canvasOrder]]['files'][$fileUseThumbs] = $thumbnailUrl;
327
                    }
328
                    if (isset($fileUseDownload)) {
329
                        $pdfRenderingUrls = $canvas->getRenderingUrlsForFormat('application/pdf');
330
                        if (!empty($pdfRenderingUrls)) {
331
                            $this->physicalStructureInfo[$elements[$canvasOrder]]['files'][$fileUseDownload] = $pdfRenderingUrls[0];
332
                        }
333
                    }
334
                }
335
                $this->numPages = $canvasOrder;
336
                // Merge and re-index the array to get nice numeric indexes.
337
                $this->physicalStructure = array_merge($physSeq, $elements);
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $elements seems to be defined by a foreach iteration on line 268. Are you sure the iterator is never empty, otherwise this variable is not defined?
Loading history...
338
            }
339
            $this->physicalStructureLoaded = TRUE;
340
        }
341
        return $this->physicalStructure;
342
    }
343
344
    /**
345
     * {@inheritDoc}
346
     * @see Document::getDownloadLocation()
347
     */
348
    public function getDownloadLocation($id) {
349
        $fileLocation = $this->getFileLocation($id);
350
        $resource = $this->iiif->getContainedResourceById($fileLocation);
351
        if ($resource instanceof AbstractImageService) {
352
            return $resource->getImageUrl();
353
        }
354
        return $fileLocation;
355
    }
356
357
    /**
358
     * {@inheritDoc}
359
     * @see Document::getFileLocation()
360
     */
361
    public function getFileLocation($id)
362
    {
363
        if ($id == null) {
364
            return null;
365
        }
366
        $resource = $this->iiif->getContainedResourceById($id);
367
        if (isset($resource)) {
368
            if ($resource instanceof CanvasInterface) {
369
                return (!empty($resource->getImageAnnotations()) && $resource->getImageAnnotations()->getSingleService() != null) ? $resource->getImageAnnotations()[0]->getSingleService()->getId() : $id;
370
            } elseif ($resource instanceof ContentResourceInterface) {
371
                return $resource->getSingleService() != null && $resource->getSingleService() instanceof Service ? $resource->getSingleService()->getId() : $id;
372
            } elseif ($resource instanceof AbstractImageService) {
373
                return $resource->getId();
374
            } elseif ($resource instanceof AnnotationContainerInterface) {
375
                return $id;
376
            }
377
        } else {
378
            return $id;
379
        }
380
    }
381
382
    /**
383
     * {@inheritDoc}
384
     * @see Document::getFileMimeType()
385
     */
386
    public function getFileMimeType($id)
387
    {
388
        $fileResource = $this->iiif->getContainedResourceById($id);
389
        if ($fileResource instanceof CanvasInterface) {
390
            $format = "application/vnd.kitodo.iiif";
391
        } elseif ($fileResource instanceof AnnotationInterface) {
392
            $format = "application/vnd.kitodo.iiif";
393
        } elseif ($fileResource instanceof ContentResourceInterface) {
394
            if ($fileResource->isText() || $fileResource->isImage() && ($fileResource->getSingleService() == null || !($fileResource->getSingleService() instanceof AbstractImageService))) {
395
                // Support static images without an image service
396
                return $fileResource->getFormat();
397
            }
398
            $format = "application/vnd.kitodo.iiif";
399
        } elseif ($fileResource instanceof AbstractImageService) {
400
            $format = "application/vnd.kitodo.iiif";
401
        } else {
402
            // Assumptions: this can only be the thumbnail and the thumbnail is a jpeg - TODO determine mimetype
403
            $format = "image/jpeg";
404
        }
405
        return $format;
406
    }
407
408
    /**
409
     * {@inheritDoc}
410
     * @see Document::getLogicalStructure()
411
     */
412
    public function getLogicalStructure($id, $recursive = FALSE)
413
    {
414
        $details = array ();
415
        if (!$recursive && !empty($this->logicalUnits[$id])) {
416
            return $this->logicalUnits[$id];
417
        } elseif (!empty($id)) {
418
            $logUnits[] = $this->iiif->getContainedResourceById($id);
1 ignored issue
show
Comprehensibility Best Practice introduced by
$logUnits was never initialized. Although not strictly required by PHP, it is generally a good practice to add $logUnits = array(); before regardless.
Loading history...
419
        } else {
420
            $logUnits[] = $this->iiif;
421
        }
422
        if (!empty($logUnits)) {
423
            if (!$recursive) {
424
                $details = $this->getLogicalStructureInfo($logUnits[0]);
425
            } else {
426
                // cache the ranges - they might occure multiple times in the structures "tree" - with full data as well as referenced as id
427
                $processedStructures = array();
428
                foreach ($logUnits as $logUnit) {
429
                    if (array_search($logUnit->getId(), $processedStructures) == false) {
0 ignored issues
show
Bug Best Practice introduced by
It seems like you are loosely comparing array_search($logUnit->g..., $processedStructures) of type false|integer|string against false; this is ambiguous if the integer can be zero. Consider using a strict comparison === instead.
Loading history...
430
                        $this->tableOfContents[] = $this->getLogicalStructureInfo($logUnit, TRUE, $processedStructures);
431
                    }
432
                }
433
            }
434
        }
435
        return $details;
436
    }
437
438
    /**
439
     * Get the details about a IIIF resource (manifest or range) in the logical structure
440
     *
441
     * @access protected
442
     *
443
     * @param IiifResourceInterface $resource: IIIF resource, either a manifest or range.
444
     * @param boolean $recursive: Whether to include the child elements
445
     * @param array $processedStructures: IIIF resources that already have been processed
446
     * @return array Logical structure array
447
     */
448
    protected function getLogicalStructureInfo(IiifResourceInterface $resource, $recursive = false, &$processedStructures = array()) {
449
        $details = array ();
450
        $details['id'] = $resource->getId();
451
        $details['dmdId'] = '';
452
        $details['label'] = $resource->getLabelForDisplay() !== null ? $resource->getLabelForDisplay() : '';
0 ignored issues
show
introduced by
The condition $resource->getLabelForDisplay() !== null is always true.
Loading history...
453
        $details['orderlabel'] = $resource->getLabelForDisplay() !== null ? $resource->getLabelForDisplay() : '';
0 ignored issues
show
introduced by
The condition $resource->getLabelForDisplay() !== null is always true.
Loading history...
454
        $details['contentIds'] = '';
455
        $details['volume'] = '';
456
        $details['pagination'] = '';
457
        $cPid = ($this->cPid ? $this->cPid : $this->pid);
458
        if ($details['id'] == $this->_getToplevelId()) {
459
            $metadata = $this->getMetadata($details['id'], $cPid);
460
            if (!empty($metadata['type'][0])) {
461
                $details['type'] = $metadata['type'][0];
462
            }
463
        }
464
        $details['thumbnailId'] = $resource->getThumbnailUrl();
465
        $details['points'] = '';
466
        // Load strucural mapping
467
        $this->_getSmLinks();
468
        // Load physical structure.
469
        $this-> _getPhysicalStructure();
470
        $canvases = array();
471
        if ($resource instanceof ManifestInterface) {
472
            $startCanvas = $resource->getStartCanvasOrFirstCanvas();
473
            $canvases = $resource->getDefaultCanvases();
0 ignored issues
show
Unused Code introduced by
The assignment to $canvases is dead and can be removed.
Loading history...
474
        } elseif ($resource instanceof RangeInterface) {
475
            $startCanvas = $resource->getStartCanvasOrFirstCanvas();
476
            $canvases = $resource->getAllCanvases();
477
        }
478
        if ($startCanvas != null) {
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $startCanvas does not seem to be defined for all execution paths leading up to this point.
Loading history...
479
            $details['pagination'] = $startCanvas->getLabel();
480
            $startCanvasIndex = array_search($startCanvas, $this->iiif->getDefaultCanvases());
481
            if ($startCanvasIndex!==false) {
482
                $details['points'] = $startCanvasIndex + 1;
483
            }
484
        }
485
        $useGroups = $this->getUseGroups('fileGrps');
486
        if (is_string($useGroups)) {
487
            $useGroups = array($useGroups);
0 ignored issues
show
Unused Code introduced by
The assignment to $useGroups is dead and can be removed.
Loading history...
488
        }
489
        // Keep for later usage.
490
        $this->logicalUnits[$details['id']] = $details;
491
        // Walk the structure recursively? And are there any children of the current element?
492
        if ($recursive) {
493
            $processedStructures[] = $resource->getId();
494
            $details['children'] = array ();
495
            if ($resource instanceof ManifestInterface && $resource->getRootRanges() != null) {
496
                $rangesToAdd = [];
497
                $rootRanges = [];
498
                if (sizeof($this->iiif->getRootRanges()) == 1 && $this->iiif->getRootRanges()[0]->isTopRange()) {
499
                    $rangesToAdd = $this->iiif->getRootRanges()[0]->getMemberRangesAndRanges();
0 ignored issues
show
Bug introduced by
The method getMemberRangesAndRanges() does not exist on Ubl\Iiif\Presentation\Co...esources\RangeInterface. It seems like you code against a sub-type of Ubl\Iiif\Presentation\Co...esources\RangeInterface such as Ubl\Iiif\Presentation\V2\Model\Resources\Range2. ( Ignorable by Annotation )

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

499
                    /** @scrutinizer ignore-call */ 
500
                    $rangesToAdd = $this->iiif->getRootRanges()[0]->getMemberRangesAndRanges();
Loading history...
500
                } else {
501
                    $rangesToAdd = $this->iiif->getRootRanges();
502
                }
503
                foreach ($rangesToAdd as $range) {
504
                    $rootRanges[] = $range;
505
                }
506
                foreach ($rootRanges as $range) {
507
                    if ((array_search($range->getId(), $processedStructures) == false)) {
0 ignored issues
show
Bug Best Practice introduced by
It seems like you are loosely comparing array_search($range->get..., $processedStructures) of type false|integer|string against false; this is ambiguous if the integer can be zero. Consider using a strict comparison === instead.
Loading history...
508
                        $details['children'][] = $this->getLogicalStructureInfo($range, TRUE, $processedStructures);
509
                    }
510
                }
511
            } elseif ($resource instanceof RangeInterface) {
512
                if (!empty($resource->getAllRanges())) {
513
                    foreach ($resource->getAllRanges() as $range) {
514
                        if ((array_search($range->getId(), $processedStructures) == false)) {
0 ignored issues
show
Bug Best Practice introduced by
It seems like you are loosely comparing array_search($range->get..., $processedStructures) of type false|integer|string against false; this is ambiguous if the integer can be zero. Consider using a strict comparison === instead.
Loading history...
515
                            $details['children'][] = $this->getLogicalStructureInfo($range, TRUE, $processedStructures);
516
                        }
517
                    }
518
                }
519
            }
520
        }
521
        return $details;
522
    }
523
524
    /**
525
     * Returns metadata for IIIF resources with the ID $id in there original form in
526
     * the manifest, but prepared for display to the user.
527
     *
528
     * @access public
529
     *
530
     * @param string $id: the ID of the IIIF resource
531
     * @param number $cPid: the configuration folder's id
532
     * @param boolean $withDescription: add description / summary to the return value
533
     * @param boolean $withRights: add attribution and license / rights and requiredStatement to the return value
534
     * @param boolean $withRelated: add related links / homepage to the return value
535
     *
536
     * @return array
537
     *
538
     * @todo This method is still in experimental; the method signature may change.
539
     */
540
    public function getManifestMetadata($id, $cPid = 0, $withDescription = true, $withRights = true, $withRelated = true) {
0 ignored issues
show
Unused Code introduced by
The parameter $cPid is not used and could be removed. ( Ignorable by Annotation )

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

540
    public function getManifestMetadata($id, /** @scrutinizer ignore-unused */ $cPid = 0, $withDescription = true, $withRights = true, $withRelated = true) {

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
541
        if (!empty($this->originalMetadataArray[$id])) {
542
            return $this->originalMetadataArray[$id];
543
        }
544
        $iiifResource = $this->iiif->getContainedResourceById($id);
545
        $result = array();
546
        if ($iiifResource != null) {
547
            if ($iiifResource->getLabel()!=null && $iiifResource->getLabel() != "") {
548
                $result['label'] = $iiifResource->getLabel();
549
            }
550
            if (!empty($iiifResource->getMetadata())) {
551
                $result['metadata'] = [];
552
                foreach ($iiifResource->getMetadataForDisplay() as $metadata) {
553
                    $result['metadata'][$metadata['label']] = $metadata['value'];
554
                }
555
            }
556
            if ($withDescription && !empty($iiifResource->getSummary())) {
557
                $result["description"] = $iiifResource->getSummaryForDisplay();
558
            }
559
            if ($withRights) {
560
                if (!empty($iiifResource->getRights())) {
561
                    $result["rights"] = $iiifResource->getRights();
562
                }
563
                if (!empty($iiifResource->getRequiredStatement())) {
564
                    $result["requiredStatement"] = $iiifResource->getRequiredStatementForDisplay();
565
                }
566
            }
567
            if ($withRelated && !empty($iiifResource->getWeblinksForDisplay())) {
568
                $result["weblinks"] = [];
569
                foreach ($iiifResource->getWeblinksForDisplay() as $link) {
570
                    $key = array_key_exists("label", $link) ? $link["label"] : $link["@id"];
571
                    $result["weblinks"][$key] = $link["@id"];
572
                }
573
            }
574
        }
575
        return $result;
576
    }
577
578
    /**
579
     * {@inheritDoc}
580
     * @see Document::getMetadata()
581
     */
582
    public function getMetadata($id, $cPid = 0)
583
    {
584
        if (!empty($this->metadataArray[$id]) && $this->metadataArray[0] == $cPid) {
585
            return $this->metadataArray[$id];
586
        }
587
        // Initialize metadata array with empty values.
588
        // TODO initialize metadata in abstract class
589
        $metadata = array (
590
            'title' => array (),
591
            'title_sorting' => array (),
592
            'author' => array (),
593
            'place' => array (),
594
            'year' => array (),
595
            'prod_id' => array (),
596
            'record_id' => array (),
597
            'opac_id' => array (),
598
            'union_id' => array (),
599
            'urn' => array (),
600
            'purl' => array (),
601
            'type' => array (),
602
            'volume' => array (),
603
            'volume_sorting' => array (),
604
            'collection' => array (),
605
            'owner' => array (),
606
        );
607
        $metadata['document_format'][] = 'IIIF';
608
        $result = $GLOBALS['TYPO3_DB']->exec_SELECTquery(
609
            'tx_dlf_metadata.index_name AS index_name,tx_dlf_metadataformat.xpath AS xpath,tx_dlf_metadataformat.xpath_sorting AS xpath_sorting,tx_dlf_metadata.is_sortable AS is_sortable,tx_dlf_metadata.default_value AS default_value,tx_dlf_metadata.format AS format',
610
            'tx_dlf_metadata,tx_dlf_metadataformat,tx_dlf_formats',
611
            'tx_dlf_metadata.pid='.intval($cPid)
612
                .' AND tx_dlf_metadataformat.pid='.intval($cPid)
613
                .' AND ((tx_dlf_metadata.uid=tx_dlf_metadataformat.parent_id AND tx_dlf_metadataformat.encoded=tx_dlf_formats.uid AND tx_dlf_formats.type='.$GLOBALS['TYPO3_DB']->fullQuoteStr($this->getIiifVersion(), 'tx_dlf_formats').') OR tx_dlf_metadata.format=0)'
614
                .Helper::whereClause('tx_dlf_metadata', TRUE).Helper::whereClause('tx_dlf_metadataformat').Helper::whereClause('tx_dlf_formats')
615
        );
616
        $iiifResource = $this->iiif->getContainedResourceById($id);
617
        while ($resArray = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($result)) {
618
            // Set metadata field's value(s).
619
            if ($resArray['format'] > 0 && !empty($resArray['xpath']) && ($values = $iiifResource->jsonPath($resArray['xpath'])) != null) {
620
                if (is_string($values)) {
621
                    $metadata[$resArray['index_name']] = array (trim((string) $values));
622
                } elseif ($values instanceof JSONPath && is_array($values->data()) && count($values->data())>1 ) {
623
                    $metadata[$resArray['index_name']] = array ();
624
                    foreach ($values->data() as $value) {
625
                        $metadata[$resArray['index_name']][] = trim((string) $value);
626
                    }
627
                }
628
            }
629
            // Set default value if applicable.
630
            if (empty($metadata[$resArray['index_name']][0]) && strlen($resArray['default_value']) > 0) {
631
                $metadata[$resArray['index_name']] = array ($resArray['default_value']);
632
            }
633
            // Set sorting value if applicable.
634
            if (!empty($metadata[$resArray['index_name']]) && $resArray['is_sortable']) {
635
                if ($resArray['format'] > 0 && !empty($resArray['xpath_sorting'])
636
                    && ($values = $iiifResource->jsonPath($resArray['xpath_sorting']) != null)) {
637
                    if ($values instanceof string) {
0 ignored issues
show
Bug introduced by
The type Kitodo\Dlf\Common\string was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
638
                        $metadata[$resArray['index_name'].'_sorting'][0] = array (trim((string) $values));
639
                    } elseif ($values instanceof JSONPath && is_array($values->data()) && count($values->data()>1 )) {
0 ignored issues
show
Bug introduced by
$values->data() > 1 of type boolean is incompatible with the type Countable|array expected by parameter $var of count(). ( Ignorable by Annotation )

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

639
                    } elseif ($values instanceof JSONPath && is_array($values->data()) && count(/** @scrutinizer ignore-type */ $values->data()>1 )) {
Loading history...
640
                        $metadata[$resArray['index_name']] = array ();
641
                        foreach ($values->data() as $value) {
642
                            $metadata[$resArray['index_name'].'_sorting'][0] = trim((string) $value);
643
                        }
644
                    }
645
                }
646
                if (empty($metadata[$resArray['index_name'].'_sorting'][0])) {
647
                    $metadata[$resArray['index_name'].'_sorting'][0] = $metadata[$resArray['index_name']][0];
648
                }
649
            }
650
        }
651
        return $metadata;
652
    }
653
654
    /**
655
     * {@inheritDoc}
656
     * @see Document::_getSmLinks()
657
     */
658
    protected function _getSmLinks() {
659
        if (!$this->smLinksLoaded && isset($this->iiif) && $this->iiif instanceof ManifestInterface) {
660
            if (!empty($this->iiif->getDefaultCanvases())) {
661
                foreach ($this->iiif->getDefaultCanvases() as $canvas) {
662
                    $this->smLinkCanvasToResource($canvas, $this->iiif);
663
                }
664
            }
665
            if (!empty($this->iiif->getStructures())) {
666
                foreach ($this->iiif->getStructures() as $range) {
667
                    $this->smLinkRangeCanvasesRecursively($range);
668
                }
669
            }
670
            $this->smLinksLoaded = true;
671
        }
672
        return $this->smLinks;
673
    }
674
675
    /**
676
     * Construct a link between a range and it's sub ranges and all contained canvases.
677
     *
678
     * @access private
679
     *
680
     * @param RangeInterface $range: Current range whose canvases shall be linked
681
     */
682
    private function smLinkRangeCanvasesRecursively(RangeInterface $range) {
683
        // map range's canvases including all child ranges' canvases
684
        if (!$range->isTopRange()) {
685
            foreach ($range->getAllCanvasesRecursively() as $canvas) {
686
                $this->smLinkCanvasToResource($canvas, $range);
687
            }
688
        }
689
        // recursive call for all ranges
690
        if (!empty($range->getAllRanges())) {
691
            foreach ($range->getAllRanges() as $childRange) {
692
                $this->smLinkRangeCanvasesRecursively($childRange);
693
            }
694
        }
695
    }
696
697
    /**
698
     * Link a single canvas to a containing range
699
     *
700
     * @access private
701
     *
702
     * @param CanvasInterface $canvas
703
     * @param IiifResourceInterface $resource
704
     */
705
    private function smLinkCanvasToResource(CanvasInterface $canvas, IiifResourceInterface $resource)
706
    {
707
        $this->smLinks['l2p'][$resource->getId()][] = $canvas->getId();
708
        if (!is_array($this->smLinks['p2l'][$canvas->getId()]) || !in_array($resource->getId(), $this->smLinks['p2l'][$canvas->getId()])) {
709
            $this->smLinks['p2l'][$canvas->getId()][] = $resource->getId();
710
        }
711
    }
712
713
    /**
714
     * Currently not supported for IIIF. Multivolume works _could_ be modelled
715
     * as IIIF Collections, but we can't tell them apart from actual collections.
716
     *
717
     * @access protected
718
     *
719
     * @see Document::getParentDocumentUidForSaving()
720
     */
721
    protected function getParentDocumentUidForSaving($pid, $core)
722
    {
723
        // Do nothing.
724
    }
725
726
    /**
727
     * {@inheritDoc}
728
     * @see Document::getRawText()
729
     */
730
    public function getRawText($id) {
731
        $rawText = '';
732
        // Get text from raw text array if available.
733
        if (!empty($this->rawTextArray[$id])) {
734
            return $this->rawTextArray[$id];
735
        }
736
        $this->ensureHasFulltextIsSet();
737
        if ($this->hasFulltext) {
738
            // Load physical structure ...
739
            $this->_getPhysicalStructure();
740
            // ... and extension configuration.
741
            $extConf = unserialize($GLOBALS['TYPO3_CONF_VARS']['EXT']['extConf'][self::$extKey]);
742
            if (!empty($this->physicalStructureInfo[$id])) {
743
                if (!empty($this->physicalStructureInfo[$id]['files'][$extConf['fileGrpFulltext']])) {
744
                    $rawText = parent::getRawTextFromXml($id);
745
                }
746
                if ($extConf['indexAnnotations'] == 1) {
747
                    $iiifResource = $this->iiif->getContainedResourceById($id);
748
                    // Get annotation containers
749
                    $annotationContainerIds = $this->physicalStructureInfo[$id]['annotationContainers'];
750
                    if (!empty($annotationContainerIds)) {
751
                        $annotationTexts = array();
752
                        foreach ($annotationContainerIds as $annotationListId) {
753
                            $annotationContainer = $this->iiif->getContainedResourceById($annotationListId);
754
                            /* @var $annotationContainer \Ubl\Iiif\Presentation\Common\Model\Resources\AnnotationContainerInterface */
755
                            foreach ($annotationContainer->getTextAnnotations(Motivation::PAINTING) as $annotation) {
0 ignored issues
show
Bug introduced by
The method getTextAnnotations() does not exist on Ubl\Iiif\Presentation\Co...s\IiifResourceInterface. It seems like you code against a sub-type of Ubl\Iiif\Presentation\Co...s\IiifResourceInterface such as Ubl\Iiif\Presentation\Co...ationContainerInterface or Ubl\Iiif\Presentation\V2...sources\AnnotationList2 or Ubl\Iiif\Presentation\V3...sources\AnnotationPage3 or Ubl\Iiif\Presentation\V1...sources\AnnotationList1 or Ubl\Iiif\Presentation\V2...sources\AnnotationList2 or Ubl\Iiif\Presentation\V3...sources\AnnotationPage3 or Ubl\Iiif\Presentation\V1...sources\AnnotationList1. ( Ignorable by Annotation )

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

755
                            foreach ($annotationContainer->/** @scrutinizer ignore-call */ getTextAnnotations(Motivation::PAINTING) as $annotation) {
Loading history...
756
                                if ($annotation->getTargetResourceId() == $iiifResource->getId() &&
757
                                    $annotation->getBody()!=null && $annotation->getBody()->getChars()!=null) {
758
                                    $annotationTexts[] = $annotation->getBody()->getChars();
759
                                }
760
                            }
761
                        }
762
                        $rawText .= implode(' ', $annotationTexts);
763
                    }
764
                }
765
            } else {
766
                Helper::devLog('Invalid structure resource @id "'.$id.'"', DEVLOG_SEVERITY_WARNING);
767
                return $rawText;
768
            }
769
            $this->rawTextArray[$id] = $rawText;
770
        }
771
        return $rawText;
772
    }
773
774
    /**
775
     * Returns the underlying IiifResourceInterface.
776
     *
777
     * @access public
778
     *
779
     * @return IiifResourceInterface
780
     */
781
    public function getIiif()
782
    {
783
        return $this->iiif;
784
    }
785
786
    /**
787
     * {@inheritDoc}
788
     * @see Document::init()
789
     */
790
    protected function init()
791
    {
792
        // Nothing to do here, at the moment
793
    }
794
795
    /**
796
     * {@inheritDoc}
797
     * @see Document::loadLocation()
798
     */
799
    protected function loadLocation($location)
800
    {
801
        $content = GeneralUtility::getUrl($location);
802
        $conf = unserialize($GLOBALS['TYPO3_CONF_VARS']['EXT']['extConf'][self::$extKey]);
803
        IiifHelper::setUrlReader(IiifUrlReader::getInstance());
804
        IiifHelper::setMaxThumbnailHeight($conf['iiifThumbnailHeight']);
805
        IiifHelper::setMaxThumbnailWidth($conf['iiifThumbnailWidth']);
806
        $resource = IiifHelper::loadIiifResource($content);
0 ignored issues
show
Bug introduced by
It seems like $content can also be of type false; however, parameter $resource of Ubl\Iiif\Tools\IiifHelper::loadIiifResource() does only seem to accept array|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

806
        $resource = IiifHelper::loadIiifResource(/** @scrutinizer ignore-type */ $content);
Loading history...
807
        if ($resource != null ) {
808
            if ($resource instanceof ManifestInterface) {
809
                $this->iiif = $resource;
810
                return true;
811
            }
812
        } else {
813
            Helper::devLog('Could not load IIIF manifest from "'.$location.'"', self::$extKey, SYSLOG_SEVERITY_ERROR);
0 ignored issues
show
Unused Code introduced by
The call to Kitodo\Dlf\Common\Helper::devLog() has too many arguments starting with Kitodo\Dlf\Common\SYSLOG_SEVERITY_ERROR. ( Ignorable by Annotation )

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

813
            Helper::/** @scrutinizer ignore-call */ 
814
                    devLog('Could not load IIIF manifest from "'.$location.'"', self::$extKey, SYSLOG_SEVERITY_ERROR);

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress. Please note the @ignore annotation hint above.

Loading history...
Bug introduced by
The constant Kitodo\Dlf\Common\SYSLOG_SEVERITY_ERROR was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
814
        }
815
    }
816
817
    /**
818
     * {@inheritDoc}
819
     * @see \Kitodo\Dlf\Common\Document::prepareMetadataArray()
820
     */
821
    protected function prepareMetadataArray($cPid)
822
    {
823
        $id = $this->iiif->getId();
824
        $this->metadataArray[(string) $id] = $this->getMetadata((string) $id, $cPid);
825
    }
826
827
    /**
828
     * {@inheritDoc}
829
     * @see Document::setPreloadedDocument()
830
     */
831
    protected function setPreloadedDocument($preloadedDocument) {
832
        if ($preloadedDocument instanceof ManifestInterface) {
833
            $this->iiif = $preloadedDocument;
834
            return true;
835
        }
836
        return false;
837
    }
838
839
    /**
840
     * {@inheritDoc}
841
     * @see Document::ensureHasFulltextIsSet()
842
     */
843
    protected function ensureHasFulltextIsSet()
844
    {
845
        /*
846
         *  TODO Check annotations and annotation lists of canvas for ALTO documents.
847
         *  Example:
848
         *  https://digi.ub.uni-heidelberg.de/diglit/iiif/hirsch_hamburg1933_04_25/manifest.json links
849
         *  https://digi.ub.uni-heidelberg.de/diglit/iiif/hirsch_hamburg1933_04_25/list/0001.json
850
         */
851
        if (!$this->hasFulltextSet && $this->iiif instanceof ManifestInterface) {
852
            $manifest = $this->iiif;
853
            $canvases = $manifest->getDefaultCanvases();
854
            foreach ($canvases as $canvas) {
855
                if (!empty($canvas->getSeeAlsoUrlsForFormat("application/alto+xml")) ||
856
                    !empty($canvas->getSeeAlsoUrlsForProfile("http://www.loc.gov/standards/alto/"))) {
857
                    $this->hasFulltextSet = true;
858
                    $this->hasFulltext = true;
859
                    return;
860
                }
861
                $extConf = unserialize($GLOBALS['TYPO3_CONF_VARS']['EXT']['extConf'][self::$extKey]);
862
                if ($extConf['indexAnnotations'] == 1 && !empty($canvas->getPossibleTextAnnotationContainers(Motivation::PAINTING))) {
0 ignored issues
show
Unused Code introduced by
The call to Ubl\Iiif\Presentation\Co...tAnnotationContainers() has too many arguments starting with Ubl\Iiif\Presentation\Co...ry\Motivation::PAINTING. ( Ignorable by Annotation )

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

862
                if ($extConf['indexAnnotations'] == 1 && !empty($canvas->/** @scrutinizer ignore-call */ getPossibleTextAnnotationContainers(Motivation::PAINTING))) {

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress. Please note the @ignore annotation hint above.

Loading history...
863
                    foreach ($canvas->getPossibleTextAnnotationContainers(Motivation::PAINTING) as $annotationContainer) {
864
                        if (($textAnnotations = $annotationContainer->getTextAnnotations(Motivation::PAINTING)) != null) {
865
                            foreach ($textAnnotations as $annotation) {
866
                                if ($annotation->getBody() != null &&
867
                                    $annotation->getBody()->getFormat() == "text/plain" &&
868
                                    $annotation->getBody()->getChars() != null) {
869
                                    $this->hasFulltextSet = true;
870
                                    $this->hasFulltext = true;
871
                                    return;
872
                                }
873
                            }
874
                        }
875
                    }
876
                }
877
            }
878
            $this->hasFulltextSet = true;
879
        }
880
    }
881
882
    /**
883
     * {@inheritDoc}
884
     * @see \Kitodo\Dlf\Common\Document::_getThumbnail()
885
     */
886
    protected function _getThumbnail($forceReload = FALSE)
887
    {
888
        return $this->iiif->getThumbnailUrl();
889
    }
890
891
    /**
892
     * {@inheritDoc}
893
     * @see \Kitodo\Dlf\Common\Document::_getToplevelId()
894
     */
895
    protected function _getToplevelId()
896
    {
897
        if (empty($this->toplevelId)) {
898
            if (isset($this->iiif)) {
899
                $this->toplevelId = $this->iiif->getId();
900
            }
901
        }
902
        return $this->toplevelId;
903
    }
904
905
    /**
906
     * This magic method is executed after the object is deserialized
907
     * @see __sleep()
908
     *
909
     * @access public
910
     *
911
     * @return void
912
     */
913
    public function __wakeup() {
914
        $conf = unserialize($GLOBALS['TYPO3_CONF_VARS']['EXT']['extConf'][self::$extKey]);
915
        IiifHelper::setUrlReader(IiifUrlReader::getInstance());
916
        IiifHelper::setMaxThumbnailHeight($conf['iiifThumbnailHeight']);
917
        IiifHelper::setMaxThumbnailWidth($conf['iiifThumbnailWidth']);
918
        $resource = IiifHelper::loadIiifResource($this->asJson);
919
        if ($resource != null && $resource instanceof ManifestInterface) {
920
            $this->asJson='';
921
            $this->iiif = $resource;
922
            $this->init();
923
        } else {
924
            Helper::devLog('Could not load IIIF after deserialization', self::$extKey, SYSLOG_SEVERITY_ERROR);
0 ignored issues
show
Unused Code introduced by
The call to Kitodo\Dlf\Common\Helper::devLog() has too many arguments starting with Kitodo\Dlf\Common\SYSLOG_SEVERITY_ERROR. ( Ignorable by Annotation )

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

924
            Helper::/** @scrutinizer ignore-call */ 
925
                    devLog('Could not load IIIF after deserialization', self::$extKey, SYSLOG_SEVERITY_ERROR);

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress. Please note the @ignore annotation hint above.

Loading history...
Bug introduced by
The constant Kitodo\Dlf\Common\SYSLOG_SEVERITY_ERROR was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
925
        }
926
    }
927
928
    /**
929
     *
930
     * @return string[]
931
     */
932
    public function __sleep() {
933
        // TODO implement serializiation in IIIF library
934
        $jsonArray = $this->iiif->getOriginalJsonArray();
935
        $this->asJson = json_encode($jsonArray);
936
        return array ('uid', 'pid', 'recordId', 'parentId', 'asJson');
937
    }
938
}
939