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 ( c777d8...b54a62 )
by Steeven
03:18
created

AbstractCommander::__construct()   A

Complexity

Conditions 5
Paths 10

Size

Total Lines 24
Code Lines 14

Duplication

Lines 0
Ratio 0 %

Importance

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

184
                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...
185
                    (new Format())
186
                        ->setContextualClass(Format::INFO)
187
                        ->setString(ucfirst($this->commandName) . ' v' . $this->commandVersion)
188
                        ->setNewLinesAfter(1)
189
                );
190
            }
191
        }
192
    }
193
194
    // ------------------------------------------------------------------------
195
196
    /**
197
     * AbstractCommander::__callOptions
198
     *
199
     * Options call executer.
200
     *
201
     * @return void
202
     */
203
    protected function __callOptions()
204
    {
205
        if(false !== ($options = input()->get())) {
206
            if(count($options)) {
207
                $command = new \ReflectionClass($this);
208
209
                foreach ($options as $method => $arguments) {
210
211
                    if (array_key_exists('-' . $method, $this->commandOptionsShortcuts)) {
212
                        $method = $this->commandOptionsShortcuts[ '-' . $method ];
213
                    }
214
215
                    if ( ! $command->hasMethod($optionMethod = camelcase('option-' . $method))) {
216
                        $commandMethod = $command->getMethod($optionMethod);
217
                    } elseif($command->hasMethod($optionMethod = camelcase($method))) {
218
                        $commandMethod = $command->getMethod($optionMethod);
219
                    }
220
221
                    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...
222
                        if ($commandMethod->getNumberOfRequiredParameters() == 0) {
223
                            call_user_func_array([&$this, $optionMethod], [$arguments]);
224
                        } elseif ($commandMethod->getNumberOfRequiredParameters() > 0 and empty($arguments)) {
225
                            if (isset($this->commandOptions[ $method ][ 'help' ])) {
226
                                output()->write(
227
                                    (new Format())
228
                                        ->setContextualClass(Format::INFO)
229
                                        ->setString(language()->getLine('CLI_USAGE') . ':')
230
                                        ->setNewLinesBefore(1)
231
                                        ->setNewLinesAfter(1)
232
                                );
233
234
                                output()->write(
235
                                    (new Format())
236
                                        ->setContextualClass(Format::INFO)
237
                                        ->setString(language()->getLine($this->commandOptions[ $method ][ 'help' ]))
238
                                        ->setNewLinesAfter(2)
239
                                );
240
                            }
241
                        } else {
242
                            $optionArguments = is_array($arguments)
243
                                ? $arguments
244
                                : [$arguments];
245
246
                            call_user_func_array([&$this, $optionMethod], $optionArguments);
247
                        }
248
                    }
249
                }
250
            }
251
        }
252
    }
253
254
    // ------------------------------------------------------------------------
255
256
    /**
257
     * AbstractCommander::execute
258
     *
259
     * Default abstract commander execution to execute help option.
260
     *
261
     * @return void
262
     * @throws \ReflectionException
263
     */
264
    public function execute()
265
    {
266
        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...
267
            $this->__callOptions();
268
        } else {
269
            $this->optionHelp();
270
        }
271
    }
272
273
    // ------------------------------------------------------------------------
274
275
    /**
276
     * AbstractCommander::optionHelp
277
     *
278
     * Option help method, write commander help.
279
     *
280
     * @return void
281
     * @throws \ReflectionException
282
     */
283
    final public function optionHelp()
