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
Pull Request — master (#376)
by Sebastian
03:43
created

DocumentList::moveUp()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 2
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 1
nc 1
nop 1
dl 0
loc 2
rs 10
c 0
b 0
f 0
1
<?php
2
namespace Kitodo\Dlf\Common;
3
4
/**
5
 * (c) Kitodo. Key to digital objects e.V. <[email protected]>
6
 *
7
 * This file is part of the Kitodo and TYPO3 projects.
8
 *
9
 * @license GNU General Public License version 3 or later.
10
 * For the full copyright and license information, please read the
11
 * LICENSE.txt file that was distributed with this source code.
12
 */
13
14
use TYPO3\CMS\Core\Database\ConnectionPool;
15
use TYPO3\CMS\Core\Database\Query\QueryBuilder;
16
use TYPO3\CMS\Core\Utility\GeneralUtility;
17
use TYPO3\CMS\Core\Utility\MathUtility;
18
19
/**
20
 * List class for the 'dlf' extension
21
 *
22
 * @author Sebastian Meyer <[email protected]>
23
 * @author Frank Ulrich Weber <[email protected]>
24
 * @package TYPO3
25
 * @subpackage dlf
26
 * @access public
27
 */
28
class DocumentList implements \ArrayAccess, \Countable, \Iterator, \TYPO3\CMS\Core\SingletonInterface {
29
    /**
30
     * This holds the number of documents in the list
31
     * @see \Countable
32
     *
33
     * @var integer
34
     * @access protected
35
     */
36
    protected $count = 0;
37
38
    /**
39
     * This holds the list entries in sorted order
40
     * @see \ArrayAccess
41
     *
42
     * @var array
43
     * @access protected
44
     */
45
    protected $elements = [];
46
47
    /**
48
     * This holds the list's metadata
49
     *
50
     * @var array
51
     * @access protected
52
     */
53
    protected $metadata = [];
54
55
    /**
56
     * This holds the current list position
57
     * @see \Iterator
58
     *
59
     * @var integer
60
     * @access protected
61
     */
62
    protected $position = 0;
63
64
    /**
65
     * This holds the full records of already processed list elements
66
     *
67
     * @var array
68
     * @access protected
69
     */
70
    protected $records = [];
71
72
    /**
73
     * Instance of \Kitodo\Dlf\Common\Solr class
74
     *
75
     * @var \Kitodo\Dlf\Common\Solr
76
     * @access protected
77
     */
78
    protected $solr;
79
80
    /**
81
     * This holds the Solr metadata configuration
82
     *
83
     * @var array
84
     * @access protected
85
     */
86
    protected $solrConfig = [];
87
88
    /**
89
     * This adds an array of elements at the given position to the list
90
     *
91
     * @access public
92
     *
93
     * @param array $elements: Array of elements to add to list
94
     * @param integer $position: Numeric position for including
95
     *
96
     * @return void
97
     */
98
    public function add(array $elements, $position = -1) {
99
        $position = MathUtility::forceIntegerInRange($position, 0, $this->count, $this->count);
100
        if (!empty($elements)) {
101
            array_splice($this->elements, $position, 0, $elements);
102
            $this->count = count($this->elements);
103
        }
104
    }
105
106
    /**
107
     * This counts the elements
108
     * @see \Countable::count()
109
     *
110
     * @access public
111
     *
112
     * @return integer The number of elements in the list
113
     */
114
    public function count() {
115
        return $this->count;
116
    }
117
118
    /**
119
     * This returns the current element
120
     * @see \Iterator::current()
121
     *
122
     * @access public
123
     *
124
     * @return array The current element
125
     */
126
    public function current() {
127
        if ($this->valid()) {
128
            return $this->getRecord($this->elements[$this->position]);
129
        } else {
130
            Helper::devLog('Invalid position "'.$this->position.'" for list element', DEVLOG_SEVERITY_NOTICE);
131
            return;
132
        }
133
    }
134
135
    /**
136
     * This returns the full record of any list element
137
     *
138
     * @access protected
139
     *
140
     * @param mixed $element: The list element
141
     *
142
     * @return mixed The element's full record
143
     */
144
    protected function getRecord($element) {
145
        if (is_array($element)
146
            && array_keys($element) == ['u', 'h', 's', 'p']) {
147
            // Return already processed record if possible.
148
            if (!empty($this->records[$element['u']])) {
149
                return $this->records[$element['u']];
150
            }
151
            $record = [
152
                'uid' => $element['u'],
153
                'page' => 1,
154
                'preview' => '',
155
                'subparts' => $element['p']
156
            ];
157
            // Check if it's a list of database records or Solr documents.
158
            if (!empty($this->metadata['options']['source'])
159
                && $this->metadata['options']['source'] == 'collection') {
160
                /** @var QueryBuilder $queryBuilder */
161
                $queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)
162
                    ->getQueryBuilderForTable('tx_dlf_documents');
163
164
                // Get document's thumbnail and metadata from database.
165
                $result = $queryBuilder
166
                    ->select(
167
                        'tx_dlf_documents.uid AS uid',
168
                        'tx_dlf_documents.thumbnail AS thumbnail',
169
                        'tx_dlf_documents.metadata AS metadata'
170
                    )
171
                    ->from('tx_dlf_documents')
172
                    ->where(
173
                        $queryBuilder->expr()->orX(
174
                            $queryBuilder->expr()->eq('tx_dlf_documents.uid', intval($record['uid'])),
175
                            $queryBuilder->expr()->eq('tx_dlf_documents.partof', intval($record['uid']))),
176
                        Helper::whereExpression('tx_dlf_documents')
177
                    )
178
                    ->execute();
179
180
                // Process results.
181
                while ($resArray = $result->fetch()) {
182
                    // Prepare document's metadata.
183
                    $metadata = unserialize($resArray['metadata']);
184
                    if (!empty($metadata['type'][0])
185
                        && MathUtility::canBeInterpretedAsInteger($metadata['type'][0])) {
186
                        $metadata['type'][0] = Helper::getIndexNameFromUid($metadata['type'][0], 'tx_dlf_structures', $this->metadata['options']['pid']);
187
                    }
188
                    if (!empty($metadata['owner'][0])
189
                        && MathUtility::canBeInterpretedAsInteger($metadata['owner'][0])) {
190
                        $metadata['owner'][0] = Helper::getIndexNameFromUid($metadata['owner'][0], 'tx_dlf_libraries', $this->metadata['options']['pid']);
191
                    }
192
                    if (!empty($metadata['collection'])
193
                        && is_array($metadata['collection'])) {
194
                        foreach ($metadata['collection'] as $i => $collection) {
195
                            if (MathUtility::canBeInterpretedAsInteger($collection)) {
196
                                $metadata['collection'][$i] = Helper::getIndexNameFromUid($metadata['collection'][$i], 'tx_dlf_collections', $this->metadata['options']['pid']);
197
                            }
198
                        }
199
                    }
200
                    // Add metadata to list element.
201
                    if ($resArray['uid'] == $record['uid']) {
202
                        $record['thumbnail'] = $resArray['thumbnail'];
203
                        $record['metadata'] = $metadata;
204
                    } elseif (($key = array_search(['u' => $resArray['uid']], $record['subparts'], TRUE)) !== FALSE) {
205
                        $record['subparts'][$key] = [
206
                            'uid' => $resArray['uid'],
207
                            'page' => 1,
208
                            'preview' => (!empty($record['subparts'][$key]['h']) ? $record['subparts'][$key]['h'] : ''),
209
                            'thumbnail' => $resArray['thumbnail'],
210
                            'metadata' => $metadata
211
                        ];
212
                    }
213
                }
214
            } elseif (!empty($this->metadata['options']['source'])
215
                && $this->metadata['options']['source'] == 'search') {
216
                if ($this->solrConnect()) {
217
                    $params = [];
218
                    // Restrict the fields to the required ones
219
                    $params['fields'] = 'uid,id,toplevel,thumbnail,page';
220
                    foreach ($this->solrConfig as $solr_name) {
221
                        $params['fields'] .= ','.$solr_name;
222
                    }
223
                    // If it is a fulltext search, enable highlighting.
224
                    if ($this->metadata['fulltextSearch']) {
225
                        $params['component'] = [
226
                            'highlighting' => [
227
                                'query' => Solr::escapeQuery($this->metadata['searchString']),
228
                                'field' => 'fulltext',
229
                                'usefastvectorhighlighter' => TRUE
230
                            ]
231
                        ];
232
                    }
233
                    // Set additional query parameters.
234
                    $params['start'] = 0;
235
                    // Set reasonable limit for safety reasons.
236
                    // We don't expect to get more than 10.000 hits per UID.
237
                    $params['rows'] = 10000;
238
                    // Take over existing filter queries.
239
                    $params['filterquery'] = isset($this->metadata['options']['params']['filterquery']) ? $this->metadata['options']['params']['filterquery'] : [];
240
                    // Extend filter query to get all documents with the same UID.
241
                    foreach ($params['filterquery'] as $key => $value) {
242
                        if (isset($value['query'])) {
243
                            $params['filterquery'][$key]['query'] = $value['query'].' OR toplevel:true';
244
                        }
245
                    }
246
                    // Add filter query to get all documents with the required uid.
247
                    $params['filterquery'][] = ['query' => 'uid:'.Solr::escapeQuery($record['uid'])];
248
                    // Add sorting.
249
                    $params['sort'] = $this->metadata['options']['params']['sort'];
250
                    // Set query.
251
                    $params['query'] = $this->metadata['options']['select'].' OR toplevel:true';
252
                    // Perform search for all documents with the same uid that either fit to the search or marked as toplevel.
253
                    $selectQuery = $this->solr->service->createSelect($params);
0 ignored issues
show
Bug Best Practice introduced by
The property $service is declared protected in Kitodo\Dlf\Common\Solr. Since you implement __get, consider adding a @property or @property-read.
Loading history...
254
                    $result = $this->solr->service->select($selectQuery);
255
                    // If it is a fulltext search, fetch the highlighting results.
256
                    if ($this->metadata['fulltextSearch']) {
257
                        $highlighting = $result->getHighlighting();
258
                    }
259
                    // Process results.
260
                    foreach ($result as $resArray) {
261
                        // Prepare document's metadata.
262
                        $metadata = [];
263
                        foreach ($this->solrConfig as $index_name => $solr_name) {
264
                            if (!empty($resArray->$solr_name)) {
265
                                $metadata[$index_name] = (is_array($resArray->$solr_name) ? $resArray->$solr_name : [$resArray->$solr_name]);
266
                            }
267
                        }
268
                        // Add metadata to list elements.
269
                        if ($resArray->toplevel) {
270
                            $record['thumbnail'] = $resArray->thumbnail;
271
                            $record['metadata'] = $metadata;
272
                        } else {
273
                            $highlightedDoc = !empty($highlighting) ? $highlighting->getResult($resArray->id) : NULL;
274
                            $highlight = !empty($highlightedDoc) ? $highlightedDoc->getField('fulltext')[0] : '';
275
                            $record['subparts'][$resArray->id] = [
276
                                'uid' => $resArray->uid,
277
                                'page' => $resArray->page,
278
                                'preview' => $highlight,
279
                                'thumbnail' => $resArray->thumbnail,
280
                                'metadata' => $metadata
281
                            ];
282
                        }
283
                    }
284
                }
285
            }
286
            // Save record for later usage.
287
            $this->records[$element['u']] = $record;
288
        } else {
289
            Helper::devLog('No UID of list element to fetch full record', DEVLOG_SEVERITY_NOTICE);
290
            $record = $element;
291
        }
292
        return $record;
293
    }
294
295
    /**
296
     * This returns the current position
297
     * @see \Iterator::key()
298
     *
299
     * @access public
300
     *
301
     * @return integer The current position
302
     */
303
    public function key() {
304
        return $this->position;
305
    }
306
307
    /**
308
     * This moves the element at the given position up or down
309
     *
310
     * @access public
311
     *
312
     * @param integer $position: Numeric position for moving
313
     * @param integer $steps: Amount of steps to move up or down
314
     *
315
     * @return void
316
     */
317
    public function move($position, $steps) {
318
        $position = intval($position);
319
        // Check if list position is valid.
320
        if ($position < 0
321
            || $position >= $this->count) {
322
            Helper::devLog('Invalid position "'.$position.'" for element moving', DEVLOG_SEVERITY_WARNING);
323
            return;
324
        }
325
        $steps = intval($steps);
326
        // Check if moving given amount of steps is possible.
327
        if (($position + $steps) < 0
328
            || ($position + $steps) >= $this->count) {
329
            Helper::devLog('Invalid steps "'.$steps.'" for moving element at position "'.$position.'"', DEVLOG_SEVERITY_WARNING);
330
            return;
331
        }
332
        $element = $this->remove($position);
333
        $this->add([$element], $position + $steps);
334
    }
335
336
    /**
337
     * This moves the element at the given position up
338
     *
339
     * @access public
340
     *
341
     * @param integer $position: Numeric position for moving
342
     *
343
     * @return void
344
     */
345
    public function moveUp($position) {
346
        $this->move($position, -1);
347
    }
348
349
    /**
350
     * This moves the element at the given position down
351
     *
352
     * @access public
353
     *
354
     * @param integer $position: Numeric position for moving
355
     *
356
     * @return void
357
     */
358
    public function moveDown($position) {
359
        $this->move($position, 1);
360
    }
361
362
    /**
363
     * This increments the current list position
364
     * @see \Iterator::next()
365
     *
366
     * @access public
367
     *
368
     * @return void
369
     */
370
    public function next() {
371
        $this->position++;
372
    }
373
374
    /**
375
     * This checks if an offset exists
376
     * @see \ArrayAccess::offsetExists()
377
     *
378
     * @access public
379
     *
380
     * @param mixed $offset: The offset to check
381
     *
382
     * @return boolean Does the given offset exist?
383
     */
384
    public function offsetExists($offset) {
385
        return isset($this->elements[$offset]);
386
    }
387
388
    /**
389
     * This returns the element at the given offset
390
     * @see \ArrayAccess::offsetGet()
391
     *
392
     * @access public
393
     *
394
     * @param mixed $offset: The offset to return
395
     *
396
     * @return array The element at the given offset
397
     */
398
    public function offsetGet($offset) {
399
        if ($this->offsetExists($offset)) {
400
            return $this->getRecord($this->elements[$offset]);
401
        } else {
402
            Helper::devLog('Invalid offset "'.$offset.'" for list element', DEVLOG_SEVERITY_NOTICE);
403
            return;
404
        }
405
    }
406
407
    /**
408
     * This sets the element at the given offset
409
     * @see \ArrayAccess::offsetSet()
410
     *
411
     * @access public
412
     *
413
     * @param mixed $offset: The offset to set (non-integer offsets will be appended)
414
     * @param mixed $value: The value to set
415
     *
416
     * @return void
417
     */
418
    public function offsetSet($offset, $value) {
419
        if (\TYPO3\CMS\Core\Utility\MathUtility::canBeInterpretedAsInteger($offset)) {
420
            $this->elements[$offset] = $value;
421
        } else {
422
            $this->elements[] = $value;
423
        }
424
        // Re-number the elements.
425
        $this->elements = array_values($this->elements);
426
        $this->count = count($this->elements);
427
    }
428
429
    /**
430
     * This removes the element at the given position from the list
431
     *
432
     * @access public
433
     *
434
     * @param integer $position: Numeric position for removing
435
     *
436
     * @return array The removed element
437
     */
438
    public function remove($position) {
439
        $position = intval($position);
440
        if ($position < 0
441
            || $position >= $this->count) {
442
            Helper::devLog('Invalid position "'.$position.'" for element removing', DEVLOG_SEVERITY_WARNING);
443
            return;
444
        }
445
        $removed = array_splice($this->elements, $position, 1);
446
        $this->count = count($this->elements);
447
        return $this->getRecord($removed[0]);
448
    }
449
450
    /**
451
     * This removes elements at the given range from the list
452
     *
453
     * @access public
454
     *
455
     * @param integer $position: Numeric position for start of range
456
     * @param integer $length: Numeric position for length of range
457
     *
458
     * @return array The indizes of the removed elements
459
     */
460
    public function removeRange($position, $length) {
461
        $position = intval($position);
462
        if ($position < 0
463
            || $position >= $this->count) {
464
            Helper::devLog('Invalid position "'.$position.'" for element removing', DEVLOG_SEVERITY_WARNING);
465
            return;
466
        }
467
        $removed = array_splice($this->elements, $position, $length);
468
        $this->count = count($this->elements);
469
        return $removed;
470
    }
471
472
    /**
473
     * This clears the current list
474
     *
475
     * @access public
476
     *
477
     * @return void
478
     */
479
    public function reset() {
480
        $this->elements = [];
481
        $this->records = [];
482
        $this->metadata = [];
483
        $this->count = 0;
484
        $this->position = 0;
485
    }
486
487
    /**
488
     * This resets the list position
489
     * @see \Iterator::rewind()
490
     *
491
     * @access public
492
     *
493
     * @return void
494
     */
495
    public function rewind() {
496
        $this->position = 0;
497
    }
498
499
    /**
500
     * This saves the current list
501
     *
502
     * @access public
503
     *
504
     * @param integer $pid: PID for saving in database
505
     *
506
     * @return void
507
     */
508
    public function save($pid = 0) {
509
        $pid = max(intval($pid), 0);
510
        // If no PID is given, save to the user's session instead
511
        if ($pid > 0) {
512
            // TODO: Liste in Datenbank speichern (inkl. Sichtbarkeit, Beschreibung, etc.)
513
        } else {
514
            Helper::saveToSession([$this->elements, $this->metadata], get_class($this));
515
        }
516
    }
517
518
    /**
519
     * Connects to Solr server.
520
     *
521
     * @access protected
522
     *
523
     * @return boolean TRUE on success or FALSE on failure
524
     */
525
    protected function solrConnect() {
526
        // Get Solr instance.
527
        if (!$this->solr) {
528
            // Connect to Solr server.
529
            if ($this->solr = Solr::getInstance($this->metadata['options']['core'])) {
530
                /** @var QueryBuilder $queryBuilder */
531
                $queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)
532
                    ->getQueryBuilderForTable('tx_dlf_metadata');
533
534
                // Load index configuration.
535
                $result = $queryBuilder
536
                    ->select(
537
                        'tx_dlf_metadata.index_name AS index_name',
538
                        'tx_dlf_metadata.index_tokenized AS index_tokenized',
539
                        'tx_dlf_metadata.index_indexed AS index_indexed'
540
                    )
541
                    ->from('tx_dlf_metadata')
542
                    ->where(
543
                        $queryBuilder->expr()->eq('tx_dlf_metadata.is_listed', intval($this->metadata['options']['pid'])),
544
                        Helper::whereExpression('tx_dlf_metadata')
545
                    )
546
                    ->orderBy('tx_dlf_metadata.sorting', 'ASC')
547
                    ->execute();
548
549
                while ($resArray = $result->fetch()) {
550
                    $this->solrConfig[$resArray['index_name']] = $resArray['index_name'].'_'.($resArray['index_tokenized'] ? 't' : 'u').'s'.($resArray['index_indexed'] ? 'i' : 'u');
551
                }
552
                // Add static fields.
553
                $this->solrConfig['type'] = 'type';
554
            } else {
555
                return FALSE;
556
            }
557
        }
558
        return TRUE;
559
    }
