Scrutinizer GitHub App not installed

We could not synchronize checks via GitHub's checks API since Scrutinizer's GitHub App is not installed for this repository.

Install GitHub App

GitHub Access Token became invalid

It seems like the GitHub access token used for retrieving details about this repository from GitHub became invalid. This might prevent certain types of inspections from being run (in particular, everything related to pull requests).
Please ask an admin of your repository to re-new the access token on this website.
Passed
Push — master ( 4dcf02...06ff64 )
by Sebastian
28:47 queued 11:26
created

tx_dlf_document::getRawText()   C

Complexity

Conditions 11
Paths 10

Size

Total Lines 99
Code Lines 33

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
c 0
b 0
f 0
dl 0
loc 99
rs 5.2653
cc 11
eloc 33
nc 10
nop 1

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
     * This holds the documents' raw text pages with their corresponding structMap//div's ID as array key
222
     *
223
     * @var	array
224
     * @access protected
225
     */
226
    protected $rawTextArray = array ();
227
228
    /**
229
     * Is the document instantiated successfully?
230
     *
231
     * @var	boolean
232
     * @access protected
233
     */
234
    protected $ready = FALSE;
235
236
    /**
237
     * The METS file's record identifier
238
     *
239
     * @var	string
240
     * @access protected
241
     */
242
    protected $recordId;
243
244
    /**
245
     * This holds the singleton object of the document
246
     *
247
     * @var	array (tx_dlf_document)
248
     * @access protected
249
     */
250
    protected static $registry = array ();
251
252
    /**
253
     * This holds the UID of the root document or zero if not multi-volumed
254
     *
255
     * @var	integer
256
     * @access protected
257
     */
258
    protected $rootId = 0;
259
260
    /**
261
     * Is the root id loaded?
262
     * @see $rootId
263
     *
264
     * @var	boolean
265
     * @access protected
266
     */
267
    protected $rootIdLoaded = FALSE;
268
269
    /**
270
     * This holds the smLinks between logical and physical structMap
271
     *
272
     * @var	array
273
     * @access protected
274
     */
275
    protected $smLinks = array ('l2p' => array (), 'p2l' => array ());
276
277
    /**
278
     * Are the smLinks loaded?
279
     * @see $smLinks
280
     *
281
     * @var	boolean
282
     * @access protected
283
     */
284
    protected $smLinksLoaded = FALSE;
285
286
    /**
287
     * This holds the logical structure
288
     *
289
     * @var	array
290
     * @access protected
291
     */
292
    protected $tableOfContents = array ();
293
294
    /**
295
     * Is the table of contents loaded?
296
     * @see $tableOfContents
297
     *
298
     * @var	boolean
299
     * @access protected
300
     */
301
    protected $tableOfContentsLoaded = FALSE;
302
303
    /**
304
     * This holds the document's thumbnail location.
305
     *
306
     * @var	string
307
     * @access protected
308
     */
309
    protected $thumbnail = '';
310
311
    /**
312
     * Is the document's thumbnail location loaded?
313
     * @see $thumbnail
314
     *
315
     * @var	boolean
316
     * @access protected
317
     */
318
    protected $thumbnailLoaded = FALSE;
319
320
    /**
321
     * This holds the toplevel structure's @ID
322
     *
323
     * @var	string
324
     * @access protected
325
     */
326
    protected $toplevelId = '';
327
328
    /**
329
     * This holds the UID or the URL of the document
330
     *
331
     * @var	mixed
332
     * @access protected
333
     */
334
    protected $uid = 0;
335
336
    /**
337
     * This holds the whole XML file as SimpleXMLElement object
338
     *
339
     * @var	SimpleXMLElement
340
     * @access protected
341
     */
342
    protected $xml;
343
344
    /**
345
     * This clears the static registry to prevent memory exhaustion
346
     *
347
     * @access	public
348
     *
349
     * @return	void
350
     */
351
    public static function clearRegistry() {
352
353
        // Reset registry array.
354
        self::$registry = array ();
355
356
    }
357
358
    /**
359
     * This gets the location of a file representing a physical page or track
360
     *
361
     * @access	public
362
     *
363
     * @param	string		$id: The @ID attribute of the file node
364
     *
365
     * @return	string		The file's location as URL
366
     */
367
    public function getFileLocation($id) {
368
369
        if (!empty($id) && ($location = $this->mets->xpath('./mets:fileSec/mets:fileGrp/mets:file[@ID="'.$id.'"]/mets:FLocat[@LOCTYPE="URL"]'))) {
370
371
            return (string) $location[0]->attributes('http://www.w3.org/1999/xlink')->href;
372
373
        } else {
374
375
            if (TYPO3_DLOG) {
376
377
                \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...
378
379
            }
380
381
            return '';
382
383
        }
384
385
    }
386
387
    /**
388
     * This gets the MIME type of a file representing a physical page or track
389
     *
390
     * @access	public
391
     *
392
     * @param	string		$id: The @ID attribute of the file node
393
     *
394
     * @return	string		The file's MIME type
395
     */
396
    public function getFileMimeType($id) {
397
398
        if (!empty($id) && ($mimetype = $this->mets->xpath('./mets:fileSec/mets:fileGrp/mets:file[@ID="'.$id.'"]/@MIMETYPE'))) {
399
400
            return (string) $mimetype[0];
401
402
        } else {
403
404
            if (TYPO3_DLOG) {
405
406
                \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...
407
408
            }
409
410
            return '';
411
412
        }
413
414
    }
415
416
    /**
417
     * This is a singleton class, thus an instance must be created by this method
418
     *
419
     * @access	public
420
     *
421
     * @param	mixed		$uid: The unique identifier of the document to parse or URL of XML file
422
     * @param	integer		$pid: If > 0, then only document with this PID gets loaded
423
     * @param	boolean		$forceReload: Force reloading the document instead of returning the cached instance
424
     *
425
     * @return	&tx_dlf_document		Instance of this class
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...
426
     */
427
    public static function &getInstance($uid, $pid = 0, $forceReload = FALSE) {
428
429
        // Sanitize input.
430
        $pid = max(intval($pid), 0);
431
432
        if (!$forceReload) {
433
434
            $regObj = md5($uid);
435
436
            if (is_object(self::$registry[$regObj]) && self::$registry[$regObj] instanceof self) {
437
438
                // Check if instance has given PID.
439
                if (!$pid || !self::$registry[$regObj]->pid || $pid == self::$registry[$regObj]->pid) {
440
441
                    // Return singleton instance if available.
442
                    return self::$registry[$regObj];
443
444
                }
445
446
            } else {
447
448
                // Check the user's session...
449
                $sessionData = tx_dlf_helper::loadFromSession(get_called_class());
450
451
                if (is_object($sessionData[$regObj]) && $sessionData[$regObj] instanceof self) {
452
453
                    // Check if instance has given PID.
454
                    if (!$pid || !$sessionData[$regObj]->pid || $pid == $sessionData[$regObj]->pid) {
455
456
                        // ...and restore registry.
457
                        self::$registry[$regObj] = $sessionData[$regObj];
458
459
                        return self::$registry[$regObj];
460
461
                    }
462
463
                }
464
465
            }
466
467
        }
468
469
        // Create new instance...
470
        $instance = new self($uid, $pid);
471
472
        // ...and save it to registry.
473
        if ($instance->ready) {
474
475
            self::$registry[md5($instance->uid)] = $instance;
476
477
            if ($instance->uid != $instance->location) {
478
479
                self::$registry[md5($instance->location)] = $instance;
480
481
            }
482
483
            // Load extension configuration
484
            $extConf = unserialize($GLOBALS['TYPO3_CONF_VARS']['EXT']['extConf']['dlf']);
485
486
            // Save registry to session if caching is enabled.
487
            if (!empty($extConf['caching'])) {
488
489
                tx_dlf_helper::saveToSession(self::$registry, get_class($instance));
490
491
            }
492
493
        }
494
495
        // Return new instance.
496
        return $instance;
497
498
    }
499
500
    /**
501
     * This gets details about a logical structure element
502
     *
503
     * @access	public
504
     *
505
     * @param	string		$id: The @ID attribute of the logical structure node
506
     * @param	boolean		$recursive: Whether to include the child elements
507
     *
508
     * @return	array		Array of the element's id, label, type and physical page indexes/mptr link
509
     */
510
    public function getLogicalStructure($id, $recursive = FALSE) {
511
512
        $details = array ();
513
514
        // Is the requested logical unit already loaded?
515
        if (!$recursive && !empty($this->logicalUnits[$id])) {
516
517
            // Yes. Return it.
518
            return $this->logicalUnits[$id];
519
520
        } elseif (!empty($id)) {
521
522
            // Get specified logical unit.
523
            $divs = $this->mets->xpath('./mets:structMap[@TYPE="LOGICAL"]//mets:div[@ID="'.$id.'"]');
524
525
        } else {
526
527
            // Get all logical units at top level.
528
            $divs = $this->mets->xpath('./mets:structMap[@TYPE="LOGICAL"]/mets:div');
529
530
        }
531
532
        if (!empty($divs)) {
533
534
            if (!$recursive) {
535
536
                // Get the details for the first xpath hit.
537
                $details = $this->getLogicalStructureInfo($divs[0]);
538
539
            } else {
540
541
                // Walk the logical structure recursively and fill the whole table of contents.
542
                foreach ($divs as $div) {
543
544
                    $this->tableOfContents[] = $this->getLogicalStructureInfo($div, TRUE);
545
546
                }
547
548
            }
549
550
        }
551
552
        return $details;
553
554
    }
555
556
    /**
557
     * This gets details about a logical structure element
558
     *
559
     * @access	protected
560
     *
561
     * @param	SimpleXMLElement		$structure: The logical structure node
562
     * @param	boolean		$recursive: Whether to include the child elements
563
     *
564
     * @return	array		Array of the element's id, label, type and physical page indexes/mptr link
565
     */
