Passed
Branch dev (5a99cc)
by Kris
01:42
created

ShellUtils   B

Complexity

Total Complexity 48

Size/Duplication

Total Lines 398
Duplicated Lines 0 %

Importance

Changes 4
Bugs 0 Features 0
Metric Value
eloc 122
c 4
b 0
f 0
dl 0
loc 398
rs 8.5599
wmc 48

17 Methods

Rating   Name   Duplication   Size   Complexity  
A printResult() 0 12 4
A printVersion() 0 17 1
A printLogo() 0 11 2
A printBanner() 0 8 2
A isDefaultOuput() 0 3 1
A getScoreBadge() 0 16 3
A printFooter() 0 19 3
A clearTempMessage() 0 5 2
A printTempMessage() 0 4 2
A printTitle() 0 6 2
A hasErrors() 0 3 3
A printFormattedErrors() 0 25 5
A getNumericParameter() 0 13 3
A checkForEmpty() 0 8 3
A parseErrors() 0 19 6
A error() 0 12 2
A validate() 0 9 4

How to fix   Complexity   

Complex Class

Complex classes like ShellUtils often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use ShellUtils, and based on these observations, apply Extract Interface, too.

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, ErrorsTrait;
1 ignored issue
show
Bug introduced by
The trait Kristuff\AbuseIPDB\ErrorsTrait requires the property $errors which is not provided by Kristuff\AbuseIPDB\ShellUtils.
Loading history...
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
     * Check and print errors in API response. 
274
     * 
275
     * @access protected
276
     * @static
277
     * @param object     $response       
278
     * @param bool       $checkForEmpty     
279
     * 
280
     * @return bool     
281
     */
282
    private static function parseErrors(object $response)
283
    {
284
        if (isset($response) && isset($response->errors)){
285
            switch (self::$outputFormat){
286
                case self::OUTPUT_DEFAULT:
287
                    self::printFormattedErrors($response);
288
                    break;
289
290
                case self::OUTPUT_PLAINTEXT:
291
                    self::printPlainTextErrors($response);
292
                    break;
293
294
                case self::OUTPUT_JSON:
295
                    echo json_encode($response, JSON_PRETTY_PRINT);
296
                    break;
297
            }
298
            return true;
299
        }
300
        return false;    
301
    }
302
303
    /**
304
     * Check and print errors in API response. 
305
     * 
306
     * @access protected
307
     * @static
308
     * @param object     $response       
309
     * 
310
     * @return bool     
311
     */
312
    protected static function checkForEmpty(object $response)
313
    {
314
        // check for empty response ?
315
        if ( empty($response) || empty($response->data) ){
316
            self::error('An unexpected error occurred.');
317
            return true;
318
        }
319
        return false;    
320
    }
321
322
    /**
323
     * 
324
     * @access protected
325
     * @static
326
     * @param object     $response       
327
     * 
328
     * @return void     
329
     */
330
    protected static function printFormattedErrors(object $response)
331
    {
332
        // top error badge    
333
        Console::log('  ' .   Console::text(' ERROR ','white', 'red'));
334
335
        $num = 0;
336
        // errors is an array, could have more than one error..
337
        foreach ($response->errors as $err){
338
            $num++;
339
340
            Console::log(Console::text('   ✗', 'red') .  self::printResult(' Number:    ', $num, 'lightyellow','', false));
341
            self::printResult('     Status:    ', $err->status ?? null, 'lightyellow','');    
342
            
343
            if (!empty($err->source) && !empty($err->source->parameter)){
344
                self::printResult('     Parameter: ', $err->source->parameter, 'lightyellow');    
345
            }
346
            self::printResult('     Title:     ', $err->title ?? null, 'lightyellow');    
347
            self::printResult('     Detail:    ', $err->detail ?? null, 'lightyellow');    
348
349
            // separate errors
350
            if (count($response->errors) > 1){
351
                Console::log('   ---');
352
            }
353
        }
354
        Console::log();           
355
    }
356
357
    /**
358
     * Print a single error
359
     * 
360
     * @access protected
361
     * @static
362
     * @param string    $error      The error message
363
     * 
364
     * @return void
365
     */
366
    protected static function error(string $error)
367
    {
368
        if (self::isDefaultOuput()) {
369
            // ✗
370
            Console::log('  ' .   Console::text(' ERROR ','white', 'red'));
371
            Console::log(
372
                Console::text('   ✗', 'red') . 
373
                Console::text(' Detail:    ', 'white') . 
374
                Console::text($error, 'lightyellow') . 
375
                Console::text('', 'white')
376
            );    
377
            Console::log();
378
        }    
379
    }
380
    
381
    /**
382
     * Helper to validate a condition or exit with an error
383
     * 
384
     * @access protected
385
     * @static
386
     * @param bool      $condition      The condition to evaluate
387
     * @param string    $message        Error message
388
     * @param bool      $print          True to print error. Default is true
389
     * 
390
     * @return bool
391
     */
392
    protected static function validate(bool $condition, string $message, bool $print = true)
393
    {
394
        if ( !$condition ){
395
            if ($print && self::isDefaultOuput()) {
396
                Console::log();
397
                self::error($message);
398
                self::printFooter();
399
            }
400
            Program::exit(1);
401
        }
402
    }
403
404
    /**
405
     * Get numeric parameter and exit on error
406
     * 
407
     * @access protected
408
     * @static
409
     * @param array     $arguments
410
     * @param string    $shortArg           The short argument name
411
     * @param string    $longArg            The long argument name
412
     * @param int       $defaultValue
413
     * 
414
     * @return int
415
     */
416
    protected static function getNumericParameter(array $arguments, string $shortArg, string $longArg, int $defaultValue)
417
    {
418
         if (self::inArguments($arguments,$shortArg, $longArg)){
419
            $val = self::getArgumentValue($arguments,$shortArg, $longArg);
420
421
            if (!is_numeric($val)){
422
                self::error("Invalid parameter: $longArg must be a numeric value.");
423
                self::printFooter();
424
                Program::exit(1);
425
            }
426
            return intval($val);
427
        }
428
        return $defaultValue;
429
    }
430
431
}