ArrayObject   A
last analyzed

Complexity

Total Complexity 15

Size/Duplication

Total Lines 104
Duplicated Lines 0 %

Test Coverage

Coverage 100%

Importance

Changes 0
Metric Value
eloc 30
dl 0
loc 104
c 0
b 0
f 0
rs 10
ccs 37
cts 37
cp 1
wmc 15

8 Methods

Rating   Name   Duplication   Size   Complexity  
A set() 0 4 1
A setElements() 0 4 1
A getElements() 0 3 1
A sortByKey() 0 14 2
A each() 0 5 3
A reindexByColumn() 0 20 5
A append() 0 4 1
A __construct() 0 3 1
1
<?php
2
3
declare(strict_types=1);
4
5
namespace DanBettles\Gestalt;
6
7
use Closure;
8
use InvalidArgumentException;
9
10
use function array_flip;
11
use function array_intersect_key;
12
use function array_key_exists;
13
use function array_replace;
14
use function is_array;
15
use function is_object;
16
use function ksort;
17
18
use const false;
19
20
/**
21
 * A simple array class.  Instances are mutable (i.e. methods change the state of the object).
22
 */
23
class ArrayObject
24
{
25
    /** @var array */
26
    private $elements;
27
28 17
    public function __construct(array $elements = [])
29
    {
30 17
        $this->setElements($elements);
31
    }
32
33
    /**
34
     * Appends an element with the specified value.
35
     *
36
     * @param mixed $value
37
     */
38 1
    public function append($value): self
39
    {
40 1
        $this->elements[] = $value;
41 1
        return $this;
42
    }
43
44
    /**
45
     * Adds or updates an element.
46
     *
47
     * @param mixed $key
48
     * @param mixed $value
49
     */
50 1
    public function set($key, $value): self
51
    {
52 1
        $this->elements[$key] = $value;
53 1
        return $this;
54
    }
55
56 17
    private function setElements(array $elements): self
57
    {
58 17
        $this->elements = $elements;
59 17
        return $this;
60
    }
61
62 17
    public function getElements(): array
63
    {
64 17
        return $this->elements;
65
    }
66
67
    /**
68
     * When no arguments are passed, behaves the same as [ksort()](https://www.php.net/manual/en/function.ksort.php).
69
     * Otherwise, the elements can be put in the order specified in `$order`; this applies to arrays with numeric or
70
     * non-numeric keys.
71
     */
72 7
    public function sortByKey(array $order = []): self
73
    {
74 7
        if (empty($order)) {
75 3
            $sorted = $this->getElements();
76 3
            ksort($sorted);
77
78 3
            return $this->setElements($sorted);
79
        }
80
81 4
        $elements = $this->getElements();
82 4
        $base = array_intersect_key(array_flip($order), $elements);
83 4
        $sorted = array_replace($base, $elements);
84
85 4
        return $this->setElements($sorted);
86
    }
87
88
    /**
89
     * Executes the callback for each of the elements.  The callback is passed the key and the value of the current
90
     * element, in that order.  `each()` will stop iterating if the callback returns exactly `false`.
91
     */
92 2
    public function each(Closure $callback): void
93
    {
94 2
        foreach ($this->getElements() as $key => $value) {
95 2
            if (false === $callback($key, $value)) {
96 1
                return;
97
            }
98
        }
99
    }
100
101
    /**
102
     * Reindexes the elements, which must be array/object records, using the values in the column with the specified key.
103
     *
104
     * @throws InvalidArgumentException If an element is not a record.
105
     * @throws InvalidArgumentException If a record does not contain a field with the specified name.
106
     */
107 5
    public function reindexByColumn(string $columnKey): self
108
    {
109 5
        $reindexed = [];
110
111 5
        foreach ($this->getElements() as $key => $element) {
112 5
            if (!is_array($element) && !is_object($element)) {
113 1
                throw new InvalidArgumentException("The element at index `{$key}` is not a record.");
114
            }
115
116 5
            $normalizedRecord = (array) $element;
117
118 5
            if (!array_key_exists($columnKey, $normalizedRecord)) {
119 1
                throw new InvalidArgumentException("The record at index `{$key}` does not contain the field `{$columnKey}`.");
120
            }
121
122 5
            $newKey = $normalizedRecord[$columnKey];
123 5
            $reindexed[$newKey] = $element;
124
        }
125
126 3
        return $this->setElements($reindexed);
127
    }
128
}
129