ResourceObject::offsetGet()   A
last analyzed

Complexity

Conditions 2
Paths 2

Size

Total Lines 9
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 1
CRAP Score 2

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 2
eloc 5
nc 2
nop 1
dl 0
loc 9
ccs 1
cts 1
cp 1
crap 2
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
 * @phpstan-implements ArrayAccess<string, mixed>
35
 * @phpstan-implements IteratorAggregate<(int|string), mixed>
36
 */
37
abstract class ResourceObject implements AcceptTransferInterface, ArrayAccess, Countable, IteratorAggregate, JsonSerializable, Stringable, InvokeRequestInterface
38
{
39
    /**
40
     * @var AbstractUri
41
     * @psalm-suppress PropertyNotSetInConstructor
42
     */
43
    public $uri;
44
45
    /** @var int */
46
    public $code = 200;
47
48
    /** @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...
49
    public $headers = [];
50
51
    /**
52
     * Resource representation
53
     *
54
     * @var ?string
55
     */
56
    public $view;
57
58
    /** @var mixed */
59
    public $body;
60
61
    /** @var ?RenderInterface */
62
    protected $renderer;
63
64 15
    /**
65
     * Return representational string
66
     *
67 15
     * Return object hash if representation renderer is not set.
68 1
     *
69 1
     * @return string
70 1
     */
71
    #[Override]
72 1
    public function __toString()
73
    {
74
        try {
75 14
            $view = $this->toString();
76
        } catch (Throwable $e) {
77
            $msg = sprintf("%s(%s)\n%s", $e::class, $e->getMessage(), $e->getTraceAsString());
78 1
            trigger_error($msg, E_USER_WARNING);
79
80 1
            return '';
81 1
        }
82 1
83 1
        return $view;
84
    }
85
86
    /** @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...
87
    public function __sleep()
88 1
    {
89
        if (is_array($this->body)) {
90
            /** @psalm-suppress MixedAssignment */
91
            foreach ($this->body as &$item) {
92
                if (! ($item instanceof RequestInterface)) {
93
                    continue;
94
                }
95
96 12
                $item = ($item)();
97
            }
98 12
        }
99
100
        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...
101
    }
102
103
    /**
104
     * Returns the body value at the specified index
105
     *
106
     * @param int|string $offset offset
107 37
     *
108
     * @return mixed
109 37
     */
110 37
    #[Override]
111
    #[ReturnTypeWillChange]
112
    public function offsetGet($offset)
113
    {
114
        if (is_array($this->body)) {
115
            return $this->body[$offset];
116
        }
117
118
        throw new IlligalAccessException((string) $offset);
119 3
    }
120
121 3
    /**
122
     * Sets the body value at the specified index to renew
123
     *
124
     * @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...
125
     * @param mixed     $value  value
126
     *
127
     * @return void
128
     */
129 1
    #[Override]
130
    #[ReturnTypeWillChange]
131 1
    public function offsetSet($offset, mixed $value)
132 1
    {
133
        if ($this->body === null) {
134
            $this->body = [];
135
        }
136
137
        if (! is_array($this->body)) {
138
            throw new IlligalAccessException((string) $offset);
139 1
        }
140
141 1
        $this->body[$offset] = $value;
142
    }
143
144
    /**
145
     * Returns whether the requested index in body exists
146
     *
147 2
     * @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...
148
     *
149 2
     * @return bool
150 1
     */
151
    #[Override]
152 1
    #[ReturnTypeWillChange]
153 1
    public function offsetExists($offset)
154
    {
155
        if (is_array($this->body)) {
156
            return isset($this->body[$offset]);
157
        }
158 2
159
        return false;
160 2
    }
161 1
162
    /**
163 1
     * Set the value at the specified index
164 1
     *
165
     * @param int|string $offset offset
166
     */
167
    #[Override]
168
    #[ReturnTypeWillChange]
169
    public function offsetUnset($offset): void
170
    {
171 2
        assert(is_array($this->body));
172
        unset($this->body[$offset]);
173 2
    }
174
175 2
    /**
176
     * Get the number of public properties in the ArrayObject
177
     */
178
    #[Override]
179
    public function count(): int
180
    {
181
        if (is_countable($this->body)) {
182
            return count($this->body);
183
        }
184 50
185
        throw new IlligalAccessException();
186 50
    }
187
188 50
    /**
189
     * Sort the entries by key
190
     */
191
    public function ksort(): void
192
    {
193
        if (! is_array($this->body)) {
194 16
            return;
195
        }
196 16
197 1
        ksort($this->body);
198
    }
199 15
200 4
    /**
201
     * Sort the entries by key
202
     */
203 15
    public function asort(): void
204
    {
205
        if (! is_array($this->body)) {
206 12
            return;
207
        }
208 12
209 12
        asort($this->body);
210 12
    }
211 2
212
    /**
213
     * @return ArrayIterator<int|string, mixed>
214 10
     * @psalm-return ArrayIterator<empty, empty>|ArrayIterator<int|string, mixed>
215
     * @phpstan-return ArrayIterator<int|string, mixed>
216
     */
217
    #[Override]
218
    public function getIterator(): ArrayIterator
219
    {
220 1
        return is_array($this->body) ? new ArrayIterator($this->body) : new ArrayIterator([]);
221
    }
222 1
223 1
    /** @return self */
224
    #[Inject(optional: true)]
225 12
    public function setRenderer(RenderInterface $renderer)
226
    {
227 12
        $this->renderer = $renderer;
228
229 10
        return $this;
230 10
    }
231 5
232 10
    /**
233
     * {@inheritDoc}
234
     */
235
    public function toString(): string
236
    {
237 12
        if (is_string($this->view)) {
238
            return $this->view;
239
        }
240
241
        if (! $this->renderer instanceof RenderInterface) {
242
            $this->renderer = new JsonRenderer();
243
        }
244
245
        return $this->renderer->render($this);
246
    }
247
248
    /** @return array<int|string, mixed> */
249
    #[Override]
250
    public function jsonSerialize(): array
251
    {
252
        /** @psalm-suppress MixedAssignment */
253
        if (! is_iterable($this->body)) {
254
            return ['value' => $this->body];
255
        }
256
257
        assert(is_array($this->body));
258
259
        return $this->body;
260
    }
261
262
    /**
263
     * {@inheritDoc}
264
     */
265
    #[Override]
266
    public function transfer(TransferInterface $responder, array $server)
267
    {
268
        $responder($this, $server);
269
    }
270
271
    public function __clone()
272
    {
273
        $this->uri = clone $this->uri;
274
    }
275
276
    /**
277
     * {@inheritDoc}
278
     *
279
     * @SuppressWarnings(PHPMD.CamelCaseMethodName)
280
     */
281
    #[Override]
282
    public function _invokeRequest(InvokerInterface $invoker, AbstractRequest $request): ResourceObject
283
    {
284
        return $invoker->invoke($request);
285
    }
286
}
287