Test Failed
Push — develop ( 7fb7cc...c3d980 )
by nguereza
02:34
created

ConsoleKernel::getConsoleApp()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 1
c 0
b 0
f 0
nc 1
nop 0
dl 0
loc 3
rs 10
1
<?php
2
3
/**
4
 * Platine Framework
5
 *
6
 * Platine Framework is a lightweight, high-performance, simple and elegant
7
 * PHP Web framework
8
 *
9
 * This content is released under the MIT License (MIT)
10
 *
11
 * Copyright (c) 2020 Platine Framework
12
 *
13
 * Permission is hereby granted, free of charge, to any person obtaining a copy
14
 * of this software and associated documentation files (the "Software"), to deal
15
 * in the Software without restriction, including without limitation the rights
16
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
17
 * copies of the Software, and to permit persons to whom the Software is
18
 * furnished to do so, subject to the following conditions:
19
 *
20
 * The above copyright notice and this permission notice shall be included in all
21
 * copies or substantial portions of the Software.
22
 *
23
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
24
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
25
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
26
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
27
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
28
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
29
 * SOFTWARE.
30
 */
31
32
/**
33
 *  @file ConsoleKernel.php
34
 *
35
 *  The Console Kernel class
36
 *
37
 *  @package    Platine\Framework\Kernel
38
 *  @author Platine Developers team
39
 *  @copyright  Copyright (c) 2020
40
 *  @license    http://opensource.org/licenses/MIT  MIT License
41
 *  @link   http://www.iacademy.cf
42
 *  @version 1.0.0
43
 *  @filesource
44
 */
45
46
declare(strict_types=1);
47
48
namespace Platine\Framework\Kernel;
49
50
use InvalidArgumentException;
51
use Platine\Config\Config;
52
use Platine\Console\Application as ConsoleApp;
53
use Platine\Console\Command\Command;
54
use Platine\Framework\App\Application;
55
56
/**
57
 * class ConsoleKernel
58
 * @package Platine\Framework\Kernel
59
 */
60
class ConsoleKernel
61
{
62
63
    protected ConsoleApp $console;
64
    protected Application $app;
65
66
    /**
67
     * The list of middlewares
68
     * @var Command[]
69
     */
70
    protected array $commands = [];
71
72
    /**
73
     * Whether the commands already loaded
74
     * @var bool
75
     */
76
    protected bool $commandsLoaded = false;
77
78
    /**
79
     *
80
     * @param Application $app
81
     * @param ConsoleApp $console
82
     */
83
    public function __construct(Application $app, ConsoleApp $console)
84
    {
85
        $this->app = $app;
86
        $this->console = $console;
87
    }
88
89
    public function run(array $argv): void
90
    {
91
        $this->bootstrap();
92
93
        foreach ($this->commands as $command) {
94
            $this->console->addCommand($command);
95
        }
96
97
        $this->console->handle($argv);
98
    }
99
100
    /**
101
     * Bootstrap the application
102
     * @return void
103
     */
104
    public function bootstrap(): void
105
    {
106
        $this->app->registerConfiguration();
107
        $this->app->registerConfiguredServiceProviders();
108
        $this->app->boot();
109
110
        if (!$this->commandsLoaded) {
111
            $this->registerConfiguredCommands();
112
113
            $this->commandsLoaded = true;
114
        }
115
    }
116
117
    /**
118
     *
119
     * @param string|Command $command
120
     * @return void
121
     */
122
    public function addCommand($command): void
123
    {
124
        if (is_string($command)) {
125
            $command = $this->createCommand($command);
126
        }
127
128
        $this->commands[] = $command;
129
    }
130
131
    /**
132
     *
133
     * @return ConsoleApp
134
     */
135
    public function getConsoleApp(): ConsoleApp
136
    {
137
        return $this->console;
138
    }
139
140
    /**
141
     * Load configured commands
142
     * @return void
143
     */
144
    protected function registerConfiguredCommands(): void
145
    {
146
        /** @template T @var Config<T> $config */
147
        $config = $this->app->get(Config::class);
148
149
        /** @var string[] $commands */
150
        $commands = $config->get('commands', []);
151
        foreach ($commands as $command) {
152
            $this->addCommand($command);
153
        }
154
    }
155
156
    /**
157
     * Create new command
158
     * @param string $command
159
     * @return Command
160
     */
161
    protected function createCommand(string $command): Command
162
    {
163
        if ($this->app->has($command)) {
164
            return $this->app->get($command);
165
        }
166
167
        if (class_exists($command)) {
168
            return new $command();
169
        }
170
171
        throw new InvalidArgumentException(
172
            sprintf('The command must be an identifier of container or class')
173
        );
174
    }
175
}
176