tx_dlf_document::getLogicalStructureInfo()   F
last analyzed

Complexity

Conditions 21
Paths 3456

Size

Total Lines 124
Code Lines 42

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 21
eloc 42
nc 3456
nop 2
dl 0
loc 124
rs 2
c 0
b 0
f 0

How to fix   Long Method    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
/**
13
 * Document class 'tx_dlf_document' for the 'dlf' extension.
14
 *
15
 * @author	Sebastian Meyer <[email protected]>
16
 * @author	Henrik Lochmann <[email protected]>
17
 * @package	TYPO3
18
 * @subpackage	tx_dlf
19
 * @access	public
20
 */
21
final class tx_dlf_document {
22
23
    /**
24
     * This holds the whole XML file as string for serialization purposes
25
     * @see __sleep() / __wakeup()
26
     *
27
     * @var	string
28
     * @access protected
29
     */
30
    protected $asXML = '';
31
32
    /**
33
     * This holds the PID for the configuration
34
     *
35
     * @var	integer
36
     * @access protected
37
     */
38
    protected $cPid = 0;
39
40
    /**
41
     * This holds the XML file's dmdSec parts with their IDs as array key
42
     *
43
     * @var	array
44
     * @access protected
45
     */
46
    protected $dmdSec = array ();
47
48
    /**
49
     * Are the METS file's dmdSecs loaded?
50
     * @see $dmdSec
51
     *
52
     * @var	boolean
53
     * @access protected
54
     */
55
    protected $dmdSecLoaded = FALSE;
56
57
    /**
58
     * The extension key
59
     *
60
     * @var	string
61
     * @access public
62
     */
63
    public static $extKey = 'dlf';
64
65
    /**
66
     * This holds the file ID -> USE concordance
67
     * @see _getFileGrps()
68
     *
69
     * @var	array
70
     * @access protected
71
     */
72
    protected $fileGrps = array ();
73
74
    /**
75
     * Are the file groups loaded?
76
     * @see $fileGrps
77
     *
78
     * @var	boolean
79
     * @access protected
80
     */
81
    protected $fileGrpsLoaded = FALSE;
82
83
    /**
84
     * This holds the configuration for all supported metadata encodings
85
     * @see loadFormats()
86
     *
87
     * @var	array
88
     * @access protected
89
     */
90
    protected $formats = array (
91
        'OAI' => array (
92
            'rootElement' => 'OAI-PMH',
93
            'namespaceURI' => 'http://www.openarchives.org/OAI/2.0/',
94
        ),
95
        'METS' => array (
96
            'rootElement' => 'mets',
97
            'namespaceURI' => 'http://www.loc.gov/METS/',
98
        ),
99
        'XLINK' => array (
100
            'rootElement' => 'xlink',
101
            'namespaceURI' => 'http://www.w3.org/1999/xlink',
102
        )
103
    );
104
105
    /**
106
     * Are the available metadata formats loaded?
107
     * @see $formats
108
     *
109
     * @var	boolean
110
     * @access protected
111
     */
112
    protected $formatsLoaded = FALSE;
113
114
    /**
115
     * Are there any fulltext files available?
116
     *
117
     * @var boolean
118
     * @access protected
119
     */
120
    protected $hasFulltext = FALSE;
121
122
    /**
123
     * Last searched logical and physical page
124
     *
125
     * @var	array
126
     * @access protected
127
     */
128
    protected $lastSearchedPhysicalPage = array ('logicalPage' => NULL, 'physicalPage' => NULL);
129
130
    /**
131
     * This holds the documents location
132
     *
133
     * @var	string
134
     * @access protected
135
     */
136
    protected $location = '';
137
138
    /**
139
     * This holds the logical units
140
     *
141
     * @var	array
142
     * @access protected
143
     */
144
    protected $logicalUnits = array ();
145
146
    /**
147
     * This holds the documents' parsed metadata array with their corresponding structMap//div's ID as array key
148
     *
149
     * @var	array
150
     * @access protected
151
     */
152
    protected $metadataArray = array ();
153
154
    /**
155
     * Is the metadata array loaded?
156
     * @see $metadataArray
157
     *
158
     * @var	boolean
159
     * @access protected
160
     */
161
    protected $metadataArrayLoaded = FALSE;
162
163
    /**
164
     * This holds the XML file's METS part as SimpleXMLElement object
165
     *
166
     * @var	SimpleXMLElement
167
     * @access protected
168
     */
169
    protected $mets;
170
171
    /**
172
     * The holds the total number of pages
173
     *
174
     * @var	integer
175
     * @access protected
176
     */
177
    protected $numPages = 0;
178
179
    /**
180
     * This holds the UID of the parent document or zero if not multi-volumed
181
     *
182
     * @var	integer
183
     * @access protected
184
     */
185
    protected $parentId = 0;
186
187
    /**
188
     * This holds the physical structure
189
     *
190
     * @var	array
191
     * @access protected
192
     */
193
    protected $physicalStructure = array ();
194
195
    /**
196
     * This holds the physical structure metadata
197
     *
198
     * @var	array
199
     * @access protected
200
     */
201
    protected $physicalStructureInfo = array ();
202
203
    /**
204
     * Is the physical structure loaded?
205
     * @see $physicalStructure
206
     *
207
     * @var	boolean
208
     * @access protected
209
     */
210
    protected $physicalStructureLoaded = FALSE;
211
212
    /**
213
     * This holds the PID of the document or zero if not in database
214
     *
215
     * @var	integer
216
     * @access protected
217
     */
218
    protected $pid = 0;
219
220
    /**
221
     * Is the document instantiated successfully?
222
     *
223
     * @var	boolean
224
     * @access protected
225
     */
226
    protected $ready = FALSE;
227
228
    /**
229
     * The METS file's record identifier
230
     *
231
     * @var	string
232
     * @access protected
233
     */
234
    protected $recordId;
235
236
    /**
237
     * This holds the singleton object of the document
238
     *
239
     * @var	array (tx_dlf_document)
240
     * @access protected
241
     */
242
    protected static $registry = array ();
243
244
    /**
245
     * This holds the UID of the root document or zero if not multi-volumed
246
     *
247
     * @var	integer
248
     * @access protected
249
     */
250
    protected $rootId = 0;
251
252
    /**
253
     * Is the root id loaded?
254
     * @see $rootId
255
     *
256
     * @var	boolean
257
     * @access protected
258
     */
259
    protected $rootIdLoaded = FALSE;
260
261
    /**
262
     * This holds the smLinks between logical and physical structMap
263
     *
264
     * @var	array
265
     * @access protected
266
     */
267
    protected $smLinks = array ('l2p' => array (), 'p2l' => array ());
268
269
    /**
270
     * Are the smLinks loaded?
271
     * @see $smLinks
272
     *
273
     * @var	boolean
274
     * @access protected
275
     */
276
    protected $smLinksLoaded = FALSE;
277
278
    /**
279
     * This holds the logical structure
280
     *
281
     * @var	array
282
     * @access protected
283
     */
284
    protected $tableOfContents = array ();
285
286
    /**
287
     * Is the table of contents loaded?
288
     * @see $tableOfContents
289
     *
290
     * @var	boolean
291
     * @access protected
292
     */
293
    protected $tableOfContentsLoaded = FALSE;
294
295
    /**
296
     * This holds the document's thumbnail location.
297
     *
298
     * @var	string
299
     * @access protected
300
     */
301
    protected $thumbnail = '';
302
303
    /**
304
     * Is the document's thumbnail location loaded?
305
     * @see $thumbnail
306
     *
307
     * @var	boolean
308
     * @access protected
309
     */
310
    protected $thumbnailLoaded = FALSE;
311
312
    /**
313
     * This holds the toplevel structure's @ID
314
     *
315
     * @var	string
316
     * @access protected
317
     */
318
    protected $toplevelId = '';
319
320
    /**
321
     * This holds the UID or the URL of the document
322
     *
323
     * @var	mixed
324
     * @access protected
325
     */
326
    protected $uid = 0;
327
328
    /**
329
     * This holds the whole XML file as SimpleXMLElement object
330
     *
331
     * @var	SimpleXMLElement
332
     * @access protected
333
     */
334
    protected $xml;
335
336
    /**
337
     * This clears the static registry to prevent memory exhaustion
338
     *
339
     * @access	public
340
     *
341
     * @return	void
342
     */
343
    public static function clearRegistry() {
344
345
        // Reset registry array.
346
        self::$registry = array ();
347
348
    }
349
350
    /**
351
     * This gets the location of a file representing a physical page or track
352
     *
353
     * @access	public
354
     *
355
     * @param	string		$id: The @ID attribute of the file node
356
     *
357
     * @return	string		The file's location as URL
358
     */
359
    public function getFileLocation($id) {
360
361
        if (!empty($id) && ($location = $this->mets->xpath('./mets:fileSec/mets:fileGrp/mets:file[@ID="'.$id.'"]/mets:FLocat[@LOCTYPE="URL"]'))) {
362
363
            return (string) $location[0]->attributes('http://www.w3.org/1999/xlink')->href;
364
365
        } else {
366
367
            if (TYPO3_DLOG) {
0 ignored issues
show
Bug introduced by
The constant TYPO3_DLOG was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
368
369
                \TYPO3\CMS\Core\Utility\GeneralUtility::devLog('[tx_dlf_document->getFileLocation('.$id.')] There is no file node with @ID "'.$id.'"', self::$extKey, SYSLOG_SEVERITY_WARNING);
0 ignored issues
show
Bug introduced by
The constant SYSLOG_SEVERITY_WARNING was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
Bug introduced by
The type TYPO3\CMS\Core\Utility\GeneralUtility 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...
370
371
            }
372
373
            return '';
374
375
        }
376
377
    }
378
379
    /**
380
     * This gets the MIME type of a file representing a physical page or track
381
     *
382
     * @access	public
383
     *
384
     * @param	string		$id: The @ID attribute of the file node
385
     *
386
     * @return	string		The file's MIME type
387
     */
388
    public function getFileMimeType($id) {
389
390
        if (!empty($id) && ($mimetype = $this->mets->xpath('./mets:fileSec/mets:fileGrp/mets:file[@ID="'.$id.'"]/@MIMETYPE'))) {
391
392
            return (string) $mimetype[0];
393
394
        } else {
395
396
            if (TYPO3_DLOG) {
0 ignored issues
show
Bug introduced by
The constant TYPO3_DLOG was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
397
398
                \TYPO3\CMS\Core\Utility\GeneralUtility::devLog('[tx_dlf_document->getFileMimeType('.$id.')] There is no file node with @ID "'.$id.'" or no MIME type specified', self::$extKey, SYSLOG_SEVERITY_WARNING);
0 ignored issues
show
Bug introduced by
The constant SYSLOG_SEVERITY_WARNING was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
399
400
            }
401
402
            return '';
403
404
        }
405
406
    }
407
408
    /**
409
     * This is a singleton class, thus an instance must be created by this method
410
     *
411
     * @access	public
412
     *
413
     * @param	mixed		$uid: The unique identifier of the document to parse or URL of XML file
414
     * @param	integer		$pid: If > 0, then only document with this PID gets loaded
415
     * @param	boolean		$forceReload: Force reloading the document instead of returning the cached instance
416
     *
417
     * @return	&tx_dlf_document		Instance of this class
418
     */
0 ignored issues
show
Documentation Bug introduced by
The doc comment &tx_dlf_document at position 0 could not be parsed: Unknown type name '&' at position 0 in &tx_dlf_document.
Loading history...
419
    public static function &getInstance($uid, $pid = 0, $forceReload = FALSE) {
420
421
        // Sanitize input.
422
        $pid = max(intval($pid), 0);
423
424
        if (!$forceReload) {
425
426
            $regObj = md5($uid);
427
428
            if (is_object(self::$registry[$regObj]) && self::$registry[$regObj] instanceof self) {
429
430
                // Check if instance has given PID.
431
                if (!$pid || !self::$registry[$regObj]->pid || $pid == self::$registry[$regObj]->pid) {
432
433
                    // Return singleton instance if available.
434
                    return self::$registry[$regObj];
435
436
                }
437
438
            } else {
439
440
                // Check the user's session...
441
                $sessionData = tx_dlf_helper::loadFromSession(get_called_class());
442
443
                if (is_object($sessionData[$regObj]) && $sessionData[$regObj] instanceof self) {
444
445
                    // Check if instance has given PID.
446
                    if (!$pid || !$sessionData[$regObj]->pid || $pid == $sessionData[$regObj]->pid) {
447
448
                        // ...and restore registry.
449
                        self::$registry[$regObj] = $sessionData[$regObj];
450
451
                        return self::$registry[$regObj];
452
453
                    }
454
455
                }
456
457
            }
458
459
        }
460
461
        // Create new instance...
462
        $instance = new self($uid, $pid);
463
464
        // ...and save it to registry.
465
        if ($instance->ready) {
466
467
            self::$registry[md5($instance->uid)] = $instance;
468
469
            if ($instance->uid != $instance->location) {
470
471
                self::$registry[md5($instance->location)] = $instance;
472
473
            }
474
475
            // Load extension configuration
476
            $extConf = unserialize($GLOBALS['TYPO3_CONF_VARS']['EXT']['extConf']['dlf']);
477
478
            // Save registry to session if caching is enabled.
479
            if (!empty($extConf['caching'])) {
480
481
                tx_dlf_helper::saveToSession(self::$registry, get_class($instance));
482
483
            }
484
485
        }
486
487
        // Return new instance.
488
        return $instance;
489
490
    }
491
492
    /**
493
     * This gets details about a logical structure element
494
     *
495
     * @access	public
496
     *
497
     * @param	string		$id: The @ID attribute of the logical structure node
498
     * @param	boolean		$recursive: Whether to include the child elements
499
     *
500
     * @return	array		Array of the element's id, label, type and physical page indexes/mptr link
501
     */
502
    public function getLogicalStructure($id, $recursive = FALSE) {
503
504
        $details = array ();
505
506
        // Is the requested logical unit already loaded?
507
        if (!$recursive && !empty($this->logicalUnits[$id])) {
508
509
            // Yes. Return it.
510
            return $this->logicalUnits[$id];
511
512
        } elseif (!empty($id)) {
513
514
            // Get specified logical unit.
515
            $divs = $this->mets->xpath('./mets:structMap[@TYPE="LOGICAL"]//mets:div[@ID="'.$id.'"]');
516
517
        } else {
518
519
            // Get all logical units at top level.
520
            $divs = $this->mets->xpath('./mets:structMap[@TYPE="LOGICAL"]/mets:div');
521
522
        }
523
524
        if (!empty($divs)) {
525
526
            if (!$recursive) {
527
528
                // Get the details for the first xpath hit.
529
                $details = $this->getLogicalStructureInfo($divs[0]);
530
531
            } else {
532
533
                // Walk the logical structure recursively and fill the whole table of contents.
534
                foreach ($divs as $div) {
535
536
                    $this->tableOfContents[] = $this->getLogicalStructureInfo($div, TRUE);
537
538
                }
539
540
            }
541
542
        }
543
544
        return $details;
545
546
    }
547
548
    /**
549
     * This gets details about a logical structure element
550
     *
551
     * @access	protected
552
     *
553
     * @param	SimpleXMLElement		$structure: The logical structure node
554
     * @param	boolean		$recursive: Whether to include the child elements
555
     *
556
     * @return	array		Array of the element's id, label, type and physical page indexes/mptr link
557
     */
558
    protected function getLogicalStructureInfo(SimpleXMLElement $structure, $recursive = FALSE) {
559
560
        // Get attributes.
561
        foreach ($structure->attributes() as $attribute => $value) {
562
563
            $attributes[$attribute] = (string) $value;
564
565
        }
566
567
        // Load plugin configuration.
568
        $extConf = unserialize($GLOBALS['TYPO3_CONF_VARS']['EXT']['extConf'][self::$extKey]);
569
570
        // Extract identity information.
571
        $details = array ();
572
573
        $details['id'] = $attributes['ID'];
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $attributes seems to be defined by a foreach iteration on line 561. Are you sure the iterator is never empty, otherwise this variable is not defined?
Loading history...
574
575
        $details['dmdId'] = (isset($attributes['DMDID']) ? $attributes['DMDID'] : '');
576
577
        $details['label'] = (isset($attributes['LABEL']) ? $attributes['LABEL'] : '');
578
579
        $details['orderlabel'] = (isset($attributes['ORDERLABEL']) ? $attributes['ORDERLABEL'] : '');
580
581
        $details['contentIds'] = (isset($attributes['CONTENTIDS']) ? $attributes['CONTENTIDS'] : '');
582
583
        $details['volume'] = '';
584
585
        // Set volume information only if no label is set and this is the toplevel structure element.
586
        if (empty($details['label']) && $details['id'] == $this->_getToplevelId()) {
587
588
            $metadata = $this->getMetadata($details['id']);
589
590
            if (!empty($metadata['volume'][0])) {
591
592
                $details['volume'] = $metadata['volume'][0];
593
594
            }
595
596
        }
597
598
        $details['pagination'] = '';
599
600
        $details['type'] = $attributes['TYPE'];
601
602
        $details['thumbnailId'] = '';
603
604
        // Load smLinks.
605
        $this->_getSmLinks();
606
607
        // Load physical structure.
608
        $this->_getPhysicalStructure();
609
610
        // Get the physical page or external file this structure element is pointing at.
611
        $details['points'] = '';
612
613
        // Is there a mptr node?
614
        if (count($structure->children('http://www.loc.gov/METS/')->mptr)) {
615
616
            // Yes. Get the file reference.
617
            $details['points'] = (string) $structure->children('http://www.loc.gov/METS/')->mptr[0]->attributes('http://www.w3.org/1999/xlink')->href;
618
619
        // Are there any physical elements and is this logical unit linked to at least one of them?
620
        } elseif (!empty($this->physicalStructure) && array_key_exists($details['id'], $this->smLinks['l2p'])) {
621
622
            $details['points'] = max(intval(array_search($this->smLinks['l2p'][$details['id']][0], $this->physicalStructure, TRUE)), 1);
623
624
            if (!empty($this->physicalStructureInfo[$this->smLinks['l2p'][$details['id']][0]]['files'][$extConf['fileGrpThumbs']])) {
625
626
                $details['thumbnailId'] = $this->physicalStructureInfo[$this->smLinks['l2p'][$details['id']][0]]['files'][$extConf['fileGrpThumbs']];
627
628
            }
629
630
            // Get page/track number of the first page/track related to this structure element.
631
            $details['pagination'] = $this->physicalStructureInfo[$this->smLinks['l2p'][$details['id']][0]]['orderlabel'];
632
633
        // Is this the toplevel structure element?
634
        } elseif ($details['id'] == $this->_getToplevelId()) {
635
636
            // Yes. Point to itself.
637
            $details['points'] = 1;
638
639
            if (!empty($this->physicalStructure) && !empty($this->physicalStructureInfo[$this->physicalStructure[1]]['files'][$extConf['fileGrpThumbs']])) {
640
641
                $details['thumbnailId'] = $this->physicalStructureInfo[$this->physicalStructure[1]]['files'][$extConf['fileGrpThumbs']];
642
643
            }
644
645
        }
646
647
        // Get the files this structure element is pointing at.
648
        $details['files'] = array ();
649
650
        $fileUse = $this->_getFileGrps();
651
652
        // Get the file representations from fileSec node.
653
        foreach ($structure->children('http://www.loc.gov/METS/')->fptr as $fptr) {
654
655
            // Check if file has valid @USE attribute.
656
            if (!empty($fileUse[(string) $fptr->attributes()->FILEID])) {
657
658
                $details['files'][$fileUse[(string) $fptr->attributes()->FILEID]] = (string) $fptr->attributes()->FILEID;
659
660
            }
661
662
        }
663
664
        // Keep for later usage.
665
        $this->logicalUnits[$details['id']] = $details;
666
667
        // Walk the structure recursively? And are there any children of the current element?
668
        if ($recursive && count($structure->children('http://www.loc.gov/METS/')->div)) {
669
670
            $details['children'] = array ();
671
672
            foreach ($structure->children('http://www.loc.gov/METS/')->div as $child) {
673
674
                // Repeat for all children.
675
                $details['children'][] = $this->getLogicalStructureInfo($child, TRUE);
676
677
            }
678
679
        }
680
681
        return $details;
682
683
    }
684
685
    /**
686
     * This extracts all the metadata for a logical structure node
687
     *
688
     * @access	public
689
     *
690
     * @param	string		$id: The @ID attribute of the logical structure node
691
     * @param	integer		$cPid: The PID for the metadata definitions
692
     * 						(defaults to $this->cPid or $this->pid)
693
     *
694
     * @return	array		The logical structure node's parsed metadata array
695
     */
696
    public function getMetadata($id, $cPid = 0) {
697
698
        // Save parameter for logging purposes.
699
        $_cPid = $cPid;
700
701
        // Make sure $cPid is a non-negative integer.
702
        $cPid = max(intval($cPid), 0);
703
704
        // If $cPid is not given, try to get it elsewhere.
705
        if (!$cPid && ($this->cPid || $this->pid)) {
706
707
            // Retain current PID.
708
            $cPid = ($this->cPid ? $this->cPid : $this->pid);
709
710
        } elseif (!$cPid) {
711
712
            if (TYPO3_DLOG) {
0 ignored issues
show
Bug introduced by
The constant TYPO3_DLOG was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
713
714
                \TYPO3\CMS\Core\Utility\GeneralUtility::devLog('[tx_dlf_document->getMetadata('.$id.', '.$_cPid.')] Invalid PID "'.$cPid.'" for metadata definitions', self::$extKey, SYSLOG_SEVERITY_ERROR);
0 ignored issues
show
Bug introduced by
The constant SYSLOG_SEVERITY_ERROR was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
715
716
            }
717
718
            return array ();
719
720
        }
721
722
        // Get metadata from parsed metadata array if available.
723
        if (!empty($this->metadataArray[$id]) && $this->metadataArray[0] == $cPid) {
724
725
            return $this->metadataArray[$id];
726
727
        }
728
729
        // Initialize metadata array with empty values.
730
        $metadata = array (
731
            'title' => array (),
732
            'title_sorting' => array (),
733
            'author' => array (),
734
            'place' => array (),
735
            'year' => array (),
736
            'prod_id' => array (),
737
            'record_id' => array (),
738
            'opac_id' => array (),
739
            'union_id' => array (),
740
            'urn' => array (),
741
            'purl' => array (),
742
            'type' => array (),
743
            'volume' => array (),
744
            'volume_sorting' => array (),
745
            'collection' => array (),
746
            'owner' => array (),
747
        );
748
749
        // Get the logical structure node's DMDID.
750
        if (!empty($this->logicalUnits[$id])) {
751
752
            $dmdId = $this->logicalUnits[$id]['dmdId'];
753
754
        } else {
755
756
            $dmdId = $this->mets->xpath('./mets:structMap[@TYPE="LOGICAL"]//mets:div[@ID="'.$id.'"]/@DMDID');
757
758
            $dmdId = (string) $dmdId[0];
759
760
        }
761
762
        if (!empty($dmdId)) {
763
764
            // Load available metadata formats and dmdSecs.
765
            $this->loadFormats();
766
767
            $this->_getDmdSec();
768
769
            // Is this metadata format supported?
770
            if (!empty($this->formats[$this->dmdSec[$dmdId]['type']])) {
771
772
                if (!empty($this->formats[$this->dmdSec[$dmdId]['type']]['class'])) {
773
774
                    $class = $this->formats[$this->dmdSec[$dmdId]['type']]['class'];
775
776
                    // Get the metadata from class.
777
                    if (class_exists($class) && ($obj = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance($class)) instanceof tx_dlf_format) {
778
779
                        $obj->extractMetadata($this->dmdSec[$dmdId]['xml'], $metadata);
780
781
                    } else {
782
783
                        if (TYPO3_DLOG) {
784
785
                            \TYPO3\CMS\Core\Utility\GeneralUtility::devLog('[tx_dlf_document->getMetadata('.$id.', '.$_cPid.')] Invalid class/method "'.$class.'->extractMetadata()" for metadata format "'.$this->dmdSec[$dmdId]['type'].'"', self::$extKey, SYSLOG_SEVERITY_WARNING);
0 ignored issues
show
Bug introduced by
The constant SYSLOG_SEVERITY_WARNING was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
786
787
                        }
788
789
                    }
790
791
                }
792
793
            } else {
794
795
                if (TYPO3_DLOG) {
796
797
                    \TYPO3\CMS\Core\Utility\GeneralUtility::devLog('[tx_dlf_document->getMetadata('.$id.', '.$_cPid.')] Unsupported metadata format "'.$this->dmdSec[$dmdId]['type'].'" in dmdSec with @ID "'.$dmdId.'"', self::$extKey, SYSLOG_SEVERITY_WARNING);
798
799
                }
800
801
                return array ();
802
803
            }
804
805
            // Get the structure's type.
806
            if (!empty($this->logicalUnits[$id])) {
807
808
                $metadata['type'] = array ($this->logicalUnits[$id]['type']);
809
810
            } else {
811
812
                $struct = $this->mets->xpath('./mets:structMap[@TYPE="LOGICAL"]//mets:div[@ID="'.$id.'"]/@TYPE');
813
814
                $metadata['type'] = array ((string) $struct[0]);
815
816
            }
817
818
            // Get the additional metadata from database.
819
            $result = $GLOBALS['TYPO3_DB']->exec_SELECTquery(
820
                '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',
821
                'tx_dlf_metadata,tx_dlf_metadataformat,tx_dlf_formats',
822
                'tx_dlf_metadata.pid='.$cPid.' AND tx_dlf_metadataformat.pid='.$cPid.' 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->dmdSec[$dmdId]['type'], 'tx_dlf_formats').') OR tx_dlf_metadata.format=0)'.tx_dlf_helper::whereClause('tx_dlf_metadata', TRUE).tx_dlf_helper::whereClause('tx_dlf_metadataformat').tx_dlf_helper::whereClause('tx_dlf_formats'),
823
                '',
824
                '',
825
                ''
826
            );
827
828
            // We need a DOMDocument here, because SimpleXML doesn't support XPath functions properly.
829
            $domNode = dom_import_simplexml($this->dmdSec[$dmdId]['xml']);
830
831
            $domXPath = new DOMXPath($domNode->ownerDocument);
832
833
            $this->registerNamespaces($domXPath);
834
835
            // OK, now make the XPath queries.
836
            while ($resArray = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($result)) {
837
838
                // Set metadata field's value(s).
839
                if ($resArray['format'] > 0 && !empty($resArray['xpath']) && ($values = $domXPath->evaluate($resArray['xpath'], $domNode))) {
840
841
                    if ($values instanceof DOMNodeList && $values->length > 0) {
842
843
                        $metadata[$resArray['index_name']] = array ();
844
845
                        foreach ($values as $value) {
846
847
                            $metadata[$resArray['index_name']][] = trim((string) $value->nodeValue);
848
849
                        }
850
851
                    } elseif (!($values instanceof DOMNodeList)) {
852
853
                        $metadata[$resArray['index_name']] = array (trim((string) $values));
854
855
                    }
856
857
                }
858
859
                // Set default value if applicable.
860
                if (empty($metadata[$resArray['index_name']][0])) {
861
862
                    $metadata[$resArray['index_name']] = array ($resArray['default_value']);
863
864
                }
865
866
                // Set sorting value if applicable.
867
                if (!empty($metadata[$resArray['index_name']]) && $resArray['is_sortable']) {
868
869
                    if ($resArray['format'] > 0 && !empty($resArray['xpath_sorting']) && ($values = $domXPath->evaluate($resArray['xpath_sorting'], $domNode))) {
870
871
                        if ($values instanceof DOMNodeList && $values->length > 0) {
872
873
                            $metadata[$resArray['index_name'].'_sorting'][0] = trim((string) $values->item(0)->nodeValue);
874
875
                        } elseif (!($values instanceof DOMNodeList)) {
876
877
                            $metadata[$resArray['index_name'].'_sorting'][0] = trim((string) $values);
878
879
                        }
880
881
                    }
882
883
                    if (empty($metadata[$resArray['index_name'].'_sorting'][0])) {
884
885
                        $metadata[$resArray['index_name'].'_sorting'][0] = $metadata[$resArray['index_name']][0];
886
887
                    }
888
889
                }
890
891
            }
892
893
            // Set title to empty string if not present.
894
            if (empty($metadata['title'][0])) {
895
896
                $metadata['title'][0] = '';
897
898
                $metadata['title_sorting'][0] = '';
899
900
            }
901
902
        } else {
903
904
            // There is no dmdSec for this structure node.
905
            return array ();
906
907
        }