566
    protected function getLogicalStructureInfo(SimpleXMLElement $structure, $recursive = FALSE) {
567
568
        // Get attributes.
569
        foreach ($structure->attributes() as $attribute => $value) {
570
571
            $attributes[$attribute] = (string) $value;
572
573
        }
574
575
        // Load plugin configuration.
576
        $extConf = unserialize($GLOBALS['TYPO3_CONF_VARS']['EXT']['extConf'][self::$extKey]);
577
578
        // Extract identity information.
579
        $details = array ();
580
581
        $details['id'] = $attributes['ID'];
1 ignored issue
show
Comprehensibility Best Practice introduced by
The variable $attributes seems to be defined by a foreach iteration on line 569. Are you sure the iterator is never empty, otherwise this variable is not defined?
Loading history...
582
583
        $details['dmdId'] = (isset($attributes['DMDID']) ? $attributes['DMDID'] : '');
584
585
        $details['label'] = (isset($attributes['LABEL']) ? $attributes['LABEL'] : '');
586
587
        $details['orderlabel'] = (isset($attributes['ORDERLABEL']) ? $attributes['ORDERLABEL'] : '');
588
589
        $details['contentIds'] = (isset($attributes['CONTENTIDS']) ? $attributes['CONTENTIDS'] : '');
590
591
        $details['volume'] = '';
592
593
        // Set volume information only if no label is set and this is the toplevel structure element.
594
        if (empty($details['label']) && $details['id'] == $this->_getToplevelId()) {
595
596
            $metadata = $this->getMetadata($details['id']);
597
598
            if (!empty($metadata['volume'][0])) {
599
600
                $details['volume'] = $metadata['volume'][0];
601
602
            }
603
604
        }
605
606
        $details['pagination'] = '';
607
608
        $details['type'] = $attributes['TYPE'];
609
610
        $details['thumbnailId'] = '';
611
612
        // Load smLinks.
613
        $this->_getSmLinks();
614
615
        // Load physical structure.
616
        $this->_getPhysicalStructure();
617
618
        // Get the physical page or external file this structure element is pointing at.
619
        $details['points'] = '';
620
621
        // Is there a mptr node?
622
        if (count($structure->children('http://www.loc.gov/METS/')->mptr)) {
623
624
            // Yes. Get the file reference.
625
            $details['points'] = (string) $structure->children('http://www.loc.gov/METS/')->mptr[0]->attributes('http://www.w3.org/1999/xlink')->href;
626
627
        // Are there any physical elements and is this logical unit linked to at least one of them?
628
        } elseif (!empty($this->physicalStructure) && array_key_exists($details['id'], $this->smLinks['l2p'])) {
629
630
            $details['points'] = max(intval(array_search($this->smLinks['l2p'][$details['id']][0], $this->physicalStructure, TRUE)), 1);
631
632
            if (!empty($this->physicalStructureInfo[$this->smLinks['l2p'][$details['id']][0]]['files'][$extConf['fileGrpThumbs']])) {
633
634
                $details['thumbnailId'] = $this->physicalStructureInfo[$this->smLinks['l2p'][$details['id']][0]]['files'][$extConf['fileGrpThumbs']];
635
636
            }
637
638
            // Get page/track number of the first page/track related to this structure element.
639
            $details['pagination'] = $this->physicalStructureInfo[$this->smLinks['l2p'][$details['id']][0]]['orderlabel'];
640
641
        // Is this the toplevel structure element?
642
        } elseif ($details['id'] == $this->_getToplevelId()) {
643
644
            // Yes. Point to itself.
645
            $details['points'] = 1;
646
647
            if (!empty($this->physicalStructure) && !empty($this->physicalStructureInfo[$this->physicalStructure[1]]['files'][$extConf['fileGrpThumbs']])) {
648
649
                $details['thumbnailId'] = $this->physicalStructureInfo[$this->physicalStructure[1]]['files'][$extConf['fileGrpThumbs']];
650
651
            }
652
653
        }
654
655
        // Get the files this structure element is pointing at.
656
        $details['files'] = array ();
657
658
        $fileUse = $this->_getFileGrps();
659
660
        // Get the file representations from fileSec node.
661
        foreach ($structure->children('http://www.loc.gov/METS/')->fptr as $fptr) {
662
663
            // Check if file has valid @USE attribute.
664
            if (!empty($fileUse[(string) $fptr->attributes()->FILEID])) {
665
666
                $details['files'][$fileUse[(string) $fptr->attributes()->FILEID]] = (string) $fptr->attributes()->FILEID;
667
668
            }
669
670
        }
671
672
        // Keep for later usage.
673
        $this->logicalUnits[$details['id']] = $details;
674
675
        // Walk the structure recursively? And are there any children of the current element?
676
        if ($recursive && count($structure->children('http://www.loc.gov/METS/')->div)) {
677
678
            $details['children'] = array ();
679
680
            foreach ($structure->children('http://www.loc.gov/METS/')->div as $child) {
681
682
                // Repeat for all children.
683
                $details['children'][] = $this->getLogicalStructureInfo($child, TRUE);
684
685
            }
686
687
        }
688
689
        return $details;
690
691
    }
692
693
    /**
694
     * This extracts all the metadata for a logical structure node
695
     *
696
     * @access	public
697
     *
698
     * @param	string		$id: The @ID attribute of the logical structure node
699
     * @param	integer		$cPid: The PID for the metadata definitions
700
     * 						(defaults to $this->cPid or $this->pid)
701
     *
702
     * @return	array		The logical structure node's parsed metadata array
703
     */
704
    public function getMetadata($id, $cPid = 0) {
705
706
        // Save parameter for logging purposes.
707
        $_cPid = $cPid;
708
709
        // Make sure $cPid is a non-negative integer.
710
        $cPid = max(intval($cPid), 0);
711
712
        // If $cPid is not given, try to get it elsewhere.
713
        if (!$cPid && ($this->cPid || $this->pid)) {
714
715
            // Retain current PID.
716
            $cPid = ($this->cPid ? $this->cPid : $this->pid);
717
718
        } elseif (!$cPid) {
719
720
            if (TYPO3_DLOG) {
721
722
                \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...
723
724
            }
725
726
            return array ();
727
728
        }
729
730
        // Get metadata from parsed metadata array if available.
731
        if (!empty($this->metadataArray[$id]) && $this->metadataArray[0] == $cPid) {
732
733
            return $this->metadataArray[$id];
734
735
        }
736
737
        // Initialize metadata array with empty values.
738
        $metadata = array (
739
            'title' => array (),
740
            'title_sorting' => array (),
741
            'author' => array (),
742
            'place' => array (),
743
            'year' => array (),
744
            'prod_id' => array (),
745
            'record_id' => array (),
746
            'opac_id' => array (),
747
            'union_id' => array (),
748
            'urn' => array (),
749
            'purl' => array (),
750
            'type' => array (),
751
            'volume' => array (),
752
            'volume_sorting' => array (),
753
            'collection' => array (),
754
            'owner' => array (),
755
        );
756
757
        // Get the logical structure node's DMDID.
758
        if (!empty($this->logicalUnits[$id])) {
759
760
            $dmdId = $this->logicalUnits[$id]['dmdId'];
761
762
        } else {
763
764
            $dmdId = $this->mets->xpath('./mets:structMap[@TYPE="LOGICAL"]//mets:div[@ID="'.$id.'"]/@DMDID');
765
766
            $dmdId = (string) $dmdId[0];
767
768
        }
769
770
        if (!empty($dmdId)) {
771
772
            // Load available metadata formats and dmdSecs.
773
            $this->loadFormats();
774
775
            $this->_getDmdSec();
776
777
            // Is this metadata format supported?
778
            if (!empty($this->formats[$this->dmdSec[$dmdId]['type']])) {
779
780
                if (!empty($this->formats[$this->dmdSec[$dmdId]['type']]['class'])) {
781
782
                    $class = $this->formats[$this->dmdSec[$dmdId]['type']]['class'];
783
784
                    // Get the metadata from class.
785
                    if (class_exists($class) && ($obj = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance($class)) instanceof tx_dlf_format) {
786
787
                        $obj->extractMetadata($this->dmdSec[$dmdId]['xml'], $metadata);
788
789
                    } else {
790
791
                        if (TYPO3_DLOG) {
792
793
                            \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...
794
795
                        }
796
797
                    }
798
799
                }
800
801
            } else {
802
803
                if (TYPO3_DLOG) {
804
805
                    \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);
806
807
                }
808
809
                return array ();
810
811
            }
812
813
            // Get the structure's type.
814
            if (!empty($this->logicalUnits[$id])) {
815
816
                $metadata['type'] = array ($this->logicalUnits[$id]['type']);
817
818
            } else {
819
820
                $struct = $this->mets->xpath('./mets:structMap[@TYPE="LOGICAL"]//mets:div[@ID="'.$id.'"]/@TYPE');
821
822
                $metadata['type'] = array ((string) $struct[0]);
823
824
            }
825
826
            // Get the additional metadata from database.
827
            $result = $GLOBALS['TYPO3_DB']->exec_SELECTquery(
828
                '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',
829
                'tx_dlf_metadata,tx_dlf_metadataformat,tx_dlf_formats',
830
                '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'),
831
                '',
832
                '',
833
                ''
834
            );
835
836
            // We need a DOMDocument here, because SimpleXML doesn't support XPath functions properly.
837
            $domNode = dom_import_simplexml($this->dmdSec[$dmdId]['xml']);
838
839
            $domXPath = new DOMXPath($domNode->ownerDocument);
840
841
            $this->registerNamespaces($domXPath);
842
843
            // OK, now make the XPath queries.
844
            while ($resArray = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($result)) {
845
846
                // Set metadata field's value(s).
847
                if ($resArray['format'] > 0 && !empty($resArray['xpath']) && ($values = $domXPath->evaluate($resArray['xpath'], $domNode))) {
848
849
                    if ($values instanceof DOMNodeList && $values->length > 0) {
850
851
                        $metadata[$resArray['index_name']] = array ();
852
853
                        foreach ($values as $value) {
854
855
                            $metadata[$resArray['index_name']][] = trim((string) $value->nodeValue);
856
857
                        }
858
859
                    } elseif (!($values instanceof DOMNodeList)) {
860
861
                        $metadata[$resArray['index_name']] = array (trim((string) $values));
862
863
                    }
864
865
                }
866
867
                // Set default value if applicable.
868
                // '!empty($resArray['default_value'])' is not possible, because '0' is a valid default value.
869
                // Setting an empty default value creates a lot of empty fields within the index.
870
                // These empty fields are then shown within the search facets as 'empty'.
871
                if (empty($metadata[$resArray['index_name']][0]) && strlen($resArray['default_value']) > 0) {
872
873
                    $metadata[$resArray['index_name']] = array ($resArray['default_value']);
874
875
                }
876
877
                // Set sorting value if applicable.
878
                if (!empty($metadata[$resArray['index_name']]) && $resArray['is_sortable']) {
879
880
                    if ($resArray['format'] > 0 && !empty($resArray['xpath_sorting']) && ($values = $domXPath->evaluate($resArray['xpath_sorting'], $domNode))) {
881
882
                        if ($values instanceof DOMNodeList && $values->length > 0) {
883
884
                            $metadata[$resArray['index_name'].'_sorting'][0] = trim((string) $values->item(0)->nodeValue);
885
886
                        } elseif (!($values instanceof DOMNodeList)) {
887
888
                            $metadata[$resArray['index_name'].'_sorting'][0] = trim((string) $values);
889
890
                        }
891
892
                    }
893
894
                    if (empty($metadata[$resArray['index_name'].'_sorting'][0])) {
895
896
                        $metadata[$resArray['index_name'].'_sorting'][0] = $metadata[$resArray['index_name']][0];
897
898
                    }
899
900
                }
901
902
            }
