Passed
Push — v3 ( dc00fa...37cdd6 )
by
unknown
02:41
created

Recursively   A

Complexity

Total Complexity 7

Size/Duplication

Total Lines 53
Duplicated Lines 0 %

Test Coverage

Coverage 100%

Importance

Changes 1
Bugs 0 Features 0
Metric Value
wmc 7
eloc 16
c 1
b 0
f 0
dl 0
loc 53
ccs 16
cts 16
cp 1
rs 10

2 Methods

Rating   Name   Duplication   Size   Complexity  
A getArrayIteratorCopyOrReference() 0 8 2
A handleArrayIteratorCopyOrReference() 0 31 5
1
<?php
2
/**
3
 * This file is part of GameQ.
4
 *
5
 * GameQ is free software; you can redistribute it and/or modify
6
 * it under the terms of the GNU Lesser General Public License as published by
7
 * the Free Software Foundation; either version 3 of the License, or
8
 * (at your option) any later version.
9
 *
10
 * GameQ is distributed in the hope that it will be useful,
11
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13
 * GNU Lesser General Public License for more details.
14
 *
15
 * You should have received a copy of the GNU Lesser General Public License
16
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
17
 */
18
19
namespace GameQ\Helpers\Arr;
20
21
use ArrayIterator;
22
use Closure;
23
use RecursiveArrayIterator;
24
use RecursiveIteratorIterator;
25
26
/**
27
 * This helper contains functions to work with arrays.
28
 *
29
 * @mixin \GameQ\Helpers\Arr
30
 *
31
 * @package GameQ\Helpers
32
 */
33
trait Recursively
34
{
35
    /**
36
     * This function is responsible for handling behaivour specific to PHP versions before 8.1.
37
     *
38
     * @param array &$data
39
     * @param RecursiveIteratorIterator $recursiveIterator
40
     * @param RecursiveArrayIterator $iterator
41
     * @param Closure $callback
42
     * @return void
43
     */
44 36
    protected static function handleArrayIteratorCopyOrReference(
45
        array &$data,
46
        RecursiveIteratorIterator $recursiveIterator,
47
        RecursiveArrayIterator $iterator,
48
        Closure $callback
49
    ) {
50
        /* ArrayIterator before PHP 8.1 does use a copy instead of reference */
51 36
        if (PHP_VERSION_ID < 80100) {
52
            /* Hash the current state of the iterator */
53 18
            $hashes = static::hashes((array) $iterator);
54
55
            /* Continue with the provided callback */
56 18
            $callback();
57
58
            /* Determine if the current iterator has been modified */
59 18
            if (! empty($diff = array_diff_assoc(static::hashes((array) $iterator), $hashes))) {
60
                /* Determine path to the current iterator */
61 18
                $path = [];
62 18
                for ($depth = 0; $depth < $recursiveIterator->getDepth(); $depth++) {
63 12
                    $path[] = $recursiveIterator->getSubIterator($depth)->key();
64
                }
65
66
                /* Process all modified values */
67 18
                foreach (array_keys($diff) as $modified) {
68
                    /* Write the modified value to the original array */
69 18
                    static::set($data, array_merge($path, [$modified]), $iterator->offsetGet($modified));
70
                }
71
            }
72
        } else {
73
            /* There is no need to write back any changes when ArrayIterator does use a reference */
74 18
            $callback();
75
        }
76 6
    }
77
78 36
    protected static function getArrayIteratorCopyOrReference(array &$data, ArrayIterator $arrayIterator)
79
    {
80 36
        if (PHP_VERSION_ID < 80100) {
81
            /* Return the actual array reference */
82 18
            return $data;
83
        } else {
84
            /* Return the ArrayIterator's internal reference */
85 18
            return $arrayIterator->getArrayCopy();
86
        }
87
    }
88
}
89