Completed
Push — master ( 7e5acf...5aee8b )
by Timur
02:24
created

Provider::initProvider()   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 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];
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
     * @deprecated since 1.3.1
259
     * @see Provider::asNodeBalancer()
260
     *
261
     * @return static
262
     */
263
    public function asLoadBalancer(bool $install = true)
264
    {
265
        return $this->asNodeBalancer($install);
266
    }
267
268
    /**
269
     * Indicates that server should be provisioned as load balancer.
270
     *
271
     * @param bool $install = true
272
     *
273
     * @return static
274
     */
275
    public function asNodeBalancer(bool $install = true)
276
    {
277
        return $this->togglePayload('node_balancer', $install);
278
    }
279
280
    /**
281
     * Servers ID that the new server should be connected to.
282
     *
283
     * @param array $servers
284
     *
285
     * @return static
286
     */
287
    public function connectedTo(array $servers)
288
    {
289
        $this->payload['network'] = $servers;
290
291
        return $this;
292
    }
293
294
    /**
295
     * Public IP address.
296
     *
297
     * @param string $ip
298
     *
299
     * @return static
300
     */
301
    public function usingPublicIp(string $ip)
302
    {
303
        $this->payload['ip_address'] = $ip;
304
305
        return $this;
306
    }
307
308
    /**
309
     * Private IP address.
310
     *
311
     * @param string $ip
312
     *
313
     * @return static
314
     */
315
    public function usingPrivateIp(string $ip)
316
    {
317
        $this->payload['private_ip_address'] = $ip;
318
319
        return $this;
320
    }
321
322
    /**
323
     * Create new server.
324
     *
325
     * @throws \GuzzleHttp\Exception\RequestException
326
     * @throws \InvalidArgumentException
327
     *
328
     * @return \Laravel\Forge\Server
329
     */
330
    public function save()
331
    {
332
        $validationResult = $this->validate();
333
334
        if ($validationResult !== true) {
335
            throw new InvalidArgumentException(
336
                'Some required parameters are missing: '.implode(', ', $validationResult)
337
            );
338
        }
339
340
        $response = $this->api->getClient()->request('POST', 'servers', [
341
            'json' => $this->sortPayload(),
342
        ]);
343
344
        return Server::createFromResponse($response, $this->api);
345
    }
346
347
    /**
348
     * Sort payload data by key name.
349
     *
350
     * @return array
351
     */
352
    protected function sortPayload(): array
353
    {
354
        $payload = $this->payload;
355
356
        ksort($payload);
357
358
        return $payload;
359
    }
360
361
    /**
362
     * Toggle boolean payload key.
363
     *
364
     * @param string $key
365
     * @param bool   $install
366
     *
367
     * @return static
368
     */
369
    protected function togglePayload(string $key, bool $install)
370
    {
371
        if ($install === false && isset($this->payload[$key])) {
372
            unset($this->payload[$key]);
373
        } elseif ($install === true) {
374
            $this->payload[$key] = 1;
375
        }
376
377
        return $this;
378
    }
379
}
380