CommandTrait   A
last analyzed

Complexity

Total Complexity 9

Size/Duplication

Total Lines 91
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 6

Test Coverage

Coverage 100%

Importance

Changes 0
Metric Value
wmc 9
lcom 1
cbo 6
dl 0
loc 91
ccs 26
cts 26
cp 1
rs 10
c 0
b 0
f 0

6 Methods

Rating   Name   Duplication   Size   Complexity  
A wrapIo() 0 4 1
A createContainer() 0 24 3
A getAutoloadPath() 0 4 1
A getExtra() 0 4 1
A isValidApplicationClass() 0 8 2
A createApplication() 0 4 1
1
<?php declare(strict_types=1);
2
3
namespace Limoncello\Commands\Traits;
4
5
/**
6
 * Copyright 2015-2019 [email protected]
7
 *
8
 * Licensed under the Apache License, Version 2.0 (the "License");
9
 * you may not use this file except in compliance with the License.
10
 * You may obtain a copy of the License at
11
 *
12
 * http://www.apache.org/licenses/LICENSE-2.0
13
 *
14
 * Unless required by applicable law or agreed to in writing, software
15
 * distributed under the License is distributed on an "AS IS" BASIS,
16
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17
 * See the License for the specific language governing permissions and
18
 * limitations under the License.
19
 */
20
21
use Composer\Composer;
22
use Limoncello\Commands\CommandConstants;
23
use Limoncello\Commands\Exceptions\ConfigurationException;
24
use Limoncello\Commands\Wrappers\ConsoleIoWrapper;
25
use Limoncello\Contracts\Commands\IoInterface;
26
use Limoncello\Contracts\Core\ApplicationInterface;
27
use Psr\Container\ContainerInterface;
28
use ReflectionClass;
29
use ReflectionException;
30
use Symfony\Component\Console\Input\InputInterface;
31
use Symfony\Component\Console\Output\OutputInterface;
32
use function file_exists;
33
34
/**
35
 * @package Limoncello\Commands
36
 */
37
trait CommandTrait
38
{
39
    /**
40
     * @param InputInterface  $input
41
     * @param OutputInterface $output
42 10
     *
43
     * @return IoInterface
44 10
     */
45
    protected function wrapIo(InputInterface $input, OutputInterface $output): IoInterface
46
    {
47
        return new ConsoleIoWrapper($input, $output);
48
    }
49
50
    /**
51
     * @param Composer $composer
52
     *
53
     * @return ContainerInterface
54 2
     *
55
     * @throws ReflectionException
56
     */
57 2
    protected function createContainer(Composer $composer): ContainerInterface
58 2
    {
59
        // use application auto loader otherwise no app classes will be visible for us
60 2
        $autoLoaderPath = $this->getAutoloadPath($composer);
61
        if (file_exists($autoLoaderPath) === true) {
62
            /** @noinspection PhpIncludeInspection */
63 2
            require_once $autoLoaderPath;
64 2
        }
65 2
66 2
        $extra    = $this->getExtra($composer);
67 2
        $appKey   = CommandConstants::COMPOSER_JSON__EXTRA__APPLICATION;
68 1
        $classKey = CommandConstants::COMPOSER_JSON__EXTRA__APPLICATION__CLASS;
69 1
        $appClass = $extra[$appKey][$classKey] ?? CommandConstants::DEFAULT_APPLICATION_CLASS_NAME;
70 1
        if ($this->isValidApplicationClass($appClass) === false) {
71
            $settingsPath = "extra->$appKey->$classKey";
72
            throw new ConfigurationException(
73
                "Invalid application class specified '$appClass'. Check your settings at composer.json $settingsPath."
74 1
            );
75
        }
76 1
77
        $container = $this->createApplication($appClass)->createContainer();
78
79
        return $container;
80
    }
81
82
    /**
83
     * @param Composer $composer
84 2
     *
85
     * @return string
86 2
     */
87
    protected function getAutoloadPath(Composer $composer): string
88
    {
89
        return $composer->getConfig()->get('vendor-dir') . DIRECTORY_SEPARATOR . 'autoload.php';
90
    }
91
92
    /**
93
     * @param Composer $composer
94 2
     *
95
     * @return array
96 2
     */
97
    protected function getExtra(Composer $composer): array
98
    {
99
        return $composer->getPackage()->getExtra();
100
    }
101
102
    /**
103
     * @param string $className
104
     *
105
     * @return bool
106 2
     *
107
     * @throws ReflectionException
108 2
     */
109
    protected function isValidApplicationClass(string $className): bool
110
    {
111 2
        $reflectionClass = new ReflectionClass($className);
112 2
113
        return
114
            $reflectionClass->isInstantiable() === true &&
115
            $reflectionClass->implementsInterface(ApplicationInterface::class) === true;
116
    }
117
118
    /**
119
     * @param string $className
120 1
     *
121
     * @return ApplicationInterface
122 1
     */
123
    protected function createApplication(string $className): ApplicationInterface
124
    {
125
        return new $className();
126
    }
127
}
128