Failed Conditions
Branch refactor/kernels (f9ae97)
by Atanas
01:58
created

src/Application/Application.php (1 issue)

Labels
Severity
1
<?php
2
/**
3
 * @package   WPEmerge
4
 * @author    Atanas Angelov <[email protected]>
5
 * @copyright 2018 Atanas Angelov
6
 * @license   https://www.gnu.org/licenses/gpl-2.0.html GPL-2.0
7
 * @link      https://wpemerge.com/
8
 */
9
10
namespace WPEmerge\Application;
11
12
use Pimple\Container;
13
use Psr\Http\Message\ResponseInterface;
14
use WPEmerge\Controllers\ControllersServiceProvider;
15
use WPEmerge\Csrf\CsrfServiceProvider;
16
use WPEmerge\Exceptions\ConfigurationException;
17
use WPEmerge\Exceptions\ExceptionsServiceProvider;
18
use WPEmerge\Facades\Route;
0 ignored issues
show
The type WPEmerge\Facades\Route was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
19
use WPEmerge\Flash\FlashServiceProvider;
20
use WPEmerge\Input\OldInputServiceProvider;
21
use WPEmerge\Kernels\KernelsServiceProvider;
22
use WPEmerge\Requests\RequestsServiceProvider;
23
use WPEmerge\Responses\ResponsesServiceProvider;
24
use WPEmerge\Routing\RoutingServiceProvider;
25
use WPEmerge\ServiceProviders\ServiceProviderInterface;
26
use WPEmerge\Support\AliasLoader;
27
use WPEmerge\View\ViewServiceProvider;
28
29
/**
30
 * Main communication channel with the application.
31
 */
