Passed
Pull Request — master (#39)
by Sergei
10:00 queued 07:45
created

ApplicationRunner::withoutCheckingEvents()   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 14
    public function __construct(
35
        protected string $rootPath,
36
        protected bool $debug,
37
        protected bool $useBootstrap,
38
        protected bool $checkEvents,
39
        protected ?string $configGroupPostfix,
40
        protected ?string $environment,
41
    ) {
42 14
    }
43
44
    abstract public function run(): void;
45
46
    /**
47
     * Returns a new instance with the specified config instance {@see ConfigInterface}.
48
     *
49
     * @param ConfigInterface $config The config instance.
50
     */
51 3
    public function withConfig(ConfigInterface $config): static
52
    {
53 3
        $new = clone $this;
54 3
        $new->config = $config;
55 3
        return $new;
56
    }
57
58
    /**
59
     * Returns a new instance with the specified container instance {@see ContainerInterface}.
60
     *
61
     * @param ContainerInterface $container The container instance.
62
     */
63 4
    public function withContainer(ContainerInterface $container): static
64
    {
65 4
        $new = clone $this;
66 4
        $new->container = $container;
67 4
        return $new;
68
    }
69
70
    /**
71
     * @throws ErrorException|RuntimeException
72
     */
73 4
    protected function runBootstrap(): void
74
    {
75 4
        if ($this->useBootstrap) {
76 3
            $bootstrapList = $this->getConfiguration('bootstrap');
77 3
            if ($bootstrapList !== null) {
78 2
                (new BootstrapRunner($this->getContainer(), $bootstrapList))->run();
79
            }
80
        }
81
    }
82
83
    /**
84
     * @throws ContainerExceptionInterface|ErrorException|NotFoundExceptionInterface
85
     */
86 4
    protected function checkEvents(): void
87
    {
88 4
        if ($this->debug && $this->checkEvents) {
89 3
            $configuration = $this->getConfiguration('events');
90 3
            if ($configuration !== null) {
91
                /** @psalm-suppress MixedMethodCall */
92 2
                $this->getContainer()
93 2
                    ->get(ListenerConfigurationChecker::class)
94 2
                    ->check($configuration);
95
            }
96
        }
97
    }
98
99
    /**
100
     * @throws ErrorException
101
     */
102 9
    protected function getConfig(): ConfigInterface
103
    {
104 9
        return $this->config ??= $this->createDefaultConfig();
105
    }
106
107
    /**
108
     * @throws ErrorException|InvalidConfigException
109
     */
110 6
    protected function getContainer(): ContainerInterface
111
    {
112 6
        $this->container ??= $this->createDefaultContainer();
113
114 6
        if ($this->container instanceof Container) {
115 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

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