Completed
Push — master ( 9561ee...bb752b )
by Dawid
02:42
created

Application   A

Complexity

Total Complexity 25

Size/Duplication

Total Lines 143
Duplicated Lines 0 %

Test Coverage

Coverage 93.88%

Importance

Changes 0
Metric Value
dl 0
loc 143
ccs 46
cts 49
cp 0.9388
rs 10
c 0
b 0
f 0
wmc 25

9 Methods

Rating   Name   Duplication   Size   Complexity  
A handleOnErrorListeners() 0 5 3
A initialize() 0 11 3
A handleOnShutDownListeners() 0 5 3
A __construct() 0 7 1
B initializeModule() 0 16 5
A handleOnBootListeners() 0 5 3
A handleOnRunListeners() 0 5 3
A extend() 0 6 3
A getConfig() 0 3 1
1
<?php declare(strict_types=1);
2
3
namespace Igni\Application;
4
5
use Igni\Application\Controller\ControllerAggregate;
6
use Igni\Application\Exception\ApplicationException;
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 Igni\Http;
17
use Psr\Container\ContainerInterface;
18
use Throwable;
19
20
/**
21
 * Main glue between all components.
22
 *
23
 * @package Igni\Application
24
 */
25
abstract class Application
26
{
27
    /**
28
     * @var ServiceLocator|ContainerInterface
29
     */
30
    protected $serviceLocator;
31
32
    /**
33
     * @var Config
34
     */
35
    protected $config;
36
37
    /**
38
     * @var bool
39
     */
40
    private $initialized = false;
41
42
    /**
43
     * @var object[]|class[]
44
     */
45
    protected $modules;
46
47
    /**
48
     * @var DependencyResolver
49
     */
50
    protected $dependencyResolver;
51
52
    /**
53
     * Application constructor.
54
     *
55
     * @param ContainerInterface|null $container
56
     * @param Config|null $config
57
     */
58 17
    public function __construct(ContainerInterface $container = null, Config $config = null)
59
    {
60 17
        $this->serviceLocator = $container ?? new ServiceLocator();
61 17
        $this->config = $config ?? new Config([]);
62
63 17
        $this->dependencyResolver = new DependencyResolver($this->serviceLocator);
64 17
        $this->modules = [];
65 17
    }
66
67
    /**
68
     * Allows for application extension by modules.
69
     * Module can be any valid object or class name.
70
     *
71
     * @param $module
72
     */
73 3
    public function extend($module): void
74
    {
75 3
        if (is_object($module) || class_exists($module)) {
76 2
            $this->modules[] = $module;
77
        } else {
78 1
            throw ApplicationException::forInvalidModule($module);
79
        }
80 2
    }
81
82
    /**
83
     * Starts the application.
84
     * Initialize modules. Performs tasks to generate response for the client.
85
     *
86
     * @return mixed
87
     */
88
    abstract public function run();
89
90
    /**
91
     * @return ControllerAggregate
92
     */
93
    abstract public function getControllerAggregate(): ControllerAggregate;
94
95
    /**
96
     * @return Config
97
     */
98 1
    public function getConfig(): Config
99
    {
100 1
        return $this->config;
101
    }
102
103 9
    protected function handleOnBootListeners(): void
104
    {
105 9
        foreach ($this->modules as $module) {
106 2
            if ($module instanceof OnBootListener) {
107 2
                $module->onBoot($this);
108
            }
109
        }
110 9
    }
111
112 2
    protected function handleOnShutDownListeners(): void
113
    {
114 2
        foreach ($this->modules as $module) {
115 2
            if ($module instanceof OnShutDownListener) {
116 2
                $module->onShutDown($this);
117
            }
118
        }
119 2
    }
120
121 2
    protected function handleOnErrorListeners(Throwable $exception): void
122
    {
123 2
        foreach ($this->modules as $module) {
124 1
            if ($module instanceof OnErrorListener) {
125 1
                $module->onError($this, $exception);
126
            }
127
        }
128 2
    }
129
130 12
    protected function handleOnRunListeners(): void
131
    {
132 12
        foreach ($this->modules as $module) {
133 2
            if ($module instanceof OnRunListener) {
134 2
                $module->onRun($this);
135
            }
136
        }
137 12
    }
138
139 9
    protected function initialize(): void
140
    {
141 9
        if ($this->initialized) {
142
            return;
143
        }
144
145 9
        foreach ($this->modules as &$module) {
146 2
            $this->initializeModule($module);
147
        }
148
149 9
        $this->initialized = true;
150 9
    }
151
152 2
    protected function initializeModule(&$module): void
153
    {
154 2
        if (is_string($module)) {
155 1
            $module = $this->dependencyResolver->resolve($module);
156
        }
157
158 2
        if ($module instanceof ConfigProvider) {
159
            $module->provideConfig($this->config);
160
        }
161
162 2
        if ($module instanceof ControllerProvider) {
163 1
            $module->provideControllers($this->getControllerAggregate());
164
        }
165
166 2
        if ($module instanceof ServiceProvider) {
167
            $module->provideServices($this->serviceLocator);
168
        }
169 2
    }
170
}
171