Passed
Push — develop ( 30ebd1...915009 )
by Brent
06:10
created

App::loadConfig()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 6
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 4
CRAP Score 2

Importance

Changes 0
Metric Value
cc 2
eloc 3
nc 2
nop 1
dl 0
loc 6
ccs 4
cts 4
cp 1
crap 2
rs 9.4285
c 0
b 0
f 0
1
<?php
2
3
namespace Stitcher;
4
5
use Illuminate\Support\Arr;
6
use Pageon\Config;
7
use Stitcher\Application\DevelopmentServer;
8
use Stitcher\Application\ProductionServer;
9
use Stitcher\Application\Router;
10
use Stitcher\Exception\InvalidConfiguration;
11
use Stitcher\Exception\InvalidPlugin;
12
use Symfony\Component\Config\FileLocator;
13
use Symfony\Component\DependencyInjection\ContainerBuilder;
14
use Symfony\Component\DependencyInjection\Definition;
15
use Symfony\Component\DependencyInjection\Exception\ParameterNotFoundException;
16
use Symfony\Component\DependencyInjection\Loader\YamlFileLoader;
17
18
class App
19
{
20
    /** @var ContainerBuilder */
21
    protected static $container;
22
23 9
    public static function init()
24
    {
25 9
        Config::init();
26
27 9
        self::$container = new ContainerBuilder();
28
29 9
        self::loadConfig(Config::all());
30
31 9
        self::loadServices('services.yaml');
32
33 9
        self::loadPlugins();
34
35 9
        self::loadRoutes();
36 9
    }
37
38
    /**
39
     * @param string $id
40
     *
41
     * @return mixed
42
     * @throws \Exception
43
     */
44 8
    public static function get(string $id)
45
    {
46 8
        return self::$container->get($id);
47
    }
48
49 1 View Code Duplication
    public static function developmentServer(): DevelopmentServer
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
50
    {
51
        try {
52
            /** @var DevelopmentServer $server */
53 1
            $server = self::get(DevelopmentServer::class);
54
55 1
            return $server;
56
        } catch (ParameterNotFoundException $e) {
57
            throw InvalidConfiguration::missingParameter($e->getKey());
58
        }
59
    }
60
61 1 View Code Duplication
    public static function productionServer(): ProductionServer
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
62
    {
63
        try {
64
            /** @var ProductionServer $server */
65 1
            $server = self::get(ProductionServer::class);
66
67 1
            return $server;
68
        } catch (ParameterNotFoundException $e) {
69
            throw InvalidConfiguration::missingParameter($e->getKey());
70
        }
71
    }
72
73 2
    public static function router(): Router
74
    {
75
        /** @var Router $router */
76 2
        $router = self::get(Router::class);
77
78 2
        return $router;
79
    }
80
81 9
    protected static function loadConfig(array $config): void
82
    {
83 9
        foreach ($config as $key => $value) {
84 9
            self::$container->setParameter($key, $value);
85
        }
86 9
    }
87
88 9
    protected static function loadServices(string $servicesPath): void
89
    {
90 9
        $loader = new YamlFileLoader(self::$container, new FileLocator(__DIR__));
91
92 9
        $loader->load($servicesPath);
93
94
        /** @var Definition $definition */
95 9
        foreach (self::$container->getDefinitions() as $id => $definition) {
96 9
            self::$container->setAlias($definition->getClass(), $id);
97
        }
98 9
    }
99
100 9
    protected static function loadPlugins(): void
101
    {
102 9
        foreach (Config::plugins() as $pluginClass) {
103 9
            if (!class_implements($pluginClass, Plugin::class)) {
104
                throw InvalidPlugin::doesntImplementPluginInterface($pluginClass);
105
            }
106
107 9
            self::loadPluginConfiguration($pluginClass);
108
109 9
            self::loadPluginServices($pluginClass);
110
111 9
            self::registerPluginDefinition($pluginClass);
112
        }
113 9
    }
114
115 9
    protected static function loadPluginConfiguration(string $pluginClass): void
116
    {
117 9
        $configurationPath = forward_static_call([$pluginClass, 'getConfigurationPath']);
118
119 9
        if (!$configurationPath) {
120
            return;
121
        }
122
123 9
        if (!file_exists($configurationPath)) {
124
            throw InvalidPlugin::configurationFileNotFound($pluginClass, $configurationPath);
125
        }
126
127 9
        $pluginConfiguration = require $configurationPath;
128
129 9
        if (!is_array($pluginConfiguration)) {
130
            throw InvalidPlugin::configurationMustBeArray($pluginClass, $configurationPath);
131
        }
132
133 9
        self::loadConfig(Arr::dot($pluginConfiguration));
134 9
    }
135
136 9
    protected static function loadPluginServices(string $pluginClass): void
137
    {
138 9
        $servicesPath = forward_static_call([$pluginClass, 'getServicesPath']);
139
140 9
        if (!$servicesPath) {
141
            return;
142
        }
143
144 9
        if (!file_exists($servicesPath)) {
145
            throw InvalidPlugin::serviceFileNotFound($pluginClass, $servicesPath);
146
        }
147
148 9
        self::loadServices($servicesPath);
149 9
    }
150
151 9
    protected static function registerPluginDefinition(string $pluginClass): void
152
    {
153 9
        $definition = new Definition($pluginClass);
154
155 9
        $definition->setAutowired(true);
156
157 9
        self::$container->setDefinition($pluginClass, $definition);
158
159 9
        forward_static_call([$pluginClass, 'boot']);
160 9
    }
161
162 9
    protected static function loadRoutes(): void
163
    {
164 9
        $routeFile = File::path('src/routes.php');
165
166 9
        if (! file_exists($routeFile)) {
167
            return;
168
        }
169
170 9
        require_once $routeFile;
171 9
    }
172
}
173