908
909
        return $metadata;
910
911
    }
912
913
    /**
914
     * This returns the first corresponding physical page number of a given logical page label
915
     *
916
     * @access	public
917
     *
918
     * @param	string		$logicalPage: The label (or a part of the label) of the logical page
919
     *
920
     * @return	integer		The physical page number
921
     */
922
    public function getPhysicalPage($logicalPage) {
923
924
        if (!empty($this->lastSearchedPhysicalPage['logicalPage']) && $this->lastSearchedPhysicalPage['logicalPage'] == $logicalPage) {
925
926
            return $this->lastSearchedPhysicalPage['physicalPage'];
927
928
        } else {
929
930
            $physicalPage = 0;
931
932
            foreach ($this->physicalStructureInfo as $page) {
933
934
                if (strpos($page['orderlabel'], $logicalPage) !== FALSE) {
935
936
                    $this->lastSearchedPhysicalPage['logicalPage'] = $logicalPage;
937
                    $this->lastSearchedPhysicalPage['physicalPage'] = $physicalPage;
938
939
                    return $physicalPage;
940
941
                }
942
943
                $physicalPage++;
944
945
            }
946
947
        }
948
949
        return 1;
950
951
    }
952
953
    /**
954
     * This determines a title for the given document
955
     *
956
     * @access	public
957
     *
958
     * @param	integer		$uid: The UID of the document
959
     * @param	boolean		$recursive: Search superior documents for a title, too?
960
     *
961
     * @return	string		The title of the document itself or a parent document
962
     */
