Issues (169)

src/ResourcePure.php (1 issue)

1
<?php
2
3
declare(strict_types=1);
4
5
namespace BEAR\Resource;
6
7
use Override;
8
use Ray\Di\Di\Set;
9
use Ray\Di\ProviderInterface;
10
11
use function array_merge;
12
use function assert;
13
use function is_string;
14
use function trigger_error;
15
16
use const E_USER_DEPRECATED;
17
18
/**
19
 * Pure singleton Resource client - coroutine safe
20
 *
21
 * This class is stateless and can be safely shared across coroutines.
22
 * For legacy fluent interface usage ($resource->get->uri()), a deprecation
23
 * warning is triggered and a new Resource instance is created for fallback.
24
 *
25
 * @psalm-import-type Query from Types
26
 */
27
final class ResourcePure implements ResourceInterface
28
{
29
    /**
30
     * @param FactoryInterface                   $factory        Resource factory
31
     * @param InvokerInterface                   $invoker        Resource request invoker
32
     * @param AnchorInterface                    $anchor         Resource anchor
33
     * @param ProviderInterface<LinkerInterface> $linkerProvider Resource linker provider
34
     * @param UriFactory                         $uri            URI factory
35
     */
36
    public function __construct(
37
        private readonly FactoryInterface $factory,
38
        private readonly InvokerInterface $invoker,
39
        private readonly AnchorInterface $anchor,
40
        #[Set(LinkerInterface::class)]
41
        private readonly ProviderInterface $linkerProvider,
42
        private readonly UriFactory $uri,
43
    ) {
44
    }
45
46
    /**
47
     * Fallback to legacy Resource for deprecated fluent interface
48
     *
49
     * @deprecated Use createRequest() or direct method calls instead
50
     * @psalm-suppress DeprecatedMethod
51
     */
52
    public function __get(string $name): Resource
53
    {
54
        trigger_error(
55
            'Fluent interface ($resource->get->uri()) is deprecated. Use createRequest() instead.',
56
            E_USER_DEPRECATED,
57
        );
58
59
        // Create a new mutable Resource instance for legacy compatibility
60
        $linker = $this->linkerProvider->get();
61
        $resource = new Resource($this->factory, $this->invoker, $this->anchor, $linker, $this->uri);
62
63
        // Set the method and return for chaining
64
        return $resource->__get($name);
65
    }
66
67
    /**
68
     * {@inheritDoc}
69
     */
70
    #[Override]
71
    public function newInstance($uri): ResourceObject
72
    {
73
        if (is_string($uri)) {
74
            $uri = ($this->uri)($uri);
75
        }
76
77
        return $this->factory->newInstance($uri);
78
    }
79
80
    /**
81
     * {@inheritDoc}
82
     */
83
    #[Override]
84
    public function object(ResourceObject $ro): RequestInterface
85
    {
86
        return new Request($this->invoker, $ro, Request::GET);
87
    }
88
89
    /**
90
     * {@inheritDoc}
91
     *
92
     * @deprecated Use createRequest() instead
93
     */
94
    #[Override]
95
    public function uri($uri): RequestInterface
96
    {
97
        return $this->createRequest(Request::GET, (string) $uri);
98
    }
99
100
    /**
101
     * {@inheritDoc}
102
     */
103
    #[Override]
104
    public function createRequest(string $method, string $uri, array $query = []): RequestInterface
105
    {
106
        $linker = $this->linkerProvider->get();
107
        $ro = $this->newInstance($uri);
108
        $ro->uri->method = $method;
109
        $ro->uri->query = array_merge($ro->uri->query, $query);
0 ignored issues
show
Documentation Bug introduced by
It seems like array_merge($ro->uri->query, $query) of type array is incompatible with the declared type BEAR\Resource\Query of property $query.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
110
111
        return new Request($this->invoker, $ro, $method, $ro->uri->query, [], $linker);
112
    }
113
114
    /**
115
     * {@inheritDoc}
116
     *
117
     * @psalm-suppress NoInterfaceProperties
118
     * @psalm-suppress MixedMethodCall
119
     */
120
    #[Override]
121
    public function crawl(string $uri, string $linkKey, array $query = []): ResourceObject
122
    {
123
        /** @var Request $request */
124
        $request = $this->createRequest(Request::GET, $uri, $query)->linkCrawl($linkKey);
125
        $request->in = 'eager';
126
        $ro = $request->request();
127
        assert($ro instanceof ResourceObject);
128
129
        return $ro;
130
    }
131
132
    /**
133
     * {@inheritDoc}
134
     *
135
     * @psalm-suppress NoInterfaceProperties
136
     * @psalm-suppress MixedMethodCall
137
     */
138
    #[Override]
139
    public function href(string $rel, array $query = [], ResourceObject|null $ro = null): ResourceObject
140
    {
141
        assert($ro instanceof ResourceObject, 'ResourceObject is required for ResourcePure::href()');
142
        $sourceRequest = new Request($this->invoker, $ro, $ro->uri->method, $ro->uri->query);
143
        [$method, $uri] = $this->anchor->href($rel, $sourceRequest, $query);
144
        /** @var Request $request */
145
        $request = $this->createRequest($method, $uri, $query);
146
        $request->in = 'eager';
147
        $result = $request->request();
148
        assert($result instanceof ResourceObject);
149
150
        return $result;
151
    }
152
153
    /**
154
     * {@inheritDoc}
155
     */
156
    #[Override]
157
    public function get(string $uri, array $query = []): ResourceObject
158
    {
159
        return $this->methodUri(Request::GET, $uri)($query);
160
    }
161
162
    /**
163
     * {@inheritDoc}
164
     */
165
    #[Override]
166
    public function post(string $uri, array $query = []): ResourceObject
167
    {
168
        return $this->methodUri(Request::POST, $uri)($query);
169
    }
170
171
    /**
172
     * {@inheritDoc}
173
     */
174
    #[Override]
175
    public function put(string $uri, array $query = []): ResourceObject
176
    {
177
        return $this->methodUri(Request::PUT, $uri)($query);
178
    }
179
180
    /**
181
     * {@inheritDoc}
182
     */
183
    #[Override]
184
    public function patch(string $uri, array $query = []): ResourceObject
185
    {
186
        return $this->methodUri(Request::PATCH, $uri)($query);
187
    }
188
189
    /**
190
     * {@inheritDoc}
191
     */
192
    #[Override]
193
    public function delete(string $uri, array $query = []): ResourceObject
194
    {
195
        return $this->methodUri(Request::DELETE, $uri)($query);
196
    }
197
198
    /**
199
     * {@inheritDoc}
200
     */
201
    #[Override]
202
    public function options(string $uri, array $query = []): ResourceObject
203
    {
204
        return $this->methodUri(Request::OPTIONS, $uri)($query);
205
    }
206
207
    /**
208
     * {@inheritDoc}
209
     */
210
    #[Override]
211
    public function head(string $uri, array $query = []): ResourceObject
212
    {
213
        return $this->methodUri(Request::HEAD, $uri)($query);
214
    }
215
216
    private function methodUri(string $method, string $uri): RequestInterface
217
    {
218
        return $this->createRequest($method, $uri);
219
    }
220
}
221