903
904
            // Set title to empty string if not present.
905
            if (empty($metadata['title'][0])) {
906
907
                $metadata['title'][0] = '';
908
909
                $metadata['title_sorting'][0] = '';
910
911
            }
912
913
        } else {
914
915
            // There is no dmdSec for this structure node.
916
            return array ();
917
918
        }
919
920
        return $metadata;
921
922
    }
923
924
    /**
925
     * This returns the first corresponding physical page number of a given logical page label
926
     *
927
     * @access	public
928
     *
929
     * @param	string		$logicalPage: The label (or a part of the label) of the logical page
930
     *
931
     * @return	integer		The physical page number
932
     */
933
    public function getPhysicalPage($logicalPage) {
934
935
        if (!empty($this->lastSearchedPhysicalPage['logicalPage']) && $this->lastSearchedPhysicalPage['logicalPage'] == $logicalPage) {
936
937
            return $this->lastSearchedPhysicalPage['physicalPage'];
938
939
        } else {
940
941
            $physicalPage = 0;
942
943
            foreach ($this->physicalStructureInfo as $page) {
944
945
                if (strpos($page['orderlabel'], $logicalPage) !== FALSE) {
946
947
                    $this->lastSearchedPhysicalPage['logicalPage'] = $logicalPage;
948
                    $this->lastSearchedPhysicalPage['physicalPage'] = $physicalPage;
949
950
                    return $physicalPage;
951
952
                }
953
954
                $physicalPage++;
955
956
            }
957
958
        }
959
960
        return 1;
961
962
    }
963
964
    /**
965
     * This extracts the raw text for a physical structure node
966
     *
967
     * @access	public
968
     *
969
     * @param	string		$id: The @ID attribute of the physical structure node
970
     *
971
     * @return	string		The physical structure node's raw text
972
     */
973
    public function getRawText($id) {
974
975
        $rawText = '';
976
977
        // Get text from raw text array if available.
978
        if (!empty($this->rawTextArray[$id])) {
979
980
            return $this->rawTextArray[$id];
981
982
        }
983
984
        // Load fileGrps and check for fulltext files.
985
        $this->_getFileGrps();
986
987
        if ($this->hasFulltext) {
988
989
            // Load available text formats, ...
990
            $this->loadFormats();
991
992
            // ... physical structure ...
993
            $this->_getPhysicalStructure();
994
995
            // ... and extension configuration.
996
            $extConf = unserialize($GLOBALS['TYPO3_CONF_VARS']['EXT']['extConf'][self::$extKey]);
997
998
            if (!empty($this->physicalStructureInfo[$id])) {
999
1000
                // Get fulltext file.
1001
                $file = $this->getFileLocation($this->physicalStructureInfo[$id]['files'][$extConf['fileGrpFulltext']]);
1002
1003
                // Turn off libxml's error logging.
1004
                $libxmlErrors = libxml_use_internal_errors(TRUE);
1005
1006
                // Disables the functionality to allow external entities to be loaded when parsing the XML, must be kept.
1007
                $previousValueOfEntityLoader = libxml_disable_entity_loader(TRUE);
1008
1009
                // Load XML from file.
1010
                $rawTextXml = simplexml_load_string(\TYPO3\CMS\Core\Utility\GeneralUtility::getUrl($file));
0 ignored issues
show
Bug introduced by
It seems like TYPO3\CMS\Core\Utility\G...lUtility::getUrl($file) can also be of type mixed and false; however, parameter $data of simplexml_load_string() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

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

1010
                $rawTextXml = simplexml_load_string(/** @scrutinizer ignore-type */ \TYPO3\CMS\Core\Utility\GeneralUtility::getUrl($file));
Loading history...
1011
1012
                // Reset entity loader setting.
1013
                libxml_disable_entity_loader($previousValueOfEntityLoader);
1014
1015
                // Reset libxml's error logging.
1016
                libxml_use_internal_errors($libxmlErrors);
1017
1018
                // Get the root element's name as text format.
1019
                $textFormat = strtoupper($rawTextXml->getName());
1020
1021
            } else {
1022
1023
                if (TYPO3_DLOG) {
1024
1025
                    \TYPO3\CMS\Core\Utility\GeneralUtility::devLog('[tx_dlf_document->getRawText('.$id.')] Invalid structure node @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...
1026
1027
                }
1028
1029
                return $rawText;
1030
1031
            }
1032
1033
            // Is this text format supported?
1034
            if (!empty($this->formats[$textFormat])) {
1035
1036
                if (!empty($this->formats[$textFormat]['class'])) {
1037
1038
                    $class = $this->formats[$textFormat]['class'];
1039
1040
                    // Get the raw text from class.
1041
                    if (class_exists($class) && ($obj = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance($class)) instanceof tx_dlf_fulltext) {
1042
1043
                        $rawText = $obj->getRawText($rawTextXml);
0 ignored issues
show
Bug introduced by
It seems like $rawTextXml can also be of type false; however, parameter $xml of tx_dlf_fulltext::getRawText() does only seem to accept SimpleXMLElement, maybe add an additional type check? ( Ignorable by Annotation )

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

1043
                        $rawText = $obj->getRawText(/** @scrutinizer ignore-type */ $rawTextXml);
Loading history...
1044
1045
                        $this->rawTextArray[$id] = $rawText;
1046
1047
                    } else {
1048
1049
                        if (TYPO3_DLOG) {
1050
1051
                            \TYPO3\CMS\Core\Utility\GeneralUtility::devLog('[tx_dlf_document->getRawText('.$id.')] Invalid class/method "'.$class.'->getRawText()" for text format "'.$textFormat.'"', self::$extKey, SYSLOG_SEVERITY_WARNING);
1052
1053
                        }
1054
1055
                    }
1056
1057
                }
1058
1059
            } else {
1060
1061
                if (TYPO3_DLOG) {
1062
1063
                    \TYPO3\CMS\Core\Utility\GeneralUtility::devLog('[tx_dlf_document->getRawText('.$id.')] Unsupported text format "'.$textFormat.'" in physical node with @ID "'.$id.'"', self::$extKey, SYSLOG_SEVERITY_WARNING);
1064
1065
                }
1066
1067
            }
1068
1069
        }
1070
1071
        return $rawText;
1072
1073
    }
1074
1075
    /**
1076
     * This determines a title for the given document
1077
     *
1078
     * @access	public
1079
     *
1080
     * @param	integer		$uid: The UID of the document
1081
     * @param	boolean		$recursive: Search superior documents for a title, too?
1082
     *
1083
     * @return	string		The title of the document itself or a parent document
1084
     */
1085
    public static function getTitle($uid, $recursive = FALSE) {
1086
1087
        // Save parameter for logging purposes.
1088
        $_uid = $uid;
1089
1090
        $title = '';
1091
1092
        // Sanitize input.
1093
        $uid = max(intval($uid), 0);
1094
1095
        if ($uid) {
1096
1097
            $result = $GLOBALS['TYPO3_DB']->exec_SELECTquery(
1098
                'tx_dlf_documents.title,tx_dlf_documents.partof',
1099
                'tx_dlf_documents',
1100
                'tx_dlf_documents.uid='.$uid.tx_dlf_helper::whereClause('tx_dlf_documents'),
1101
                '',
1102
                '',
1103
                '1'
1104
            );
1105
1106
            if ($GLOBALS['TYPO3_DB']->sql_num_rows($result)) {
1107
1108
                // Get title information.
1109
                list ($title, $partof) = $GLOBALS['TYPO3_DB']->sql_fetch_row($result);
1110
1111
                // Search parent documents recursively for a title?
1112
                if ($recursive && empty($title) && intval($partof) && $partof != $uid) {
1113
1114
                    $title = self::getTitle($partof, TRUE);
1115
1116
                }
1117
1118
            } else {
1119
1120
                if (TYPO3_DLOG) {
1121
1122
                    \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...
1123
1124
                }
1125
1126
            }
1127
1128
        } else {
1129
1130
            if (TYPO3_DLOG) {
1131
1132
                \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...
1133
1134
            }
1135
1136
        }
1137
1138
        return $title;
1139
1140
    }
1141
1142
    /**
1143
     * This extracts all the metadata for the toplevel logical structure node
1144
     *
1145
     * @access	public
1146
     *
1147
     * @param	integer		$cPid: The PID for the metadata definitions
1148
     *
1149
     * @return	array		The logical structure node's parsed metadata array
1150
     */
1151
    public function getTitledata($cPid = 0) {
1152
1153
        $titledata = $this->getMetadata($this->_getToplevelId(), $cPid);
1154
1155
        // Set record identifier for METS file if not present.
1156
        if (is_array($titledata) && array_key_exists('record_id', $titledata)) {
1157
1158
            if (!empty($this->recordId) && !in_array($this->recordId, $titledata['record_id'])) {
1159
1160
                array_unshift($titledata['record_id'], $this->recordId);
1161
1162
            }
1163
1164
        };
1165
1166
        return $titledata;
1167
1168
    }
1169
1170
    /**
1171
     * This sets some basic class properties
1172
     *
1173
     * @access	protected
1174
     *
1175
     * @return	void
1176
     */
1177
    protected function init() {
1178
1179
        // Get METS node from XML file.
1180
        $this->registerNamespaces($this->xml);
1181
1182
        $mets = $this->xml->xpath('//mets:mets');
1183
1184
        if ($mets) {
1185
1186
            $this->mets = $mets[0];
1187
1188
            // Register namespaces.
1189
            $this->registerNamespaces($this->mets);
1190
1191
        } else {
1192
1193
            if (TYPO3_DLOG) {
1194
1195
                \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...
1196
1197
            }
1198
1199
        }
1200
1201
    }
1202
1203
    /**
1204
     * Load XML file from URL
1205
     *
1206
     * @access	protected
1207
     *
1208
     * @param	string		$location: The URL of the file to load
1209
     *
1210
     * @return	boolean		TRUE on success or FALSE on failure
1211
     */
1212
    protected function load($location) {
1213
1214
        // Load XML file.
1215
        if (\TYPO3\CMS\Core\Utility\GeneralUtility::isValidUrl($location)) {
1216
1217
            // Load extension configuration
1218
            $extConf = unserialize($GLOBALS['TYPO3_CONF_VARS']['EXT']['extConf']['dlf']);
1219
1220
            // Set user-agent to identify self when fetching XML data.
1221
            if (!empty($extConf['useragent'])) {
1222
1223
                @ini_set('user_agent', $extConf['useragent']);
1 ignored issue
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

1223
                /** @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...
1224
1225
            }
1226
1227
            // Turn off libxml's error logging.
1228
            $libxmlErrors = libxml_use_internal_errors(TRUE);
1229
1230
            // Disables the functionality to allow external entities to be loaded when parsing the XML, must be kept
1231
            $previousValueOfEntityLoader = libxml_disable_entity_loader(TRUE);
1232
1233
            // Load XML from file.
1234
            $xml = simplexml_load_string(\TYPO3\CMS\Core\Utility\GeneralUtility::getUrl($location));
0 ignored issues
show
Bug introduced by
It seems like TYPO3\CMS\Core\Utility\G...lity::getUrl($location) can also be of type mixed and false; however, parameter $data of simplexml_load_string() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

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

1234
            $xml = simplexml_load_string(/** @scrutinizer ignore-type */ \TYPO3\CMS\Core\Utility\GeneralUtility::getUrl($location));
Loading history...
1235
1236
            // reset entity loader setting
1237
            libxml_disable_entity_loader($previousValueOfEntityLoader);
1238
1239
            // Reset libxml's error logging.
1240
            libxml_use_internal_errors($libxmlErrors);
1241
1242
            // Set some basic properties.
1243
            if ($xml !== FALSE) {
1244
1245
                $this->xml = $xml;
1246
1247
                return TRUE;
1248
1249
            } else {
1250
1251
                if (TYPO3_DLOG) {
1252
1253
                    \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...
1254
1255
                }
1256
1257
            }
1258
1259
        } else {
1260
1261
            if (TYPO3_DLOG) {
1262
1263
                \TYPO3\CMS\Core\Utility\GeneralUtility::devLog('[tx_dlf_document->load('.$location.')] Invalid file location "'.$location.'" for document loading', self::$extKey, SYSLOG_SEVERITY_ERROR);
1264
1265
            }
1266
1267
        }
1268
1269
        return FALSE;
1270
1271
    }
1272
1273
    /**
1274
     * Register all available data formats
1275
     *
1276
     * @access	protected
1277
     *
1278
     * @return	void
1279
     */
1280
    protected function loadFormats() {
1281
1282
        if (!$this->formatsLoaded) {
1283
1284
            // Get available data formats from database.
1285
            $result = $GLOBALS['TYPO3_DB']->exec_SELECTquery(
1286
                'tx_dlf_formats.type AS type,tx_dlf_formats.root AS root,tx_dlf_formats.namespace AS namespace,tx_dlf_formats.class AS class',
1287
                'tx_dlf_formats',
1288
                'tx_dlf_formats.pid=0'.tx_dlf_helper::whereClause('tx_dlf_formats'),
1289
                '',
1290
                '',
1291
                ''
1292
            );
1293
1294
            while ($resArray = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($result)) {
1295
1296
                // Update format registry.
1297
                $this->formats[$resArray['type']] = array (
1298
                    'rootElement' => $resArray['root'],
1299
                    'namespaceURI' => $resArray['namespace'],
1300
                    'class' => $resArray['class']
1301
                );
1302
1303
            }
1304
1305
            $this->formatsLoaded = TRUE;
1306
1307
        }
1308
1309
    }
1310
1311
    /**
1312
     * Register all available namespaces for a SimpleXMLElement object
1313
     *
1314
     * @access	public
1315
     *
1316
     * @param	SimpleXMLElement|DOMXPath		&$obj: SimpleXMLElement or DOMXPath object
1317
     *
1318
     * @return	void
1319
     */
1320
    public function registerNamespaces(&$obj) {
1321
1322
        $this->loadFormats();
1323
1324
        // Do we have a SimpleXMLElement or DOMXPath object?
1325
        if ($obj instanceof SimpleXMLElement) {
1326
1327
            $method = 'registerXPathNamespace';
1328
1329
        } elseif ($obj instanceof DOMXPath) {
1330
1331
            $method = 'registerNamespace';
1332
1333
        } else {
1334
1335
            if (TYPO3_DLOG) {
1336
1337
                \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...
1338
1339
            }
1340
1341
            return;
1342
1343
        }
1344
1345
        // Register metadata format's namespaces.
1346
        foreach ($this->formats as $enc => $conf) {
1347
1348
            $obj->$method(strtolower($enc), $conf['namespaceURI']);
1349
1350
        }
1351
1352
    }
1353
1354
    /**
1355
     * This saves the document to the database and index
1356
     *
1357
     * @access	public
1358
     *
1359
     * @param	integer		$pid: The PID of the saved record
1360
     * @param	integer		$core: The UID of the Solr core for indexing
1361
     *
1362
     * @return	boolean		TRUE on success or FALSE on failure
1363
     */
1364
    public function save($pid = 0, $core = 0) {
1365
1366
        // Save parameters for logging purposes.
1367
        $_pid = $pid;
1368
1369
        $_core = $core;
1370
1371
        if (TYPO3_MODE !== 'BE') {
1 ignored issue
show
introduced by
The condition TYPO3_MODE !== 'BE' is always false.
Loading history...
1372
1373
            if (TYPO3_DLOG) {
1374
1375
                \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...
1376
1377
            }
1378
1379
            return FALSE;
1380
1381
        }
1382
1383
        // Make sure $pid is a non-negative integer.
1384
        $pid = max(intval($pid), 0);
1385
1386
        // Make sure $core is a non-negative integer.
1387
        $core = max(intval($core), 0);
1388
1389
        // If $pid is not given, try to get it elsewhere.
1390
        if (!$pid && $this->pid) {
1391
1392
            // Retain current PID.
1393
            $pid = $this->pid;
1394
1395
        } elseif (!$pid) {
1396
1397
            if (TYPO3_DLOG) {
1398
1399
                \TYPO3\CMS\Core\Utility\GeneralUtility::devLog('[tx_dlf_document->save('.$_pid.', '.$_core.')] Invalid PID "'.$pid.'" for document saving', self::$extKey, SYSLOG_SEVERITY_ERROR);
1400
1401
            }
1402
1403
            return FALSE;
1404
1405
        }
1406
1407
        // Set PID for metadata definitions.
1408
        $this->cPid = $pid;
1409
1410
        // Set UID placeholder if not updating existing record.
1411
        if ($pid != $this->pid) {
1412
1413
            $this->uid = uniqid('NEW');
1414
1415
        }
1416
1417
        // Get metadata array.
1418
        $metadata = $this->getTitledata($pid);
1419
1420
        // Check for record identifier.
1421
        if (empty($metadata['record_id'][0])) {
1422
1423
            if (TYPO3_DLOG) {
1424
1425
                \TYPO3\CMS\Core\Utility\GeneralUtility::devLog('[tx_dlf_document->save('.$_pid.', '.$_core.')] No record identifier found to avoid duplication', self::$extKey, SYSLOG_SEVERITY_ERROR);
1426
1427
            }
1428
1429
            return FALSE;
1430
1431
        }
1432
1433
        // Load plugin configuration.
1434
        $conf = unserialize($GLOBALS['TYPO3_CONF_VARS']['EXT']['extConf'][self::$extKey]);
1435
1436
        // Get UID for user "_cli_dlf".
1437
        $result = $GLOBALS['TYPO3_DB']->exec_SELECTquery(
1438
            'be_users.uid AS uid',
1439
            'be_users',
1440
            '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'),
1441
            '',
1442
            '',
1443
            '1'
1444
        );
1445
1446
        if ($GLOBALS['TYPO3_DB']->sql_num_rows($result)) {
1447
1448
            list ($be_user) = $GLOBALS['TYPO3_DB']->sql_fetch_row($result);
1449
1450
        } else {
1451
1452
            if (TYPO3_DLOG) {
1453
1454
                \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);
1455
1456
            }
1457
1458
            return FALSE;
1459
1460
        }