963
    public static function getTitle($uid, $recursive = FALSE) {
964
965
        // Save parameter for logging purposes.
966
        $_uid = $uid;
967
968
        $title = '';
969
970
        // Sanitize input.
971
        $uid = max(intval($uid), 0);
972
973
        if ($uid) {
974
975
            $result = $GLOBALS['TYPO3_DB']->exec_SELECTquery(
976
                'tx_dlf_documents.title,tx_dlf_documents.partof',
977
                'tx_dlf_documents',
978
                'tx_dlf_documents.uid='.$uid.tx_dlf_helper::whereClause('tx_dlf_documents'),
979
                '',
980
                '',
981
                '1'
982
            );
983
984
            if ($GLOBALS['TYPO3_DB']->sql_num_rows($result)) {
985
986
                // Get title information.
987
                list ($title, $partof) = $GLOBALS['TYPO3_DB']->sql_fetch_row($result);
988
989
                // Search parent documents recursively for a title?
990
                if ($recursive && empty($title) && intval($partof) && $partof != $uid) {
991
992
                    $title = self::getTitle($partof, TRUE);
993
994
                }
995
996
            } else {
997
998
                if (TYPO3_DLOG) {
0 ignored issues
show
Bug introduced by
The constant TYPO3_DLOG was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
999
1000
                    \TYPO3\CMS\Core\Utility\GeneralUtility::devLog('[tx_dlf_document->getTitle('.$_uid.', ['.($recursive ? 'TRUE' : 'FALSE').'])] No document with UID "'.$uid.'" found or document not accessible', self::$extKey, SYSLOG_SEVERITY_WARNING);
0 ignored issues
show
Bug introduced by
The constant SYSLOG_SEVERITY_WARNING was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
1001
1002
                }
1003
1004
            }
1005
1006
        } else {
1007
1008
            if (TYPO3_DLOG) {
1009
1010
                \TYPO3\CMS\Core\Utility\GeneralUtility::devLog('[tx_dlf_document->getTitle('.$_uid.', ['.($recursive ? 'TRUE' : 'FALSE').'])] Invalid UID "'.$uid.'" for document', self::$extKey, SYSLOG_SEVERITY_ERROR);
0 ignored issues
show
Bug introduced by
The constant SYSLOG_SEVERITY_ERROR was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
1011
1012
            }
1013
1014
        }
1015
1016
        return $title;
1017
1018
    }
1019
1020
    /**
1021
     * This extracts all the metadata for the toplevel logical structure node
1022
     *
1023
     * @access	public
1024
     *
1025
     * @param	integer		$cPid: The PID for the metadata definitions
1026
     *
1027
     * @return	array		The logical structure node's parsed metadata array
1028
     */
1029
    public function getTitledata($cPid = 0) {
1030
1031
        $titledata = $this->getMetadata($this->_getToplevelId(), $cPid);
1032
1033
        // Set record identifier for METS file if not present.
1034
        if (is_array($titledata) && array_key_exists('record_id', $titledata)) {
1035
1036
            if (!empty($this->recordId) && !in_array($this->recordId, $titledata['record_id'])) {
1037
1038
                array_unshift($titledata['record_id'], $this->recordId);
1039
1040
            }
1041
1042
        };
1043
1044
        return $titledata;
1045
1046
    }
1047
1048
    /**
1049
     * This sets some basic class properties
1050
     *
1051
     * @access	protected
1052
     *
1053
     * @return	void
1054
     */
1055
    protected function init() {
1056
1057
        // Get METS node from XML file.
1058
        $this->registerNamespaces($this->xml);
1059
1060
        $mets = $this->xml->xpath('//mets:mets');
1061
1062
        if ($mets) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $mets of type SimpleXMLElement[] is implicitly converted to a boolean; are you sure this is intended? If so, consider using ! empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
1063
1064
            $this->mets = $mets[0];
1065
1066
            // Register namespaces.
1067
            $this->registerNamespaces($this->mets);
1068
1069
        } else {
1070
1071
            if (TYPO3_DLOG) {
0 ignored issues
show
Bug introduced by
The constant TYPO3_DLOG was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
1072
1073
                \TYPO3\CMS\Core\Utility\GeneralUtility::devLog('[tx_dlf_document->init()] No METS part found in document with UID "'.$this->uid.'"', self::$extKey, SYSLOG_SEVERITY_ERROR);
0 ignored issues
show
Bug introduced by
The constant SYSLOG_SEVERITY_ERROR was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
1074
1075
            }
1076
1077
        }
1078
1079
    }
1080
1081
    /**
1082
     * Load XML file from URL
1083
     *
1084
     * @access	protected
1085
     *
1086
     * @param	string		$location: The URL of the file to load
1087
     *
1088
     * @return	boolean		TRUE on success or FALSE on failure
1089
     */
