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(); |
|
|
|
|
124
|
|
|
} |
125
|
|
|
|
126
|
|
|
$headers = ['Id', 'Server Id','Name','Status','Created at']; |
127
|
|
|
|
128
|
|
|
$rows = []; |
129
|
|
View Code Duplication |
foreach ($databases as $database) { |
|
|
|
|
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(); |
|
|
|
|
151
|
|
|
} |
152
|
|
|
} |
153
|
|
|
} |
154
|
|
|
|
155
|
|
|
/** |
156
|
|
|
* Get data. |
157
|
|
|
* |
158
|
|
|
* @return array |
159
|
|
|
*/ |
160
|
|
View Code Duplication |
protected function getData() |
|
|
|
|
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
|
|
|
|
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.