ResourceObject::offsetExists()   A
last analyzed

Complexity

Conditions 2
Paths 2

Size

Total Lines 9
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 2
eloc 5
c 1
b 0
f 0
nc 2
nop 1
dl 0
loc 9
rs 10
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
65
    /**
66
     * Return representational string
67
     *
68
     * Return object hash if representation renderer is not set.
69
     *
70
     * @return string
71
     */
72
    #[Override]
73
    public function __toString()
74
    {
75
        try {
76
            $view = $this->toString();
77
        } catch (Throwable $e) {
78
            $msg = sprintf("%s(%s)\n%s", $e::class, $e->getMessage(), $e->getTraceAsString());
79
            trigger_error($msg, E_USER_WARNING);
80
81
            return '';
82
        }
83
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
    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
97
                $item = ($item)();
98
            }
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
     * @param int|string $offset offset
108
     *
109
     * @return mixed
110
     */
111
    #[Override]
112
    #[ReturnTypeWillChange]
113
    public function offsetGet($offset)
114
    {
115
        if (is_array($this->body)) {
116
            return $this->body[$offset];
117
        }
118
119
        throw new IlligalAccessException((string) $offset);
120
    }
121
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
     */
130
    #[Override]
131
    #[ReturnTypeWillChange]
132
    public function offsetSet($offset, mixed $value)
133
    {
134
        if ($this->body === null) {
135
            $this->body = [];
136
        }
137
138
        if (! is_array($this->body)) {
139
            throw new IlligalAccessException((string) $offset);
140
        }
141
142
        $this->body[$offset] = $value;
143
    }
144
145
    /**
146
     * Returns whether the requested index in body exists
147
     *
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
     *
150
     * @return bool
151
     */
152
    #[Override]
153
    #[ReturnTypeWillChange]
154
    public function offsetExists($offset)
155
    {
156
        if (is_array($this->body)) {
157
            return isset($this->body[$offset]);
158
        }
159
160
        return false;
161
    }
162
163
    /**
164
     * 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
    {
172
        assert(is_array($this->body));
173
        unset($this->body[$offset]);
174
    }
175
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
        }
185
186
        throw new IlligalAccessException();
187
    }
188
189
    /**
190
     * Sort the entries by key
191
     */
192
    public function ksort(): void
193
    {
194
        if (! is_array($this->body)) {
195
            return;
196
        }
197
198
        ksort($this->body);
199
    }
200
201
    /**
202
     * Sort the entries by key
203
     */
204
    public function asort(): void
205
    {
206
        if (! is_array($this->body)) {
207
            return;
208
        }
209
210
        asort($this->body);
211
    }
212
213
    /**
214
     * @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
    {
221
        return is_array($this->body) ? new ArrayIterator($this->body) : new ArrayIterator([]);
222
    }
223
224
    /** @return self */
225
    #[Inject(optional: true)]
226
    public function setRenderer(RenderInterface $renderer)
227
    {
228
        $this->renderer = $renderer;
229
230
        return $this;
231
    }
232
233
    /**
234
     * {@inheritDoc}
235
     */
236
    public function toString(): string
237
    {
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