Passed
Push — master ( ca0a0b...aa0ed6 )
by Atanas
02:10
created

Framework::boot()   B

Complexity

Conditions 2
Paths 2

Size

Total Lines 27
Code Lines 16

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 6

Importance

Changes 0
Metric Value
cc 2
eloc 16
c 0
b 0
f 0
nc 2
nop 1
dl 0
loc 27
rs 8.8571
ccs 0
cts 0
cp 0
crap 6
1
<?php
2
3
namespace Obsidian;
4
5
use ReflectionException;
6
use ReflectionMethod;
7
use Exception;
8
use Pimple\Container;
9
use Psr\Http\Message\ResponseInterface;
10
use Obsidian\Support\Facade;
11
use Obsidian\Support\AliasLoader;
12
use Obsidian\Routing\RoutingServiceProvider;
13
use Obsidian\Flash\FlashServiceProvider;
14
use Obsidian\Input\OldInputServiceProvider;
15
use Obsidian\Templating\TemplatingServiceProvider;
16
use Obsidian\Controllers\ControllersServiceProvider;
17
18
/**
19
 * Main communication channel with the framework
20
 */
21
class Framework {
22
	/**
23
	 * Flag whether the framework has been booted
24
	 *
25
	 * @var boolean
26
	 */
27
	protected static $booted = false;
28
29
	/**
30
	 * IoC container
31
	 *
32
	 * @var Container
33
	 */
34
	protected static $container = null;
35
36
	/**
37
	 * Array of framework service providers
38
	 *
39
	 * @var string[]
40
	 */
41
	protected static $service_proviers = [
42
		RoutingServiceProvider::class,
43
		FlashServiceProvider::class,
44
		OldInputServiceProvider::class,
45
		TemplatingServiceProvider::class,
46
		ControllersServiceProvider::class,
47
	];
48
49
	/**
50
	 * Get whether WordPress is in debug mode
51
	 *
52
	 * @return boolean
53
	 */
54 1
	public static function debugging() {
55 1
		$debugging = ( defined( 'WP_DEBUG' ) && WP_DEBUG );
56 1
		$debugging = apply_filters( 'obsidian.debug', $debugging );
57 1
		return $debugging;
58
	}
59
60
	/**
61
	 * Get whether the framework has been booted
62
	 *
63
	 * @return boolean
64
	 */
65 1
	public static function isBooted() {
66 1
		return static::$booted;
67
	}
68
69
	/**
70
	 * Throw an exception if the framework has not been booted
71
	 *
72
	 * @codeCoverageIgnore
73
	 * @throws Exception
74
	 * @return void
75
	 */
76
	protected static function verifyBoot() {
77
		if ( ! static::isBooted() ) {
78
			throw new Exception( get_called_class() . ' must be booted first.' );
79
		}
80
	}
81
82
	/**
83
	 * Get the IoC container instance
84
	 *
85
	 * @return Container
86
	 */
87 2
	public static function getContainer() {
88
		// @codeCoverageIgnoreStart
89
		if ( static::$container === null ) {
90
			static::$container = new Container();
91
		}
92
		// @codeCoverageIgnoreEnd
93 2
		return static::$container;
94
	}
95
96
	/**
97
	 * Boot the framework
98
	 * WordPress's 'after_setup_theme' action is a good place to call this
99
	 *
100
	 * @codeCoverageIgnore
101
	 * @param  array     $config
102
	 * @throws Exception
103
	 * @return void
104
	 */
105
	public static function boot( $config = [] ) {
106
		if ( static::isBooted() ) {
107
			throw new Exception( get_called_class() . ' already booted.' );
108
		}
109
110
		do_action( 'obsidian.booting' );
111
112
		$container = static::getContainer();
113
114
		$container['framework.config'] = array_merge( [
115
			'providers' => [],
116
		], $config );
117
118
		$container['framework.service_providers'] = array_merge(
119
			static::$service_proviers,
120
			$container['framework.config']['providers']
121
		);
122
123
		Facade::setFacadeApplication( $container );
124
		AliasLoader::getInstance()->register();
125
126
		static::loadServiceProviders( $container );
127
128
		static::$booted = true;
129
130
		do_action( 'obsidian.booted' );
131
	}
132
133
	/**
134
	 * Register and boot all service providers
135
	 *
136
	 * @codeCoverageIgnore
137
	 * @param  Container $container
138
	 * @return void
139
	 */
140
	protected static function loadServiceProviders( $container ) {
141
		$container['framework.service_providers'] = apply_filters(
142
			'obsidian.service_providers',
143
			$container['framework.service_providers']
144
		);
145
146
		$service_providers = array_map( function( $service_provider ) {
147
			return new $service_provider();
148
		}, $container['framework.service_providers'] );
149
150
		static::registerServiceProviders( $service_providers, $container );
151
		static::bootServiceProviders( $service_providers, $container );
152
	}
153
154
	/**
155
	 * Register all service providers
156
	 *
157
	 * @codeCoverageIgnore
158
	 * @param  \Obsidian\ServiceProviders\ServiceProviderInterface[] $service_providers
159
	 * @param  Container                                             $container
160
	 * @return void
161
	 */
162
	protected static function registerServiceProviders( $service_providers, $container ) {
163
		foreach ( $service_providers as $provider ) {
164
			$provider->register( $container );
165
		}
166
	}
167
168
	/**
169
	 * Boot all service providers
170
	 *
171
	 * @codeCoverageIgnore
172
	 * @param  \Obsidian\ServiceProviders\ServiceProviderInterface[] $service_providers
173
	 * @param  Container                                             $container
174
	 * @return void
175
	 */
176
	protected static function bootServiceProviders( $service_providers, $container ) {
177
		foreach ( $service_providers as $provider ) {
178
			$provider->boot( $container );
179
		}
180
	}
181
182
	/**
183
	 * Register a facade class
184
	 *
185
	 * @param  string $alias
186
	 * @param  string $facade_class
187
	 * @return void
188
	 */
189 1
	public static function facade( $alias, $facade_class ) {
190 1
		AliasLoader::getInstance()->alias( $alias, $facade_class );
191 1
	}
192
193
	/**
194
	 * Resolve a dependency from the IoC container
195
	 *
196
	 * @param  string   $key
197
	 * @return mixed|null
198
	 */
199 2
	public static function resolve( $key ) {
200 2
		static::verifyBoot();
201
202 2
		if ( ! isset( static::getContainer()[ $key ] ) ) {
203 1
			return null;
204
		}
205
206 1
		return static::getContainer()[ $key ];
207
	}
208
209
	/**
210
	 * Create and return a class instance
211
	 *
212
	 * @param  string $class
213
	 * @return object
214
	 */
215 2
	public static function instantiate( $class ) {
216 2
		static::verifyBoot();
217
218 2
		$instance = static::resolve( $class );
219
220 2
		if ( $instance === null ) {
221 1
			$instance = new $class();
222
		}
223
224 2
		return $instance;
225
	}
226
227
	/**
228
	 * Send output based on a response object
229
	 *
230
	 * @codeCoverageIgnore
231
	 * @param  ResponseInterface $response
232
	 * @return void
233
	 */
234
	public static function respond( ResponseInterface $response ) {
235
		Response::respond( $response );
236
	}
237
}
238