Application::getConfig()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

Changes 0
Metric Value
cc 1
eloc 1
nc 1
nop 0
dl 0
loc 3
ccs 2
cts 2
cp 1
crap 1
rs 10
c 0
b 0
f 0
1
<?php declare(strict_types=1);
2
3
namespace Igni\Application;
4
5
use Igni\Application\Exception\ApplicationException;
6
use Igni\Application\Http\MiddlewareAggregator;
7
use Igni\Application\Listeners\OnBootListener;
8
use Igni\Application\Listeners\OnErrorListener;
9
use Igni\Application\Listeners\OnRunListener;
10
use Igni\Application\Listeners\OnShutDownListener;
11
use Igni\Application\Providers\ConfigProvider;
12
use Igni\Application\Providers\ControllerProvider;
13
use Igni\Application\Providers\ServiceProvider;
14
use Igni\Container\DependencyResolver;
15
use Igni\Container\ServiceLocator;
16
use Psr\Container\ContainerInterface;
17
use Throwable;
18
19
/**
20
 * Main glue between all components.
21
 *
22
 * @package Igni\Application
23
 */
24
abstract class Application
25
{
26
    /**
27
     * @var ServiceLocator|ContainerInterface
28
     */
29
    private $container;
30
31
    /**
32
     * @var Config
33
     */
34
    private $config;
35
36
    /**
37
     * @var bool
38
     */
39
    private $initialized = false;
40
41
    /**
42
     * @var object[]|class[]
43
     */
44
    protected $modules;
45
46
    /**
47
     * @var DependencyResolver
48
     */
49
    protected $resolver;
50
51
    /**
52
     * Application constructor.
53
     *
54
     * @param ContainerInterface|null $container
55
     */
56 23
    public function __construct(ContainerInterface $container = null)
57
    {
58 23
        if ($container === null) {
59 20
            $container = new ServiceLocator();
60
        }
61
62 23
        $this->container = $container;
63 23
        $this->resolver = new DependencyResolver($this->container);
64
65 23
        if ($this->container->has(Config::class)) {
66
            $this->config = $this->container->get(Config::class);
67
        } else {
68 23
            $this->config = new Config([]);
69
        }
70
71 23
        $this->modules = [];
72 23
    }
73
74
    /**
75
     * Allows for application extension by modules.
76
     * Module can be any valid object or class name.
77
     *
78
     * @param $module
79
     */
80 4
    public function extend($module): void
81
    {
82 4
        if (is_object($module) || class_exists($module)) {
83 3
            $this->modules[] = $module;
84
        } else {
85 1
            throw ApplicationException::forInvalidModule($module);
86
        }
87 3
    }
88
89
    /**
90
     * Starts the application.
91
     * Initialize modules. Performs tasks to generate response for the client.
92
     *
93
     * @return mixed
94
     */
95
    abstract public function run();
96
97
    /**
98
     * Controller aggregator is used to register application's controllers.
99
     * @return ControllerAggregator
100
     */
101
    abstract public function getControllerAggregator(): ControllerAggregator;
102
103
    /**
104
     * Middleware aggregator is used to register application's middlewares.
105
     * @return MiddlewareAggregator
106
     */
107
    abstract public function getMiddlewareAggregator(): MiddlewareAggregator;
108
109
    /**
110
     * @return Config
111
     */
112 1
    public function getConfig(): Config
113
    {
114 1
        return $this->config;
115
    }
116
117 23
    public function getContainer(): ContainerInterface
118
    {
119 23
        return $this->container;
120
    }
121
122 9
    protected function handleOnBootListeners(): void
123
    {
124 9
        foreach ($this->modules as $module) {
125 2
            if ($module instanceof OnBootListener) {
126 2
                $module->onBoot($this);
127
            }
128
        }
129 9
    }
130
131 2
    protected function handleOnShutDownListeners(): void
132
    {
133 2
        foreach ($this->modules as $module) {
134 2
            if ($module instanceof OnShutDownListener) {
135 2
                $module->onShutDown($this);
136
            }
137
        }
138 2
    }
139
140 3
    protected function handleOnErrorListeners(Throwable $exception): Throwable
141
    {
142 3
        foreach ($this->modules as $module) {
143 2
            if ($module instanceof OnErrorListener) {
144 2
                $exception = $module->onError($this, $exception);
145
            }
146
        }
147
148 3
        return $exception;
149
    }
150
151 9
    protected function handleOnRunListeners(): void
152
    {
153 9
        foreach ($this->modules as $module) {
154 2
            if ($module instanceof OnRunListener) {
155 2
                $module->onRun($this);
156
            }
157
        }
158 9
    }
159
160 9
    protected function initialize(): void
161
    {
162 9
        if ($this->initialized) {
163
            return;
164
        }
165
166 9
        foreach ($this->modules as &$module) {
167 2
            $this->initializeModule($module);
168
        }
169
170 9
        $this->initialized = true;
171 9
    }
172
173 2
    protected function initializeModule(&$module): void
174
    {
175 2
        if (is_string($module)) {
176 1
            $module = $this->resolver->resolve($module);
177
        }
178
179 2
        if ($module instanceof ConfigProvider) {
180
            $module->provideConfig($this->getConfig());
181
        }
182
183 2
        if ($module instanceof ControllerProvider) {
184 1
            $module->provideControllers($this->getControllerAggregator());
185
        }
186
187 2
        if ($module instanceof ServiceProvider) {
188
            $module->provideServices($this->getContainer());
189
        }
190 2
    }
191
}
192