Completed
Push — master ( 640af0...429745 )
by Timur
04:28
created

Provider::provider()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 4
rs 10
c 0
b 0
f 0
cc 1
nc 1
nop 0
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, 72, 73];
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 View Code Duplication
    public function withMemoryOf($memory)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
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 View Code Duplication
    public function at(string $region)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
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 View Code Duplication
    public function withMariaDb(string $database = 'forge')
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
231
    {
232
        $this->payload['maria'] = 1;
233
        $this->payload['database'] = $database;
234
        $this->payload['database_type'] = 'maria';
235
236
        return $this;
237
    }
238
239
    /**
240
     * Indicates that server should be provisioned with MySQL.
241
     *
242
     * @param string $database = 'forge'
243
     *
244
     * @return static
245
     */
246 View Code Duplication
    public function withMysql(string $database = 'forge')
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
247
    {
248
        $this->payload['maria'] = 0;
249
        $this->payload['database'] = $database;
250
        $this->payload['database_type'] = 'mysql';
251
252
        return $this;
253
    }
254
255
    /**
256
     * Indicates that server should be provisioned with PostrgreSQL.
257
     *
258
     * @param string $database = 'forge'
259
     *
260
     * @return static
261
     */
262 View Code Duplication
    public function withPostgres(string $database = 'forge')
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
263
    {
264
        $this->payload['maria'] = 0;
265
        $this->payload['database'] = $database;
266
        $this->payload['database_type'] = 'postgres';
267
268
        return $this;
269
    }
270
271
    /**
272
     * Indicates that server should be provisioned as load balancer.
273
     *
274
     * @param bool $install = true
275
     *
276
     * @deprecated since 1.3.1
277
     * @see Provider::asNodeBalancer()
278
     *
279
     * @return static
280
     */
281
    public function asLoadBalancer(bool $install = true)
282
    {
283
        return $this->asNodeBalancer($install);
284
    }
285
286
    /**
287
     * Indicates that server should be provisioned as load balancer.
288
     *
289
     * @param bool $install = true
290
     *
291
     * @return static
292
     */
293
    public function asNodeBalancer(bool $install = true)
294
    {
295
        return $this->togglePayload('node_balancer', $install);
296
    }
297
298
    /**
299
     * Servers ID that the new server should be connected to.
300
     *
301
     * @param array $servers
302
     *
303
     * @return static
304
     */
305
    public function connectedTo(array $servers)
306
    {
307
        $this->payload['network'] = $servers;
308
309
        return $this;
310
    }
311
312
    /**
313
     * Public IP address.
314
     *
315
     * @param string $ip
316
     *
317
     * @return static
318
     */
319
    public function usingPublicIp(string $ip)
320
    {
321
        $this->payload['ip_address'] = $ip;
322
323
        return $this;
324
    }
325
326
    /**
327
     * Private IP address.
328
     *
329
     * @param string $ip
330
     *
331
     * @return static
332
     */
333
    public function usingPrivateIp(string $ip)
334
    {
335
        $this->payload['private_ip_address'] = $ip;
336
337
        return $this;
338
    }
339
340
    /**
341
     * Set recipe that should be run after provisioning.
342
     *
343
     * @param int $id
344
     *
345
     * @return static
346
     */
347
    public function withRecipe(int $id)
348
    {
349
        $this->payload['recipe_id'] = $id;
350
351
        return $this;
352
    }
353
354
    /**
355
     * Create new server.
356
     *
357
     * @throws \GuzzleHttp\Exception\RequestException
358
     * @throws \InvalidArgumentException
359
     *
360
     * @return \Laravel\Forge\Server
361
     */
362
    public function save()
363
    {
364
        $validationResult = $this->validate();
365
366
        if ($validationResult !== true) {
367
            throw new InvalidArgumentException(
368
                'Some required parameters are missing: '.implode(', ', $validationResult)
369
            );
370
        }
371
372
        $response = $this->api->getClient()->request('POST', 'servers', [
373
            'json' => $this->sortPayload(),
374
        ]);
375
376
        return Server::createFromResponse($response, $this->api);
377
    }
378
379
    /**
380
     * Sort payload data by key name.
381
     *
382
     * @return array
383
     */
384
    protected function sortPayload(): array
385
    {
386
        $payload = $this->payload;
387
388
        ksort($payload);
389
390
        return $payload;
391
    }
392
393
    /**
394
     * Toggle boolean payload key.
395
     *
396
     * @param string $key
397
     * @param bool   $install
398
     *
399
     * @return static
400
     */
401
    protected function togglePayload(string $key, bool $install)
402
    {
403
        if ($install === false && isset($this->payload[$key])) {
404
            unset($this->payload[$key]);
405
        } elseif ($install === true) {
406
            $this->payload[$key] = 1;
407
        }
408
409
        return $this;
410
    }
411
}
412