Completed
Push — master ( 0b79b7...fa8b49 )
by Dawid
10s
created

Application::getContainer()   A

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\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 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
     * @param Config|null $config
56
     */
57 17
    public function __construct(ContainerInterface $container = null)
58
    {
59 17
        $this->container = new Container($container);
60 17
        $this->resolver = new DependencyResolver($this->container);
61
62 17
        if (!$this->container->has(Config::class)) {
63 17
            $this->container->set(Config::class, new Config([]));
64
        }
65 17
        $this->config = $this->container->get(Config::class);
66 17
        $this->modules = [];
67 17
    }
68
69
    /**
70
     * Allows for application extension by modules.
71
     * Module can be any valid object or class name.
72
     *
73
     * @param $module
74
     */
75 3
    public function extend($module): void
76
    {
77 3
        if (is_object($module) || class_exists($module)) {
78 2
            $this->modules[] = $module;
79
        } else {
80 1
            throw ApplicationException::forInvalidModule($module);
81
        }
82 2
    }
83
84
    /**
85
     * Starts the application.
86
     * Initialize modules. Performs tasks to generate response for the client.
87
     *
88
     * @return mixed
89
     */
90
    abstract public function run();
91
92
    /**
93
     * @return ControllerAggregate
94
     */
95
    abstract public function getControllerAggregate(): ControllerAggregate;
96
97
    /**
98
     * @return Config
99
     */
100 1
    public function getConfig(): Config
101
    {
102 1
        return $this->config;
103
    }
104
105 14
    public function getContainer(): ContainerInterface
106
    {
107 14
        return $this->container;
108
    }
109
110 9
    protected function handleOnBootListeners(): void
111
    {
112 9
        foreach ($this->modules as $module) {
113 2
            if ($module instanceof OnBootListener) {
114 2
                $module->onBoot($this);
115
            }
116
        }
117 9
    }
118
119 2
    protected function handleOnShutDownListeners(): void
120
    {
121 2
        foreach ($this->modules as $module) {
122 2
            if ($module instanceof OnShutDownListener) {
123 2
                $module->onShutDown($this);
124
            }
125
        }
126 2
    }
127
128 2
    protected function handleOnErrorListeners(Throwable $exception): void
129
    {
130 2
        foreach ($this->modules as $module) {
131 1
            if ($module instanceof OnErrorListener) {
132 1
                $module->onError($this, $exception);
133
            }
134
        }
135 2
    }
136
137 12
    protected function handleOnRunListeners(): void
138
    {
139 12
        foreach ($this->modules as $module) {
140 2
            if ($module instanceof OnRunListener) {
141 2
                $module->onRun($this);
142
            }
143
        }
144 12
    }
145
146 9
    protected function initialize(): void
147
    {
148 9
        if ($this->initialized) {
149
            return;
150
        }
151
152 9
        foreach ($this->modules as &$module) {
153 2
            $this->initializeModule($module);
154
        }
155
156 9
        $this->initialized = true;
157 9
    }
158
159 2
    protected function initializeModule(&$module): void
160
    {
161 2
        if (is_string($module)) {
162 1
            $module = $this->resolver->resolve($module);
163
        }
164
165 2
        if ($module instanceof ConfigProvider) {
166
            $module->provideConfig($this->getConfig());
167
        }
168
169 2
        if ($module instanceof ControllerProvider) {
170 1
            $module->provideControllers($this->getControllerAggregate());
171
        }
172
173 2
        if ($module instanceof ServiceProvider) {
174
            $module->provideServices($this->getContainer());
175
        }
176 2
    }
177
}
178