ResourceObject::offsetSet()   A
last analyzed

Complexity

Conditions 3
Paths 4

Size

Total Lines 13
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 4
CRAP Score 3

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 3
eloc 7
nc 4
nop 2
dl 0
loc 13
ccs 4
cts 4
cp 1
crap 3
rs 10
c 1
b 0
f 0
1
<?php
2
3
declare(strict_types=1);
4
5
namespace BEAR\Resource;
6
7
use ArrayAccess;
8
use ArrayIterator;
9
use BEAR\Resource\Exception\IlligalAccessException;
10
use Countable;
11
use IteratorAggregate;
12
use JsonSerializable;
13
use Override;
14
use Ray\Di\Di\Inject;
15
use ReturnTypeWillChange;
0 ignored issues
show
Bug introduced by
The type ReturnTypeWillChange was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
16
use Stringable;
17
use Throwable;
18
19
use function asort;
20
use function assert;
21
use function count;
22
use function is_array;
23
use function is_countable;
24
use function is_iterable;
25
use function is_string;
26
use function ksort;
27
use function sprintf;
28
use function trigger_error;
29
30
use const E_USER_WARNING;
31
32
/**
33
 * @psalm-import-type Headers from Types
34
 * @psalm-import-type Body from Types
35
 * @phpstan-implements ArrayAccess<string, mixed>
36
 * @phpstan-implements IteratorAggregate<(int|string), mixed>
37
 */
