Completed
Push — master ( 28cf18...e97c13 )
by Timur
03:57
created

Provider::hasPayload()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 4
rs 10
c 0
b 0
f 0
cc 1
eloc 2
nc 1
nop 1
1
<?php
2
3
namespace Laravel\Forge\Servers\Providers;
4
5
use Laravel\Forge\Server;
6
use InvalidArgumentException;
7
use Laravel\Forge\ApiProvider;
8
9
abstract class Provider
10
{
11
    /**
12
     * @var \Laravel\Forge\ApiProvider
13
     */
14
    protected $api;
15
16
    /**
17
     * @var array
18
     */
19
    protected $payload = [];
20
21
    /**
22
     * Create new server provider instance.
23
     *
24
     * @param \Laravel\Forge\ApiProvider $api
25
     */
26
    public function __construct(ApiProvider $api)
27
    {
28
        $this->api = $api;
29
        $this->initProvider();
30
    }
31
32
    /**
33
     * Initializes server provider.
34
     */
35
    protected function initProvider()
36
    {
37
        $this->payload['provider'] = $this->provider();
38
    }
39
40
    /**
41
     * Server provider name.
42
     *
43
     * @return string
44
     */
45
    public function provider()
46
    {
47
        return 'abstract';
48
    }
49
50
    /**
51
     * Server provider regions list.
52
     *
53
     * @return array
54
     */
55
    public function regions()
56
    {
57
        return [];
58
    }
59
60
    /**
61
     * Server provider server sizes.
62
     *
63
     * @return array
64
     */
65
    public function sizes()
66
    {
67
        return [];
68
    }
69
70
    /**
71
     * Available PHP versions.
72
     *
73
     * @return array
74
     */
75
    public function phpVersions()
76
    {
77
        return [56, 70, 71];
78
    }
79
80
    /**
81
     * Validates payload before sending to Forge API.
82
     *
83
     * @return bool|array
84
     */
85
    public function validate()
86
    {
87
        return true;
88
    }
89
90
    /**
91
     * Determines if given region is available at current provider.
92
     *
93
     * @param string $region
94
     *
95
     * @return bool
96
     */
97
    public function regionAvailable(string $region)
98
    {
99
        return $this->resourceAvailable($this->regions(), $region);
100
    }
101
102
    /**
103
     * Determines if given memory size is available at current provider.
104
     *
105
     * @param string|int $memory
106
     *
107
     * @return bool
108
     */
109
    public function memoryAvailable($memory)
110
    {
111
        return $this->resourceAvailable($this->sizes(), $memory);
112
    }
113
114
    /**
115
     * Determines if given resource exists in resources list.
116
     *
117
     * @param array $resources
118
     * @param mixed $resource
119
     *
120
     * @return bool
121
     */
122
    protected function resourceAvailable(array $resources, $resource)
123
    {
124
        return isset($resources[$resource]);
125
    }
126
127
    /**
128
     * Determines if given key exists in current payload.
129
     *
130
     * @param string $key
131
     *
132
     * @return bool
133
     */
134
    public function hasPayload(string $key): bool
135
    {
136
        return !empty($this->payload[$key]);
137
    }
138
139
    /**
140
     * Set credential ID to create server with.
141
     *
142
     * @param int $credentialId
143
     *
144
     * @return static
145
     */
146
    public function usingCredential(int $credentialId)
147
    {
148
        $this->payload['credential_id'] = $credentialId;
149
150
        return $this;
151
    }
152
153
    /**
154
     * Set new server name.
155
     *
156
     * @param string $name
157
     *
158
     * @return static
159
     */
160
    public function identifiedAs(string $name)
161
    {
162
        $this->payload['name'] = $name;
163
164
        return $this;
165
    }
166
167
    /**
168
     * Set memory / server size.
169
     *
170
     * @param int|string $memory
171
     *
172
     * @return static
173
     */
174
    public function withMemoryOf($memory)
175
    {
176
        if (!$this->memoryAvailable($memory)) {
177
            throw new InvalidArgumentException('Given memory value is not supported by '.$this->provider().' provider.');
178
        }
179
180
        $this->payload['size'] = $memory;
181
182
        return $this;
183
    }
184
185
    /**
186
     * Set server region.
187
     *
188
     * @param string $region
189
     *
190
     * @return static
191
     */
192
    public function at(string $region)
193
    {
194
        if (!$this->regionAvailable($region)) {
195
            throw new InvalidArgumentException('Given region is not supported by '.$this->provider().' provider.');
196
        }
197
198
        $this->payload['region'] = $region;
199
200
        return $this;
201
    }
202
203
    /**
204
     * Set PHP version.
205
     *
206
     * @param int|string $version
207
     *
208
     * @return static
209
     */
210
    public function runningPhp($version)
211
    {
212
        $phpVersion = intval(str_replace(['php', '.'], '', $version));
213
214
        if (!in_array($phpVersion, $this->phpVersions())) {
215
            throw new InvalidArgumentException('PHP version "php'.$phpVersion.'" is not supported.');
216
        }
217
218
        $this->payload['php_version'] = 'php'.$phpVersion;
219
220
        return $this;
221
    }
222
223
    /**
224
     * Indicates that server should be provisioned with MariaDB instead of MySQL.
225
     *
226
     * @param string $database = 'forge'
227
     *
228
     * @return static
229
     */
230
    public function withMariaDb(string $database = 'forge')
231
    {
232
        $this->payload['maria'] = 1;
233
        $this->payload['database'] = $database;
234
235
        return $this;
236
    }
237
238
    /**
239
     * Indicates that server should be provisioned with MySQL.
240
     *
241
     * @param string $database = 'forge'
242
     *
243
     * @return static
244
     */
245
    public function withMysql(string $database = 'forge')
246
    {
247
        $this->payload['maria'] = 0;
248
        $this->payload['database'] = $database;
249
250
        return $this;
251
    }
252
253
    /**
254
     * Indicates that server should be provisioned as load balancer.
255
     *
256
     * @param bool $install = true
257
     *
258
     * @return static
259
     */
260
    public function asLoadBalancer(bool $install = true)
261
    {
262
        return $this->togglePayload('load_balancer', $install);
263
    }
264
265
    /**
266
     * Servers ID that the new server should be connected to.
267
     *
268
     * @param array $servers
269
     *
270
     * @return static
271
     */
272
    public function connectedTo(array $servers)
273
    {
274
        $this->payload['network'] = $servers;
275
276
        return $this;
277
    }
278
279
    /**
280
     * Public IP address.
281
     *
282
     * @param string $ip
283
     *
284
     * @return static
285
     */
286
    public function usingPublicIp(string $ip)
287
    {
288
        $this->payload['ip_address'] = $ip;
289
290
        return $this;
291
    }
292
293
    /**
294
     * Private IP address.
295
     *
296
     * @param string $ip
297
     *
298
     * @return static
299
     */
300
    public function usingPrivateIp(string $ip)
301
    {
302
        $this->payload['private_ip_address'] = $ip;
303
304
        return $this;
305
    }
306
307
    /**
308
     * Create new server.
309
     *
310
     * @throws \GuzzleHttp\Exception\RequestException
311
     * @throws \InvalidArgumentException
312
     *
313
     * @return \Laravel\Forge\Server
314
     */
315
    public function save()
316
    {
317
        $validationResult = $this->validate();
318
319
        if ($validationResult !== true) {
320
            throw new InvalidArgumentException(
321
                'Some required parameters are missing: '.implode(', ', $validationResult)
322
            );
323
        }
324
325
        $response = $this->api->getClient()->request('POST', 'servers', [
326
            'form_params' => $this->sortPayload(),
327
        ]);
328
329
        return Server::createFromResponse($response, $this->api);
330
    }
331
332
    /**
333
     * Sort payload data by key name.
334
     *
335
     * @return array
336
     */
337
    protected function sortPayload(): array
338
    {
339
        $payload = $this->payload;
340
341
        ksort($payload);
342
343
        return $payload;
344
    }
345
346
    /**
347
     * Toggle boolean payload key.
348
     *
349
     * @param string $key
350
     * @param bool   $install
351
     *
352
     * @return static
353
     */
354
    protected function togglePayload(string $key, bool $install)
355
    {
356
        if ($install === false && isset($this->payload[$key])) {
357
            unset($this->payload[$key]);
358
        } elseif ($install === true) {
359
            $this->payload[$key] = 1;
360
        }
361
362
        return $this;
363
    }
364
}
365