560
561
    /**
562
     * This sorts the current list by the given field
563
     *
564
     * @access public
565
     *
566
     * @param string $by: Sort the list by this field
567
     * @param boolean $asc: Sort ascending?
568
     *
569
     * @return void
570
     */
571
    public function sort($by, $asc = TRUE) {
572
        $newOrder = [];
573
        $nonSortable = [];
574
        foreach ($this->elements as $num => $element) {
575
            // Is this element sortable?
576
            if (!empty($element['s'][$by])) {
577
                $newOrder[$element['s'][$by].str_pad($num, 6, '0', STR_PAD_LEFT)] = $element;
578
            } else {
579
                $nonSortable[] = $element;
580
            }
581
        }
582
        // Reorder elements.
583
        if ($asc) {
584
            ksort($newOrder, SORT_LOCALE_STRING);
585
        } else {
586
            krsort($newOrder, SORT_LOCALE_STRING);
587
        }
588
        // Add non sortable elements to the end of the list.
589
        $newOrder = array_merge(array_values($newOrder), $nonSortable);
590
        // Check if something is missing.
591
        if ($this->count == count($newOrder)) {
592
            $this->elements = $newOrder;
593
        } else {
594
            Helper::devLog('Sorted list elements do not match unsorted elements', DEVLOG_SEVERITY_ERROR);
595
        }
596
    }
