RegisterIdCommand::getClientId()   A
last analyzed

Complexity

Conditions 4
Paths 8

Size

Total Lines 24
Code Lines 12

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 8
CRAP Score 4.9102

Importance

Changes 0
Metric Value
cc 4
eloc 12
nc 8
nop 0
dl 0
loc 24
ccs 8
cts 13
cp 0.6153
crap 4.9102
rs 9.8666
c 0
b 0
f 0
1
<?php
2
/**
3
 * src/Console/RegisterIdCommand.php.
4
 */
5
6
namespace Bmatovu\MtnMomo\Console;
7
8
use Bmatovu\MtnMomo\Traits\CommandUtilTrait;
9
use GuzzleHttp\ClientInterface;
10
use GuzzleHttp\Exception\ClientException;
11
use GuzzleHttp\Exception\ConnectException;
12
use GuzzleHttp\Exception\ServerException;
13
use Illuminate\Console\Command;
14
use Ramsey\Uuid\Uuid;
15
16
/**
17
 * Register client ID in sandbox environment.
18
 *
19
 * The client application ID is a user generate UUID format 4,
20
 * that is then registered with MTN Momo API.
21
 */
22
class RegisterIdCommand extends Command
23
{
24
    use CommandUtilTrait;
25
26
    /**
27
     * Guzzle HTTP client instance.
28
     *
29
     * @var \GuzzleHttp\ClientInterface
30
     */
31
    protected $client;
32
33
    /**
34
     * Product subscribed to.
35
     *
36
     * @var string
37
     */
38
    protected $product;
39
40
    /**
41
     * The name and signature of the console command.
42
     *
43
     * @var string
44
     */
45
    protected $signature = 'mtn-momo:register-id
46
                                {--id= : Client APP ID.}
47
                                {--callback= : Client APP Callback URI.}
48
                                {--product= : Product subscribed to.}
49
                                {--no-write : Don\'t credentials to .env file.}
50
                                {--f|force : Force the operation to run when in production.}';
51
52
    /**
53
     * The console command description.
54
     *
55
     * @var string
56
     */
57
    protected $description = "Register client APP ID; 'apiuser'";
58
59
    /**
60
     * Create a new command instance.
61
     *
62
     * @param \GuzzleHttp\ClientInterface $client
63
     */
64 25
    public function __construct(ClientInterface $client)
65
    {
66 25
        parent::__construct();
67
68 25
        $this->client = $client;
69
    }
70
71
    /**
72
     * Execute the console command.
73
     *
74
     * @throws \GuzzleHttp\Exception\GuzzleException
75
     *
76
     * @return void
77
     */
78 6
    public function handle()
79
    {
80 6
        if (! $this->runInProduction()) {
81 1
            return;
82
        }
83
84 5
        $this->product = $this->option('product');
85
86 5
        if (! $this->product) {
87 5
            $this->product = $this->laravel['config']->get('mtn-momo.product');
88
        }
89
90 5
        $id = $this->getClientId();
91
92 5
        $callbackUri = $this->getClientCallbackUri();
93
94 5
        $providerCallbackHost = parse_url($callbackUri)['host'] ?? '';
95
96 5
        $isRegistered = $this->registerClientId($id, $providerCallbackHost);
97
98 5
        if (! $isRegistered) {
99 2
            return;
100
        }
101
102 4
        $this->info('Writing configurations to .env file...');
103
104 4
        $this->updateSetting("MOMO_{$this->product}_ID", "mtn-momo.products.{$this->product}.id", $id);
105 4
        $this->updateSetting('MOMO_PROVIDER_CALLBACK_HOST', 'mtn-momo.provider_callback_host', $providerCallbackHost);
106 4
        $this->updateSetting("MOMO_{$this->product}_CALLBACK_URI", "mtn-momo.products.{$this->product}.callback_uri", $callbackUri);
107
108 4
        if (! $this->confirm('Do you wish to request for the app secret?', true)) {
109 4
            $this->info("\r\nNext: Validate your client application's ID.");
110 4
            $this->line("\r\n>>> php artisan mtn-momo:validate-id");
111
112 4
            return;
113
        }
114
115
        $this->call('mtn-momo:request-secret', [
116
            '--id' => $id,
117
            '--product' => $this->option('product'),
118
            '--force' => $this->option('force'),
119
        ]);
120
    }
121
122
    /**
123
     * Determine client ID.
124
     *
125
     * @throws \Exception
126
     *
127
     * @return string
128
     */
129 5
    protected function getClientId()
130
    {
131 5
        $this->info('Client APP ID - [X-Reference-Id, api_user_id]');
132
133 5
        $id = $this->option('id');
134
135 5
        if (! $id) {
136
            $id = $this->laravel['config']->get("mtn-momo.products.{$this->product}.id");
137
        }
138
139 5
        if (! $id) {
140
            $this->comment('> Generating random client ID...');
141
142
            $id = Uuid::uuid4()->toString();
143
        }
144
145 5
        $id = $this->ask('Use client app ID?', $id);
146
147 5
        while (! Uuid::isValid($id)) {
148
            $this->info(' Invalid UUID (Format: 4). #IETF RFC4122');
149
            $id = $this->ask('MOMO_CLIENT_ID');
150
        }
151
152 5
        return $id;
153
    }
154
155
    /**
156
     * Determine client Callback URI.
157
     *
158
     * @return string
159
     */
160 5
    protected function getClientCallbackUri()
161
    {
162 5
        $this->info('Client APP callback URI - [X-Callback-Url]');
163
164 5
        $callbackUri = $this->option('callback');
165
166 5
        if (! $callbackUri) {
167
            $callbackUri = $this->laravel['config']->get("mtn-momo.products.{$this->product}.callback_uri");
168
        }
169
170 5
        if (! $callbackUri) {
171
            $callbackUri = $this->laravel['config']->get('app.url');
172
        }
173
174 5
        $callbackUri = $this->ask('Use client app callback URI?', $callbackUri);
175
176 5
        while ($callbackUri && ! filter_var($callbackUri, FILTER_VALIDATE_URL)) {
177
            $this->info(' Invalid URI. #IETF RFC3986');
178
            $callbackUri = $this->ask('MOMO_CLIENT_CALLBACK_URI?');
179
        }
180
181 5
        return $callbackUri;
182
    }
183
184
    /**
185
     * Register client ID.
186
     *
187
     * The Callback URI is implemented in sandbox environment,
188
     * but is still required when registering a client ID.
189
     *
190
     * @link https://momodeveloper.mtn.com/docs/services/sandbox-provisioning-api/operations/post-v1_0-apiuser Documenation.
191
     *
192
     * @param string $clientId
193
     * @param string $providerCallbackHost
194
     *
195
     * @throws \GuzzleHttp\Exception\GuzzleException
196
     *
197
     * @return bool Is registered.
198
     */
199 5
    protected function registerClientId($clientId, $providerCallbackHost)
200
    {
201 5
        $this->info('Registering Client ID');
202
203 5
        $registerIdUri = $this->laravel['config']->get('mtn-momo.api.register_id_uri');
204
205
        try {
206 5
            $response = $this->client->request('POST', $registerIdUri, [
207 5
                'headers' => [
208 5
                    'X-Reference-Id' => $clientId,
209 5
                ],
210 5
                'json' => [
211 5
                    'providerCallbackHost' => $providerCallbackHost,
212 5
                ],
213 5
            ]);
214
215 4
            $this->line("\r\nStatus: <fg=green>".$response->getStatusCode().' '.$response->getReasonPhrase().'</>');
216
217 4
            return true;
218 2
        } catch (ConnectException $ex) {
219 1
            $this->line("\r\n<fg=red>".$ex->getMessage().'</>');
220 1
        } catch (ClientException $ex) {
221 1
            $response = $ex->getResponse();
222 1
            $this->line("\r\nStatus: <fg=yellow>".$response->getStatusCode().' '.$response->getReasonPhrase().'</>');
223 1
            $this->line("\r\nBody: <fg=yellow>".$response->getBody()."\r\n</>");
224
        } catch (ServerException $ex) {
225
            $response = $ex->getResponse();
226
            $this->line("\r\nStatus: <fg=red>".$response->getStatusCode().' '.$response->getReasonPhrase().'</>');
227
            $this->line("\r\nBody: <fg=red>".$response->getBody()."\r\n</>");
228
        }
229
230 2
        return false;
231
    }
232
}
233