Passed
Push — develop ( 7c7d13...1e3e9e )
by Brent
02:40
created

App::developmentServer()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 8
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 2.5

Importance

Changes 0
Metric Value
cc 2
eloc 5
nc 2
nop 0
dl 0
loc 8
ccs 2
cts 4
cp 0.5
crap 2.5
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 10
    public static function init(): void
24
    {
25 10
        Config::init();
26
27 10
        self::$container = new ContainerBuilder();
28
29 10
        self::loadConfig(Config::all());
30
31 10
        self::loadServices('services.yaml');
32
33 10
        self::loadPlugins();
34
35 10
        self::loadRoutes();
36 10
    }
37
38
    /**
39
     * @param string $id
40
     *
41
     * @return mixed
42
     * @throws \Exception
43
     */
44 10
    public static function get(string $id)
45
    {
46 10
        return self::$container->get($id);
47
    }
48
49 1
    public static function developmentServer(): DevelopmentServer
50
    {
51
        try {
52 1
            return self::get(DevelopmentServer::class);
53
        } catch (ParameterNotFoundException $e) {
54
            throw InvalidConfiguration::missingParameter($e->getKey());
55
        }
56
    }
57
58 1
    public static function productionServer(): ProductionServer
59
    {
60
        try {
61 1
            return self::get(ProductionServer::class);
62
        } catch (ParameterNotFoundException $e) {
63
            throw InvalidConfiguration::missingParameter($e->getKey());
64
        }
65
    }
66
67 2
    public static function router(): Router
68
    {
69 2
        return self::get(Router::class);
70
    }
71
72 10
    protected static function loadConfig(array $config): void
73
    {
74 10
        foreach ($config as $key => $value) {
75 10
            self::$container->setParameter($key, $value);
76
        }
77 10
    }
78
79 10
    protected static function loadServices(string $servicesPath): void
80
    {
81 10
        $loader = new YamlFileLoader(self::$container, new FileLocator(__DIR__));
82
83 10
        $loader->load($servicesPath);
84
85
        /** @var Definition $definition */
86 10
        foreach (self::$container->getDefinitions() as $id => $definition) {
87 10
            self::$container->setAlias($definition->getClass(), $id);
88
        }
89 10
    }
90
91 10
    protected static function loadPlugins(): void
92
    {
93 10
        foreach (Config::plugins() as $pluginClass) {
94 10
            if (!class_implements($pluginClass, Plugin::class)) {
95
                throw InvalidPlugin::doesntImplementPluginInterface($pluginClass);
96
            }
97
98 10
            self::loadPluginConfiguration($pluginClass);
99
100 10
            self::loadPluginServices($pluginClass);
101
102 10
            self::registerPluginDefinition($pluginClass);
103
        }
104 10
    }
105
106 10
    protected static function loadPluginConfiguration(string $pluginClass): void
107
    {
108 10
        $configurationPath = forward_static_call([$pluginClass, 'getConfigurationPath']);
109
110 10
        if (!$configurationPath) {
111
            return;
112
        }
113
114 10
        if (!file_exists($configurationPath)) {
115
            throw InvalidPlugin::configurationFileNotFound($pluginClass, $configurationPath);
116
        }
117
118 10
        $pluginConfiguration = require $configurationPath;
119
120 10
        if (!is_array($pluginConfiguration)) {
121
            throw InvalidPlugin::configurationMustBeArray($pluginClass, $configurationPath);
122
        }
123
124 10
        self::loadConfig(Arr::dot($pluginConfiguration));
125 10
    }
126
127 10
    protected static function loadPluginServices(string $pluginClass): void
128
    {
129 10
        $servicesPath = forward_static_call([$pluginClass, 'getServicesPath']);
130
131 10
        if (!$servicesPath) {
132
            return;
133
        }
134
135 10
        if (!file_exists($servicesPath)) {
136
            throw InvalidPlugin::serviceFileNotFound($pluginClass, $servicesPath);
137
        }
138
139 10
        self::loadServices($servicesPath);
140 10
    }
141
142 10
    protected static function registerPluginDefinition(string $pluginClass): void
143
    {
144 10
        $definition = new Definition($pluginClass);
145
146 10
        $definition->setAutowired(true);
147
148 10
        self::$container->setDefinition($pluginClass, $definition);
149
150 10
        forward_static_call([$pluginClass, 'boot']);
151 10
    }
152
153 10
    protected static function loadRoutes(): void
154
    {
155 10
        $routeFile = File::path('src/routes.php');
156
157 10
        if (! file_exists($routeFile)) {
158
            return;
159
        }
160
161 10
        require_once $routeFile;
162 10
    }
163
}
164