GitHub Access Token became invalid

It seems like the GitHub access token used for retrieving details about this repository from GitHub became invalid. This might prevent certain types of inspections from being run (in particular, everything related to pull requests).
Please ask an admin of your repository to re-new the access token on this website.
Passed
Push — master ( b54a62...410491 )
by Steeven
03:04
created

AbstractCommander::execute()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 6
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
eloc 4
nc 2
nop 0
dl 0
loc 6
rs 10
c 0
b 0
f 0
1
<?php
2
/**
3
 * This file is part of the O2System Framework package.
4
 *
5
 * For the full copyright and license information, please view the LICENSE
6
 * file that was distributed with this source code.
7
 *
8
 * @author         Steeve Andrian Salim
9
 * @copyright      Copyright (c) Steeve Andrian Salim
10
 */
11
12
// ------------------------------------------------------------------------
13
14
namespace O2System\Kernel\Cli\Abstracts;
15
16
// ------------------------------------------------------------------------
17
18
use O2System\Kernel\Cli\Writers\Format;
19
use O2System\Kernel\Cli\Writers\Table;
20
21
/**
22
 * Class AbstractCommander
23
 *
24
 * @package O2System\Cli\Abstracts
25
 */
26
abstract class AbstractCommander
27
{
28
    /**
29
     * AbstractCommander::$commandName
30
     *
31
     * Command name.
32
     *
33
     * @var string
34
     */
35
    protected $commandName;
36
37
    /**
38
     * AbstractCommander::$commandVersion
39
     *
40
     * Command version.
41
     *
42
     * @var string
43
     */
44
    protected $commandVersion;
45
46
    /**
47
     * AbstractCommander::$commandDescription
48
     *
49
     * Command description.
50
     *
51
     * @var string
52
     */
53
    protected $commandDescription;
54
55
    /**
56
     * AbstractCommander::$commandOptions
57
     *
58
     * Command options.
59
     *
60
     * @var array
61
     */
62
    protected $commandOptions = [];
63
64
    /**
65
     * AbstractCommander::$commandOptionsShortcuts
66
     *
67
     * Command options.
68
     *
69
     * @var array
70
     */
71
    protected $commandOptionsShortcuts = [
72
        '-h'  => 'help',
73
        '-v'  => 'version',
74
        '-vv' => 'verbose',
75
    ];
76
77
    protected $actionsPool = [];
78
79
    /**
80
     * AbstractCommander::$verbose
81
     *
82
     * Command options.
83
     *
84
     * @var bool
85
     */
86
    protected $optionVerbose = false;
87
88
    // ------------------------------------------------------------------------
89
90
    /**
91
     * AbstractCommander::__construct
92
     *
93
     * Commander class constructor.
94
     *
95
     * @final   This method cannot be overwritten.
96
     */
97
    final public function __construct()
98
    {
99
        language()->loadFile('cli');
100
101
        $className = explode('Commanders\\', get_class($this));
102
        $className = str_replace('\\', '/', end($className));
103
        $this->commandName = implode('/', array_map('strtolower', explode('/', $className)));
104
105
        foreach ($this->commandOptions as $optionName => $optionConfig) {
106
            $shortcut = empty($optionConfig[ 'shortcut' ])
107
                ? '-' . substr($optionName, 0, 1)
108
                : '-' . rtrim($optionConfig[ 'shortcut' ]);
109
110
            if (array_key_exists($shortcut, $this->commandOptionsShortcuts)) {
111
                $shortcut = '-' . substr($optionName, 0, 2);
112
            }
113
114
            $this->commandOptions[ $optionName ][ 'shortcut' ] = $shortcut;
115
116
            $this->commandOptionsShortcuts[ $shortcut ] = $optionName;
117
        }
118
119
        if (array_key_exists('VERBOSE', $_ENV)) {
120
            $this->optionVerbose = true;
121
        }
122
    }
123
124
    // ------------------------------------------------------------------------
125
126
    /**
127
     * AbstractCommander::setCommandOptions
128
     *
129
     * Sets command options.
130
     *
131
     * @param array $commandOptions Array of commander options.
132
     *
133
     * @return static
134
     */
135
    public function setCommandOptions(array $commandOptions)
136
    {
137
        foreach ($commandOptions as $caller => $props) {
138
            call_user_func_array([&$this, 'addOption'], $props);
139
        }
140
141
        return $this;
142
    }
143
144
    // ------------------------------------------------------------------------
145
146
    /**
147
     * AbstractCommander::addCommandOption
148
     *
149
     * Add command option.
150
     *
151
     * @param string $optionName
152
     * @param string $optionDescription
153
     * @param string $optionShortcut
154
     *
155
     * @return $this;
156
     */
157
    public function addCommandOption($optionName, $optionDescription, $optionShortcut = null)
158
    {
159
        $optionShortcut = empty($optionShortcut)
160
            ? '-' . substr($optionName, 0, 1)
161
            : '-' . rtrim($optionShortcut);
162
163
        $this->commandOptions[ $optionName ] = [
164
            'shortcut'    => $optionShortcut,
165
            'description' => $optionDescription,
166
        ];
167
    }
168
169
    // ------------------------------------------------------------------------
170
171
    /**
172
     * AbstractCommander::optionVersion
173
     *
174
     * Option version method, write commander version string.
175
     *
176
     * @return void
177
     */
178
    public function optionVersion()
179
    {
180
        if (property_exists($this, 'commandVersion')) {
181
            if ( ! empty($this->commandVersion)) {
182
                // Show Name & Version Line
183
                output()->write(
0 ignored issues
show
Bug introduced by
The method write() does not exist on O2System\Kernel\Http\Output. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

183
                output()->/** @scrutinizer ignore-call */ write(

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
184
                    (new Format())
185
                        ->setContextualClass(Format::INFO)
186
                        ->setString(ucfirst($this->commandName) . ' v' . $this->commandVersion)
187
                        ->setNewLinesAfter(1)
188
                );
189
            }
190
        }
191
    }
192
193
    // ------------------------------------------------------------------------
194
195
    /**
196
     * AbstractCommander::optionVerbose
197
     *
198
     * Option verbose method, activate verbose output mode.
199
     *
200
     * @return void
201
     */
202
    public function optionVerbose()
203
    {
204
        $this->optionVerbose = true;
205
    }
206
207
    /**
208
     * AbstractCommander::__callOptions
209
     *
210
     * Options call executer.
211
     *
212
     * @return void
213
     */
214
    protected function __callOptions()
215
    {
216
        if (false !== ($options = input()->get())) {
217
            if (count($options)) {
218
                $command = new \ReflectionClass($this);
219
220
                foreach ($options as $method => $arguments) {
221
222
                    if (array_key_exists('-' . $method, $this->commandOptionsShortcuts)) {
223
                        $method = $this->commandOptionsShortcuts[ '-' . $method ];
224
                    }
225
226
                    if ($command->hasMethod($commandMethodName = camelcase('option-' . $method))) {
227
                        $commandMethod = $command->getMethod($commandMethodName);
228
                    } elseif ($command->hasMethod($commandMethodName = camelcase($method))) {
229
                        $commandMethod = $command->getMethod($commandMethodName);
230
                    }
231
232
                    if ($commandMethod instanceof \ReflectionMethod) {
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $commandMethod does not seem to be defined for all execution paths leading up to this point.
Loading history...
233
                        if ($commandMethod->getNumberOfRequiredParameters() == 0) {
234
                            call_user_func([&$this, $commandMethodName]);
235
                        } elseif ($commandMethod->getNumberOfRequiredParameters() > 0 and empty($arguments)) {
236
                            if (isset($this->commandOptions[ $method ][ 'help' ])) {
237
                                output()->write(
238
                                    (new Format())
239
                                        ->setContextualClass(Format::INFO)
240
                                        ->setString(language()->getLine('CLI_USAGE') . ':')
241
                                        ->setNewLinesBefore(1)
242
                                        ->setNewLinesAfter(1)
243
                                );
244
245
                                output()->write(
246
                                    (new Format())
247
                                        ->setContextualClass(Format::INFO)
248
                                        ->setString(language()->getLine($this->commandOptions[ $method ][ 'help' ]))
249
                                        ->setNewLinesAfter(2)
250
                                );
251
                            }
252
                        } else {
253
                            $optionArguments = is_array($arguments)
254
                                ? $arguments
255
                                : [$arguments];
256
257
                            call_user_func_array([&$this, $commandMethodName], $optionArguments);
258
                        }
259
                    }
260
                }
261
            }
262
        }
263
    }
264
265
    // ------------------------------------------------------------------------
266
267
    /**
268
     * AbstractCommander::execute
269
     *
270
     * Default abstract commander execution to execute help option.
271
     *
272
     * @return void
273
     * @throws \ReflectionException
274
     */
275
    public function execute()
276
    {
277
        if (false !== ($options = input()->get())) {
0 ignored issues
show
Unused Code introduced by
The assignment to $options is dead and can be removed.
Loading history...
278
            $this->__callOptions();
279
        } else {
280
            $this->optionHelp();
281
        }
282
    }
283
284
    // ------------------------------------------------------------------------
285
286
    /**
287
     * AbstractCommander::optionHelp
288
     *
289
     * Option help method, write commander help.
290
     *
291
     * @return void
292
     * @throws \ReflectionException
293
     */
294
    final public function optionHelp()
295
    {
296
        // Show Usage
297
        output()->write(
298
            (new Format())
299
                ->setContextualClass(Format::INFO)
300
                ->setString(language()->getLine('CLI_USAGE') . ':')
301
                ->setNewLinesBefore(1)
302
                ->setNewLinesAfter(1)
303
        );
304
305
        // Show Actions
306
        $this->loadActions();
307
308
        if (count($this->actionsPool)) {
309
            output()->write(
310
                (new Format())
311
                    ->setContextualClass(Format::INFO)
312
                    ->setString($this->commandName . '/action --option=value')
313
            );
314
315
            output()->write(
316
                (new Format())
317
                    ->setString(language()->getLine('CLI_ACTIONS') . ':')
318
                    ->setNewLinesBefore(2)
319
                    ->setNewLinesAfter(1)
320
            );
321
322
            $table = new Table();
323
            $table->isShowBorder = false;
324
325
            foreach ($this->actionsPool as $action) {
326
327
                if ($action instanceof AbstractCommander) {
328
                    $table
329
                        ->addRow()
330
                        ->addColumn($action->getCommandName())
331
                        ->addColumn(language()->getLine($action->getCommandDescription()));
332
                }
333
            }
334
335
            output()->write(
336
                (new Format())
337
                    ->setString($table->render())
338
            );
339
        } else {
340
            output()->write(
341
                (new Format())
342
                    ->setContextualClass(Format::INFO)
343
                    ->setString($this->commandName . ' --option=value')
344
            );
345
        }
346
347
        // Show Options
348
        output()->write(
349
            (new Format())
350
                ->setString(language()->getLine('CLI_OPTIONS') . ':')
351
                ->setNewLinesBefore(2)
352
                ->setNewLinesAfter(1)
353
        );
354
355
        $table = new Table();
356
        $table->isShowBorder = false;
357
358
        foreach ($this->commandOptions as $optionCaller => $optionProps) {
359
            $table
360
                ->addRow()
361
                ->addColumn('--' . $optionCaller)
362
                ->addColumn($optionProps[ 'shortcut' ])
363
                ->addColumn(language()->getLine($optionProps[ 'description' ]));
364
        }
365
366
        output()->write(
367
            (new Format())
368
                ->setString($table->render())
369
                ->setNewLinesAfter(2)
370
        );
371
372
        exit(EXIT_SUCCESS);
0 ignored issues
show
Best Practice introduced by
Using exit here is not recommended.

In general, usage of exit should be done with care and only when running in a scripting context like a CLI script.

Loading history...
373
    }
374
375
    // ------------------------------------------------------------------------
376
377
    /**
378
     * AbstractCommander::loadActions
379
     *
380
     * Load all actions.
381
     *
382
     * @param $namespace
383
     * @param $commandsPath
384
     *
385
     * @throws \ReflectionException
386
     */
387
    protected function loadActions()
388
    {
389
        $reflection = new \ReflectionClass($this);
390
        $actionNamespace = $reflection->name . '\\';
391
        $actionDirectory = get_class_name($reflection->name);
392
        $actionsPath = dirname($reflection->getFileName()) . DIRECTORY_SEPARATOR . $actionDirectory . DIRECTORY_SEPARATOR;
393
394
        foreach (glob($actionsPath . '*.php') as $filePath) {
395
            if (is_file($filePath)) {
396
                $commandClassName = $actionNamespace . pathinfo($filePath, PATHINFO_FILENAME);
397
                $this->addCommander(new $commandClassName);
398
            }
399
        }
400
    }
401
402
    // ------------------------------------------------------------------------
403
404
    /**
405
     * AbstractCommander::addCommander
406
     *
407
     * Add new commander to the pool.
408
     *
409
     * @param AbstractCommander $commander
410
     */
411
    public function addCommander(AbstractCommander $commander)
412
    {
413
        $this->actionsPool[ $commander->getCommandName() ] = $commander;
414
    }
415
416
    // ------------------------------------------------------------------------
417
418
    /**
419
     * AbstractCommander::getCommandName
420
     *
421
     * Gets command description.
422
     *
423
     * @return string
424
     */
425
    public function getCommandName()
426
    {
427
        return $this->commandName;
428
    }
429
430
    // ------------------------------------------------------------------------
431
432
    /**
433
     * AbstractCommander::getCommandDescription
434
     *
435
     * Gets command description.
436
     *
437
     * @return string
438
     */
439
    public function getCommandDescription()
440
    {
441
        return $this->commandDescription;
442
    }
443
444
    // ------------------------------------------------------------------------
445
446
    /**
447
     * AbstractCommander::setCommandDescription
448
     *
449
     * Sets command description.
450
     *
451
     * @param string $commandDescription
452
     *
453
     * @return static
454
     */
455
    public function setCommandDescription($commandDescription)
456
    {
457
        $this->commandDescription = trim($commandDescription);
458
459
        return $this;
460
    }
461
}