Completed
Push — master ( c84e1c...f32b00 )
by Sergi Tur
03:36
created

LlumCommand::setupLaravelConfigFile()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 9
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 9
rs 9.6666
cc 2
eloc 5
nc 2
nop 2
1
<?php
2
3
namespace Acacha\Llum\Console;
4
5
use Acacha\Llum\Exceptions\InvalidCommandException;
6
use Acacha\Llum\Traits\LaravelConfigFile;
7
use Illuminate\Config\Repository;
8
use Symfony\Component\Console\Command\Command;
9
use Symfony\Component\Console\Input\InputArgument;
10
use Symfony\Component\Console\Input\InputInterface;
11
use Symfony\Component\Console\Output\OutputInterface;
12
use Symfony\Component\Process\Process;
13
14
/**
15
 * Class LlumCommand.
16
 */
17
abstract class LlumCommand extends Command
18
{
19
    use LaravelConfigFile;
20
21
    /**
22
     * The output interface.
23
     *
24
     * @var OutputInterface
25
     */
26
    protected $output;
27
28
    /**
29
     * Command name.
30
     *
31
     * @var string
32
     */
33
    protected $commandName;
34
35
    /**
36
     * Command description.
37
     *
38
     * @var string
39
     */
40
    protected $commandDescription;
41
42
    /**
43
     * Command argument.
44
     *
45
     * @var string
46
     */
47
    protected $argument;
48
49
    /**
50
     * Argument type.
51
     *
52
     * @var int
53
     */
54
    protected $argumentType = InputArgument::REQUIRED;
55
56
    /**
57
     * Command argument description.
58
     *
59
     * @var string
60
     */
61
    protected $argumentDescription;
62
63
    /**
64
     * Method to execute.
65
     *
66
     * @var string
67
     */
68
    protected $method;
69
70
    /**
71
     * Laravel config file (config/app.php).
72
     *
73
     * @var string
74
     */
75
    protected $laravel_config_file;
76
77
    /**
78
     * Path to config folder.
79
     *
80
     * @var string
81
     */
82
    protected $configPath;
83
84
    /**
85
     * Config repository.
86
     *
87
     * @var Repository
88
     */
89
    protected $config;
90
91
    /**
92
     * LlumCommand constructor.
93
     */
94
    public function __construct()
95
    {
96
        parent::__construct();
97
        $this->configPath = __DIR__.'/../config/';
98
        $this->laravel_config_file = getcwd().'/config/app.php';
99
        $this->config = $this->obtainConfig();
100
    }
101
102
    /**
103
     * Require composer package.
104
     *
105
     * @param $package
106
     */
107
    private function requireComposerPackage($package)
108
    {
109
        $composer = $this->findComposer();
110
111
        $process = new Process($composer.' require '.$package.'', null, null, null, null);
112
        $this->output->writeln('<info>Running composer require '.$package.'</info>');
113
        $process->run(function ($type, $line) {
114
            $this->output->write($line);
115
        });
116
    }
117
118
    /**
119
     * Get the composer command for the environment.
120
     *
121
     * @return string
122
     */
123
    private function findComposer()
124
    {
125
        if (file_exists(getcwd().'/composer.phar')) {
126
            return '"'.PHP_BINARY.'" composer.phar"';
127
        }
128
129
        return 'composer';
130
    }
131
132
    /**
133
     * get package from config.
134
     *
135
     * @param $name
136
     *
137
     * @return array
138
     */
139
    private function getPackageFromConfig($name)
140
    {
141
        //Check if package name is a composer package name
142
        if (str_contains($name, '/')) {
143
            return $this->config->get($this->getPackageNameByComposerName($name));
144
        }
145
146
        return $this->config->get($name);
147
    }
148
149
    /**
150
     * Installs laravel package form config/packages.php file.
151
     *
152
     * @param string $name
153
     * @return int -1 if error occurred
154
     */
155
    protected function package($name)
156
    {
157
        $package = $this->obtainPackage($name);
158
159
        list($name, $providers, $aliases, $after) = array_fill(0, 4, null);
160
        extract($package, EXTR_IF_EXISTS);
161
162
        $this->requireComposerPackage($name);
163
164
        $this->setupLaravelConfigFile($providers, $aliases);
165
166
        $this->executeScriptAfterPackageInstallation($after);
167
    }
168
169
    /**
170
     * Obtain package.
171
     *
172
     * @param $name
173
     * @return array|int
174
     */
175
    private function obtainPackage($name)
176
    {
177
        $package = $this->getPackageFromConfig($name);
178
179
        if ($package == null) {
180
            $this->showPackageNotFoundError($name);
181
182
            return -1;
183
        }
184
185
        return $package;
186
    }
187
188
    /**
189
     * Execute post package installation script.
190
     *
191
     * @param $after
192
     */
193
    private function executeScriptAfterPackageInstallation($after)
194
    {
195
        if ($after != null) {
196
            passthru($after);
197
        }
198
    }
199
200
201
202
    /**
203
     * Get config repository.
204
     *
205
     * @return Repository
206
     */
207
    protected function obtainConfig()
208
    {
209
        return new Repository(require $this->configPath.'packages.php');
210
    }
211
212
    /**
213
     * Get package name by composer package name.
214
     * 
215
     * @param $composerPackageName
216
     *
217
     * @return string
218
     */
219
    private function getPackageNameByComposerName($composerPackageName)
220
    {
221
        foreach ($this->config->all() as $key => $configItem) {
222
            if ($configItem[ 'name' ] == $composerPackageName) {
223
                return $key;
224
            }
225
        }
226
227
        return;
228
    }
229
230
    /**
231
     * Show package not found error.
232
     *
233
     * @param $name
234
     */
235
    protected function showPackageNotFoundError($name)
236
    {
237
        $this->output->writeln('<error>Package '.$name.' not found in file '.$this->configPath.'packages.php</error>');
238
239
        return;
240
    }
241
242
    /**
243
     * Configure the command options.
244
     *
245
     * @param ConsoleCommand $command
246
     * @throws \Acacha\Llum\Exceptions\InvalidCommandException
247
     */
248
    protected function configureCommand(ConsoleCommand $command)
249
    {
250
        $this->ignoreValidationErrors();
251
252
        $name = $command->name();
253
        $description = $command->description();
254
255
        if (! is_string($name) || ! is_string($description)) {
256
            throw new InvalidCommandException;
257
        }
258
259
        $this->setName($name)
260
             ->setDescription($description);
261
        if ($command->argument() != null) {
262
            $this->addArgument($command->argument()[ 'name' ],
263
                $command->argument()[ 'type' ],
264
                $command->argument()[ 'description' ]
265
            );
266
        }
267
    }
268
269
    /**
270
     * Execute the command.
271
     *
272
     * @param InputInterface  $input
273
     * @param OutputInterface $output
274
     *
275
     * @return int|null|void
276
     */
277
    protected function execute(InputInterface $input, OutputInterface $output)
278
    {
279
        $this->output = $output;
280
        $method = $this->method;
281
        if ($this->argument != null) {
282
            $argument = $input->getArgument($this->argument);
283
            $this->$method($argument);
284
285
            return;
286
        }
287
288
        $this->$method();
289
    }
290
291
    /**
292
     * Configure the command options.
293
     */
294
    protected function configure()
295
    {
296
        $command = new ConsoleCommand();
297
298
        $command->name($this->commandName)
299
                ->description($this->commandDescription);
300
301
        if ($this->argument != null) {
302
            $command->argument([
303
                'name' => $this->argument,
304
                'description' => $this->argumentDescription,
305
                'type' => $this->argumentType,
306
            ]);
307
        }
308
        $this->configureCommand($command);
309
    }
310
}
311