ArrayResourceContext::toArray()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 7
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 5
CRAP Score 1

Importance

Changes 0
Metric Value
cc 1
eloc 4
nc 1
nop 1
dl 0
loc 7
ccs 5
cts 5
cp 1
crap 1
rs 10
c 0
b 0
f 0
1
<?php
2
3
namespace Mblarsen\LaravelRepository;
4
5
use Illuminate\Database\Eloquent\Model;
6
use Illuminate\Support\Arr;
7
use InvalidArgumentException;
8
9
final class ArrayResourceContext implements ResourceContext
10
{
11
    /** @var array $context_keys */
12
    protected static $context_keys = [
13
        'filters',
14
        'page',
15
        'per_page',
16
        'sort_by',
17
        'sort_order',
18
        'user',
19
        'with',
20
    ];
21
22
    /** @var array */
23
    protected $context;
24
25 42
    public static function create(array $context = []): self
26
    {
27 42
        return new self($context);
28
    }
29
30 42
    public function __construct(array $context = [])
31
    {
32 42
        $context = $this->validateContext($context);
33
34
        /** @var array */
35 42
        $this->context = $context;
36 42
    }
37
38 42
    public function validateContext(array $context): array
39
    {
40 42
        $valid_keys = self::$context_keys;
41 42
        return Arr::only(
42 42
            $context,
43 42
            array_intersect(
44 42
                $valid_keys,
45 42
                array_keys($context)
46
            )
47
        );
48
    }
49
50 39
    public function validateKey(string $key): string
51
    {
52 39
        [$head] = $this->splitKey($key);
53
54 39
        if (!in_array($head, self::$context_keys)) {
55 1
            throw new InvalidArgumentException("Invalid key '$head'");
56
        }
57
58 38
        return $key;
59
    }
60
61
    /**
62
     * @inheritdoc
63
     */
64 28
    public function filters(): array
65
    {
66 28
        return $this->get('filters', []);
67
    }
68
69
    /**
70
     * @inheritdoc
71
     */
72 22
    public function page(): int
73
    {
74 22
        return $this->get('page', 1);
75
    }
76
77
    /**
78
     * @inheritdoc
79
     */
80 22
    public function perPage(): int
81
    {
82 22
        return $this->get('per_page', 15);
83
    }
84
85
    /**
86
     * @inheritdoc
87
     */
88 25
    public function paginate(): bool
89
    {
90 25
        return (bool) $this->get('page', false);
91
    }
92
93
    /**
94
     * @inheritdoc
95
     */
96 29
    public function sortBy(): array
97
    {
98
        return [
99 29
            $this->get('sort_by', null),
100 29
            $this->get('sort_order', 'asc'),
101
        ];
102
    }
103
104
    /**
105
     * @inheritdoc
106
     */
107 31
    public function with(): array
108
    {
109 31
        return $this->get('with', []);
110
    }
111
112
    /**
113
     * @inheritdoc
114
     */
115 2
    public function user($guard = null): ?Model
116
    {
117 2
        return $this->get('user');
118
    }
119
120 1
    public function merge(array $values)
121
    {
122 1
        $values = $this->validateContext($values);
123
124 1
        $this->context = array_merge_recursive($this->context, $values);
125
126 1
        return $this;
127
    }
128
129 38
    public function get($key, $default = null)
130
    {
131 38
        $this->validateKey($key);
132
133 38
        return data_get($this->context, $key, $default);
134
    }
135
136 3
    public function set(string $key, $value)
137
    {
138 3
        $this->validateKey($key);
139
140 2
        [$head, $tail] = $this->splitKey($key);
141
142 2
        if ($tail) {
143 2
            $this->context[$head][$tail] = $value;
144
        } else {
145 1
            $this->context[$head] = $value;
146
        }
147
148
149 2
        return $this;
150
    }
151
152 2
    public function exclude(array $keys)
153
    {
154 2
        $this->context = Arr::except($this->context, $keys);
155
156 2
        return $this;
157
    }
158
159
    /**
160
     * @inheritdoc
161
     */
162 1
    public function toArray($guard = null): array
163
    {
164 1
        return array_merge(
165 1
            $this->context,
166
            [
167 1
                'paginate' => $this->paginate(),
168 1
                'user' => $this->user($guard)
169
            ]
170
        );
171
    }
172
173 39
    private function splitKey($key)
174
    {
175 39
        $dos_position = strpos($key, '.');
176 39
        $head = $dos_position !== false
177 4
            ? substr($key, 0, $dos_position)
178 39
            : $key;
179 39
        $tail = $dos_position !== false
180 4
            ? substr($key, $dos_position + 1)
181 39
            : null;
182 39
        return [$head, $tail];
183
    }
184
}
185