1461
1462
        // Get UID for structure type.
1463
        $result = $GLOBALS['TYPO3_DB']->exec_SELECTquery(
1464
            'tx_dlf_structures.uid AS uid',
1465
            'tx_dlf_structures',
1466
            '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'),
1467
            '',
1468
            '',
1469
            '1'
1470
        );
1471
1472
        if ($GLOBALS['TYPO3_DB']->sql_num_rows($result)) {
1473
1474
            list ($structure) = $GLOBALS['TYPO3_DB']->sql_fetch_row($result);
1475
1476
        } else {
1477
1478
            if (TYPO3_DLOG) {
1479
1480
                \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'),
1481
                                            self::$extKey, SYSLOG_SEVERITY_ERROR);
1482
1483
            }
1484
1485
            return FALSE;
1486
1487
        }
1488
1489
        $metadata['type'][0] = $structure;
1490
1491
        // Get UIDs for collections.
1492
        $collections = array ();
1493
1494
        $result = $GLOBALS['TYPO3_DB']->exec_SELECTquery(
1495
            'tx_dlf_collections.index_name AS index_name,tx_dlf_collections.uid AS uid',
1496
            'tx_dlf_collections',
1497
            'tx_dlf_collections.pid='.intval($pid).' AND tx_dlf_collections.sys_language_uid IN (-1,0)'.tx_dlf_helper::whereClause('tx_dlf_collections'),
1498
            '',
1499
            '',
1500
            ''
1501
        );
1502
1503
        for ($i = 0, $j = $GLOBALS['TYPO3_DB']->sql_num_rows($result); $i < $j; $i++) {
1504
1505
            $resArray = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($result);
1506
1507
            $collUid[$resArray['index_name']] = $resArray['uid'];
1508
1509
        }