597
598
    /**
599
     * This unsets the element at the given offset
600
     * @see \ArrayAccess::offsetUnset()
601
     *
602
     * @access public
603
     *
604
     * @param mixed $offset: The offset to unset
605
     *
606
     * @return void
607
     */
608
    public function offsetUnset($offset) {
609
        unset ($this->elements[$offset]);
610
        // Re-number the elements.
611
        $this->elements = array_values($this->elements);
612
        $this->count = count($this->elements);
613
    }
614
615
    /**
616
     * This checks if the current list position is valid
617
     * @see \Iterator::valid()
618
     *
619
     * @access public
620
     *
621
     * @return boolean Is the current list position valid?
622
     */
623
    public function valid() {
624
        return isset($this->elements[$this->position]);
625
    }
626
627
    /**
628
     * This returns $this->metadata via __get()
629
     *
630
     * @access protected
631
     *
632
     * @return array The list's metadata
633
     */
634
    protected function _getMetadata() {
635
        return $this->metadata;
636
    }
637
638
    /**
639
     * This sets $this->metadata via __set()
640
     *
641
     * @access protected
642
     *
643
     * @param array $metadata: Array of new metadata
644
     *
645
     * @return void
646
     */
647
    protected function _setMetadata(array $metadata = []) {
648
        $this->metadata = $metadata;
649
    }
