Passed
Branch dev (d97c1f)
by Kris
01:38
created

ShellUtils::error()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 12
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Importance

Changes 2
Bugs 0 Features 0
Metric Value
cc 2
eloc 8
c 2
b 0
f 0
nc 2
nop 1
dl 0
loc 12
rs 10
1
<?php
2
3
/**
4
 *     _    _                    ___ ____  ____  ____
5
 *    / \  | |__  _   _ ___  ___|_ _|  _ \|  _ \| __ )
6
 *   / _ \ | '_ \| | | / __|/ _ \| || |_) | | | |  _ \
7
 *  / ___ \| |_) | |_| \__ \  __/| ||  __/| |_| | |_) |
8
 * /_/   \_\_.__/ \__,_|___/\___|___|_|   |____/|____/
9
 *
10
 * This file is part of Kristuff\AbsuseIPDB.
11
 *
12
 * (c) Kristuff <[email protected]>
13
 *
14
 * For the full copyright and license information, please view the LICENSE
15
 * file that was distributed with this source code.
16
 *
17
 * @version    0.9.10
18
 * @copyright  2020-2021 Kristuff
19
 */
20
namespace Kristuff\AbuseIPDB;
21
22
use Kristuff\Mishell\Console;
23
use Kristuff\Mishell\Program;
24
use Kristuff\AbuseIPDB\ApiHandler;
25
26
/**
27
 * Class ShellUtils
28
 * 
29
 * Abstract base class for main cli program
30
 */
