ResourceObject   A
last analyzed

Complexity

Total Complexity 31

Size/Duplication

Total Lines 248
Duplicated Lines 0 %

Test Coverage

Coverage 100%

Importance

Changes 13
Bugs 2 Features 0
Metric Value
eloc 71
dl 0
loc 248
rs 9.92
c 13
b 2
f 0
ccs 63
cts 63
cp 1
wmc 31

16 Methods

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