38
abstract class ResourceObject implements AcceptTransferInterface, ArrayAccess, Countable, IteratorAggregate, JsonSerializable, Stringable, InvokeRequestInterface
39
{
40
    /**
41
     * @var AbstractUri
42
     * @psalm-suppress PropertyNotSetInConstructor
43
     */
44
    public $uri;
45
46
    /** @var int */
47
    public $code = 200;
48
49
    /** @var Headers */
0 ignored issues
show
Bug introduced by
The type BEAR\Resource\Headers was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
50
    public $headers = [];
51
52
    /**
53
     * Resource representation
54
     *
55
     * @var ?string
56
     */
57
    public $view;
58
59
    /** @var mixed */
60
    public $body;
61
62
    /** @var ?RenderInterface */
63
    protected $renderer;
64 15
65
    /**
66
     * Return representational string
67 15
     *
68 1
     * Return object hash if representation renderer is not set.
69 1
     *
70 1
     * @return string
71
     */
72 1
    #[Override]
73
    public function __toString()
74
    {
75 14
        try {
76
            $view = $this->toString();
77
        } catch (Throwable $e) {
78 1
            $msg = sprintf("%s(%s)\n%s", $e::class, $e->getMessage(), $e->getTraceAsString());
79
            trigger_error($msg, E_USER_WARNING);
80 1
81 1
            return '';
82 1
        }
83 1
84
        return $view;
85
    }
86
87
    /** @return list<string> */
0 ignored issues
show
Bug introduced by
The type BEAR\Resource\list was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
88 1
    public function __sleep()
89
    {
90
        if (is_array($this->body)) {
91
            /** @psalm-suppress MixedAssignment */
92
            foreach ($this->body as &$item) {
93
                if (! ($item instanceof RequestInterface)) {
94
                    continue;
95
                }
96 12
97
                $item = ($item)();
98 12
            }
99
        }
100
101
        return ['uri', 'code', 'headers', 'body', 'view'];
0 ignored issues
show
Bug Best Practice introduced by
The expression return array('uri', 'cod...aders', 'body', 'view') returns the type array<integer,string> which is incompatible with the documented return type BEAR\Resource\list.
Loading history...
102
    }
103
104
    /**
105
     * Returns the body value at the specified index
106
     *
107 37
     * @param int|string $offset offset
108
     *
109 37
     * @return mixed
110 37
     */
111
    #[Override]
112
    #[ReturnTypeWillChange]
113
    public function offsetGet($offset)
114
    {
115
        if (is_array($this->body)) {
116
            return $this->body[$offset];
117
        }
118
119 3
        throw new IlligalAccessException((string) $offset);
120
    }
121 3
122
    /**
123
     * Sets the body value at the specified index to renew
124
     *
125
     * @param array-key $offset offset
0 ignored issues
show
Documentation Bug introduced by
The doc comment array-key at position 0 could not be parsed: Unknown type name 'array-key' at position 0 in array-key.
Loading history...
126
     * @param mixed     $value  value
127
     *
128
     * @return void
129 1
     */
130
    #[Override]
131 1
    #[ReturnTypeWillChange]
132 1
    public function offsetSet($offset, mixed $value)
133
    {
134
        if ($this->body === null) {
135
            $this->body = [];
136
        }
137
138
        if (! is_array($this->body)) {
139 1
            throw new IlligalAccessException((string) $offset);
140
        }
141 1
142
        $this->body[$offset] = $value;
143
    }
144
145
    /**
146
     * Returns whether the requested index in body exists
147 2
     *
148
     * @param array-key $offset offset
0 ignored issues
show
Documentation Bug introduced by
The doc comment array-key at position 0 could not be parsed: Unknown type name 'array-key' at position 0 in array-key.
Loading history...
149 2
     *
150 1
     * @return bool
151
     */
152 1
    #[Override]
153 1
    #[ReturnTypeWillChange]
154
    public function offsetExists($offset)
155
    {
156
        if (is_array($this->body)) {
157
            return isset($this->body[$offset]);
158 2
        }
159
160 2
        return false;
161 1
    }
162
163 1
    /**
164 1
     * Set the value at the specified index
165
     *
166
     * @param int|string $offset offset
167
     */
168
    #[Override]
169
    #[ReturnTypeWillChange]
170
    public function offsetUnset($offset): void
171 2
    {
172
        assert(is_array($this->body));
173 2
        unset($this->body[$offset]);
174
    }
175 2
176
    /**
177
     * Get the number of public properties in the ArrayObject
178
     */
179
    #[Override]
180
    public function count(): int
181
    {
182
        if (is_countable($this->body)) {
183
            return count($this->body);
184 50
        }
185
186 50
        throw new IlligalAccessException();
187
    }
188 50
189
    /**
190
     * Sort the entries by key
191
     */
192
    public function ksort(): void
193
    {
194 16
        if (! is_array($this->body)) {
195
            return;
196 16
        }
197 1
198
        ksort($this->body);
199 15
    }
200 4
201
    /**
202
     * Sort the entries by key
203 15
     */
204
    public function asort(): void
205
    {
206 12
        if (! is_array($this->body)) {
207
            return;
208 12
        }
209 12
210 12
        asort($this->body);
211 2
    }
212
213
    /**
214 10
     * @return ArrayIterator<int|string, mixed>
215
     * @psalm-return ArrayIterator<empty, empty>|ArrayIterator<int|string, mixed>
216
     * @phpstan-return ArrayIterator<int|string, mixed>
217
     */
218
    #[Override]
219
    public function getIterator(): ArrayIterator
220 1
    {
221
        return is_array($this->body) ? new ArrayIterator($this->body) : new ArrayIterator([]);
222 1
    }
223 1
224
    /** @return self */
225 12
    #[Inject(optional: true)]
226
    public function setRenderer(RenderInterface $renderer)
227 12
    {
228
        $this->renderer = $renderer;
229 10
230 10
        return $this;
231 5
    }
232 10
233
    /**
234
     * {@inheritDoc}
235
     */
236
    public function toString(): string
237 12
    {
238
        if (is_string($this->view)) {
239
            return $this->view;
240
        }
241
242
        if (! $this->renderer instanceof RenderInterface) {
243
            $this->renderer = new JsonRenderer();
244
        }
245
246
        return $this->renderer->render($this);
247
    }
248
249
    /** @return Body */
0 ignored issues
show
Bug introduced by
The type BEAR\Resource\Body was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
250
    #[Override]
251
    public function jsonSerialize(): array
252
    {
253
        /** @psalm-suppress MixedAssignment */
254
        if (! is_iterable($this->body)) {
255
            return ['value' => $this->body];
0 ignored issues
show
Bug Best Practice introduced by
The expression return array('value' => $this->body) returns the type array<string,mixed> which is incompatible with the documented return type BEAR\Resource\Body.
Loading history...
256
        }
257
258
        assert(is_array($this->body));
259
260
        return $this->body;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this->body returns the type array which is incompatible with the documented return type BEAR\Resource\Body.
Loading history...
261
    }
262
263
    /**
264
     * {@inheritDoc}
265
     */
266
    #[Override]
267
    public function transfer(TransferInterface $responder, array $server)
268
    {
269
        $responder($this, $server);
270
    }
271
272
    public function __clone()
273
    {
274
        $this->uri = clone $this->uri;
275
    }
276
277
    /**
278
     * {@inheritDoc}
279
     *
280
     * @SuppressWarnings(PHPMD.CamelCaseMethodName) Underscore prefix indicates internal API method
281
     */
282
    #[Override]
283
    public function _invokeRequest(InvokerInterface $invoker, AbstractRequest $request): ResourceObject
284
    {
285
        return $invoker->invoke($request);
286
    }
287
}
288