1090
    protected function load($location) {
1091
1092
        // Load XML file.
1093
        if (\TYPO3\CMS\Core\Utility\GeneralUtility::isValidUrl($location)) {
1094
1095
            // Load extension configuration
1096
            $extConf = unserialize($GLOBALS['TYPO3_CONF_VARS']['EXT']['extConf']['dlf']);
1097
1098
            // Set user-agent to identify self when fetching XML data.
1099
            if (!empty($extConf['useragent'])) {
1100
1101
                @ini_set('user_agent', $extConf['useragent']);
0 ignored issues
show
Security Best Practice introduced by
It seems like you do not handle an error condition for ini_set(). This can introduce security issues, and is generally not recommended. ( Ignorable by Annotation )

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

1101
                /** @scrutinizer ignore-unhandled */ @ini_set('user_agent', $extConf['useragent']);

If you suppress an error, we recommend checking for the error condition explicitly:

// For example instead of
@mkdir($dir);

// Better use
if (@mkdir($dir) === false) {
    throw new \RuntimeException('The directory '.$dir.' could not be created.');
}
Loading history...
1102
1103
            }
1104
1105
            // Turn off libxml's error logging.
1106
            $libxmlErrors = libxml_use_internal_errors(TRUE);
1107
1108
            // Disables the functionality to allow external entities to be loaded when parsing the XML, must be kept
1109
            $previousValueOfEntityLoader = libxml_disable_entity_loader(TRUE);
1110
1111
            // Load XML from file.
1112
            $xml = simplexml_load_string(\TYPO3\CMS\Core\Utility\GeneralUtility::getUrl($location));
1113
1114
            // reset entity loader setting
1115
            libxml_disable_entity_loader($previousValueOfEntityLoader);
1116
1117
            // Reset libxml's error logging.
1118
            libxml_use_internal_errors($libxmlErrors);
1119
1120
            // Set some basic properties.
1121
            if ($xml !== FALSE) {
1122
1123
                $this->xml = $xml;
1124
1125
                return TRUE;
1126
1127
            } else {
1128
1129
                if (TYPO3_DLOG) {
0 ignored issues
show
Bug introduced by
The constant TYPO3_DLOG was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
1130
1131
                    \TYPO3\CMS\Core\Utility\GeneralUtility::devLog('[tx_dlf_document->load('.$location.')] Could not load XML file from "'.$location.'"', self::$extKey, SYSLOG_SEVERITY_ERROR);
0 ignored issues
show
Bug introduced by
The constant SYSLOG_SEVERITY_ERROR was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
1132
1133
                }
1134
1135
            }
1136
1137
        } else {
1138
1139
            if (TYPO3_DLOG) {
1140
1141
                \TYPO3\CMS\Core\Utility\GeneralUtility::devLog('[tx_dlf_document->load('.$location.')] Invalid file location "'.$location.'" for document loading', self::$extKey, SYSLOG_SEVERITY_ERROR);
1142
1143
            }
1144
1145
        }
1146
1147
        return FALSE;
1148
1149
    }
1150
1151
    /**
1152
     * Register all available data formats
1153
     *
1154
     * @access	protected
1155
     *
1156
     * @return	void
1157
     */
1158
    protected function loadFormats() {
1159
1160
        if (!$this->formatsLoaded) {
1161
1162
            // Get available data formats from database.
1163
            $result = $GLOBALS['TYPO3_DB']->exec_SELECTquery(
1164
                'tx_dlf_formats.type AS type,tx_dlf_formats.root AS root,tx_dlf_formats.namespace AS namespace,tx_dlf_formats.class AS class',
1165
                'tx_dlf_formats',
1166
                'tx_dlf_formats.pid=0'.tx_dlf_helper::whereClause('tx_dlf_formats'),
1167
                '',
1168
                '',
1169
                ''
1170
            );
1171
1172
            while ($resArray = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($result)) {
1173
1174
                // Update format registry.
1175
                $this->formats[$resArray['type']] = array (
1176
                    'rootElement' => $resArray['root'],
1177
                    'namespaceURI' => $resArray['namespace'],
1178
                    'class' => $resArray['class']
1179
                );
1180
1181
            }
1182
1183
            $this->formatsLoaded = TRUE;
1184
1185
        }
1186
1187
    }
1188
1189
    /**
1190
     * Register all available namespaces for a SimpleXMLElement object
1191
     *
1192
     * @access	public
1193
     *
1194
     * @param	SimpleXMLElement|DOMXPath		&$obj: SimpleXMLElement or DOMXPath object
1195
     *
1196
     * @return	void
1197
     */
1198
    public function registerNamespaces(&$obj) {
1199
1200
        $this->loadFormats();
1201
1202
        // Do we have a SimpleXMLElement or DOMXPath object?
1203
        if ($obj instanceof SimpleXMLElement) {
1204
1205
            $method = 'registerXPathNamespace';
1206
1207
        } elseif ($obj instanceof DOMXPath) {
1208
1209
            $method = 'registerNamespace';
1210
1211
        } else {
1212
1213
            if (TYPO3_DLOG) {
0 ignored issues
show
Bug introduced by
The constant TYPO3_DLOG was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
1214
1215
                \TYPO3\CMS\Core\Utility\GeneralUtility::devLog('[tx_dlf_document->registerNamespaces(['.get_class($obj).'])] Given object is neither a SimpleXMLElement nor a DOMXPath instance', self::$extKey, SYSLOG_SEVERITY_ERROR);
0 ignored issues
show
Bug introduced by
The constant SYSLOG_SEVERITY_ERROR was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
1216
1217
            }
1218
1219
            return;
1220
1221
        }
1222
1223
        // Register metadata format's namespaces.
1224
        foreach ($this->formats as $enc => $conf) {
1225
1226
            $obj->$method(strtolower($enc), $conf['namespaceURI']);
1227
1228
        }
1229
1230
    }
1231
1232
    /**
1233
     * This saves the document to the database and index
1234
     *
1235
     * @access	public
1236
     *
1237
     * @param	integer		$pid: The PID of the saved record
1238
     * @param	integer		$core: The UID of the Solr core for indexing
1239
     *
1240
     * @return	boolean		TRUE on success or FALSE on failure
1241
     */