650
651
    /**
652
     * This is the constructor
653
     *
654
     * @access public
655
     *
656
     * @param array $elements: Array of documents initially setting up the list
657
     * @param array $metadata: Array of initial metadata
658
     *
659
     * @return void
660
     */
661
    public function __construct(array $elements = [], array $metadata = []) {
662
        if (empty($elements)
663
            && empty($metadata)) {
664
            // Let's check the user's session.
665
            $sessionData = Helper::loadFromSession(get_class($this));
666
            // Restore list from session data.
667
            if (is_array($sessionData)) {
668
                if (is_array($sessionData[0])) {
669
                    $this->elements = $sessionData[0];
670
                }
671
                if (is_array($sessionData[1])) {
672
                    $this->metadata = $sessionData[1];
673
                }
674
            }
675
        } else {
676
            // Add metadata to the list.
677
            $this->metadata = $metadata;
678
            // Add initial set of elements to the list.
679
            $this->elements = $elements;
680
        }
681
        $this->count = count($this->elements);
682
    }
683
684
    /**
685
     * This magic method is invoked each time a clone is called on the object variable
686
     * (This method is defined as private/protected because singleton objects should not be cloned)
687
     *
688
     * @access protected
689
     *
690
     * @return void
691
     */
692
    protected function __clone() {}
