PublishMySQL::createMySQLDatabase()   B
last analyzed

Complexity

Conditions 5
Paths 17

Size

Total Lines 26
Code Lines 18

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 5
eloc 18
nc 17
nop 0
dl 0
loc 26
rs 8.439
c 0
b 0
f 0
1
<?php
2
3
namespace Acacha\ForgePublish\Commands;
4
5
use Acacha\ForgePublish\Commands\Traits\ChecksEnv;
6
use Acacha\ForgePublish\Commands\Traits\DiesIfEnvVariableIsnotInstalled;
7
use Acacha\ForgePublish\Commands\Traits\WaitsForMySQLDatabase;
8
use GuzzleHttp\Client;
9
use Illuminate\Console\Command;
10
11
/**
12
 * Class PublishMySQL.
13
 *
14
 * @package Acacha\ForgePublish\Commands
15
 */
16
class PublishMySQL extends Command
17
{
18
    use ChecksEnv, DiesIfEnvVariableIsnotInstalled, WaitsForMySQLDatabase;
19
20
    /**
21
     * The name and signature of the console command.
22
     *
23
     * @var string
24
     */
25
    protected $signature = 'publish:mysql {name?} {user?} {password?} {--server=} {--dump} {--wait}';
26
27
    /**
28
     * The console command description.
29
     *
30
     * @var string
31
     */
32
    protected $description = 'Manage MySQL databases';
33
34
    /**
35
     * Server forge id.
36
     *
37
     * @var string
38
     */
39
    protected $server;
40
41
    /**
42
     * API endpoint URL.
43
     *
44
     * @var string
45
     */
46
    protected $url;
47
48
    /**
49
     * Guzzle http client.
50
     *
51
     * @var Client
52
     */
53
    protected $http;
54
55
    /**
56
     * Create a new command instance.
57
     *
58
     */
59
    public function __construct(Client $http)
60
    {
61
        parent::__construct();
62
        $this->http = $http;
63
    }
64
65
    /**
66
     * Execute the console command.
67
     *
68
     */
69
    public function handle()
70
    {
71
        $this->abortCommandExecution();
72
73
        if ($this->argument('name')) {
74
            $this->createMySQLDatabase();
75
        } else {
76
            $this->listMySQLDatabases();
77
        }
78
    }
79
80
    /**
81
     * Create MySQL database.
82
     */
83
    protected function createMySQLDatabase()
84
    {
85
        $this->checkParameters();
86
        $this->url = $this->obtainAPIURLEndpoint();
87
        try {
88
            $this->http->post($this->url, [
89
                    'form_params' => $data = $this->getData(),
90
                    'headers' => [
91
                        'X-Requested-With' => 'XMLHttpRequest',
92
                        'Authorization' => 'Bearer ' . fp_env('ACACHA_FORGE_ACCESS_TOKEN')
93
                    ]
94
                ]
95
            );
96
            if ($this->option('wait')) {
97
                $this->info('Waiting for database to be installed in Laravel Forge server...');
98
                $this->waitForMySQLDatabaseByName($data['name']);
99
                $this->info('Installed!');
100
            }
101
        } catch (\GuzzleHttp\Exception\ServerException $se) {
102
            if (str_contains($se->getResponse()->getBody()->getContents(), 'The given data failed to pass validation')) {
103
                $this->error('Skipping installation. Some of the data you provided already exists in server');
104
            }
105
        } catch (\Exception $e) {
106
            dump($e->getMessage());
107
        }
108
    }
109
110
    /**
111
     * List MySQL databases.
112
     */
113
    protected function listMySQLDatabases()
114
    {
115
        $databases = $this->fetchMySQLDatabases();
116
117
        if ($this->option('dump')) {
118
            dump($databases);
119
        }
120
121
        if (empty($databases)) {
122
            $this->error('No databases found.');
123
            die();
0 ignored issues
show
Coding Style Compatibility introduced by
The method listMySQLDatabases() contains an exit expression.

An exit expression should only be used in rare cases. For example, if you write a short command line script.

In most cases however, using an exit expression makes the code untestable and often causes incompatibilities with other libraries. Thus, unless you are absolutely sure it is required here, we recommend to refactor your code to avoid its usage.

Loading history...
124
        }
125
126
        $headers = ['Id', 'Server Id','Name','Status','Created at'];
127
128
        $rows = [];
129 View Code Duplication
        foreach ($databases as $database) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across 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...
130
            $rows[] = [
131
                $database['id'],
132
                $database['serverId'],
133
                $database['name'],
134
                $database['status'],
135
                $database['createdAt']
136
            ];
137
        }
138
139
        $this->table($headers, $rows);
140
    }
141
142
    /**
143
     * Check parameters.
144
     */
145
    protected function checkParameters()
146
    {
147
        if ($this->argument('user')) {
148
            if (! $this->argument('password')) {
149
                $this->error('Password argument is required if user argument is provided!');
150
                die();
0 ignored issues
show
Coding Style Compatibility introduced by
The method checkParameters() contains an exit expression.

An exit expression should only be used in rare cases. For example, if you write a short command line script.

In most cases however, using an exit expression makes the code untestable and often causes incompatibilities with other libraries. Thus, unless you are absolutely sure it is required here, we recommend to refactor your code to avoid its usage.

Loading history...
151
            }
152
        }
153
    }
154
155
    /**
156
     * Get data.
157
     *
158
     * @return array
159
     */
160 View Code Duplication
    protected function getData()
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...
161
    {
162
        if ($this->argument('user')) {
163
            return [
164
                'name' => $this->argument('name'),
165
                'user' => $this->argument('user'),
166
                'password' => $this->argument('password')
167
            ];
168
        } else {
169
            return [
170
                'name' => $this->argument('name')
171
            ];
172
        }
173
    }
174
175
    /**
176
     * Obtain API URL endpoint.
177
     *
178
     * @return string
179
     */
180
    protected function obtainAPIURLEndpoint()
181
    {
182
        $uri = str_replace('{forgeserver}', $this->server, config('forge-publish.post_mysql_uri'));
183
        return config('forge-publish.url') . $uri;
184
    }
185
186
187
    /**
188
     * Abort command execution.
189
     */
190
    protected function abortCommandExecution()
191
    {
192
        $this->server = $this->checkEnv('server', 'ACACHA_FORGE_SERVER');
193
        $this->dieIfEnvVarIsNotInstalled('ACACHA_FORGE_ACCESS_TOKEN');
194
    }
195
}
196