1242
    public function save($pid = 0, $core = 0) {
1243
1244
        // Save parameters for logging purposes.
1245
        $_pid = $pid;
1246
1247
        $_core = $core;
1248
1249
        if (TYPO3_MODE !== 'BE') {
0 ignored issues
show
Bug introduced by
The constant TYPO3_MODE was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
1250
1251
            if (TYPO3_DLOG) {
0 ignored issues
show
Bug introduced by
The constant TYPO3_DLOG was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
1252
1253
                \TYPO3\CMS\Core\Utility\GeneralUtility::devLog('[tx_dlf_document->save('.$_pid.', '.$_core.')] Saving a document is only allowed in the backend', self::$extKey, SYSLOG_SEVERITY_ERROR);
0 ignored issues
show
Bug introduced by
The constant SYSLOG_SEVERITY_ERROR was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
1254
1255
            }
1256
1257
            return FALSE;
1258
1259
        }
1260
1261
        // Make sure $pid is a non-negative integer.
1262
        $pid = max(intval($pid), 0);
1263
1264
        // Make sure $core is a non-negative integer.
1265
        $core = max(intval($core), 0);
1266
1267
        // If $pid is not given, try to get it elsewhere.
1268
        if (!$pid && $this->pid) {
1269
1270
            // Retain current PID.
1271
            $pid = $this->pid;
1272
1273
        } elseif (!$pid) {
1274
1275
            if (TYPO3_DLOG) {
1276
1277
                \TYPO3\CMS\Core\Utility\GeneralUtility::devLog('[tx_dlf_document->save('.$_pid.', '.$_core.')] Invalid PID "'.$pid.'" for document saving', self::$extKey, SYSLOG_SEVERITY_ERROR);
1278
1279
            }
1280
1281
            return FALSE;
1282
1283
        }
1284
1285
        // Set PID for metadata definitions.
1286
        $this->cPid = $pid;
1287
1288
        // Set UID placeholder if not updating existing record.
1289
        if ($pid != $this->pid) {
1290
1291
            $this->uid = uniqid('NEW');
1292
1293
        }
1294
1295
        // Get metadata array.
1296
        $metadata = $this->getTitledata($pid);
1297
1298
        // Check for record identifier.
1299
        if (empty($metadata['record_id'][0])) {
1300
1301
            if (TYPO3_DLOG) {
1302
1303
                \TYPO3\CMS\Core\Utility\GeneralUtility::devLog('[tx_dlf_document->save('.$_pid.', '.$_core.')] No record identifier found to avoid duplication', self::$extKey, SYSLOG_SEVERITY_ERROR);
1304
1305
            }
1306
1307
            return FALSE;
1308
1309
        }
1310
1311
        // Load plugin configuration.
1312
        $conf = unserialize($GLOBALS['TYPO3_CONF_VARS']['EXT']['extConf'][self::$extKey]);
1313
1314
        // Get UID for user "_cli_dlf".
1315
        $result = $GLOBALS['TYPO3_DB']->exec_SELECTquery(
1316
            'be_users.uid AS uid',
1317
            'be_users',
1318
            'username='.$GLOBALS['TYPO3_DB']->fullQuoteStr('_cli_dlf', 'be_users').\TYPO3\CMS\Backend\Utility\BackendUtility::BEenableFields('be_users').\TYPO3\CMS\Backend\Utility\BackendUtility::deleteClause('be_users'),
0 ignored issues
show
Bug introduced by
The type TYPO3\CMS\Backend\Utility\BackendUtility 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...
1319
            '',
1320
            '',
1321
            '1'
1322
        );
1323
1324
        if ($GLOBALS['TYPO3_DB']->sql_num_rows($result)) {
1325
1326
            list ($be_user) = $GLOBALS['TYPO3_DB']->sql_fetch_row($result);
1327
1328
        } else {
1329
1330
            if (TYPO3_DLOG) {
1331
1332
                \TYPO3\CMS\Core\Utility\GeneralUtility::devLog('[tx_dlf_document->save('.$_pid.', '.$_core.')] Backend user "_cli_dlf" not found or disabled', self::$extKey, SYSLOG_SEVERITY_ERROR);
1333
1334
            }
1335
1336
            return FALSE;
1337
1338
        }
1339
1340
        // Get UID for structure type.
1341
        $result = $GLOBALS['TYPO3_DB']->exec_SELECTquery(
1342
            'tx_dlf_structures.uid AS uid',
1343
            'tx_dlf_structures',
1344
            'tx_dlf_structures.pid='.intval($pid).' AND tx_dlf_structures.index_name='.$GLOBALS['TYPO3_DB']->fullQuoteStr($metadata['type'][0], 'tx_dlf_structures').tx_dlf_helper::whereClause('tx_dlf_structures'),
1345
            '',
1346
            '',
1347
            '1'
1348
        );
1349
1350
        if ($GLOBALS['TYPO3_DB']->sql_num_rows($result)) {
1351
1352
            list ($structure) = $GLOBALS['TYPO3_DB']->sql_fetch_row($result);
1353
1354
        } else {
1355
1356
            if (TYPO3_DLOG) {
1357
1358
                \TYPO3\CMS\Core\Utility\GeneralUtility::devLog('[tx_dlf_document->save('.$_pid.', '.$_core.')] Could not identify document/structure type '.$GLOBALS['TYPO3_DB']->fullQuoteStr($metadata['type'][0], 'tx_dlf_structures'),
1359
                                            self::$extKey, SYSLOG_SEVERITY_ERROR);
1360
1361
            }
1362
1363
            return FALSE;
1364
1365
        }
1366
1367
        $metadata['type'][0] = $structure;
1368
1369
        // Get UIDs for collections.
1370
        $collections = array ();
1371
1372
        $result = $GLOBALS['TYPO3_DB']->exec_SELECTquery(
1373
            'tx_dlf_collections.index_name AS index_name,tx_dlf_collections.uid AS uid',
1374
            'tx_dlf_collections',
1375
            'tx_dlf_collections.pid='.intval($pid).' AND tx_dlf_collections.cruser_id='.intval($be_user).' AND tx_dlf_collections.fe_cruser_id=0'.tx_dlf_helper::whereClause('tx_dlf_collections'),
1376
            '',
1377
            '',
1378
            ''
1379
        );
1380
1381
        for ($i = 0, $j = $GLOBALS['TYPO3_DB']->sql_num_rows($result); $i < $j; $i++) {
1382
1383
            $resArray = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($result);
1384
1385
            $collUid[$resArray['index_name']] = $resArray['uid'];
1386
1387
        }
1388
1389
        foreach ($metadata['collection'] as $collection) {
1390
1391
            if (!empty($collUid[$collection])) {
1392
1393
                // Add existing collection's UID.
1394
                $collections[] = $collUid[$collection];
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $collUid does not seem to be defined for all execution paths leading up to this point.
Loading history...
1395
1396
            } else {
1397
1398
                // Insert new collection.
1399
                $collNewUid = uniqid('NEW');
1400
1401
                $collData['tx_dlf_collections'][$collNewUid] = array (
1402
                    'pid' => $pid,
1403
                    'label' => $collection,
1404
                    'index_name' => $collection,
1405
                    'oai_name' => (!empty($conf['publishNewCollections']) ? $collection : ''),
1406
                    'description' => '',
1407
                    'documents' => 0,
1408
                    'owner' => 0,
1409
                    'status' => 0,
1410
                );
1411
1412
                $substUid = tx_dlf_helper::processDB($collData);
1413
1414
                // Prevent double insertion.
1415
                unset ($collData);
1416
1417
                // Add new collection's UID.
1418
                $collections[] = $substUid[$collNewUid];
1419
1420
                if (!defined('TYPO3_cliMode')) {
1421
1422
                    $message = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance(
1423
                        'TYPO3\\CMS\\Core\\Messaging\\FlashMessage',
1424
                        htmlspecialchars(sprintf(tx_dlf_helper::getLL('flash.newCollection'), $collection, $substUid[$collNewUid])),
1425
                        tx_dlf_helper::getLL('flash.attention', TRUE),
1426
                        \TYPO3\CMS\Core\Messaging\FlashMessage::INFO,
0 ignored issues
show
Bug introduced by
The type TYPO3\CMS\Core\Messaging\FlashMessage 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...
1427
                        TRUE
1428
                    );
1429
1430
                    tx_dlf_helper::addMessage($message);
1431
1432
                }
1433
1434
            }
1435
1436
        }
1437
1438
        // Preserve user-defined collections.
1439
        $result = $GLOBALS['TYPO3_DB']->exec_SELECT_mm_query(
1440
            'tx_dlf_collections.uid AS uid',
1441
            'tx_dlf_documents',
1442
            'tx_dlf_relations',
1443
            'tx_dlf_collections',
1444
            'AND tx_dlf_documents.pid='.intval($pid).' AND tx_dlf_collections.pid='.intval($pid).' AND tx_dlf_documents.uid='.$GLOBALS['TYPO3_DB']->fullQuoteStr($this->uid, 'tx_dlf_documents').' AND NOT (tx_dlf_collections.cruser_id='.intval($be_user).' AND tx_dlf_collections.fe_cruser_id=0) AND tx_dlf_relations.ident='.$GLOBALS['TYPO3_DB']->fullQuoteStr('docs_colls', 'tx_dlf_relations'),
1445
            '',
1446
            '',
1447
            ''
1448
        );
1449
1450
        for ($i = 0, $j = $GLOBALS['TYPO3_DB']->sql_num_rows($result); $i < $j; $i++) {
1451
1452
            list ($collections[]) = $GLOBALS['TYPO3_DB']->sql_fetch_row($result);
1453
1454
        }
1455
1456
        $metadata['collection'] = $collections;
1457
1458
        // Get UID for owner.
1459
        $owner = !empty($metadata['owner'][0]) ? $metadata['owner'][0] : 'default';
1460
1461
        $result = $GLOBALS['TYPO3_DB']->exec_SELECTquery(
1462
            'tx_dlf_libraries.uid AS uid',
1463
            'tx_dlf_libraries',
1464
            'tx_dlf_libraries.pid='.intval($pid).' AND tx_dlf_libraries.index_name='.$GLOBALS['TYPO3_DB']->fullQuoteStr($owner, 'tx_dlf_libraries').tx_dlf_helper::whereClause('tx_dlf_libraries'),
1465
            '',
1466
            '',
1467
            '1'
1468
        );
1469
1470
        if ($GLOBALS['TYPO3_DB']->sql_num_rows($result)) {
1471
1472
            list ($ownerUid) = $GLOBALS['TYPO3_DB']->sql_fetch_row($result);
1473
1474
        } else {
1475
1476
            // Insert new library.
1477
            $libNewUid = uniqid('NEW');
1478
1479
            $libData['tx_dlf_libraries'][$libNewUid] = array (
0 ignored issues
show
Comprehensibility Best Practice introduced by
$libData was never initialized. Although not strictly required by PHP, it is generally a good practice to add $libData = array(); before regardless.
Loading history...
1480
                'pid' => $pid,
1481
                'label' => $owner,
1482
                'index_name' => $owner,
1483
                'website' => '',
1484
                'contact' => '',
1485
                'image' => '',
1486
                'oai_label' => '',
1487
                'oai_base' => '',
1488
                'opac_label' => '',
1489
                'opac_base' => '',
1490
                'union_label' => '',
1491
                'union_base' => '',
1492
            );
1493
1494
            $substUid = tx_dlf_helper::processDB($libData);
1495
1496
            // Add new library's UID.
1497
            $ownerUid = $substUid[$libNewUid];
1498
1499
            if (!defined('TYPO3_cliMode')) {
1500
1501
                $message = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance(
1502
                    'TYPO3\\CMS\\Core\\Messaging\\FlashMessage',
1503
                    htmlspecialchars(sprintf(tx_dlf_helper::getLL('flash.newLibrary'), $owner, $ownerUid)),
1504
                    tx_dlf_helper::getLL('flash.attention', TRUE),
1505
                    \TYPO3\CMS\Core\Messaging\FlashMessage::INFO,
1506
                    TRUE
1507
                );
1508
1509
                tx_dlf_helper::addMessage($message);
1510
1511
            }
1512
1513
        }
1514
1515
        $metadata['owner'][0] = $ownerUid;
1516
1517
        // Get UID of parent document.
1518
        $partof = 0;
1519
1520
        // Get the closest ancestor of the current document which has a MPTR child.
1521
        $parentMptr = $this->mets->xpath('./mets:structMap[@TYPE="LOGICAL"]//mets:div[@ID="'.$this->_getToplevelId().'"]/ancestor::mets:div[./mets:mptr][1]/mets:mptr');
1522
1523
        if (!empty($parentMptr[0])) {
1524
1525
            $parentLocation = (string) $parentMptr[0]->attributes('http://www.w3.org/1999/xlink')->href;
1526
1527
            if ($parentLocation != $this->location) {
1528
1529
                $parentDoc = & tx_dlf_document::getInstance($parentLocation, $pid);
1530
1531
                if ($parentDoc->ready) {
1532
1533
                    if ($parentDoc->pid != $pid) {
1534
1535
                        $parentDoc->save($pid, $core);
1536
1537
                    }
1538
1539
                    $partof = $parentDoc->uid;
1540
1541
                }
1542
1543
            }
1544
1545
        }
1546
1547
        // Use the date of publication or title as alternative sorting metric for parts of multi-part works.
1548
        if (!empty($partof)) {
1549
1550
            if (empty($metadata['volume'][0]) && !empty($metadata['year'][0])) {
1551
1552
                $metadata['volume'] = $metadata['year'];
1553
1554
            }
1555
1556
            if (empty($metadata['volume_sorting'][0])) {
1557
1558
                if (!empty($metadata['year_sorting'][0])) {
1559
1560
                    $metadata['volume_sorting'][0] = $metadata['year_sorting'][0];
1561
1562
                } elseif (!empty($metadata['year'][0])) {
1563
1564
                    $metadata['volume_sorting'][0] = $metadata['year'][0];
1565
1566
                }
1567
1568
            }
1569
1570
            // If volume_sorting is still empty, try to use title_sorting finally (workaround for newspapers)
1571
            if (empty($metadata['volume_sorting'][0])) {
1572
1573
                if (!empty($metadata['title_sorting'][0])) {
1574
1575
                    $metadata['volume_sorting'][0] = $metadata['title_sorting'][0];
1576
1577
                }
1578
            }
1579
1580
        }
1581
1582
        // Get metadata for lists and sorting.
1583
        $listed = array ();
1584
1585
        $sortable = array ();
1586
1587
        $result = $GLOBALS['TYPO3_DB']->exec_SELECTquery(
1588
            'tx_dlf_metadata.index_name AS index_name,tx_dlf_metadata.is_listed AS is_listed,tx_dlf_metadata.is_sortable AS is_sortable',
1589
            'tx_dlf_metadata',
1590
            '(tx_dlf_metadata.is_listed=1 OR tx_dlf_metadata.is_sortable=1) AND tx_dlf_metadata.pid='.intval($pid).tx_dlf_helper::whereClause('tx_dlf_metadata'),
1591
            '',
1592
            '',
1593
            ''
1594
        );
1595
1596
        while ($resArray = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($result)) {
1597
1598
            if (!empty($metadata[$resArray['index_name']])) {
1599
1600
                if ($resArray['is_listed']) {
1601
1602
                    $listed[$resArray['index_name']] = $metadata[$resArray['index_name']];
1603
1604
                }
1605
1606
                if ($resArray['is_sortable']) {
1607
1608
                    $sortable[$resArray['index_name']] = $metadata[$resArray['index_name']][0];
1609
1610
                }
1611
1612
            }
1613
1614
        }
1615
1616
        // Fill data array.
1617
        $data['tx_dlf_documents'][$this->uid] = array (
0 ignored issues
show
Comprehensibility Best Practice introduced by
$data was never initialized. Although not strictly required by PHP, it is generally a good practice to add $data = array(); before regardless.
Loading history...
1618
            'pid' => $pid,
1619
            $GLOBALS['TCA']['tx_dlf_documents']['ctrl']['enablecolumns']['starttime'] => 0,
1620
            $GLOBALS['TCA']['tx_dlf_documents']['ctrl']['enablecolumns']['endtime'] => 0,
1621
            'prod_id' => $metadata['prod_id'][0],
1622
            'location' => $this->location,
1623
            'record_id' => $metadata['record_id'][0],
1624
            'opac_id' => $metadata['opac_id'][0],
1625
            'union_id' => $metadata['union_id'][0],
1626
            'urn' => $metadata['urn'][0],
1627
            'purl' => $metadata['purl'][0],
1628
            'title' => $metadata['title'][0],
1629
            'title_sorting' => $metadata['title_sorting'][0],
1630
            'author' => implode('; ', $metadata['author']),
1631
            'year' => implode('; ', $metadata['year']),
1632
            'place' => implode('; ', $metadata['place']),
1633
            'thumbnail' => $this->_getThumbnail(TRUE),
1634
            'metadata' => serialize($listed),
1635
            'metadata_sorting' => serialize($sortable),
1636
            'structure' => $metadata['type'][0],
1637
            'partof' => $partof,
1638
            'volume' => $metadata['volume'][0],
1639
            'volume_sorting' => $metadata['volume_sorting'][0],
1640
            'collections' => $metadata['collection'],
1641
            'owner' => $metadata['owner'][0],
1642
            'solrcore' => $core,
1643
            'status' => 0,
1644
        );
1645
1646
        // Unhide hidden documents.
1647
        if (!empty($conf['unhideOnIndex'])) {
1648
1649
            $data['tx_dlf_documents'][$this->uid][$GLOBALS['TCA']['tx_dlf_documents']['ctrl']['enablecolumns']['disabled']] = 0;
1650
1651
        }
1652
1653
        // Process data.
1654
        $newIds = tx_dlf_helper::processDB($data);
1655
1656
        // Replace placeholder with actual UID.
1657
        if (strpos($this->uid, 'NEW') === 0) {
1658
1659
            $this->uid = $newIds[$this->uid];
1660
1661
            $this->pid = $pid;
1662
1663
            $this->parentId = $partof;
1664
1665
        }
1666
1667
        if (!defined('TYPO3_cliMode')) {
1668
1669
            $message = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance(
1670
                'TYPO3\\CMS\\Core\\Messaging\\FlashMessage',
1671
                htmlspecialchars(sprintf(tx_dlf_helper::getLL('flash.documentSaved'), $metadata['title'][0], $this->uid)),
1672
                tx_dlf_helper::getLL('flash.done', TRUE),
1673
                \TYPO3\CMS\Core\Messaging\FlashMessage::OK,
1674
                TRUE
1675
            );
1676
1677
            tx_dlf_helper::addMessage($message);
1678
1679
        }
1680
1681
        // Add document to index.
1682
        if ($core) {
1683
1684
            tx_dlf_indexing::add($this, $core);
1685
1686
        } else {
1687
1688
            if (TYPO3_DLOG) {
1689
1690
                \TYPO3\CMS\Core\Utility\GeneralUtility::devLog('[tx_dlf_document->save('.$_pid.', '.$_core.')] Invalid UID "'.$core.'" for Solr core', self::$extKey, SYSLOG_SEVERITY_NOTICE);
0 ignored issues
show
Bug introduced by
The constant SYSLOG_SEVERITY_NOTICE was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
1691
1692
            }
1693
1694
        }
1695
1696
        return TRUE;
1697
1698
    }
