Application::__construct()   A
last analyzed

Complexity

Conditions 2
Paths 2

Size

Total Lines 14
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 2
eloc 7
c 1
b 0
f 0
nc 2
nop 1
dl 0
loc 14
rs 10
1
<?php
2
3
namespace Gravatalonga\Framework;
4
5
use Gravatalonga\Container;
6
use Gravatalonga\Framework\Interfaces\ServiceProviderInterface;
7
use Psr\Container\ContainerInterface;
8
use Psr\Http\Message\ServerRequestInterface;
9
use Slim\App;
10
use Slim\Factory\AppFactory;
11
12
class Application
13
{
14
    /**
15
     * @var ContainerInterface
16
     */
17
    private $container;
18
19
    /**
20
     * @var bool
21
     */
22
    private $boot = false;
23
24
    /**
25
     * Application constructor.
26
     *
27
     * @param string $basePath
28
     */
29
    public function __construct(string $basePath = '')
30
    {
31
        $this->container = new Container(['settings' => [
32
            'base_path' => rtrim($basePath, '/')
33
        ]]);
34
35
        Container::setInstance($this->container);
36
37
        $this->container->share(App::class, function (ContainerInterface $container) {
38
            return $this->resolveApp($container);
39
        });
40
41
        if (!$this->boot) {
42
            $this->boot();
43
        }
44
    }
45
46
    /**
47
     * Get container
48
     * @return ContainerInterface
49
     */
50
    public function getContainer()
51
    {
52
        return $this->container;
53
    }
54
55
    /**
56
     * This is responsible to call services providers
57
     */
58
    protected function boot()
59
    {
60
        $this->loadConfigs();
61
62
        $this->resolveServiceProvider();
63
64
        $this->middleware();
65
66
        $this->container->share(ContainerInterface::class, function () {
67
            return $this->container;
68
        });
69
70
        $this->boot = true;
71
    }
72
73
    /**
74
     * Load all configuration into
75
     */
76
    protected function loadConfigs()
77
    {
78
        $basePath = $this->container->get('settings')['base_path'];
79
        $configs = glob($basePath.'/config/*.php');
80
81
        foreach ($configs as $config) {
82
            $name = basename($config, '.php');
83
            $this->container->set('config.'.$name, function () use ($config) {
84
                return require $config;
85
            });
86
        }
87
    }
88
89
    /**
90
     * This will resolve all services provider of application
91
     */
92
    protected function resolveServiceProvider()
93
    {
94
        if (!$this->container->has('config.provider')) {
95
            return;
96
        }
97
98
        // User Service Provider
99
        $providers = $this->container->get('config.provider');
100
        foreach ($providers as $provider) {
101
            /** @var ServiceProviderInterface $class */
102
            $class = new $provider();
103
            $register = $class->register();
104
            foreach ($register as $bind => $factory) {
105
                $name = class_exists($bind) ? $bind : 'service.'.$bind;
106
                $this->container->set($name, $factory);
107
            }
108
        }
109
    }
110
111
    /**
112
     * Load Middleware into Application
113
     */
114
    protected function middleware()
115
    {
116
        if (!$this->container->has('config.middleware')) {
117
            return;
118
        }
119
120
        $midlewares = $this->container->get('config.middleware');
121
        /** @var \Slim\App $app */
122
        $app = $this->container->get(App::class);
123
        foreach ($midlewares as $middleware) {
124
            $app->addMiddleware($middleware);
125
        }
126
    }
127
128
    /**
129
     * Resolve Slim
130
     *
131
     * @param ContainerInterface $container
132
     * @return App
133
     */
134
    protected function resolveApp(ContainerInterface $container)
135
    {
136
        $slim = AppFactory::createFromContainer($container);
137
        $slim->addBodyParsingMiddleware();
138
139
        return $slim;
140
    }
141
142
    /**
143
     * Run Application
144
     *
145
     * @param ServerRequestInterface|null $request
146
     * @return mixed
147
     */
148
    public function run(?ServerRequestInterface $request = null)
149
    {
150
        $slim = $this->container->get(App::class);
151
        return $slim->run($request);
152
    }
153
154
    /**
155
     * Call Slim methods
156
     *
157
     * @param string $method
158
     * @param array $arguments
159
     * @return mixed
160
     */
161
    public function __call($method, $arguments)
162
    {
163
        $slim = $this->container->get(App::class);
164
        if (method_exists($slim, $method)) {
165
            return call_user_func_array([$slim, $method], $arguments);
166
        }
167
    }
168
}
169