284
    {
285
        // Show Usage
286
        output()->write(
287
            (new Format())
288
                ->setContextualClass(Format::INFO)
289
                ->setString(language()->getLine('CLI_USAGE') . ':')
290
                ->setNewLinesBefore(1)
291
                ->setNewLinesAfter(1)
292
        );
293
294
        // Show Actions
295
        $this->loadActions();
296
297
        if (count($this->actionsPool)) {
298
            output()->write(
299
                (new Format())
300
                    ->setContextualClass(Format::INFO)
301
                    ->setString($this->commandName . '/action --option=value')
302
            );
303
304
            output()->write(
305
                (new Format())
306
                    ->setString(language()->getLine('CLI_ACTIONS') . ':')
307
                    ->setNewLinesBefore(2)
308
                    ->setNewLinesAfter(1)
309
            );
310
311
            $table = new Table();
312
            $table->isShowBorder = false;
313
314
            foreach ($this->actionsPool as $action) {
315
316
                if ($action instanceof AbstractCommander) {
317
                    $table
318
                        ->addRow()
319
                        ->addColumn($action->getCommandName())
320
                        ->addColumn(language()->getLine($action->getCommandDescription()));
321
                }
322
            }
323
324
            output()->write(
325
                (new Format())
326
                    ->setString($table->render())
327
            );
328
        } else {
329
            output()->write(
330
                (new Format())
331
                    ->setContextualClass(Format::INFO)
332
                    ->setString($this->commandName . ' --option=value')
333
            );
334
        }
335
336
        // Show Options
337
        output()->write(
338
            (new Format())
339
                ->setString(language()->getLine('CLI_OPTIONS') . ':')
340
                ->setNewLinesBefore(2)
341
                ->setNewLinesAfter(1)
342
        );
343
344
        $table = new Table();
345
        $table->isShowBorder = false;
346
347
        foreach ($this->commandOptions as $optionCaller => $optionProps) {
348
            $table
349
                ->addRow()
350
                ->addColumn('--' . $optionCaller)
351
                ->addColumn($optionProps[ 'shortcut' ])
352
                ->addColumn(language()->getLine($optionProps[ 'description' ]));
353
        }
354
355
        output()->write(
356
            (new Format())
357
                ->setString($table->render())
358
                ->setNewLinesAfter(2)
359
        );
360
361
        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...
362
    }
363
364
    // ------------------------------------------------------------------------
365
366
    /**
367
     * AbstractCommander::loadActions
368
     *
369
     * Load all actions.
370
     *
371
     * @param $namespace
372
     * @param $commandsPath
373
     *
374
     * @throws \ReflectionException
375
     */
376
    protected function loadActions()
377
    {
378
        $reflection = new \ReflectionClass($this);
379
        $actionNamespace = $reflection->name . '\\';
380
        $actionDirectory = get_class_name($reflection->name);
381
        $actionsPath = dirname($reflection->getFileName()) . DIRECTORY_SEPARATOR . $actionDirectory . DIRECTORY_SEPARATOR;
382
383
        foreach (glob($actionsPath . '*.php') as $filePath) {
384
            if (is_file($filePath)) {
385
                $commandClassName = $actionNamespace . pathinfo($filePath, PATHINFO_FILENAME);
386
                $this->addCommander(new $commandClassName);
387
            }
388
        }
389
    }
390
391
    // ------------------------------------------------------------------------
392
393
    /**
394
     * AbstractCommander::addCommander
395
     *
396
     * Add new commander to the pool.
397
     *
398
     * @param AbstractCommander $commander
399
     */
400
    public function addCommander(AbstractCommander $commander)
401
    {
402
        $this->actionsPool[ $commander->getCommandName() ] = $commander;
403
    }
404
405
    // ------------------------------------------------------------------------
406
407
    /**
408
     * AbstractCommander::getCommandName
409
     *
410
     * Gets command description.
411
     *
412
     * @return string
413
     */
414
    public function getCommandName()
415
    {
416
        return $this->commandName;
417
    }
418
419
    // ------------------------------------------------------------------------
420
421
    /**
422
     * AbstractCommander::getCommandDescription
423
     *
424
     * Gets command description.
425
     *
426
     * @return string
427
     */
428
    public function getCommandDescription()
429
    {
430
        return $this->commandDescription;
431
    }
432
433
    // ------------------------------------------------------------------------
434
435
    /**
436
     * AbstractCommander::setCommandDescription
437
     *
438
     * Sets command description.
439
     *
440
     * @param string $commandDescription
441
     *
442
     * @return static
443
     */
444
    public function setCommandDescription($commandDescription)
445
    {
446
        $this->commandDescription = trim($commandDescription);
447
448
        return $this;
449
    }
450
}