Test Failed
Push — master ( 75b28b...0c032b )
by Roman
03:23
created

Collection::jsonSerialize()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 1
nc 1
nop 0
dl 0
loc 3
rs 10
c 0
b 0
f 0
1
<?php
2
3
namespace kartavik\Collections;
4
5
use kartavik\Collections\Exceptions\InvalidElementException;
6
7
/**
8
 * Class Collection
9
 * @package kartavik\Collections
10
 */
11
class Collection extends \ArrayObject implements \JsonSerializable
12
{
13
    /** @var string */
14
    protected $type = null;
15
16
    protected function __construct(
17
        array $elements = [],
18
        string $type = null,
19
        int $flags = 0,
20
        string $iteratorClass = \ArrayIterator::class
21
    ) {
22
        $this->type = $type;
23
24
        foreach ($elements as $element) {
25
            $this->instanceOfType($element);
26
        }
27
28
        parent::__construct($elements, $flags, $iteratorClass);
29
    }
30
31
    public function type(): string
32
    {
33
        return $this->type;
34
    }
35
36
    /**
37
     * @param mixed $value
38
     *
39
     * @throws InvalidElementException
40
     */
41
    public function append($value): void
42
    {
43
        $this->instanceOfType($value);
44
45
        parent::append($value);
46
    }
47
48
    /**
49
     * @param mixed $index
50
     * @param mixed $value
51
     *
52
     * @throws InvalidElementException
53
     */
54
    public function offsetSet($index, $value): void
55
    {
56
        $this->instanceOfType($value);
57
58
        parent::offsetSet($index, $value);
59
    }
60
61
    public function jsonSerialize(): array
62
    {
63
        return (array)$this;
64
    }
65
66
    /**
67
     * @param $object
68
     *
69
     * @throws InvalidElementException
70
     */
71
    public function instanceOfType($object): void
72
    {
73
        $type = $this->type();
74
75
        if (!$object instanceof $type) {
76
            throw new InvalidElementException($object, $type);
77
        }
78
    }
79
80
    public function map(callable $function, Collection ...$arrays): Collection
81
    {
82
        $mappedType = get_class(call_user_func(
83
            $function,
84
            $this->offsetGet(0)
85
        ));
86
87
        return Collection::{$mappedType}(array_map(
88
            $function,
89
            $this->jsonSerialize(),
90
            $arrays
91
        ));
92
    }
93
94
    public function chunk(int $size): Collection
95
    {
96
        $mappedType = get_class($this->offsetGet(0));
97
        /** @var Collection $collection */
98
        $collection = Collection::{Collection::class}();
99
        $chunked = array_chunk($this->jsonSerialize(), $size);
100
101
        foreach ($chunked as $index => $chunk) {
102
            $collection->append(Collection::{$mappedType}());
103
104
            foreach ($chunk as $item) {
105
                $collection[$index]->append($item);
106
            }
107
        }
108
109
        return $collection;
110
    }
111
112
    public function column(string $property, callable $function = null): Collection
113
    {
114
        $getterType = get_class($this->offsetGet(0)->{$property}());
115
116
        if (!is_null($function)) {
117
            /** @var Collection $collection */
118
            $collection = Collection::{$getterType}();
119
120
            foreach ($this->jsonSerialize() as $item) {
121
                $collection->append(call_user_func($function, $item->{$property}()));
122
            }
123
124
            return $collection;
125
        } else {
126
            return Collection::{$getterType}(array_map(
127
                function ($item) use ($property) {
128
                    return $item->{$property}();
129
                },
130
                $this->jsonSerialize()
131
            ));
132
        }
133
    }
134
135
    public function pop(): object
136
    {
137
        $last = $this->count() - 1;
138
        $element = $this->offsetGet($last);
139
        $this->offsetUnset($last);
140
141
        return $element;
142
    }
143
144
    public function sum(callable $function)
145
    {
146
        $sum = 0;
147
148
        foreach ($this as $element) {
149
            $sum += call_user_func($function, $element);
150
        }
151
152
        return $sum;
153
    }
154
155
    /**
156
     * @param string $name
157
     * @param array $arguments
158
     *
159
     * @return Collection
160
     */
161
    public static function __callStatic(string $name, array $arguments)
162
    {
163
        if (!empty($arguments) && is_array($arguments[0])) {
164
            $arguments = $arguments[0];
165
        }
166
167
        if (!class_exists($name)) {
168
            throw new \BadMethodCallException("Class with name {$name} does not exist!");
169
        }
170
171
        return new static($arguments, $name);
172
    }
173
}
174