1699
1700
    /**
1701
     * This returns $this->cPid via __get()
1702
     *
1703
     * @access	protected
1704
     *
1705
     * @return	integer		The PID of the metadata definitions
1706
     */
1707
    protected function _getCPid() {
1708
1709
        return $this->cPid;
1710
1711
    }
1712
1713
    /**
1714
     * This builds an array of the document's dmdSecs
1715
     *
1716
     * @access	protected
1717
     *
1718
     * @return	array		Array of dmdSecs with their IDs as array key
1719
     */
1720
    protected function _getDmdSec() {
1721
1722
        if (!$this->dmdSecLoaded) {
1723
1724
            // Get available data formats.
1725
            $this->loadFormats();
1726
1727
            // Get dmdSec nodes from METS.
1728
            $dmdIds = $this->mets->xpath('./mets:dmdSec/@ID');
1729
1730
            foreach ($dmdIds as $dmdId) {
1731
1732
                if ($type = $this->mets->xpath('./mets:dmdSec[@ID="'.(string) $dmdId.'"]/mets:mdWrap[not(@MDTYPE="OTHER")]/@MDTYPE')) {
1733
1734
                    if (!empty($this->formats[(string) $type[0]])) {
1735
1736
                        $type = (string) $type[0];
1737
1738
                        $xml = $this->mets->xpath('./mets:dmdSec[@ID="'.(string) $dmdId.'"]/mets:mdWrap[@MDTYPE="'.$type.'"]/mets:xmlData/'.strtolower($type).':'.$this->formats[$type]['rootElement']);
1739
1740
                    }
1741
1742
                } elseif ($type = $this->mets->xpath('./mets:dmdSec[@ID="'.(string) $dmdId.'"]/mets:mdWrap[@MDTYPE="OTHER"]/@OTHERMDTYPE')) {
1743
1744
                    if (!empty($this->formats[(string) $type[0]])) {
1745
1746
                        $type = (string) $type[0];
1747
1748
                        $xml = $this->mets->xpath('./mets:dmdSec[@ID="'.(string) $dmdId.'"]/mets:mdWrap[@MDTYPE="OTHER"][@OTHERMDTYPE="'.$type.'"]/mets:xmlData/'.strtolower($type).':'.$this->formats[$type]['rootElement']);
1749
1750
                    }
1751
1752
                }
1753
1754
                if ($xml) {
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $xml does not seem to be defined for all execution paths leading up to this point.
Loading history...
Bug Best Practice introduced by
The expression $xml of type SimpleXMLElement[] is implicitly converted to a boolean; are you sure this is intended? If so, consider using ! empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
1755
1756
                    $this->dmdSec[(string) $dmdId]['type'] = $type;
1757
1758
                    $this->dmdSec[(string) $dmdId]['xml'] = $xml[0];
1759
1760
                    $this->registerNamespaces($this->dmdSec[(string) $dmdId]['xml']);
1761
1762
                }
1763
1764
            }
1765
1766
            $this->dmdSecLoaded = TRUE;
1767
1768
        }
1769
1770
        return $this->dmdSec;
1771
1772
    }
1773
1774
    /**
1775
     * This builds the file ID -> USE concordance
1776
     *
1777
     * @access	protected
1778
     *
1779
     * @return	array		Array of file use groups with file IDs
1780
     */
1781
    protected function _getFileGrps() {
1782
1783
        if (!$this->fileGrpsLoaded) {
1784
1785
            // Get configured USE attributes.
1786
            $extConf = unserialize($GLOBALS['TYPO3_CONF_VARS']['EXT']['extConf'][self::$extKey]);
1787
1788
            $useGrps = \TYPO3\CMS\Core\Utility\GeneralUtility::trimExplode(',', $extConf['fileGrps']);
1789
1790
            if (!empty($extConf['fileGrpThumbs'])) {
1791
1792
                $useGrps[] = $extConf['fileGrpThumbs'];
1793
1794
            }
1795
1796
            if (!empty($extConf['fileGrpDownload'])) {
1797
1798
                $useGrps[] = $extConf['fileGrpDownload'];
1799
1800
            }
1801
1802
            if (!empty($extConf['fileGrpFulltext'])) {
1803
1804
                $useGrps[] = $extConf['fileGrpFulltext'];
1805
1806
            }
1807
1808
            if (!empty($extConf['fileGrpAudio'])) {
1809
1810
                $useGrps[] = $extConf['fileGrpAudio'];
1811
1812
            }
1813
1814
            // Get all file groups.
1815
            $fileGrps = $this->mets->xpath('./mets:fileSec/mets:fileGrp');
1816
1817
            // Build concordance for configured USE attributes.
1818
            foreach ($fileGrps as $fileGrp) {
1819
1820
                if (in_array((string) $fileGrp['USE'], $useGrps)) {
1821
1822
                    foreach ($fileGrp->children('http://www.loc.gov/METS/')->file as $file) {
1823
1824
                        $this->fileGrps[(string) $file->attributes()->ID] = (string) $fileGrp['USE'];
1825
1826
                    }
1827
1828
                }
1829
1830
            }
1831
1832
            // Are there any fulltext files available?
1833
            if (!empty($extConf['fileGrpFulltext']) && in_array($extConf['fileGrpFulltext'], $this->fileGrps)) {
1834
1835
                $this->hasFulltext = TRUE;
1836
1837
            }
1838
1839
            $this->fileGrpsLoaded = TRUE;
1840
1841
        }
1842
1843
        return $this->fileGrps;
1844
1845
    }
1846
1847
    /**
1848
     * This returns $this->hasFulltext via __get()
1849
     *
1850
     * @access	protected
1851
     *
1852
     * @return	boolean		Are there any fulltext files available?
1853
     */
1854
    protected function _getHasFulltext() {
1855
1856
        // Are the fileGrps already loaded?
1857
        if (!$this->fileGrpsLoaded) {
1858
1859
            $this->_getFileGrps();
1860
1861
        }
1862
1863
        return $this->hasFulltext;
1864
1865
    }
1866
1867
    /**
1868
     * This returns $this->location via __get()
1869
     *
1870
     * @access	protected
1871
     *
1872
     * @return	string		The location of the document
1873
     */
1874
    protected function _getLocation() {
1875
1876
        return $this->location;
1877
1878
    }
1879
1880
    /**
1881
     * This builds an array of the document's metadata
1882
     *
1883
     * @access	protected
1884
     *
1885
     * @return	array		Array of metadata with their corresponding logical structure node ID as key
1886
     */
1887
    protected function _getMetadataArray() {
1888
1889
        // Set metadata definitions' PID.
1890
        $cPid = ($this->cPid ? $this->cPid : $this->pid);
1891
1892
        if (!$cPid) {
1893
1894
            if (TYPO3_DLOG) {
0 ignored issues
show
Bug introduced by
The constant TYPO3_DLOG was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
1895
1896
                \TYPO3\CMS\Core\Utility\GeneralUtility::devLog('[tx_dlf_document->getMetadataArray()] Invalid PID "'.$cPid.'" for metadata definitions', self::$extKey, SYSLOG_SEVERITY_ERROR);
0 ignored issues
show
Bug introduced by
The constant SYSLOG_SEVERITY_ERROR was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
1897
1898
            }
1899
1900
            return array ();
1901
1902
        }
1903
1904
        if (!$this->metadataArrayLoaded || $this->metadataArray[0] != $cPid) {
1905
1906
            // Get all logical structure nodes with metadata.
1907
            if (($ids = $this->mets->xpath('./mets:structMap[@TYPE="LOGICAL"]//mets:div[@DMDID]/@ID'))) {
1908
1909
                foreach ($ids as $id) {
1910
1911
                    $this->metadataArray[(string) $id] = $this->getMetadata((string) $id, $cPid);
1912
1913
                }
1914
1915
            }
1916
1917
            // Set current PID for metadata definitions.
1918
            $this->metadataArray[0] = $cPid;
1919
1920
            $this->metadataArrayLoaded = TRUE;
1921
1922
        }
1923
1924
        return $this->metadataArray;
1925
1926
    }
1927
1928
    /**
1929
     * This returns $this->mets via __get()
1930
     *
1931
     * @access	protected
1932
     *
1933
     * @return	SimpleXMLElement		The XML's METS part as SimpleXMLElement object
1934
     */
1935
    protected function _getMets() {
1936
1937
        return $this->mets;
1938
1939
    }
1940
1941
    /**
1942
     * This returns $this->numPages via __get()
1943
     *
1944
     * @access	protected
1945
     *
1946
     * @return	integer		The total number of pages and/or tracks
1947
     */
1948
    protected function _getNumPages() {
1949
1950
        $this->_getPhysicalStructure();
1951
1952
        return $this->numPages;
1953
1954
    }
1955
1956
    /**
1957
     * This returns $this->parentId via __get()
1958
     *
1959
     * @access	protected
1960
     *
1961
     * @return	integer		The UID of the parent document or zero if not applicable
1962
     */
1963
    protected function _getParentId() {
1964
1965
        return $this->parentId;
1966
1967
    }
1968
1969
    /**
1970
     * This builds an array of the document's physical structure
1971
     *
1972
     * @access	protected
1973
     *
1974
     * @return	array		Array of physical elements' id, type, label and file representations ordered by @ORDER attribute
1975
     */
