ApiCommand::executeOnMulitpleResources()   A
last analyzed

Complexity

Conditions 2
Paths 2

Size

Total Lines 9
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 9
c 0
b 0
f 0
rs 9.6666
cc 2
eloc 4
nc 2
nop 1
1
<?php
2
3
namespace Zurbaev\ApiClient\Commands;
4
5
use Psr\Http\Message\ResponseInterface;
6
use Zurbaev\ApiClient\Contracts\ApiResourceInterface;
7
8
abstract class ApiCommand
9
{
10
    /**
11
     * Command payload.
12
     *
13
     * @var array
14
     */
15
    protected $payload = [];
16
17
    /**
18
     * Command name.
19
     *
20
     * @return string
21
     */
22
    abstract public function command();
23
24
    /**
25
     * Command description.
26
     *
27
     * @return string
28
     */
29
    public function description()
30
    {
31
        return '';
32
    }
33
34
    /**
35
     * Determines if command can run.
36
     *
37
     * @return bool
38
     */
39
    public function runnable()
40
    {
41
        return true;
42
    }
43
44
    /**
45
     * HTTP request method.
46
     *
47
     * @return string
48
     */
49
    public function requestMethod()
50
    {
51
        return 'POST';
52
    }
53
54
    /**
55
     * HTTP request URL.
56
     *
57
     * @param ApiResourceInterface $owner
58
     *
59
     * @return string
60
     */
61
    public function requestUrl(ApiResourceInterface $owner)
62
    {
63
        return $owner->apiUrl();
64
    }
65
66
    /**
67
     * HTTP request options.
68
     *
69
     * @return array|null
70
     */
71
    public function requestOptions()
72
    {
73
        if (empty($this->payload)) {
74
            return null;
75
        }
76
77
        return [
78
            'json' => $this->payload,
79
        ];
80
    }
81
82
    /**
83
     * Set command payload.
84
     *
85
     * @param array $payload
86
     *
87
     * @return $this
88
     */
89
    public function withPayload(array $payload)
90
    {
91
        $this->payload = $payload;
92
93
        return $this;
94
    }
95
96
    /**
97
     * Set payload data.
98
     *
99
     * @param string|int $key
100
     * @param mixed      $value
101
     *
102
     * @return $this
103
     */
104
    public function attachPayload($key, $value)
105
    {
106
        if (is_null($this->payload)) {
107
            $this->payload = [];
108
        }
109
110
        $this->payload[$key] = $value;
111
112
        return $this;
113
    }
114
115
    /**
116
     * Return payload data.
117
     *
118
     * @param string|int $key
119
     * @param mixed      $default = null
120
     *
121
     * @return mixed|null
122
     */
123
    public function getPayloadData($key, $default = null)
124
    {
125
        if (is_null($this->payload)) {
126
            return null;
127
        }
128
129
        return $this->payload[$key] ?? $default;
130
    }
131
132
    /**
133
     * Determines if payload has requried keys.
134
     *
135
     * @param string|int|array $keys
136
     *
137
     * @return bool
138
     */
139
    public function hasPayloadData($keys): bool
140
    {
141
        if (is_null($this->payload)) {
142
            return false;
143
        }
144
145
        if (!is_array($keys)) {
146
            $keys = [$keys];
147
        }
148
149
        foreach ($keys as $key) {
150
            if (!isset($this->payload[$key])) {
151
                return false;
152
            }
153
        }
154
155
        return true;
156
    }
157
158
    /**
159
     * Execute command on single or multiple resources.
160
     *
161
     * @param array|ApiResourceInterface $resource
162
     *
163
     * @throws \InvalidArgumentException
164
     *
165
     * @return bool|array
166
     */
167
    public function on($resource)
168
    {
169
        if (!$this->runnable()) {
170
            throw new \InvalidArgumentException('Command execution is restricted.');
171
        }
172
173
        if (is_array($resource)) {
174
            return $this->executeOnMulitpleResources($resource);
175
        }
176
177
        return $this->executeOn($resource);
178
    }
179
180
    /**
181
     * Alias for "on" command.
182
     *
183
     * @param array|ApiResourceInterface $resource
184
     *
185
     * @throws \InvalidArgumentException
186
     *
187
     * @return bool|array
188
     */
189
    public function from($resource)
190
    {
191
        return $this->on($resource);
192
    }
193
194
    /**
195
     * Execute current command on given resource.
196
     *
197
     * @param ApiResourceInterface $resource
198
     *
199
     * @return bool|mixed
200
     */
201
    protected function executeOn(ApiResourceInterface $resource)
202
    {
203
        $response = $this->execute($resource);
204
205
        if (method_exists($this, 'handleResponse')) {
206
            return $this->handleResponse($response, $resource);
207
        }
208
209
        return true;
210
    }
211
212
    /**
213
     * Execute current command on multiple resources.
214
     *
215
     * @param array $resources
216
     *
217
     * @return array
218
     */
219
    protected function executeOnMulitpleResources(array $resources): array
220
    {
221
        $results = [];
222
223
        foreach ($resources as $resource) {
224
            $results[$resource->name()] = $this->executeOn($resource);
225
        }
226
227
        return $results;
228
    }
229
230
    /**
231
     * Execute current command.
232
     *
233
     * @param ApiResourceInterface $resource
234
     *
235
     * @return ResponseInterface
236
     */
237
    protected function execute(ApiResourceInterface $resource)
238
    {
239
        $client = $resource->getHttpClient();
240
241
        if (is_null($options = $this->requestOptions())) {
242
            return $client->request($this->requestMethod(), $this->requestUrl($resource));
243
        }
244
245
        return $client->request($this->requestMethod(), $this->requestUrl($resource), $options);
246
    }
247
}
248