PluginProbe
FluentCommunity – Ultra-Fast High-Performance Social Network, Community, LMS & Online Courses / 2.11.0
FluentCommunity – Ultra-Fast High-Performance Social Network, Community, LMS & Online Courses v2.11.0
2.11.0 2.10.0 2.10.01 2.9.1 2.9.0 2.8.1 2.8.0 2.7.7 2.7.5 2.7.0 2.6.01 2.6.0 2.5.0 2.4.01 trunk 1.0.90 1.0.91 1.0.92 1.0.93 1.0.94 1.0.95 1.0.96 1.0.97 1.0.98 1.0.99 All 78 releases
← All changes | vendor/wpfluent/framework/src/WPFluent/Foundation/Application.php +106 -32 1.0.98 → 2.11.0 View file →
@@ -1,5 +1,14 @@
1 1 <?php
2 +/**
3 + * @package WPFluent
4 + * @author Sheikh Heera <[email protected]> (https://heera.it)
5 + * @author Sheikh Heera <[email protected]>
6 + * @author Sheikh Heera <[email protected]>
7 + * @link https://github.com/wpfluent/framework2x
8 + * @license MIT https://opensource.org/licenses/MIT
9 + * @license GPL-2.0-or-later https://www.gnu.org/licenses/gpl-2.0.html
10 + */
2 11
3 12 namespace FluentCommunity\Framework\Foundation;
4 13
5 14 use InvalidArgumentException;
@@ -8,10 +17,35 @@
8 17 use FluentCommunity\Framework\Http\Client;
9 18 use FluentCommunity\Framework\Foundation\Config;
10 19 use FluentCommunity\Framework\Container\Container;
11 20 use FluentCommunity\Framework\Foundation\ComponentBinder;
12 -use FluentCommunity\Framework\Foundation\FoundationTrait;
21 +use FluentCommunity\Framework\Foundation\Concerns\FoundationTrait;
13 22
23 +/**
24 + * Application — service container with magic property access via __get.
25 + *
26 + * Properties below are bound in {@see ComponentBinder::bindComponents()} and
27 + * {@see Application::init()}/{@see Application::setAppLevelNamespace()}. Each
28 + * `@property` declaration teaches PHPStan about a runtime container binding so
29 + * `$app->view->render(...)` and similar access can be type-checked.
30 + *
31 + * @property \FluentCommunity\Framework\Foundation\Config $config
32 + * @property \FluentCommunity\Framework\View\View $view
33 + * @property \FluentCommunity\Framework\Cache\Cache $cache
34 + * @property \FluentCommunity\Framework\Http\Router $router
35 + * @property \FluentCommunity\Framework\Http\Request\Request $request
36 + * @property \FluentCommunity\Framework\Http\Response\Response $response
37 + * @property \FluentCommunity\Framework\Validator\Validator $validator
38 + * @property \FluentCommunity\Framework\Events\Dispatcher $events
39 + * @property \FluentCommunity\Framework\Encryption\Encrypter $encrypter
40 + * @property \FluentCommunity\Framework\Encryption\Encrypter $crypt
41 + * @property \FluentCommunity\Framework\Database\DatabaseManager $db
42 + * @property \FluentCommunity\Framework\Http\URL $url
43 + * @property \FluentCommunity\Framework\Support\Mail $mail
44 + * @property \FluentCommunity\Framework\Support\Pipeline $pipeline
45 + * @property string $__pluginfile__
46 + * @property string $__namespace__
47 + */
14 48 class Application extends Container
15 49 {
16 50 use FoundationTrait;
17 51
@@ -54,9 +88,9 @@
54 88 * Default namespace for policy handlers
55 89 *
56 90 * @var string
57 91 */
58 - protected $permissionNamespace = null;
92 + protected $policyNamespace = null;
59 93
60 94 /**
61 95 * Composer JSON
62 96 *
@@ -71,8 +105,15 @@
71 105 */
72 106 protected $onReady = [];
73 107
74 108 /**
109 + * Flag to check if components are bound.
110 + *
111 + * @var boolean
112 + */
113 + protected $componentsBound = false;
114 +
115 + /**
75 116 * Construct the application instance
76 117 *
77 118 * @param string $file The main plugin file's absolute path
78 119 * @return null
@@ -99,8 +140,14 @@
99 140 $this->basePath = plugin_dir_path($this->file);
100 141 $this->baseUrl = plugin_dir_url($this->file);
101 142 }
102 143
144 + /**
145 + * Load the environment bariables from .env file.
146 + *
147 + * @param string $path
148 + * @return void
149 + */
103 150 protected function loadEnvironmentVars($path = null)
104 151 {
105 152 $path = $path ?: $this->basePath . '.env';
106 153
@@ -157,11 +204,11 @@
157 204 {
158 205 $this->bindAppInstance();
159 206 $this->bindPathsAndUrls();
160 207 $this->loadConfigIfExists();
208 + $this->registerMiddleware();
161 209 $this->registerTextdomain();
162 210 $this->bindCoreComponents();
163 - $this->registerAsyncActions();
164 211 $this->requireCommonFiles($this);
165 212 $this->addRestApiInitAction($this);
166 213 }
167 214
@@ -224,21 +271,52 @@
224 271 * @return null
225 272 */
226 273 protected function loadConfigIfExists()
227 274 {
228 - $data = [];
275 + $files = [];
229 276
230 277 if (is_dir($this['path.config'])) {
231 278 foreach (glob($this['path.config'] . '*.php') as $file) {
232 - $data[basename($file, '.php')] = require($file);
279 + // middleware.php lives under app/Http/ now; it ships closures
280 + // that don't belong in Config storage.
281 + if (basename($file) === 'middleware.php') {
282 + continue;
283 + }
284 + $files[basename($file, '.php')] = $file;
233 285 }
234 286 }
235 287
236 - $this->instance('config', new Config($data));
288 + $this->instance('config', new Config([], $files));
237 289 }
238 290
239 291 /**
292 + * Register the HTTP middleware stack as a lazy container binding.
293 + *
294 + * Resolves from `app/Http/middleware.php` (canonical). Falls back to
295 + * `config/middleware.php` so un-migrated plugins keep working.
296 + *
297 + * @return void
298 + */
299 + protected function registerMiddleware()
300 + {
301 + $this->singleton('http.middleware', function ($app) {
302 + $new = $app['path.http'] . 'middleware.php';
303 + if (is_file($new)) {
304 + return require $new;
305 + }
306 +
307 + $legacy = $app['path.config'] . 'middleware.php';
308 + if (is_file($legacy)) {
309 + return require $legacy;
310 + }
311 +
312 + return [];
313 + });
314 + }
315 +
316 + /**
240 317 * Resolve the given type from the container.
318 + * This method is required for unit testing.
241 319 *
242 320 * @param string $abstract
243 321 * @param array $parameters
244 322 * @return mixed
@@ -290,9 +368,12 @@
290 368 * @return null
291 369 */
292 370 protected function bindCoreComponents()
293 371 {
294 - (new ComponentBinder($this))->bindComponents();
372 + if (!$this->componentsBound) {
373 + $this->componentsBound = true;
374 + (new ComponentBinder($this))->bindComponents();
375 + }
295 376 }
296 377
297 378 /**
298 379 * Load (include) the files where hooks are registered.
@@ -308,11 +389,11 @@
308 389 );
309 390
310 391 require_once $this->basePath . 'app/Hooks/actions.php';
311 392 require_once $this->basePath . 'app/Hooks/filters.php';
312 -
313 - if (file_exists($includes = $this->basePath . 'app/Hooks/includes.php')) {
314 - require_once $includes;
393 +
394 + if (file_exists($f = $this->basePath . 'app/Hooks/includes.php')) {
395 + require_once $f;
315 396 }
316 397 }
317 398
318 399 /**
@@ -318,11 +399,11 @@
318 399 /**
319 400 * Handler for rest_pre_serve_request filter.
320 401 *
321 402 * @param bool $served (default: false)
322 - * @param \WP_Rest_Response $result
323 - * @param \WP_Rest_Request $request
324 - * @param \WP_Rest_Server $server
403 + * @param \WP_REST_Response $result
404 + * @param \WP_REST_Request $request
405 + * @param \WP_REST_Server $server
325 406 * @return bool (false to intercept, otherwise true)
326 407 */
327 408 public function preServeRequest($served, $result, $request, $server)
328 409 {
@@ -333,8 +414,9 @@
333 414 if ($this->isRequestOfPlugin($route, $slug)) {
334 415 if ($this->isRequestForEndpoints($route)) {
335 416 status_header(200);
336 417 $result->set_status(200);
418 + // @phpstan-ignore-next-line
337 419 $result->set_data($this->endpoints);
338 420 } else {
339 421 $result->set_data(
340 422 $this->customizeNotFoundResponse(
@@ -400,10 +482,10 @@
400 482
401 483 /**
402 484 * Prepare a custom not found response.
403 485 *
404 - * @param \WP_Rest_Response $result
405 - * @param \WP_Rest_Request $request
486 + * @param \WP_REST_Response $result
487 + * @param \WP_REST_Request $request
406 488 *
407 489 * @return array
408 490 */
409 491 public function customizeNotFoundResponse($result, $request)
@@ -460,12 +542,13 @@
460 542 * Register rest routes.
461 543 *
462 544 * @param \FluentCommunity\Framework\Http\Router $router
463 545 *
464 - * @return null
546 + * @return void
465 547 */
466 548 protected function registerRestRoutes($router)
467 549 {
550 + // @phpstan-ignore-next-line
468 551 $router->registerRoutes(
469 552 $this->requireRouteFile($router)
470 553 );
471 554 }
@@ -481,37 +564,28 @@
481 564 require_once $this['path.http'] . 'Routes/routes.php';
482 565 }
483 566
484 567 /**
485 - * Register plugin booted callbacks.
568 + * Register plugin ready (booted) callbacks.
486 569 *
487 570 * @param callable $callback
488 571 * @return void
489 572 */
490 - protected function ready(callable $callback)
573 + public function ready(callable $callback)
491 574 {
492 575 $this->onReady[] = $callback;
493 576 }
494 577
495 578 /**
496 - * Register Async Actions.
497 - *
498 - * @return void
499 - */
500 - protected function registerAsyncActions()
501 - {
502 - Client::registerAsyncRequestHandler();
503 - }
504 -
505 - /**
506 579 * Execute plugin booted callbacks.
507 580 *
508 - * @param callable $callback
509 581 * @return void
510 582 */
511 583 protected function callPluginReadyCallbacks()
512 584 {
513 - while ($callback = array_shift($this->onReady)) {
514 - $callback($this);
515 - }
585 + $this->addAction('init', function() {
586 + while ($callback = array_pop($this->onReady)) {
587 + $callback($this);
588 + }
589 + });
516 590 }
517 591 }