31
abstract class ShellUtils
32
{
33
    /**
34
     * helper functions
35
     */
36
    use UtilsTrait;
37
  
38
    const OUTPUT_JSON       = 'json';
39
    const OUTPUT_DEFAULT    = 'default';
40
    const OUTPUT_PLAINTEXT  = 'plaintext';
41
    
42
    /**
43
     * @var string      $outputFormat
44
     */
45
    protected static $outputFormat = self::OUTPUT_DEFAULT; 
46
47
    /**
48
     * 
49
     */
50
    protected static function isDefaultOuput()
51
    {
52
        return self::$outputFormat === self::OUTPUT_DEFAULT; 
53
    }
54
55
    /**
56
     * Prints title action banner 
57
     * 
58
     * @access protected
59
     * @static
60
     * @param string    $title
61
     * 
62
     * @return void
63
     */
64
    protected static function printTitle(string $title)
65
    {
66
        if (self::isDefaultOuput()) {
67
            Console::log();
68
            Console::log($title);
69
            Console::log();
70
        }
71
    }
72
  
73
    /**
74
     * Print temp message during api request 
75
     * 
76
     * @access protected
77
     * @static
78
     * @param array $arguments
79
     * 
80
     * @return void
81
     */
82
    protected static function printTempMessage()
83
    {
84
        if (self::isDefaultOuput()) {
85
            Console::reLog(Console::text('   ? ', 'green') . Console::text('waiting for api response', 'white') . Console::text(' ... ', 'green'));
86
        }
87
    }
88
89
    /**
90
     * Clear the temp message set during api request 
91
     * 
92
     * @access protected
93
     * @static
94
     * @param array $arguments
95
     * 
96
     * @return void
97
     */
98
    protected static function clearTempMessage()
99
    {
100
        if (self::isDefaultOuput()) {
101
            // long blank string to overwrite previous message
102
            Console::reLog('                                                     ');
103
        }
104
    }
105
106
    /**
107
     * Print to banner 
108
     * 
109
     * @access protected
110
     * @static
111
     * @param array $arguments
112
     * 
113
     * @return void
114
     */
115
    protected static function printLogo()
116
    {
117
        if (self::isDefaultOuput()) {
118
            //Console::log("   _       _    _         __  __                   ", "darkgray");
119
            //Console::log("  | |___ _(_)__| |_ _  _ / _|/ _|                  ", "darkgray");
120
            //Console::log("  | / / '_| (_-<  _| || |  _|  _|                  ", "darkgray");
121
            //Console::log("  |_\_\_| |_/__/\__|\_,_|_| |_|                    ", "darkgray");
122
            Console::log("        _                 ___ ___ ___  ___        ", "darkgray");
123
            Console::log("   __ _| |__ _  _ ___ ___|_ _| _ \   \| _ )       ", "darkgray");
124
            Console::log("  / _` | '_ \ || (_-</ -_)| ||  _/ |) | _ \       ", "darkgray");
125
            Console::log("  \__,_|_.__/\_,_/__/\___|___|_| |___/|___/       ", "darkgray");
126
        }
127
    }
128
129
    /**
130
     * Print version 
131
     * 
132
     * @access protected
133
     * @static
134
     * @param array $arguments
135
     * 
136
     * @return void
137
     */
138
    protected static function printVersion()
139
    {
140
        self::printLogo();
141
142
        Console::log();
143
        Console::log(Console::text('  Kristuff/AbuseIPDB Client version: ', 'darkgray') . Console::text(AbuseIPDBClient::VERSION, 'lightgray'));
144
        Console::log(Console::text('  Kristuff/AbuseIPDB Core version:   ', 'darkgray') . Console::text(ApiHandler::VERSION, 'lightgray')); 
145
        Console::log(Console::text('  --------------------------------------------------', 'darkgray'));    
146
        Console::log(Console::text('  Released under the MIT licence', 'darkgray'));
147
        Console::log(Console::text('  Made with ', 'darkgray') . Console::text('♥', 'red') . Console::text(' in France', 'darkgray'));
148
        Console::log(
149
            Console::text('  © 2020-2021 Kristuff (', 'darkgray').
150
            Console::text('https://github.com/kristuff', 'darkgray', 'underlined').
151
            Console::text(')', 'darkgray')
152
        );
153
        Console::log(Console::text('  --------------------------------------------------', 'darkgray'));    
154
        Console::log();
155
    }
156
157
    /**
158
     * Print app banner
159
     * 
160
     * @access protected
161
     * @static
162
     * 
163
     * @return void
164
     */
165
    protected static function printBanner()
166
    {
167
        if (self::isDefaultOuput()) {
168
            Console::log();    
169
            Console::log( Console::text(' Kristuff\AbuseIPDB ', 'darkgray') . Console::text(' ' . AbuseIPDBClient::VERSION . ' ', 'white', 'blue')); 
170
            Console::log(Console::text(' Made with ', 'darkgray') . Console::text('♥', 'red') . Console::text(' in France', 'darkgray')); 
171
            Console::log(' © 2020-2021 Kristuff', 'darkgray'); 
172
            Console::log();  
173
        }  
174
    }
175
176
    /**
177
     * Print footer
178
     * 
179
     * @access protected
180
     * @static
181
     * 
182
     * @return void
183
     */
184
    protected static function printFooter(string $requestTime = '')
185
    {
186
        if (self::isDefaultOuput()) {
187
            if (!empty($requestTime)){
188
                $date_utc = new \DateTime("now", new \DateTimeZone("UTC"));
189
                Console::log(
190
                    Console::text('  Request time: ', 'darkgray') . Console::text($requestTime . 's', 'lightgray'). 
191
                    Console::text(' | UTC time: ', 'darkgray') . Console::text($date_utc->format('Y-m-d H:i:s'), 'lightgray')
192
                );
193
            }
194
            Console::log(Console::text('  ------------------------------------------------------------------------------------------------------', 'darkgray')); 
195
            Console::log(
196
                Console::text('  Kristuff\AbuseIPDB ', 'darkgray') . 
197
                Console::text(AbuseIPDBClient::VERSION, 'lightgray') . 
198
                Console::text(' | Made with ', 'darkgray') . 
199
                Console::text('♥', 'red') .
200
                Console::text(' in France | © 2020-2021 Kristuff (https://github.com/kristuff)', 'darkgray')
201
            ); 
202
            Console::log(); 
203
        }   
204
    }
205
206
    /**
207
     * Prints/gets a result value 
208
     * 
209
     * @access protected
210
     * @static
211
     * 
212
     * @return string
213
     */
214
    protected static function printResult($text, $value, string $foregroundColor = 'lightred', string $backgroundColor = '', bool $print = true)
215
    {
216
        
217
        // do not print null/blank values
218
        if (isset($value)){
219
            $line = Console::text($text, 'white') . Console::text($value, $foregroundColor, $backgroundColor); 
220
            if ($print && self::isDefaultOuput()){
221
                Console::log($line);
222
            }
223
            return $line;
224
        }
225
        return '';
226
    }
227
 
228
    /**
229
     * Prints score badge 
230
     * 
231
     * @access protected
232
     * @static
233
     * @param string    $text       
234
     * @param int       $score     
235
     * @param string    $textColor
236
     * 
237
     * @return string
238
     */
239
    protected static function getScoreBadge(int $score, string $padding = ' ')
240
    {
241
        $scoreforegroundColor = 'white';
242
        $scoreBackgroundColor = 'green';
243
244
        if (intval($score) > 0 ){
245
            $scoreforegroundColor = 'black';
246
            $scoreBackgroundColor = 'yellow';
247
        } 
248
        if (intval($score) > 50 ){
249
            $scoreforegroundColor = 'white';
250
            $scoreBackgroundColor = 'red';
251
        } 
252
  
253
        $badge = str_pad($score, 3, ' ',STR_PAD_LEFT); 
254
        return Console::text($padding.$badge.$padding, $scoreforegroundColor, $scoreBackgroundColor);
255
    }
256
257
    /**
258
     * Check and print errors in API response. 
259
     * 
260
     * @access protected
261
     * @static
262
     * @param object     $response       
263
     * @param bool       $checkForEmpty     
264
     * 
265
     * @return bool     
266
     */
267
    protected static function hasErrors(object $response, bool $checkForEmpty = true )
268
    {
269
        return $checkForEmpty ? self::parseErrors($response) || self::checkForEmpty($response) : self::parseErrors($response);
270
    }
271
272
273
    /**
274
     * Check and print errors in API response. 
275
     * 
276
     * @access protected
277
     * @static
278
     * @param object     $response       
279
     * @param bool       $checkForEmpty     
280
     * 
281
     * @return bool     
282
     */
283
    private static function parseErrors(object $response)
284
    {
285
        if (isset($response) && isset($response->errors)){
286
            switch (self::$outputFormat){
287
                case self::OUTPUT_DEFAULT:
288
                    self::printFormattedErrors($response);
289
                    break;
290
291
                case self::OUTPUT_PLAINTEXT:
292
                    self::printPlainTextErrors($response);
293
                    break;
294
295
                case self::OUTPUT_JSON:
296
                    echo json_encode($response, JSON_PRETTY_PRINT);
297
                    break;
298
            }
299
            return true;
300
        }
301
        return false;    
302
    }
303
304
    /**
305
     * Check and print errors in API response. 
306
     * 
307
     * @access protected
308
     * @static
309
     * @param object     $response       
310
     * 
311
     * @return bool     
312
     */
313
    protected static function checkForEmpty(object $response)
314
    {
315
        // check for empty response ?
316
        if ( empty($response) || empty($response->data) ){
317
            self::error('An unexpected error occurred.');
318
            return true;
319
        }
320
        return false;    
321
    }
322
323
    /**
324
     * 
325
     * @access protected
326
     * @static
327
     * @param object     $response       
328
     * 
329
     * @return void     
330
     */
331
    protected static function printFormattedErrors(object $response)
332
    {
333
        // top error badge    
334
        Console::log('  ' .   Console::text(' ERROR ','white', 'red'));
335
336
        $num = 0;
337
        // errors is an array, could have more than one error..
338
        foreach ($response->errors as $err){
339
            $num++;
340
341
            Console::log(Console::text('   ✗', 'red') .  self::printResult(' Number:    ', $num, 'lightyellow','', false));
342
            self::printResult('     Status:    ', $err->status ?? null, 'lightyellow','');    
343
            
344
            if (!empty($err->source) && !empty($err->source->parameter)){
345
                self::printResult('     Parameter: ', $err->source->parameter, 'lightyellow');    
346
            }
347
            self::printResult('     Title:     ', $err->title ?? null, 'lightyellow');    
348
            self::printResult('     Detail:    ', $err->detail ?? null, 'lightyellow');    
349
350
            // separate errors
351
            if (count($response->errors) > 1){
352
                Console::log('   ---');
353
            }
354
355
        }
356
        Console::log();           
357
    }
358
359
    /**
360
     * Check and print errors in API response. Null response object is considered as no errors
361
     * 
362
     * @access protected
363
     * @static
364
     * @param object     $response       
365
     * 
366
     * @return void     
367
     */
368
    protected static function printPlainTextErrors(object $response)
369
    {
370
        foreach ($response->errors as $err){
371
            $text = 'Error: ';
372
            $text .= !empty($err->title) ? ' title: ' . $err->title : '';
373
            $text .= !empty($err->status) ? ' status: ' . $err->status : '';
374
            $text .= !empty($err->source) && !empty($err->source->parameter) ? ' parameter: ' . $err->source->parameter : '';
375
            $text .= !empty($err->detail) ? ' detail: ' . $err->detail : '';
376
            $text .= PHP_EOL;
377
            echo $text;
378
        }
379
    }
380
381
    /**
382
     * Print a single error
383
     * 
384
     * @access protected
385
     * @static
386
     * @param string    $error      The error message
387
     * 
388
     * @return void
389
     */
390
    protected static function error(string $error)
391
    {
392
        if (self::isDefaultOuput()) {
393
            // ✗
394
            Console::log('  ' .   Console::text(' ERROR ','white', 'red'));
395
            Console::log(
396
                Console::text('   ✗', 'red') . 
397
                Console::text(' Detail:    ', 'white') . 
398
                Console::text($error, 'lightyellow') . 
399
                Console::text('', 'white')
400
            );    
401
            Console::log();
402
        }    
403
    }
404
    
405
    /**
406
     * helper to validate a condition or exit with an error
407
     * 
408
     * @access protected
409
     * @static
410
     * @param bool      $condition      The condition to evaluate
411
     * @param string    $message        Error message
412
     * @param bool      $print          True to print error. Default is true
413
     * 
414
     * @return bool
415
     */
416
    protected static function validate(bool $condition, string $message, bool $print = true)
417
    {
418
        if ( !$condition ){
419
            if ($print && self::isDefaultOuput()) {
420
                Console::log();
421
                self::error($message);
422
                self::printFooter();
423
            }
424
            Program::exit(1);
425
        }
426
    }
427
428
    /**
429
     * Get numeric parameter and exit on error
430
     * 
431
     * @access protected
432
     * @static
433
     * @param array     $arguments
434
     * @param string    $shortArg           The short argument name
435
     * @param string    $longArg            The long argument name
436
     * @param int       $defaultValue
437
     * 
438
     * @return int
439
     */
440
    protected static function getNumericParameter(array $arguments, string $shortArg, string $longArg, int $defaultValue)
441
    {
442
         if (self::inArguments($arguments,$shortArg, $longArg)){
443
            $val = self::getArgumentValue($arguments,$shortArg, $longArg);
444
445
            if (!is_numeric($val)){
446
                self::error("Invalid parameter: $longArg must be a numeric value.");
447
                self::printFooter();
448
                Program::exit(1);
449
            }
450
            return intval($val);
451
        }
452
        return $defaultValue;
453
    }
454
455
}