1976
    protected function _getPhysicalStructure() {
1977
1978
        // Is there no physical structure array yet?
1979
        if (!$this->physicalStructureLoaded) {
1980
1981
            // Does the document have a structMap node of type "PHYSICAL"?
1982
            $elementNodes = $this->mets->xpath('./mets:structMap[@TYPE="PHYSICAL"]/mets:div[@TYPE="physSequence"]/mets:div');
1983
1984
            if ($elementNodes) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $elementNodes of type SimpleXMLElement[] is implicitly converted to a boolean; are you sure this is intended? If so, consider using ! empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
1985
1986
                // Get file groups.
1987
                $fileUse = $this->_getFileGrps();
1988
1989
                // Get the physical sequence's metadata.
1990
                $physNode = $this->mets->xpath('./mets:structMap[@TYPE="PHYSICAL"]/mets:div[@TYPE="physSequence"]');
1991
1992
                $physSeq[0] = (string) $physNode[0]['ID'];
0 ignored issues
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...
1993
1994
                $this->physicalStructureInfo[$physSeq[0]]['id'] = $physNode[0]['ID'];
1995
1996
                $this->physicalStructureInfo[$physSeq[0]]['dmdId'] = (isset($physNode[0]['DMDID']) ? (string) $physNode[0]['DMDID'] : '');
1997
1998
                $this->physicalStructureInfo[$physSeq[0]]['label'] = (isset($physNode[0]['LABEL']) ? (string) $physNode[0]['LABEL'] : '');
1999
2000
                $this->physicalStructureInfo[$physSeq[0]]['orderlabel'] = (isset($physNode[0]['ORDERLABEL']) ? (string) $physNode[0]['ORDERLABEL'] : '');
2001
2002
                $this->physicalStructureInfo[$physSeq[0]]['type'] = (string) $physNode[0]['TYPE'];
2003
2004
                $this->physicalStructureInfo[$physSeq[0]]['contentIds'] = (isset($physNode[0]['CONTENTIDS']) ? (string) $physNode[0]['CONTENTIDS'] : '');
2005
2006
                // Get the file representations from fileSec node.
2007
                foreach ($physNode[0]->children('http://www.loc.gov/METS/')->fptr as $fptr) {
2008
2009
                    // Check if file has valid @USE attribute.
2010
                    if (!empty($fileUse[(string) $fptr->attributes()->FILEID])) {
2011
2012
                        $this->physicalStructureInfo[$physSeq[0]]['files'][$fileUse[(string) $fptr->attributes()->FILEID]] = (string) $fptr->attributes()->FILEID;
2013
2014
                    }
2015
2016
                }
2017
2018
                // Build the physical elements' array from the physical structMap node.
2019
                foreach ($elementNodes as $elementNode) {
2020
2021
                    $elements[(int) $elementNode['ORDER']] = (string) $elementNode['ID'];
2022
2023
                    $this->physicalStructureInfo[$elements[(int) $elementNode['ORDER']]]['id'] = $elementNode['ID'];
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $elements seems to be defined later in this foreach loop on line 2021. Are you sure it is defined here?
Loading history...
2024
2025
                    $this->physicalStructureInfo[$elements[(int) $elementNode['ORDER']]]['dmdId'] = (isset($elementNode['DMDID']) ? (string) $elementNode['DMDID'] : '');
2026
2027
                    $this->physicalStructureInfo[$elements[(int) $elementNode['ORDER']]]['label'] = (isset($elementNode['LABEL']) ? (string) $elementNode['LABEL'] : '');
2028
2029
                    $this->physicalStructureInfo[$elements[(int) $elementNode['ORDER']]]['orderlabel'] = (isset($elementNode['ORDERLABEL']) ? (string) $elementNode['ORDERLABEL'] : '');
2030
2031
                    $this->physicalStructureInfo[$elements[(int) $elementNode['ORDER']]]['type'] = (string) $elementNode['TYPE'];
2032
2033
                    $this->physicalStructureInfo[$elements[(int) $elementNode['ORDER']]]['contentIds'] = (isset($elementNode['CONTENTIDS']) ? (string) $elementNode['CONTENTIDS'] : '');
2034
2035
                    // Get the file representations from fileSec node.
2036
                    foreach ($elementNode->children('http://www.loc.gov/METS/')->fptr as $fptr) {
2037
2038
                        // Check if file has valid @USE attribute.
2039
                        if (!empty($fileUse[(string) $fptr->attributes()->FILEID])) {
2040
2041
                            $this->physicalStructureInfo[$elements[(int) $elementNode['ORDER']]]['files'][$fileUse[(string) $fptr->attributes()->FILEID]] = (string) $fptr->attributes()->FILEID;
2042
2043
                        }
2044
2045
                    }
2046
2047
                }
2048
2049
                // Sort array by keys (= @ORDER).
2050
                if (ksort($elements)) {
2051
2052
                    // Set total number of pages/tracks.
2053
                    $this->numPages = count($elements);
2054
2055
                    // Merge and re-index the array to get nice numeric indexes.
2056
                    $this->physicalStructure = array_merge($physSeq, $elements);
2057
2058
                }
2059
2060
            }
2061
2062
            $this->physicalStructureLoaded = TRUE;
2063
2064
        }
2065
2066
        return $this->physicalStructure;
2067
2068
    }
2069
2070
    /**
2071
     * This gives an array of the document's physical structure metadata
2072
     *
2073
     * @access	protected
2074
     *
2075
     * @return	array		Array of elements' type, label and file representations ordered by @ID attribute
2076
     */
2077
    protected function _getPhysicalStructureInfo() {
2078
2079
        // Is there no physical structure array yet?
2080
        if (!$this->physicalStructureLoaded) {
2081
2082
            // Build physical structure array.
2083
            $this->_getPhysicalStructure();
2084
2085
        }
2086
2087
        return $this->physicalStructureInfo;
2088
2089
    }
2090
2091
    /**
2092
     * This returns $this->pid via __get()
2093
     *
2094
     * @access	protected
2095
     *
2096
     * @return	integer		The PID of the document or zero if not in database
2097
     */
2098
    protected function _getPid() {
2099
2100
        return $this->pid;
2101
2102
    }
2103
2104
    /**
2105
     * This returns $this->ready via __get()
2106
     *
2107
     * @access	protected
2108
     *
2109
     * @return	boolean		Is the document instantiated successfully?
2110
     */
2111
    protected function _getReady() {
2112
2113
        return $this->ready;
2114
2115
    }
2116
2117
    /**
2118
     * This returns $this->recordId via __get()
2119
     *
2120
     * @access	protected
2121
     *
2122
     * @return	mixed		The METS file's record identifier
2123
     */
2124
    protected function _getRecordId() {
2125
2126
        return $this->recordId;
2127
2128
    }
2129
2130
    /**
2131
     * This returns $this->rootId via __get()
2132
     *
2133
     * @access	protected
2134
     *
2135
     * @return	integer		The UID of the root document or zero if not applicable
2136
     */
2137
    protected function _getRootId() {
2138
2139
        if (!$this->rootIdLoaded) {
2140
2141
            if ($this->parentId) {
2142
2143
                $parent = self::getInstance($this->parentId, $this->pid);
2144
2145
                $this->rootId = $parent->rootId;
2146
2147
            }
2148
2149
            $this->rootIdLoaded = TRUE;
2150
2151
        }
2152
2153
        return $this->rootId;
2154
2155
    }
2156
2157
    /**
2158
     * This returns the smLinks between logical and physical structMap
2159
     *
2160
     * @access	protected
2161
     *
2162
     * @return	array		The links between logical and physical nodes
2163
     */
2164
    protected function _getSmLinks() {
2165
2166
        if (!$this->smLinksLoaded) {
2167
2168
            $smLinks = $this->mets->xpath('./mets:structLink/mets:smLink');
2169
2170
            foreach ($smLinks as $smLink) {
2171
2172
                $this->smLinks['l2p'][(string) $smLink->attributes('http://www.w3.org/1999/xlink')->from][] = (string) $smLink->attributes('http://www.w3.org/1999/xlink')->to;
2173
2174
                $this->smLinks['p2l'][(string) $smLink->attributes('http://www.w3.org/1999/xlink')->to][] = (string) $smLink->attributes('http://www.w3.org/1999/xlink')->from;
2175
2176
            }
2177
2178
            $this->smLinksLoaded = TRUE;
2179
2180
        }
2181
2182
        return $this->smLinks;
2183
2184
    }
2185
2186
    /**
2187
     * This builds an array of the document's logical structure
2188
     *
2189
     * @access	protected
2190
     *
2191
     * @return	array		Array of structure nodes' id, label, type and physical page indexes/mptr link with original hierarchy preserved
2192
     */
2193
    protected function _getTableOfContents() {
2194
2195
        // Is there no logical structure array yet?
2196
        if (!$this->tableOfContentsLoaded) {
2197
2198
            // Get all logical structures.
2199
            $this->getLogicalStructure('', TRUE);
2200
2201
            $this->tableOfContentsLoaded = TRUE;
2202
2203
        }
2204
2205
        return $this->tableOfContents;
2206
2207
    }
2208
2209
    /**
2210
     * This returns the document's thumbnail location
2211
     *
2212
     * @access	protected
2213
     *
2214
     * @param	boolean		$forceReload: Force reloading the thumbnail instead of returning the cached value
2215
     *
2216
     * @return	string		The document's thumbnail location
2217
     */
2218
    protected function _getThumbnail($forceReload = FALSE) {
2219
2220
        if (!$this->thumbnailLoaded || $forceReload) {
2221
2222
            // Retain current PID.
2223
            $cPid = ($this->cPid ? $this->cPid : $this->pid);
2224
2225
            if (!$cPid) {
2226
2227
                if (TYPO3_DLOG) {
0 ignored issues
show
Bug introduced by
The constant TYPO3_DLOG was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
2228
2229
                    \TYPO3\CMS\Core\Utility\GeneralUtility::devLog('[tx_dlf_document->_getThumbnail()] Invalid PID "'.$cPid.'" for structure definitions', self::$extKey, SYSLOG_SEVERITY_ERROR);
0 ignored issues
show
Bug introduced by
The constant SYSLOG_SEVERITY_ERROR was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
2230
2231
                }
2232
2233
                $this->thumbnailLoaded = TRUE;
2234
2235
                return $this->thumbnail;
2236
2237
            }
2238
2239
            // Load extension configuration.
2240
            $extConf = unserialize($GLOBALS['TYPO3_CONF_VARS']['EXT']['extConf'][self::$extKey]);
2241
2242
            if (empty($extConf['fileGrpThumbs'])) {
2243
2244
                if (TYPO3_DLOG) {
2245
2246
                    \TYPO3\CMS\Core\Utility\GeneralUtility::devLog('[tx_dlf_document->_getThumbnail()] No fileGrp for thumbnails specified', self::$extKey, SYSLOG_SEVERITY_WARNING);
0 ignored issues
show
Bug introduced by
The constant SYSLOG_SEVERITY_WARNING was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
2247
2248
                }
2249
2250
                $this->thumbnailLoaded = TRUE;
2251
2252
                return $this->thumbnail;
2253
2254
            }
2255
2256
            $strctId = $this->_getToplevelId();
2257
2258
            $metadata = $this->getTitledata($cPid);
2259
2260
            // Get structure element to get thumbnail from.
2261
            $result = $GLOBALS['TYPO3_DB']->exec_SELECTquery(
2262
                'tx_dlf_structures.thumbnail AS thumbnail',
2263
                'tx_dlf_structures',
2264
                'tx_dlf_structures.pid='.intval($cPid).' AND tx_dlf_structures.index_name='.$GLOBALS['TYPO3_DB']->fullQuoteStr($metadata['type'][0], 'tx_dlf_structures').tx_dlf_helper::whereClause('tx_dlf_structures'),
2265
                '',
2266
                '',
2267
                '1'
2268
            );
2269
2270
            if ($GLOBALS['TYPO3_DB']->sql_num_rows($result) > 0) {
2271
2272
                $resArray = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($result);
2273
2274
                // Get desired thumbnail structure if not the toplevel structure itself.
2275
                if (!empty($resArray['thumbnail'])) {
2276
2277
                    $strctType = tx_dlf_helper::getIndexName($resArray['thumbnail'], 'tx_dlf_structures', $cPid);
2278
2279
                    // Check if this document has a structure element of the desired type.
2280
                    $strctIds = $this->mets->xpath('./mets:structMap[@TYPE="LOGICAL"]//mets:div[@TYPE="'.$strctType.'"]/@ID');
2281
2282
                    if (!empty($strctIds)) {
2283
2284
                        $strctId = (string) $strctIds[0];
2285
2286
                    }
2287
2288
                }
2289
2290
                // Load smLinks.
2291
                $this->_getSmLinks();
2292
2293
                // Get thumbnail location.
2294
                if ($this->_getPhysicalStructure() && !empty($this->smLinks['l2p'][$strctId])) {
2295
2296
                    $this->thumbnail = $this->getFileLocation($this->physicalStructureInfo[$this->smLinks['l2p'][$strctId][0]]['files'][$extConf['fileGrpThumbs']]);
2297
2298
                } else {
2299
2300
                    $this->thumbnail = $this->getFileLocation($this->physicalStructureInfo[$this->physicalStructure[1]]['files'][$extConf['fileGrpThumbs']]);
2301
2302
                }
2303
2304
            } elseif (TYPO3_DLOG) {
2305
2306
                \TYPO3\CMS\Core\Utility\GeneralUtility::devLog('[tx_dlf_document->_getThumbnail()] No structure of type "'.$metadata['type'][0].'" found in database', self::$extKey, SYSLOG_SEVERITY_ERROR);
2307
2308
            }
2309
2310
            $this->thumbnailLoaded = TRUE;
2311
2312
        }
2313
2314
        return $this->thumbnail;
2315
2316
    }
2317
2318
    /**
2319
     * This returns the ID of the toplevel logical structure node
2320
     *
2321
     * @access	protected
2322
     *
2323
     * @return	string		The logical structure node's ID
2324
     */