693
694
    /**
695
     * This magic method is called each time an invisible property is referenced from the object
696
     *
697
     * @access public
698
     *
699
     * @param string $var: Name of variable to get
700
     *
701
     * @return mixed Value of $this->$var
702
     */
703
    public function __get($var) {
704
        $method = '_get'.ucfirst($var);
705
        if (!property_exists($this, $var)
706
            || !method_exists($this, $method)) {
707
            Helper::devLog('There is no getter function for property "'.$var.'"', DEVLOG_SEVERITY_WARNING);
708
            return;
709
        } else {
710
            return $this->$method();
711
        }
712
    }
713
714
    /**
715
     * This magic method is called each time an invisible property is referenced from the object
716
     *
717
     * @access public
718
     *
719
     * @param string $var: Name of variable to set
720
     * @param mixed $value: New value of variable
721
     *
722
     * @return void
723
     */
724
    public function __set($var, $value) {
725
        $method = '_set'.ucfirst($var);
726
        if (!property_exists($this, $var)
727
            || !method_exists($this, $method)) {
728
            Helper::devLog('There is no setter function for property "'.$var.'"', DEVLOG_SEVERITY_WARNING);
729
        } else {
730
            $this->$method($value);
731
        }
732
    }
733
734
    /**
735
     * This magic method is executed prior to any serialization of the object
736
     * @see __wakeup()
737
     *
738
     * @access public
739
     *
740
     * @return array Properties to be serialized
741
     */
742
    public function __sleep() {
743
        return ['elements', 'metadata'];
744
    }
745
746
    /**
747
     * This magic method is executed after the object is deserialized
748
     * @see __sleep()
749
     *
750
     * @access public
751
     *
752
     * @return void
753
     */
754
    public function __wakeup() {
755
        $this->count = count($this->elements);
756
    }
757
}
758