Passed
Pull Request — master (#39)
by Sergei
02:20
created

ApplicationRunner::withoutBootstrap()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 5
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 4
CRAP Score 1

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 1
eloc 3
c 1
b 0
f 0
nc 1
nop 0
dl 0
loc 5
ccs 4
cts 4
cp 1
crap 1
rs 10
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Yiisoft\Yii\Runner;
6
7
use ErrorException;
8
use Psr\Container\ContainerExceptionInterface;
9
use Psr\Container\ContainerInterface;
10
use Psr\Container\NotFoundExceptionInterface;
11
use RuntimeException;
12
use Yiisoft\Config\Config;
13
use Yiisoft\Config\ConfigInterface;
14
use Yiisoft\Config\ConfigPaths;
15
use Yiisoft\Definitions\Exception\InvalidConfigException;
16
use Yiisoft\Di\Container;
17
use Yiisoft\Di\ContainerConfig;
18
use Yiisoft\Yii\Event\ListenerConfigurationChecker;
19
20
/**
21
 * Provides basic functionality for creating adapters.
22
 */
23
abstract class ApplicationRunner implements RunnerInterface
24
{
25
    private ?ConfigInterface $config = null;
26
    private ?ContainerInterface $container = null;
27
28
    /**
29
     * @param string $rootPath The absolute path to the project root.
30
     * @param bool $debug Whether the debug mode is enabled.
31
     * @param string|null $configGroupPostfix A configuration groups postfix.
32
     * @param string|null $environment The environment name.
33
     */
34 13
    public function __construct(
35
        protected string $rootPath,
36
        protected bool $debug,
37
        protected bool $checkEvents,
38
        protected ?string $configGroupPostfix,
39
        protected ?string $environment,
40
    ) {
41 13
    }
42
43
    abstract public function run(): void;
44
45
    /**
46
     * Returns a new instance with the specified config instance {@see ConfigInterface}.
47
     *
48
     * @param ConfigInterface $config The config instance.
49
     */
50 3
    public function withConfig(ConfigInterface $config): static
51
    {
52 3
        $new = clone $this;
53 3
        $new->config = $config;
54 3
        return $new;
55
    }
56
57
    /**
58
     * Returns a new instance with the specified container instance {@see ContainerInterface}.
59
     *
60
     * @param ContainerInterface $container The container instance.
61
     */
62 4
    public function withContainer(ContainerInterface $container): static
63
    {
64 4
        $new = clone $this;
65 4
        $new->container = $container;
66 4
        return $new;
67
    }
68
69
    /**
70
     * @throws ErrorException|RuntimeException
71
     */
72 3
    protected function runBootstrap(): void
73
    {
74 3
        $bootstrapList = $this->getConfiguration('bootstrap');
75 3
        if ($bootstrapList === null) {
76 1
            return;
77
        }
78
79 2
        (new BootstrapRunner($this->getContainer(), $bootstrapList))->run();
80
    }
81
82
    /**
83
     * @throws ContainerExceptionInterface|ErrorException|NotFoundExceptionInterface
84
     */
85 3
    protected function checkEvents(): void
86
    {
87 3
        if ($this->debug && $this->checkEvents) {
88 3
            $configuration = $this->getConfiguration('events');
89 3
            if ($configuration !== null) {
90
                /** @psalm-suppress MixedMethodCall */
91 2
                $this->getContainer()
92 2
                    ->get(ListenerConfigurationChecker::class)
93 2
                    ->check($configuration);
94
            }
95
        }
96
    }
97
98
    /**
99
     * @throws ErrorException
100
     */
101 9
    protected function getConfig(): ConfigInterface
102
    {
103 9
        return $this->config ??= $this->createDefaultConfig();
104
    }
105
106
    /**
107
     * @throws ErrorException|InvalidConfigException
108
     */
109 6
    protected function getContainer(): ContainerInterface
110
    {
111 6
        $this->container ??= $this->createDefaultContainer();
112
113 6
        if ($this->container instanceof Container) {
114 5
            return $this->container->get(ContainerInterface::class);
0 ignored issues
show
Bug introduced by
The method get() does not exist on null. ( Ignorable by Annotation )

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

114
            return $this->container->/** @scrutinizer ignore-call */ get(ContainerInterface::class);

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...
115
        }
116
117 1
        return $this->container;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this->container could return the type null which is incompatible with the type-hinted return Psr\Container\ContainerInterface. Consider adding an additional type-check to rule them out.
Loading history...
118
    }
119
120
    /**
121
     * @throws ErrorException
122
     */
123 8
    protected function createDefaultConfig(): Config
124
    {
125 8
        return ConfigFactory::create(
126 8
            new ConfigPaths($this->rootPath, 'config'),
127 8
            $this->environment,
128 8
            $this->configGroupPostfix,
129 8
        );
130
    }
131
132
    /**
133
     * @throws ErrorException|InvalidConfigException
134
     */
135 5
    protected function createDefaultContainer(): Container
136
    {
137 5
        $containerConfig = ContainerConfig::create()->withValidate($this->debug);
138
139 5
        $config = $this->getConfig();
140
141 5
        if (null !== $definitions = $this->getConfiguration('di')) {
142 4
            $containerConfig = $containerConfig->withDefinitions($definitions);
143
        }
144
145 5
        if (null !== $providers = $this->getConfiguration('di-providers')) {
146 4
            $containerConfig = $containerConfig->withProviders($providers);
147
        }
148
149 5
        if (null !== $delegates = $this->getConfiguration('di-delegates')) {
150 4
            $containerConfig = $containerConfig->withDelegates($delegates);
151
        }
152
153 5
        if (null !== $tags = $this->getConfiguration('di-tags')) {
154 4
            $containerConfig = $containerConfig->withTags($tags);
155
        }
156
157 5
        $containerConfig = $containerConfig->withDefinitions(
158 5
            array_merge($containerConfig->getDefinitions(), [ConfigInterface::class => $config])
159 5
        );
160
161 5
        return new Container($containerConfig);
162
    }
163
164 7
    final protected function getConfiguration(string $name): ?array
165
    {
166 7
        $config = $this->getConfig();
167
168 7
        if ($this->configGroupPostfix !== null) {
169 6
            $fullName = $name . '-' . $this->configGroupPostfix;
170 6
            if ($config->has($fullName)) {
171 6
                return $config->get($fullName);
172
            }
173
        }
174
175 2
        if ($config->has($name)) {
176
            return $config->get($name);
177
        }
178
179 2
        return null;
180
    }
181
}
182