2325
    protected function _getToplevelId() {
2326
2327
        if (empty($this->toplevelId)) {
2328
2329
            // Get all logical structure nodes with metadata, but without associated METS-Pointers.
2330
            if (($divs = $this->mets->xpath('./mets:structMap[@TYPE="LOGICAL"]//mets:div[@DMDID and not(./mets:mptr)]'))) {
2331
2332
                // Load smLinks.
2333
                $this->_getSmLinks();
2334
2335
                foreach ($divs as $div) {
2336
2337
                    $id = (string) $div['ID'];
2338
2339
                    // Are there physical structure nodes for this logical structure?
2340
                    if (array_key_exists($id, $this->smLinks['l2p'])) {
2341
2342
                        // Yes. That's what we're looking for.
2343
                        $this->toplevelId = $id;
2344
2345
                        break;
2346
2347
                    } elseif (empty($this->toplevelId)) {
2348
2349
                        // No. Remember this anyway, but keep looking for a better one.
2350
                        $this->toplevelId = $id;
2351
2352
                    }
2353
2354
                }
2355
2356
            }
2357
2358
        }
2359
2360
        return $this->toplevelId;
2361
2362
    }
2363
2364
    /**
2365
     * This returns $this->uid via __get()
2366
     *
2367
     * @access	protected
2368
     *
2369
     * @return	mixed		The UID or the URL of the document
2370
     */
2371
    protected function _getUid() {
2372
2373
        return $this->uid;
2374
2375
    }
2376
2377
    /**
2378
     * This sets $this->cPid via __set()
2379
     *
2380
     * @access	protected
2381
     *
2382
     * @param	integer		$value: The new PID for the metadata definitions
2383
     *
2384
     * @return	void
2385
     */
2386
    protected function _setCPid($value) {
2387
2388
        $this->cPid = max(intval($value), 0);
2389
2390
    }
2391
2392
    /**
2393
     * This magic method is invoked each time a clone is called on the object variable
2394
     * (This method is defined as private/protected because singleton objects should not be cloned)
2395
     *
2396
     * @access	protected
2397
     *
2398
     * @return	void
2399
     */
2400
    protected function __clone() {}
2401
2402
    /**
2403
     * This is a singleton class, thus the constructor should be private/protected
2404
     *
2405
     * @access	protected
2406
     *
2407
     * @param	integer		$uid: The UID of the document to parse or URL to XML file
2408
     * @param	integer		$pid: If > 0, then only document with this PID gets loaded
2409
     *
2410
     * @return	void
2411
     */
2412
    protected function __construct($uid, $pid) {
2413
2414
        // Prepare to check database for the requested document.
2415
        if (\TYPO3\CMS\Core\Utility\MathUtility::canBeInterpretedAsInteger($uid)) {
0 ignored issues
show
Bug introduced by
The type TYPO3\CMS\Core\Utility\MathUtility 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...
2416
2417
            $whereClause = 'tx_dlf_documents.uid='.intval($uid).tx_dlf_helper::whereClause('tx_dlf_documents');
2418
2419
        } else {
2420
2421
            // Cast to string for safety reasons.
2422
            $location = (string) $uid;
2423
2424
            // Try to load METS file.
2425
            if (\TYPO3\CMS\Core\Utility\GeneralUtility::isValidUrl($location) && $this->load($location)) {
2426
2427
                // Initialize core METS object.
2428
                $this->init();
2429
2430
                if ($this->mets !== NULL) {
2431
2432
                    // Check for METS object @ID.
2433
                    if (!empty($this->mets['OBJID'])) {
2434
2435
                        $this->recordId = (string) $this->mets['OBJID'];
2436
2437
                    }
2438
2439
                    // Get hook objects.
2440
                    $hookObjects = tx_dlf_helper::getHookObjects('common/class.tx_dlf_document.php');
2441
2442
                    // Apply hooks.
2443
                    foreach ($hookObjects as $hookObj) {
2444
2445
                        if (method_exists($hookObj, 'construct_postProcessRecordId')) {
2446
2447
                            $hookObj->construct_postProcessRecordId($this->xml, $this->recordId);
2448
2449
                        }
2450
2451
                    }
2452
2453
                } else {
2454
2455
                    // No METS part found.
2456
                    return;
2457
2458
                }
2459
2460
            } else {
2461
2462
                // Loading failed.
2463
                return;
2464
2465
            }
2466
2467
            if (!empty($this->recordId)) {
2468
2469
                $whereClause = 'tx_dlf_documents.record_id='.$GLOBALS['TYPO3_DB']->fullQuoteStr($this->recordId, 'tx_dlf_documents').tx_dlf_helper::whereClause('tx_dlf_documents');
2470
2471
            } else {
2472
2473
                // There is no record identifier and there should be no hit in the database.
2474
                $whereClause = '1=-1';
2475
2476
            }
2477
2478
        }
2479
2480
        // Check for PID if needed.
2481
        if ($pid) {
2482
2483
            $whereClause .= ' AND tx_dlf_documents.pid='.intval($pid);
2484
2485
        }
2486
2487
        // Get document PID and location from database.
2488
        $result = $GLOBALS['TYPO3_DB']->exec_SELECTquery(
2489
            'tx_dlf_documents.uid AS uid,tx_dlf_documents.pid AS pid,tx_dlf_documents.record_id AS record_id,tx_dlf_documents.partof AS partof,tx_dlf_documents.thumbnail AS thumbnail,tx_dlf_documents.location AS location',
2490
            'tx_dlf_documents',
2491
            $whereClause,
2492
            '',
2493
            '',
2494
            '1'
2495
        );
2496
2497
        if ($GLOBALS['TYPO3_DB']->sql_num_rows($result) > 0) {
2498
2499
            list ($this->uid, $this->pid, $this->recordId, $this->parentId, $this->thumbnail, $this->location) = $GLOBALS['TYPO3_DB']->sql_fetch_row($result);
2500
2501
            $this->thumbnailLoaded = TRUE;
2502
2503
            // Load XML file if necessary...
2504
            if ($this->mets === NULL && $this->load($this->location)) {
2505
2506
                // ...and set some basic properties.
2507
                $this->init();
2508
2509
            }
2510
2511
            // Do we have a METS object now?
2512
            if ($this->mets !== NULL) {
2513
2514
                // Set new location if necessary.
2515
                if (!empty($location)) {
2516
2517
                    $this->location = $location;
2518
2519
                }
2520
2521
                // Document ready!
2522
                $this->ready = TRUE;
2523
2524
            }
2525
2526
        } elseif ($this->mets !== NULL) {
2527
2528
            // Set location as UID for documents not in database.
2529
            $this->uid = $location;
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $location does not seem to be defined for all execution paths leading up to this point.
Loading history...
2530
2531
            $this->location = $location;
2532
2533
            // Document ready!
2534
            $this->ready = TRUE;
2535
2536
        } else {
2537
2538
            if (TYPO3_DLOG) {
0 ignored issues
show
Bug introduced by
The constant TYPO3_DLOG was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
2539
2540
                \TYPO3\CMS\Core\Utility\GeneralUtility::devLog('[tx_dlf_document->__construct('.$uid.', '.$pid.')] No document with UID "'.$uid.'" found or document not accessible', self::$extKey, SYSLOG_SEVERITY_ERROR);
0 ignored issues
show
Bug introduced by
The constant SYSLOG_SEVERITY_ERROR was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
2541
2542
            }
2543
2544
        }
2545
2546
    }
2547
2548
    /**
2549
     * This magic method is called each time an invisible property is referenced from the object
2550
     *
2551
     * @access	public
2552
     *
2553
     * @param	string		$var: Name of variable to get
2554
     *
2555
     * @return	mixed		Value of $this->$var
2556
     */
2557
    public function __get($var) {
2558
2559
        $method = '_get'.ucfirst($var);
2560
2561
        if (!property_exists($this, $var) || !method_exists($this, $method)) {
2562
2563
            if (TYPO3_DLOG) {
0 ignored issues
show
Bug introduced by
The constant TYPO3_DLOG was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
2564
2565
                \TYPO3\CMS\Core\Utility\GeneralUtility::devLog('[tx_dlf_document->__get('.$var.')] There is no getter function for property "'.$var.'"', self::$extKey, SYSLOG_SEVERITY_WARNING);
0 ignored issues
show
Bug introduced by
The constant SYSLOG_SEVERITY_WARNING was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
2566
2567
            }
2568
2569
            return;
2570
2571
        } else {
2572
2573
            return $this->$method();
2574
2575
        }
2576
2577
    }
2578
2579
    /**
2580
     * This magic method is called each time an invisible property is referenced from the object
2581
     *
2582
     * @access	public
2583
     *
2584
     * @param	string		$var: Name of variable to set
2585
     * @param	mixed		$value: New value of variable
2586
     *
2587
     * @return	void
2588
     */
2589
    public function __set($var, $value) {
2590
2591
        $method = '_set'.ucfirst($var);
2592
2593
        if (!property_exists($this, $var) || !method_exists($this, $method)) {
2594
2595
            if (TYPO3_DLOG) {
0 ignored issues
show
Bug introduced by
The constant TYPO3_DLOG was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
2596
2597
                \TYPO3\CMS\Core\Utility\GeneralUtility::devLog('[tx_dlf_document->__set('.$var.', '.$value.')] There is no setter function for property "'.$var.'"', self::$extKey, SYSLOG_SEVERITY_WARNING);
0 ignored issues
show
Bug introduced by
The constant SYSLOG_SEVERITY_WARNING was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
2598
2599
            }
2600
2601
        } else {
2602
2603
            $this->$method($value);
2604
2605
        }
2606
2607
    }
2608
2609
    /**
2610
     * This magic method is executed prior to any serialization of the object
2611
     * @see __wakeup()
2612
     *
2613
     * @access	public
2614
     *
2615
     * @return	array		Properties to be serialized
2616
     */
2617
    public function __sleep() {
2618
2619
        // SimpleXMLElement objects can't be serialized, thus save the XML as string for serialization
2620
        $this->asXML = $this->xml->asXML();
2621
2622
        return array ('uid', 'pid', 'recordId', 'parentId', 'asXML');
2623
2624
    }
2625
2626
    /**
2627
     * This magic method is used for setting a string value for the object
2628
     *
2629
     * @access	public
2630
     *
2631
     * @return	string		String representing the METS object
2632
     */
2633
    public function __toString() {
2634
2635
        $xml = new DOMDocument('1.0', 'utf-8');
2636
2637
        $xml->appendChild($xml->importNode(dom_import_simplexml($this->mets), TRUE));
2638
2639
        $xml->formatOutput = TRUE;
2640
2641
        return $xml->saveXML();
2642
2643
    }
2644
2645
    /**
2646
     * This magic method is executed after the object is deserialized
2647
     * @see __sleep()
2648
     *
2649
     * @access	public
2650
     *
2651
     * @return	void
2652
     */
2653
    public function __wakeup() {
2654
2655
        // Turn off libxml's error logging.
2656
        $libxmlErrors = libxml_use_internal_errors(TRUE);
2657
2658
        // Reload XML from string.
2659
        $xml = @simplexml_load_string($this->asXML);
2660
2661
        // Reset libxml's error logging.
2662
        libxml_use_internal_errors($libxmlErrors);
2663
2664
        if ($xml !== FALSE) {
2665
2666
            $this->asXML = '';
2667
2668
            $this->xml = $xml;
2669
2670
            // Rebuild the unserializable properties.
2671
            $this->init();
2672
2673
        } else {
2674
2675
            if (TYPO3_DLOG) {
0 ignored issues
show
Bug introduced by
The constant TYPO3_DLOG was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
2676
2677
                \TYPO3\CMS\Core\Utility\GeneralUtility::devLog('[tx_dlf_document->__wakeup()] Could not load XML after deserialization', self::$extKey, SYSLOG_SEVERITY_ERROR);
0 ignored issues
show
Bug introduced by
The constant SYSLOG_SEVERITY_ERROR was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
2678
2679
            }
2680
2681
        }
2682
2683
    }
2684
2685
}
2686