1510
1511
        foreach ($metadata['collection'] as $collection) {
1512
1513
            if (!empty($collUid[$collection])) {
1514
1515
                // Add existing collection's UID.
1516
                $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...
1517
1518
            } else {
1519
1520
                // Insert new collection.
1521
                $collNewUid = uniqid('NEW');
1522
1523
                $collData['tx_dlf_collections'][$collNewUid] = array (
1524
                    'pid' => $pid,
1525
                    'label' => $collection,
1526
                    'index_name' => $collection,
1527
                    'oai_name' => (!empty($conf['publishNewCollections']) ? $collection : ''),
1528
                    'description' => '',
1529
                    'documents' => 0,
1530
                    'owner' => 0,
1531
                    'status' => 0,
1532
                );
1533
1534
                $substUid = tx_dlf_helper::processDB($collData);
1535
1536
                // Prevent double insertion.
1537
                unset ($collData);
1538
1539
                // Add new collection's UID.
1540
                $collections[] = $substUid[$collNewUid];
1541
1542
                if (!defined('TYPO3_cliMode')) {
1543
1544
                    $message = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance(
1545
                        'TYPO3\\CMS\\Core\\Messaging\\FlashMessage',
1546
                        htmlspecialchars(sprintf(tx_dlf_helper::getLL('flash.newCollection'), $collection, $substUid[$collNewUid])),
1547
                        tx_dlf_helper::getLL('flash.attention', TRUE),
1548
                        \TYPO3\CMS\Core\Messaging\FlashMessage::INFO,
1549
                        TRUE
1550
                    );
1551
1552
                    tx_dlf_helper::addMessage($message);
1553
1554
                }
1555
1556
            }
1557
1558
        }
1559
1560
        // Preserve user-defined collections.
1561
        $result = $GLOBALS['TYPO3_DB']->exec_SELECT_mm_query(
1562
            'tx_dlf_collections.uid AS uid',
1563
            'tx_dlf_documents',
1564
            'tx_dlf_relations',
1565
            'tx_dlf_collections',
1566
            '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'),
1567
            '',
1568
            '',
1569
            ''
1570
        );
1571
1572
        for ($i = 0, $j = $GLOBALS['TYPO3_DB']->sql_num_rows($result); $i < $j; $i++) {
1573
1574
            list ($collections[]) = $GLOBALS['TYPO3_DB']->sql_fetch_row($result);
1575
1576
        }
1577
1578
        $metadata['collection'] = $collections;
1579
1580
        // Get UID for owner.
1581
        $owner = !empty($metadata['owner'][0]) ? $metadata['owner'][0] : 'default';
1582
1583
        $result = $GLOBALS['TYPO3_DB']->exec_SELECTquery(
1584
            'tx_dlf_libraries.uid AS uid',
1585
            'tx_dlf_libraries',
1586
            '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'),
1587
            '',
1588
            '',
1589
            '1'
1590
        );
1591
1592
        if ($GLOBALS['TYPO3_DB']->sql_num_rows($result)) {
1593
1594
            list ($ownerUid) = $GLOBALS['TYPO3_DB']->sql_fetch_row($result);
1595
1596
        } else {
1597
1598
            // Insert new library.
1599
            $libNewUid = uniqid('NEW');
1600
1601
            $libData['tx_dlf_libraries'][$libNewUid] = array (
1 ignored issue
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...
1602
                'pid' => $pid,
1603
                'label' => $owner,
1604
                'index_name' => $owner,
1605
                'website' => '',
1606
                'contact' => '',
1607
                'image' => '',
1608
                'oai_label' => '',
1609
                'oai_base' => '',
1610
                'opac_label' => '',
1611
                'opac_base' => '',
1612
                'union_label' => '',
1613
                'union_base' => '',
1614
            );
1615
1616
            $substUid = tx_dlf_helper::processDB($libData);
1617
1618
            // Add new library's UID.
1619
            $ownerUid = $substUid[$libNewUid];
1620
1621
            if (!defined('TYPO3_cliMode')) {
1622
1623
                $message = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance(
1624
                    'TYPO3\\CMS\\Core\\Messaging\\FlashMessage',
1625
                    htmlspecialchars(sprintf(tx_dlf_helper::getLL('flash.newLibrary'), $owner, $ownerUid)),
1626
                    tx_dlf_helper::getLL('flash.attention', TRUE),
1627
                    \TYPO3\CMS\Core\Messaging\FlashMessage::INFO,
1628
                    TRUE
1629
                );
1630
1631
                tx_dlf_helper::addMessage($message);
1632
1633
            }
1634
1635
        }
1636
1637
        $metadata['owner'][0] = $ownerUid;
1638
1639
        // Get UID of parent document.
1640
        $partof = 0;
1641
1642
        // Get the closest ancestor of the current document which has a MPTR child.
1643
        $parentMptr = $this->mets->xpath('./mets:structMap[@TYPE="LOGICAL"]//mets:div[@ID="'.$this->_getToplevelId().'"]/ancestor::mets:div[./mets:mptr][1]/mets:mptr');
1644
1645
        if (!empty($parentMptr[0])) {
1646
1647
            $parentLocation = (string) $parentMptr[0]->attributes('http://www.w3.org/1999/xlink')->href;
1648
1649
            if ($parentLocation != $this->location) {
1650
1651
                $parentDoc = & tx_dlf_document::getInstance($parentLocation, $pid);
1652
1653
                if ($parentDoc->ready) {
1654
1655
                    if ($parentDoc->pid != $pid) {
1656
1657
                        $parentDoc->save($pid, $core);
1658
1659
                    }
1660
1661
                    $partof = $parentDoc->uid;
1662
1663
                }
1664
1665
            }
1666
1667
        }
1668
1669
        // Use the date of publication or title as alternative sorting metric for parts of multi-part works.
1670
        if (!empty($partof)) {
1671
1672
            if (empty($metadata['volume'][0]) && !empty($metadata['year'][0])) {
1673
1674
                $metadata['volume'] = $metadata['year'];
1675
1676
            }
1677
1678
            if (empty($metadata['volume_sorting'][0])) {
1679
1680
                if (!empty($metadata['year_sorting'][0])) {
1681
1682
                    $metadata['volume_sorting'][0] = $metadata['year_sorting'][0];
1683
1684
                } elseif (!empty($metadata['year'][0])) {
1685
1686
                    $metadata['volume_sorting'][0] = $metadata['year'][0];
1687
1688
                }
1689
1690
            }
1691
1692
            // If volume_sorting is still empty, try to use title_sorting finally (workaround for newspapers)
1693
            if (empty($metadata['volume_sorting'][0])) {
1694
1695
                if (!empty($metadata['title_sorting'][0])) {
1696
1697
                    $metadata['volume_sorting'][0] = $metadata['title_sorting'][0];
1698
1699
                }
1700
            }
1701
1702
        }
1703
1704
        // Get metadata for lists and sorting.
1705
        $listed = array ();
1706
1707
        $sortable = array ();
1708
1709
        $result = $GLOBALS['TYPO3_DB']->exec_SELECTquery(
1710
            'tx_dlf_metadata.index_name AS index_name,tx_dlf_metadata.is_listed AS is_listed,tx_dlf_metadata.is_sortable AS is_sortable',
1711
            'tx_dlf_metadata',
1712
            '(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'),
1713
            '',
1714
            '',
1715
            ''
1716
        );
1717
1718
        while ($resArray = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($result)) {
1719
1720
            if (!empty($metadata[$resArray['index_name']])) {
1721
1722
                if ($resArray['is_listed']) {
1723
1724
                    $listed[$resArray['index_name']] = $metadata[$resArray['index_name']];
1725
1726
                }
1727
1728
                if ($resArray['is_sortable']) {
1729
1730
                    $sortable[$resArray['index_name']] = $metadata[$resArray['index_name']][0];
1731
1732
                }
1733
1734
            }
1735
1736
        }
1737
1738
        // Fill data array.
1739
        $data['tx_dlf_documents'][$this->uid] = array (
1 ignored issue
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...
1740
            'pid' => $pid,
1741
            $GLOBALS['TCA']['tx_dlf_documents']['ctrl']['enablecolumns']['starttime'] => 0,
1742
            $GLOBALS['TCA']['tx_dlf_documents']['ctrl']['enablecolumns']['endtime'] => 0,
1743
            'prod_id' => $metadata['prod_id'][0],
1744
            'location' => $this->location,
1745
            'record_id' => $metadata['record_id'][0],
1746
            'opac_id' => $metadata['opac_id'][0],
1747
            'union_id' => $metadata['union_id'][0],
1748
            'urn' => $metadata['urn'][0],
1749
            'purl' => $metadata['purl'][0],
1750
            'title' => $metadata['title'][0],
1751
            'title_sorting' => $metadata['title_sorting'][0],
1752
            'author' => implode('; ', $metadata['author']),
1753
            'year' => implode('; ', $metadata['year']),
1754
            'place' => implode('; ', $metadata['place']),
1755
            'thumbnail' => $this->_getThumbnail(TRUE),
1756
            'metadata' => serialize($listed),
1757
            'metadata_sorting' => serialize($sortable),
1758
            'structure' => $metadata['type'][0],
1759
            'partof' => $partof,
1760
            'volume' => $metadata['volume'][0],
1761
            'volume_sorting' => $metadata['volume_sorting'][0],
1762
            'collections' => $metadata['collection'],
1763
            'owner' => $metadata['owner'][0],
1764
            'solrcore' => $core,
1765
            'status' => 0,
1766
        );
1767
1768
        // Unhide hidden documents.
1769
        if (!empty($conf['unhideOnIndex'])) {
1770
1771
            $data['tx_dlf_documents'][$this->uid][$GLOBALS['TCA']['tx_dlf_documents']['ctrl']['enablecolumns']['disabled']] = 0;
1772
1773
        }
1774
1775
        // Process data.
1776
        $newIds = tx_dlf_helper::processDB($data);
1777
1778
        // Replace placeholder with actual UID.
1779
        if (strpos($this->uid, 'NEW') === 0) {
1780
1781
            $this->uid = $newIds[$this->uid];
1782
1783
            $this->pid = $pid;
1784
1785
            $this->parentId = $partof;
1786
1787
        }
1788
1789
        if (!defined('TYPO3_cliMode')) {
1790
1791
            $message = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance(
1792
                'TYPO3\\CMS\\Core\\Messaging\\FlashMessage',
1793
                htmlspecialchars(sprintf(tx_dlf_helper::getLL('flash.documentSaved'), $metadata['title'][0], $this->uid)),
1794
                tx_dlf_helper::getLL('flash.done', TRUE),
1795
                \TYPO3\CMS\Core\Messaging\FlashMessage::OK,
1796
                TRUE
1797
            );
1798
1799
            tx_dlf_helper::addMessage($message);
1800
1801
        }
1802
1803
        // Add document to index.
1804
        if ($core) {
1805
1806
            tx_dlf_indexing::add($this, $core);
1807
1808
        } else {
1809
1810
            if (TYPO3_DLOG) {
1811
1812
                \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...
1813
1814
            }
1815
1816
        }
1817
1818
        return TRUE;
1819
1820
    }
