Passed
Push — master ( 245cc8...c3dd65 )
by Atanas
01:47
created

Framework::facade()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 3
CRAP Score 1

Importance

Changes 0
Metric Value
cc 1
eloc 2
nc 1
nop 2
dl 0
loc 3
rs 10
c 0
b 0
f 0
ccs 3
cts 3
cp 1
crap 1
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
		Facade::setFacadeApplication( $container );
114
		AliasLoader::getInstance()->register();
115
116
		static::loadConfig( $container, $config );
117
		static::loadServiceProviders( $container );
118
119
		static::$booted = true;
120
121
		do_action( 'obsidian.booted' );
122
	}
123
124
	/**
125
	 * Load config into the service container
126
	 *
127
	 * @param  Container $container
128
	 * @param  array     $config
129
	 * @return void
130
	 */
131
	protected static function loadConfig( Container $container, $config ) {
132
		$container = static::getContainer();
133
		$container['framework.config'] = array_merge( [
134
			'providers' => [],
135
		], $config );
136
	}
137
138
	/**
139
	 * Register and boot all service providers
140
	 *
141
	 * @codeCoverageIgnore
142
	 * @param  Container $container
143
	 * @return void
144
	 */
145
	protected static function loadServiceProviders( Container $container ) {
146
		$container['framework.service_providers'] = array_merge(
147
			static::$service_proviers,
148
			$container['framework.config']['providers']
149
		);
150
151
		$container['framework.service_providers'] = apply_filters(
152
			'obsidian.service_providers',
153
			$container['framework.service_providers']
154
		);
155
156
		$service_providers = array_map( function( $service_provider ) {
157
			return new $service_provider();
158
		}, $container['framework.service_providers'] );
159
160
		static::registerServiceProviders( $service_providers, $container );
161
		static::bootServiceProviders( $service_providers, $container );
162
	}
163
164
	/**
165
	 * Register all service providers
166
	 *
167
	 * @codeCoverageIgnore
168
	 * @param  \Obsidian\ServiceProviders\ServiceProviderInterface[] $service_providers
169
	 * @param  Container                                             $container
170
	 * @return void
171
	 */
172
	protected static function registerServiceProviders( $service_providers, Container $container ) {
173
		foreach ( $service_providers as $provider ) {
174
			$provider->register( $container );
175
		}
176
	}
177
178
	/**
179
	 * Boot all service providers
180
	 *
181
	 * @codeCoverageIgnore
182
	 * @param  \Obsidian\ServiceProviders\ServiceProviderInterface[] $service_providers
183
	 * @param  Container                                             $container
184
	 * @return void
185
	 */
186
	protected static function bootServiceProviders( $service_providers, Container $container ) {
187
		foreach ( $service_providers as $provider ) {
188
			$provider->boot( $container );
189
		}
190
	}
191
192
	/**
193
	 * Register a facade class
194
	 *
195
	 * @param  string $alias
196
	 * @param  string $facade_class
197
	 * @return void
198
	 */
199 1
	public static function facade( $alias, $facade_class ) {
200 1
		AliasLoader::getInstance()->alias( $alias, $facade_class );
201 1
	}
202
203
	/**
204
	 * Resolve a dependency from the IoC container
205
	 *
206
	 * @param  string   $key
207
	 * @return mixed|null
208
	 */
209 2
	public static function resolve( $key ) {
210 2
		static::verifyBoot();
211
212 2
		if ( ! isset( static::getContainer()[ $key ] ) ) {
213 1
			return null;
214
		}
215
216 1
		return static::getContainer()[ $key ];
217
	}
218
219
	/**
220
	 * Create and return a class instance
221
	 *
222
	 * @param  string $class
223
	 * @return object
224
	 */
225 2
	public static function instantiate( $class ) {
226 2
		static::verifyBoot();
227
228 2
		$instance = static::resolve( $class );
229
230 2
		if ( $instance === null ) {
231 1
			$instance = new $class();
232 1
		}
233
234 2
		return $instance;
235
	}
236
237
	/**
238
	 * Send output based on a response object
239
	 *
240
	 * @codeCoverageIgnore
241
	 * @param  ResponseInterface $response
242
	 * @return void
243
	 */
244
	public static function respond( ResponseInterface $response ) {
245
		Response::respond( $response );
246
	}
247
}
248