32
class Application {
33
	/**
34
	 * Flag whether the application has been bootstrapped.
35
	 *
36
	 * @var boolean
37
	 */
38
	protected $bootstrapped = false;
39
40
	/**
41
	 * IoC container.
42
	 *
43
	 * @var Container
44
	 */
45
	protected $container = null;
46
47
	/**
48
	 * Array of application service providers.
49
	 *
50
	 * @var string[]
51
	 */
52
	protected $service_providers = [
53
		KernelsServiceProvider::class,
54
		ExceptionsServiceProvider::class,
55
		RequestsServiceProvider::class,
56
		ResponsesServiceProvider::class,
57
		RoutingServiceProvider::class,
58
		ViewServiceProvider::class,
59
		ControllersServiceProvider::class,
60
		CsrfServiceProvider::class,
61
		FlashServiceProvider::class,
62
		OldInputServiceProvider::class,
63
	];
64
65
	/**
66
	 * Constructor.
67
	 *
68
	 * @param Container $container
69
	 */
70 1
	public function __construct( Container $container ) {
71 1
		$this->container = $container;
72
73 1
		$config = isset( $container[ WPEMERGE_CONFIG_KEY ] ) ? $container[ WPEMERGE_CONFIG_KEY ] : [];
74 1
		$config = array_merge( [
75 1
			'providers' => [],
76 1
		], $config );
77 1
		$container[ WPEMERGE_CONFIG_KEY ] = $config;
78 1
	}
79
80
	/**
81
	 * Get whether WordPress is in debug mode.
82
	 *
83
	 * @return boolean
84
	 */
85 1
	public function debugging() {
86 1
		$debugging = ( defined( 'WP_DEBUG' ) && WP_DEBUG );
87 1
		$debugging = apply_filters( 'wpemerge.debug', $debugging );
88 1
		return $debugging;
89
	}
90
91
	/**
92
	 * Get whether the application has been bootstrapped.
93
	 *
94
	 * @return boolean
95
	 */
96 1
	public function isBootstrapped() {
97 1
		return $this->bootstrapped;
98
	}
99
100
	/**
101
	 * Throw an exception if the application has not been bootstrapped.
102
	 *
103
	 * @throws ConfigurationException
104
	 * @return void
105
	 */
106 5
	protected function verifyBootstrap() {
107 5
		if ( ! $this->isBootstrapped() ) {
108 1
			throw new ConfigurationException( static::class . ' must be bootstrapped first.' );
109
		}
110 4
	}
111
112
	/**
113
	 * Get the IoC container instance.
114
	 *
115
	 * @return Container
116
	 */
117 1
	public function getContainer() {
118 1
		return $this->container;
119
	}
120
121
	/**
122
	 * Bootstrap the application.
123
	 * WordPress' 'after_setup_theme' action is a good place to call this.
124
	 *
125
	 * @throws ConfigurationException
126
	 * @param  array   $config
127
	 * @param  boolean $run
128
	 * @return void
129 3
	 */
130 3
	public function bootstrap( $config = [], $run = true ) {
131 1
		if ( $this->isBootstrapped() ) {
132
			throw new ConfigurationException( static::class . ' already bootstrapped.' );
133
		}
134 3
135 3
		$container = $this->getContainer();
136 3
		$this->loadConfig( $container, $config );
137
		$this->loadServiceProviders( $container );
138 3
139
		$this->bootstrapped = true;
140 3
141 3
		if ( $run ) {
142
			$kernel = $this->resolve( WPEMERGE_WORDPRESS_HTTP_KERNEL_KEY );
143
			$kernel->bootstrap();
144
		}
145
	}
146
147
	/**
148
	 * Load config into the service container.
149
	 *
150
	 * @codeCoverageIgnore
151
	 * @param  Container $container
152
	 * @param  array     $config
153
	 * @return void
154
	 */
155
	protected function loadConfig( Container $container, $config ) {
156
		$container[ WPEMERGE_CONFIG_KEY ] = array_merge(
157
			$container[ WPEMERGE_CONFIG_KEY ],
158
			$config
159
		);
160
	}
161
162
	/**
163
	 * Register and bootstrap all service providers.
164
	 *
165
	 * @codeCoverageIgnore
166
	 * @param  Container $container
167
	 * @return void
168
	 */
169
	protected function loadServiceProviders( Container $container ) {
170
		$container[ WPEMERGE_SERVICE_PROVIDERS_KEY ] = array_merge(
171
			$this->service_providers,
172
			$container[ WPEMERGE_CONFIG_KEY ]['providers']
173
		);
174
175
		$service_providers = array_map( function ( $service_provider ) {
176
			if ( ! is_subclass_of( $service_provider, ServiceProviderInterface::class ) ) {
177
				throw new ConfigurationException( 'The following class does not implement ServiceProviderInterface: ' . $service_provider );
178
			}
179
180
			return new $service_provider();
181
		}, $container[ WPEMERGE_SERVICE_PROVIDERS_KEY ] );
182
183
		$this->registerServiceProviders( $service_providers, $container );
184
		$this->bootstrapServiceProviders( $service_providers, $container );
185
	}
186
187
	/**
188
	 * Register all service providers.
189
	 *
190 1
	 * @param  \WPEmerge\ServiceProviders\ServiceProviderInterface[] $service_providers
191 1
	 * @param  Container                                             $container
192 1
	 * @return void
193
	 */
194 1
	protected function registerServiceProviders( $service_providers, Container $container ) {
195
		foreach ( $service_providers as $provider ) {
196
			$provider->register( $container );
197
		}
198
	}
199
200
	/**
201
	 * Bootstrap all service providers.
202
	 *
203 1
	 * @param  \WPEmerge\ServiceProviders\ServiceProviderInterface[] $service_providers
204 1
	 * @param  Container                                             $container
205 1
	 * @return void
206
	 */
207 1
	protected function bootstrapServiceProviders( $service_providers, Container $container ) {
208
		foreach ( $service_providers as $provider ) {
209
			$provider->bootstrap( $container );
210
		}
211
	}
212
213
	/**
214
	 * Register a facade class.
215
	 *
216 1
	 * @param  string $alias
217 1
	 * @param  string $facade_class
218 1
	 * @return void
219
	 */
220
	public function facade( $alias, $facade_class ) {
221
		AliasLoader::getInstance()->alias( $alias, $facade_class );
222
	}
223
224
	/**
225
	 * Resolve a dependency from the IoC container.
226 2
	 *
227 2
	 * @param  string     $key
228
	 * @return mixed|null
229 2
	 */
230 1
	public function resolve( $key ) {
231
		$this->verifyBootstrap();
232
233 1
		if ( ! isset( $this->getContainer()[ $key ] ) ) {
234
			return null;
235
		}
236
237
		return $this->getContainer()[ $key ];
238
	}
239
240
	/**
241
	 * Create and return a class instance.
242
	 *
243 3
	 * @throws ClassNotFoundException
244 3
	 * @param  string $class
245
	 * @return object
246 3
	 */
247
	public function instantiate( $class ) {
248 3
		$this->verifyBootstrap();
249 2
250 1
		$instance = $this->resolve( $class );
251
252
		if ( $instance === null ) {
253 1
			if ( ! class_exists( $class ) ) {
254
				throw new ClassNotFoundException( 'Class not found: ' . $class );
255
			}
256 2
257
			$instance = new $class();
258
		}
259
260
		return $instance;
261
	}
262
263
	/**
264
	 * Send output based on a response object.
265
	 *
266
	 * @codeCoverageIgnore
267
	 * @param  ResponseInterface $response
268
	 * @return void
269
	 */
270
	public function respond( ResponseInterface $response ) {
271
		$this->resolve( WPEMERGE_RESPONSE_SERVICE_KEY )->respond( $response );
272
	}
273
274
	/**
275
	 * Load a route definition file, applying middleware to all routes defined within.
276
	 *
277
	 * @codeCoverageIgnore
278
	 * @param  string        $file
279
	 * @param  array<string> $middleware
280
	 * @return void
281
	 */
282
	protected function loadRoutes( $file, $middleware = [] ) {
283
		if ( empty( $file ) ) {
284
			return;
285
		}
286
287
		Route::middleware( $middleware )->group( $file );
288
	}
289
290
	/**
291
	 * Load route definition files according to the current request.
292
	 *
293
	 * @codeCoverageIgnore
294
	 * @param  string $web
295
	 * @param  string $admin
296
	 * @param  string $ajax
297
	 * @return void
298
	 */
299
	public function routes( $web = '', $admin = '', $ajax = '' ) {
300
		if ( defined( 'DOING_AJAX' ) && DOING_AJAX ) {
301
			$this->loadRoutes( $ajax, ['ajax'] );
302
			return;
303
		}
304
305
		if ( is_admin() ) {
306
			$this->loadRoutes( $admin, ['admin'] );
307
			return;
308
		}
309
310
		$this->loadRoutes( $web, ['web'] );
311
	}
312
}
313