1821
1822
    /**
1823
     * This returns $this->cPid via __get()
1824
     *
1825
     * @access	protected
1826
     *
1827
     * @return	integer		The PID of the metadata definitions
1828
     */
1829
    protected function _getCPid() {
1830
1831
        return $this->cPid;
1832
1833
    }
1834
1835
    /**
1836
     * This builds an array of the document's dmdSecs
1837
     *
1838
     * @access	protected
1839
     *
1840
     * @return	array		Array of dmdSecs with their IDs as array key
1841
     */
1842
    protected function _getDmdSec() {
1843
1844
        if (!$this->dmdSecLoaded) {
1845
1846
            // Get available data formats.
1847
            $this->loadFormats();
1848
1849
            // Get dmdSec nodes from METS.
1850
            $dmdIds = $this->mets->xpath('./mets:dmdSec/@ID');
1851
1852
            foreach ($dmdIds as $dmdId) {
1853
1854
                if ($type = $this->mets->xpath('./mets:dmdSec[@ID="'.(string) $dmdId.'"]/mets:mdWrap[not(@MDTYPE="OTHER")]/@MDTYPE')) {
1855
1856
                    if (!empty($this->formats[(string) $type[0]])) {
1857
1858
                        $type = (string) $type[0];
1859
1860
                        $xml = $this->mets->xpath('./mets:dmdSec[@ID="'.(string) $dmdId.'"]/mets:mdWrap[@MDTYPE="'.$type.'"]/mets:xmlData/'.strtolower($type).':'.$this->formats[$type]['rootElement']);
1861
1862
                    }
1863
1864
                } elseif ($type = $this->mets->xpath('./mets:dmdSec[@ID="'.(string) $dmdId.'"]/mets:mdWrap[@MDTYPE="OTHER"]/@OTHERMDTYPE')) {
1865
1866
                    if (!empty($this->formats[(string) $type[0]])) {
1867
1868
                        $type = (string) $type[0];
1869
1870
                        $xml = $this->mets->xpath('./mets:dmdSec[@ID="'.(string) $dmdId.'"]/mets:mdWrap[@MDTYPE="OTHER"][@OTHERMDTYPE="'.$type.'"]/mets:xmlData/'.strtolower($type).':'.$this->formats[$type]['rootElement']);
1871
1872
                    }
1873
1874
                }
1875
1876
                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...
1877
1878
                    $this->dmdSec[(string) $dmdId]['type'] = $type;
1879
1880
                    $this->dmdSec[(string) $dmdId]['xml'] = $xml[0];
1881
1882
                    $this->registerNamespaces($this->dmdSec[(string) $dmdId]['xml']);
1883
1884
                }
1885
1886
            }
1887
1888
            $this->dmdSecLoaded = TRUE;
1889
1890
        }
1891
1892
        return $this->dmdSec;
1893
1894
    }
1895
1896
    /**
1897
     * This builds the file ID -> USE concordance
1898
     *
1899
     * @access	protected
1900
     *
1901
     * @return	array		Array of file use groups with file IDs
1902
     */
1903
    protected function _getFileGrps() {
1904
1905
        if (!$this->fileGrpsLoaded) {
1906
1907
            // Get configured USE attributes.
1908
            $extConf = unserialize($GLOBALS['TYPO3_CONF_VARS']['EXT']['extConf'][self::$extKey]);
1909
1910
            $useGrps = \TYPO3\CMS\Core\Utility\GeneralUtility::trimExplode(',', $extConf['fileGrps']);
1911
1912
            if (!empty($extConf['fileGrpThumbs'])) {
1913
1914
                $useGrps[] = $extConf['fileGrpThumbs'];
1915
1916
            }
1917
1918
            if (!empty($extConf['fileGrpDownload'])) {
1919
1920
                $useGrps[] = $extConf['fileGrpDownload'];
1921
1922
            }
1923
1924
            if (!empty($extConf['fileGrpFulltext'])) {
1925
1926
                $useGrps[] = $extConf['fileGrpFulltext'];
1927
1928
            }
1929
1930
            if (!empty($extConf['fileGrpAudio'])) {
1931
1932
                $useGrps[] = $extConf['fileGrpAudio'];
1933
1934
            }
1935
1936
            // Get all file groups.
1937
            $fileGrps = $this->mets->xpath('./mets:fileSec/mets:fileGrp');
1938
1939
            // Build concordance for configured USE attributes.
1940
            foreach ($fileGrps as $fileGrp) {
1941
1942
                if (in_array((string) $fileGrp['USE'], $useGrps)) {
1943
1944
                    foreach ($fileGrp->children('http://www.loc.gov/METS/')->file as $file) {
1945
1946
                        $this->fileGrps[(string) $file->attributes()->ID] = (string) $fileGrp['USE'];
1947
1948
                    }
1949
1950
                }
1951
1952
            }
1953
1954
            // Are there any fulltext files available?
1955
            if (!empty($extConf['fileGrpFulltext']) && in_array($extConf['fileGrpFulltext'], $this->fileGrps)) {
1956
1957
                $this->hasFulltext = TRUE;
1958
1959
            }
1960
1961
            $this->fileGrpsLoaded = TRUE;
1962
1963
        }
1964
1965
        return $this->fileGrps;
1966
1967
    }
1968
1969
    /**
1970
     * This returns $this->hasFulltext via __get()
1971
     *
1972
     * @access	protected
1973
     *
1974
     * @return	boolean		Are there any fulltext files available?
1975
     */
1976
    protected function _getHasFulltext() {
1977
1978
        // Are the fileGrps already loaded?
1979
        if (!$this->fileGrpsLoaded) {
1980
1981
            $this->_getFileGrps();
1982
1983
        }
1984
1985
        return $this->hasFulltext;
1986
1987
    }
1988
1989
    /**
1990
     * This returns $this->location via __get()
1991
     *
1992
     * @access	protected
1993
     *
1994
     * @return	string		The location of the document
1995
     */
1996
    protected function _getLocation() {
1997
1998
        return $this->location;
1999
2000
    }
2001
2002
    /**
2003
     * This builds an array of the document's metadata
2004
     *
2005
     * @access	protected
2006
     *
2007
     * @return	array		Array of metadata with their corresponding logical structure node ID as key
2008
     */
2009
    protected function _getMetadataArray() {
2010
2011
        // Set metadata definitions' PID.
2012
        $cPid = ($this->cPid ? $this->cPid : $this->pid);
2013
2014
        if (!$cPid) {
2015
2016
            if (TYPO3_DLOG) {
2017
2018
                \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...
2019
2020
            }
2021
2022
            return array ();
2023
2024
        }
2025
2026
        if (!$this->metadataArrayLoaded || $this->metadataArray[0] != $cPid) {
2027
2028
            // Get all logical structure nodes with metadata.
2029
            if (($ids = $this->mets->xpath('./mets:structMap[@TYPE="LOGICAL"]//mets:div[@DMDID]/@ID'))) {
2030
2031
                foreach ($ids as $id) {
2032
2033
                    $this->metadataArray[(string) $id] = $this->getMetadata((string) $id, $cPid);
2034
2035
                }
2036
2037
            }
2038
2039
            // Set current PID for metadata definitions.
2040
            $this->metadataArray[0] = $cPid;
2041
2042
            $this->metadataArrayLoaded = TRUE;
2043
2044
        }
2045
2046
        return $this->metadataArray;
2047
2048
    }
2049
2050
    /**
2051
     * This returns $this->mets via __get()
2052
     *
2053
     * @access	protected
2054
     *
2055
     * @return	SimpleXMLElement		The XML's METS part as SimpleXMLElement object
2056
     */
2057
    protected function _getMets() {
2058
2059
        return $this->mets;
2060
2061
    }
2062
2063
    /**
2064
     * This returns $this->numPages via __get()
2065
     *
2066
     * @access	protected
2067
     *
2068
     * @return	integer		The total number of pages and/or tracks
2069
     */
2070
    protected function _getNumPages() {
2071
2072
        $this->_getPhysicalStructure();
2073
2074
        return $this->numPages;
2075
2076
    }
2077
2078
    /**
2079
     * This returns $this->parentId via __get()
2080
     *
2081
     * @access	protected
2082
     *
2083
     * @return	integer		The UID of the parent document or zero if not applicable
2084
     */
2085
    protected function _getParentId() {
2086
2087
        return $this->parentId;
2088
2089
    }
2090
2091
    /**
2092
     * This builds an array of the document's physical structure
2093
     *
2094
     * @access	protected
2095
     *
2096
     * @return	array		Array of physical elements' id, type, label and file representations ordered by @ORDER attribute
2097
     */
2098
    protected function _getPhysicalStructure() {
2099
2100
        // Is there no physical structure array yet?
2101
        if (!$this->physicalStructureLoaded) {
2102
2103
            // Does the document have a structMap node of type "PHYSICAL"?
2104
            $elementNodes = $this->mets->xpath('./mets:structMap[@TYPE="PHYSICAL"]/mets:div[@TYPE="physSequence"]/mets:div');
2105
2106
            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...
2107
2108
                // Get file groups.
2109
                $fileUse = $this->_getFileGrps();
2110
2111
                // Get the physical sequence's metadata.
2112
                $physNode = $this->mets->xpath('./mets:structMap[@TYPE="PHYSICAL"]/mets:div[@TYPE="physSequence"]');
2113
2114
                $physSeq[0] = (string) $physNode[0]['ID'];
1 ignored issue
show
Comprehensibility Best Practice introduced by
$physSeq was never initialized. Although not strictly required by PHP, it is generally a good practice to add $physSeq = array(); before regardless.
Loading history...
2115
2116
                $this->physicalStructureInfo[$physSeq[0]]['id'] = $physNode[0]['ID'];
2117
2118
                $this->physicalStructureInfo[$physSeq[0]]['dmdId'] = (isset($physNode[0]['DMDID']) ? (string) $physNode[0]['DMDID'] : '');
2119
2120
                $this->physicalStructureInfo[$physSeq[0]]['label'] = (isset($physNode[0]['LABEL']) ? (string) $physNode[0]['LABEL'] : '');
2121
2122
                $this->physicalStructureInfo[$physSeq[0]]['orderlabel'] = (isset($physNode[0]['ORDERLABEL']) ? (string) $physNode[0]['ORDERLABEL'] : '');
2123
2124
                $this->physicalStructureInfo[$physSeq[0]]['type'] = (string) $physNode[0]['TYPE'];
2125
2126
                $this->physicalStructureInfo[$physSeq[0]]['contentIds'] = (isset($physNode[0]['CONTENTIDS']) ? (string) $physNode[0]['CONTENTIDS'] : '');
2127
2128
                // Get the file representations from fileSec node.
2129
                foreach ($physNode[0]->children('http://www.loc.gov/METS/')->fptr as $fptr) {
2130
2131
                    // Check if file has valid @USE attribute.
2132
                    if (!empty($fileUse[(string) $fptr->attributes()->FILEID])) {
2133
2134
                        $this->physicalStructureInfo[$physSeq[0]]['files'][$fileUse[(string) $fptr->attributes()->FILEID]] = (string) $fptr->attributes()->FILEID;
2135
2136
                    }
2137
2138
                }
2139
2140
                // Build the physical elements' array from the physical structMap node.
2141
                foreach ($elementNodes as $elementNode) {
2142
2143
                    $elements[(int) $elementNode['ORDER']] = (string) $elementNode['ID'];
2144
2145
                    $this->physicalStructureInfo[$elements[(int) $elementNode['ORDER']]]['id'] = $elementNode['ID'];
1 ignored issue
show
Comprehensibility Best Practice introduced by
The variable $elements seems to be defined later in this foreach loop on line 2143. Are you sure it is defined here?
Loading history...
2146
2147
                    $this->physicalStructureInfo[$elements[(int) $elementNode['ORDER']]]['dmdId'] = (isset($elementNode['DMDID']) ? (string) $elementNode['DMDID'] : '');
2148
2149
                    $this->physicalStructureInfo[$elements[(int) $elementNode['ORDER']]]['label'] = (isset($elementNode['LABEL']) ? (string) $elementNode['LABEL'] : '');
2150
2151
                    $this->physicalStructureInfo[$elements[(int) $elementNode['ORDER']]]['orderlabel'] = (isset($elementNode['ORDERLABEL']) ? (string) $elementNode['ORDERLABEL'] : '');
2152
2153
                    $this->physicalStructureInfo[$elements[(int) $elementNode['ORDER']]]['type'] = (string) $elementNode['TYPE'];
2154
2155
                    $this->physicalStructureInfo[$elements[(int) $elementNode['ORDER']]]['contentIds'] = (isset($elementNode['CONTENTIDS']) ? (string) $elementNode['CONTENTIDS'] : '');
2156
2157
                    // Get the file representations from fileSec node.
2158
                    foreach ($elementNode->children('http://www.loc.gov/METS/')->fptr as $fptr) {
2159
2160
                        // Check if file has valid @USE attribute.
2161
                        if (!empty($fileUse[(string) $fptr->attributes()->FILEID])) {
2162
2163
                            $this->physicalStructureInfo[$elements[(int) $elementNode['ORDER']]]['files'][$fileUse[(string) $fptr->attributes()->FILEID]] = (string) $fptr->attributes()->FILEID;
2164
2165
                        }
2166
2167
                    }
2168
2169
                }
2170
2171
                // Sort array by keys (= @ORDER).
2172
                if (ksort($elements)) {
2173
2174
                    // Set total number of pages/tracks.
2175
                    $this->numPages = count($elements);
2176
2177
                    // Merge and re-index the array to get nice numeric indexes.
2178
                    $this->physicalStructure = array_merge($physSeq, $elements);
2179
2180
                }
2181
2182
            }
2183
2184
            $this->physicalStructureLoaded = TRUE;
2185
2186
        }
2187
2188
        return $this->physicalStructure;
2189
2190
    }
2191
2192
    /**
2193
     * This gives an array of the document's physical structure metadata
2194
     *
2195
     * @access	protected
2196
     *
2197
     * @return	array		Array of elements' type, label and file representations ordered by @ID attribute
2198
     */
2199
    protected function _getPhysicalStructureInfo() {
2200
2201
        // Is there no physical structure array yet?
2202
        if (!$this->physicalStructureLoaded) {
2203
2204
            // Build physical structure array.
2205
            $this->_getPhysicalStructure();
2206
2207
        }
2208
2209
        return $this->physicalStructureInfo;
2210
2211
    }
2212
2213
    /**
2214
     * This returns $this->pid via __get()
2215
     *
2216
     * @access	protected
2217
     *
2218
     * @return	integer		The PID of the document or zero if not in database
2219
     */
2220
    protected function _getPid() {
2221
2222
        return $this->pid;
2223
2224
    }
2225
2226
    /**
2227
     * This returns $this->ready via __get()
2228
     *
2229
     * @access	protected
2230
     *
2231
     * @return	boolean		Is the document instantiated successfully?
2232
     */
2233
    protected function _getReady() {
2234
2235
        return $this->ready;
2236
2237
    }
2238
2239
    /**
2240
     * This returns $this->recordId via __get()
2241
     *
2242
     * @access	protected
2243
     *
2244
     * @return	mixed		The METS file's record identifier
2245
     */
2246
    protected function _getRecordId() {
2247
2248
        return $this->recordId;
2249
2250
    }
2251
2252
    /**
2253
     * This returns $this->rootId via __get()
2254
     *
2255
     * @access	protected
2256
     *
2257
     * @return	integer		The UID of the root document or zero if not applicable
2258
     */
2259
    protected function _getRootId() {
2260
2261
        if (!$this->rootIdLoaded) {
2262
2263
            if ($this->parentId) {
2264
2265
                $parent = self::getInstance($this->parentId, $this->pid);
2266
2267
                $this->rootId = $parent->rootId;
2268
2269
            }
2270
2271
            $this->rootIdLoaded = TRUE;
2272
2273
        }
2274
2275
        return $this->rootId;
2276
2277
    }
2278
2279
    /**
2280
     * This returns the smLinks between logical and physical structMap
2281
     *
2282
     * @access	protected
2283
     *
2284
     * @return	array		The links between logical and physical nodes
2285
     */
2286
    protected function _getSmLinks() {
2287
2288
        if (!$this->smLinksLoaded) {
2289
2290
            $smLinks = $this->mets->xpath('./mets:structLink/mets:smLink');
2291
2292
            foreach ($smLinks as $smLink) {
2293
2294
                $this->smLinks['l2p'][(string) $smLink->attributes('http://www.w3.org/1999/xlink')->from][] = (string) $smLink->attributes('http://www.w3.org/1999/xlink')->to;
2295
2296
                $this->smLinks['p2l'][(string) $smLink->attributes('http://www.w3.org/1999/xlink')->to][] = (string) $smLink->attributes('http://www.w3.org/1999/xlink')->from;
2297
2298
            }
2299
2300
            $this->smLinksLoaded = TRUE;
2301
2302
        }
2303
2304
        return $this->smLinks;
2305
2306
    }
2307
2308
    /**
2309
     * This builds an array of the document's logical structure
2310
     *
2311
     * @access	protected
2312
     *
2313
     * @return	array		Array of structure nodes' id, label, type and physical page indexes/mptr link with original hierarchy preserved
2314
     */
2315
    protected function _getTableOfContents() {
2316
2317
        // Is there no logical structure array yet?
2318
        if (!$this->tableOfContentsLoaded) {
2319
2320
            // Get all logical structures.
2321
            $this->getLogicalStructure('', TRUE);
2322
2323
            $this->tableOfContentsLoaded = TRUE;
2324
2325
        }
2326
2327
        return $this->tableOfContents;
2328
2329
    }
2330
2331
    /**
2332
     * This returns the document's thumbnail location
2333
     *
2334
     * @access	protected
2335
     *
2336
     * @param	boolean		$forceReload: Force reloading the thumbnail instead of returning the cached value
2337
     *
2338
     * @return	string		The document's thumbnail location
2339
     */
2340
    protected function _getThumbnail($forceReload = FALSE) {
2341
2342
        if (!$this->thumbnailLoaded || $forceReload) {
2343
2344
            // Retain current PID.
2345
            $cPid = ($this->cPid ? $this->cPid : $this->pid);
2346
2347
            if (!$cPid) {
2348
2349
                if (TYPO3_DLOG) {
2350
2351
                    \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...
2352
2353
                }
2354
2355
                $this->thumbnailLoaded = TRUE;
2356
2357
                return $this->thumbnail;
2358
2359
            }
2360
2361
            // Load extension configuration.
2362
            $extConf = unserialize($GLOBALS['TYPO3_CONF_VARS']['EXT']['extConf'][self::$extKey]);
2363
2364
            if (empty($extConf['fileGrpThumbs'])) {
2365
2366
                if (TYPO3_DLOG) {
2367
2368
                    \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...
2369
2370
                }
2371
2372
                $this->thumbnailLoaded = TRUE;
2373
2374
                return $this->thumbnail;
2375
2376
            }
2377
2378
            $strctId = $this->_getToplevelId();
2379
2380
            $metadata = $this->getTitledata($cPid);
2381
2382
            // Get structure element to get thumbnail from.
2383
            $result = $GLOBALS['TYPO3_DB']->exec_SELECTquery(
2384
                'tx_dlf_structures.thumbnail AS thumbnail',
2385
                'tx_dlf_structures',
2386
                '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'),
2387
                '',
2388
                '',
2389
                '1'
2390
            );
2391
2392
            if ($GLOBALS['TYPO3_DB']->sql_num_rows($result) > 0) {
2393
2394
                $resArray = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($result);
2395
2396
                // Get desired thumbnail structure if not the toplevel structure itself.
2397
                if (!empty($resArray['thumbnail'])) {
2398
2399
                    $strctType = tx_dlf_helper::getIndexName($resArray['thumbnail'], 'tx_dlf_structures', $cPid);
2400
2401
                    // Check if this document has a structure element of the desired type.
2402
                    $strctIds = $this->mets->xpath('./mets:structMap[@TYPE="LOGICAL"]//mets:div[@TYPE="'.$strctType.'"]/@ID');
2403
2404
                    if (!empty($strctIds)) {
2405
2406
                        $strctId = (string) $strctIds[0];
2407
2408
                    }
2409
2410
                }
2411
2412
                // Load smLinks.
2413
                $this->_getSmLinks();
2414
2415
                // Get thumbnail location.
2416
                if ($this->_getPhysicalStructure() && !empty($this->smLinks['l2p'][$strctId])) {
2417
2418
                    $this->thumbnail = $this->getFileLocation($this->physicalStructureInfo[$this->smLinks['l2p'][$strctId][0]]['files'][$extConf['fileGrpThumbs']]);
2419
2420
                } else {
2421
2422
                    $this->thumbnail = $this->getFileLocation($this->physicalStructureInfo[$this->physicalStructure[1]]['files'][$extConf['fileGrpThumbs']]);
2423
2424
                }
2425
2426
            } elseif (TYPO3_DLOG) {
2427
2428
                \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);
2429
2430
            }
2431
2432
            $this->thumbnailLoaded = TRUE;
2433
2434
        }
2435
2436
        return $this->thumbnail;
2437
2438
    }
2439
2440
    /**
2441
     * This returns the ID of the toplevel logical structure node
2442
     *
2443
     * @access	protected
2444
     *
2445
     * @return	string		The logical structure node's ID
2446
     */
2447
    protected function _getToplevelId() {
2448
2449
        if (empty($this->toplevelId)) {
2450
2451
            // Get all logical structure nodes with metadata, but without associated METS-Pointers.
2452
            if (($divs = $this->mets->xpath('./mets:structMap[@TYPE="LOGICAL"]//mets:div[@DMDID and not(./mets:mptr)]'))) {
2453
2454
                // Load smLinks.
2455
                $this->_getSmLinks();
2456
2457
                foreach ($divs as $div) {
2458
2459
                    $id = (string) $div['ID'];
2460
2461
                    // Are there physical structure nodes for this logical structure?
2462
                    if (array_key_exists($id, $this->smLinks['l2p'])) {
2463
2464
                        // Yes. That's what we're looking for.
2465
                        $this->toplevelId = $id;
2466
2467
                        break;
2468
2469
                    } elseif (empty($this->toplevelId)) {
2470
2471
                        // No. Remember this anyway, but keep looking for a better one.
2472
                        $this->toplevelId = $id;
2473
2474
                    }
2475
2476
                }
2477
2478
            }
2479
2480
        }
2481
2482
        return $this->toplevelId;
2483
2484
    }
2485
2486
    /**
2487
     * This returns $this->uid via __get()
2488
     *
2489
     * @access	protected
2490
     *
2491
     * @return	mixed		The UID or the URL of the document
2492
     */
2493
    protected function _getUid() {
2494
2495
        return $this->uid;
2496
2497
    }
2498
2499
    /**
2500
     * This sets $this->cPid via __set()
2501
     *
2502
     * @access	protected
2503
     *
2504
     * @param	integer		$value: The new PID for the metadata definitions
2505
     *
2506
     * @return	void
2507
     */
2508
    protected function _setCPid($value) {
2509
2510
        $this->cPid = max(intval($value), 0);
2511
2512
    }
2513
2514
    /**
2515
     * This magic method is invoked each time a clone is called on the object variable
2516
     * (This method is defined as private/protected because singleton objects should not be cloned)
2517
     *
2518
     * @access	protected
2519
     *
2520
     * @return	void
2521
     */
2522
    protected function __clone() {}
2523
2524
    /**
2525
     * This is a singleton class, thus the constructor should be private/protected
2526
     * (Get an instance of this class by calling tx_dlf_document::getInstance())
2527
     *
2528
     * @access	protected
2529
     *
2530
     * @param	integer		$uid: The UID of the document to parse or URL to XML file
2531
     * @param	integer		$pid: If > 0, then only document with this PID gets loaded
2532
     *
2533
     * @return	void
2534
     */
2535
    protected function __construct($uid, $pid) {
2536
2537
        // Prepare to check database for the requested document.
2538
        if (\TYPO3\CMS\Core\Utility\MathUtility::canBeInterpretedAsInteger($uid)) {
2539
2540
            $whereClause = 'tx_dlf_documents.uid='.intval($uid).tx_dlf_helper::whereClause('tx_dlf_documents');
2541
2542
        } else {
2543
2544
            // Try to load METS file.
2545
            if (\TYPO3\CMS\Core\Utility\GeneralUtility::isValidUrl($uid) && $this->load($uid)) {
2546
2547
                // Initialize core METS object.
2548
                $this->init();
2549
2550
                if ($this->mets !== NULL) {
2551
2552
                    // Cast to string for safety reasons.
2553
                    $location = (string) $uid;
2554
2555
                    // Check for METS object @ID.
2556
                    if (!empty($this->mets['OBJID'])) {
2557
2558
                        $this->recordId = (string) $this->mets['OBJID'];
2559
2560
                    }
2561
2562
                    // Get hook objects.
2563
                    $hookObjects = tx_dlf_helper::getHookObjects('common/class.tx_dlf_document.php');
2564
2565
                    // Apply hooks.
2566
                    foreach ($hookObjects as $hookObj) {
2567
2568
                        if (method_exists($hookObj, 'construct_postProcessRecordId')) {
2569
2570
                            $hookObj->construct_postProcessRecordId($this->xml, $this->recordId);
2571
2572
                        }
2573
2574
                    }
2575
2576
                } else {
2577
2578
                    // No METS part found.
2579
                    return;
2580
2581
                }
2582
2583
            } else {
2584
2585
                // Loading failed.
2586
                return;
2587
2588
            }
2589
2590
            if (!empty($location) && !empty($this->recordId)) {
2591
2592
                // Try to match record identifier or location (both should be unique).
2593
                $whereClause = '(tx_dlf_documents.location='.$GLOBALS['TYPO3_DB']->fullQuoteStr($location, 'tx_dlf_documents').' OR tx_dlf_documents.record_id='.$GLOBALS['TYPO3_DB']->fullQuoteStr($this->recordId, 'tx_dlf_documents').')'.tx_dlf_helper::whereClause('tx_dlf_documents');
2594
2595
            } else {
2596
2597
                // Can't persistently identify document, don't try to match at all.
2598
                $whereClause = '1=-1';
2599
2600
            }
2601
2602
        }
2603
2604
        // Check for PID if needed.
2605
        if ($pid) {
2606
2607
            $whereClause .= ' AND tx_dlf_documents.pid='.intval($pid);
2608
2609
        }
2610
2611
        // Get document PID and location from database.
2612
        $result = $GLOBALS['TYPO3_DB']->exec_SELECTquery(
2613
            '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',
2614
            'tx_dlf_documents',
2615
            $whereClause,
2616
            '',
2617
            '',
2618
            '1'
2619
        );
2620
2621
        if ($GLOBALS['TYPO3_DB']->sql_num_rows($result) > 0) {
2622
2623
            list ($this->uid, $this->pid, $this->recordId, $this->parentId, $this->thumbnail, $this->location) = $GLOBALS['TYPO3_DB']->sql_fetch_row($result);
2624
2625
            $this->thumbnailLoaded = TRUE;
2626
2627
            // Load XML file if necessary...
2628
            if ($this->mets === NULL && $this->load($this->location)) {
2629
2630
                // ...and set some basic properties.
2631
                $this->init();
2632
2633
            }
2634
2635
            // Do we have a METS object now?
2636
            if ($this->mets !== NULL) {
2637
2638
                // Set new location if necessary.
2639
                if (!empty($location)) {
2640
2641
                    $this->location = $location;
2642
2643
                }
2644
2645
                // Document ready!
2646
                $this->ready = TRUE;
2647
2648
            }
2649
2650
        } elseif ($this->mets !== NULL) {
2651
2652
            // Set location as UID for documents not in database.
2653
            $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...
2654
2655
            $this->location = $location;
2656
2657
            // Document ready!
2658
            $this->ready = TRUE;
2659
2660
        } else {
2661
2662
            if (TYPO3_DLOG) {
2663
2664
                \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...
2665
2666
            }
2667
2668
        }
2669
2670
    }
2671
2672
    /**
2673
     * This magic method is called each time an invisible property is referenced from the object
2674
     *
2675
     * @access	public
2676
     *
2677
     * @param	string		$var: Name of variable to get
2678
     *
2679
     * @return	mixed		Value of $this->$var
2680
     */
2681
    public function __get($var) {
2682
2683
        $method = '_get'.ucfirst($var);
2684
2685
        if (!property_exists($this, $var) || !method_exists($this, $method)) {
2686
2687
            if (TYPO3_DLOG) {
2688
2689
                \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...
2690
2691
            }
2692
2693
            return;
2694
2695
        } else {
2696
2697
            return $this->$method();
2698
2699
        }
2700
2701
    }
2702
2703
    /**
2704
     * This magic method is called each time an invisible property is referenced from the object
2705
     *
2706
     * @access	public
2707
     *
2708
     * @param	string		$var: Name of variable to set
2709
     * @param	mixed		$value: New value of variable
2710
     *
2711
     * @return	void
2712
     */
2713
    public function __set($var, $value) {
2714
2715
        $method = '_set'.ucfirst($var);
2716
2717
        if (!property_exists($this, $var) || !method_exists($this, $method)) {
2718
2719
            if (TYPO3_DLOG) {
2720
2721
                \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...
2722
2723
            }
2724
2725
        } else {
2726
2727
            $this->$method($value);
2728
2729
        }
2730
2731
    }
2732
2733
    /**
2734
     * This magic method is executed prior to any serialization of the object
2735
     * @see __wakeup()
2736
     *
2737
     * @access	public
2738
     *
2739
     * @return	array		Properties to be serialized
2740
     */
2741
    public function __sleep() {
2742
2743
        // SimpleXMLElement objects can't be serialized, thus save the XML as string for serialization
2744
        $this->asXML = $this->xml->asXML();
2745
2746
        return array ('uid', 'pid', 'recordId', 'parentId', 'asXML');
2747
2748
    }
2749
2750
    /**
2751
     * This magic method is used for setting a string value for the object
2752
     *
2753
     * @access	public
2754
     *
2755
     * @return	string		String representing the METS object
2756
     */
2757
    public function __toString() {
2758
2759
        $xml = new DOMDocument('1.0', 'utf-8');
2760
2761
        $xml->appendChild($xml->importNode(dom_import_simplexml($this->mets), TRUE));
2762
2763
        $xml->formatOutput = TRUE;
2764
2765
        return $xml->saveXML();
2766
2767
    }
2768
2769
    /**
2770
     * This magic method is executed after the object is deserialized
2771
     * @see __sleep()
2772
     *
2773
     * @access	public
2774
     *
2775
     * @return	void
2776
     */
2777
    public function __wakeup() {
2778
2779
        // Turn off libxml's error logging.
2780
        $libxmlErrors = libxml_use_internal_errors(TRUE);
2781
2782
        // Reload XML from string.
2783
        $xml = @simplexml_load_string($this->asXML);
2784
2785
        // Reset libxml's error logging.
2786
        libxml_use_internal_errors($libxmlErrors);
2787
2788
        if ($xml !== FALSE) {
2789
2790
            $this->asXML = '';
2791
2792
            $this->xml = $xml;
2793
2794
            // Rebuild the unserializable properties.
2795
            $this->init();
2796
2797
        } else {
2798
2799
            if (TYPO3_DLOG) {
2800
2801
                \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...
2802
2803
            }
2804
2805
        }
2806
2807
    }
2808
2809
}
2810