PluginProbe
FluentCommunity – Ultra-Fast High-Performance Social Network, Community, LMS & Online Courses / 2.7.7
FluentCommunity – Ultra-Fast High-Performance Social Network, Community, LMS & Online Courses v2.7.7
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
fluent-community / vendor / wpfluent / framework / src / WPFluent / Foundation / ComponentBinder.php

ComponentBinder.php in FluentCommunity – Ultra-Fast High-Performance Social Network, Community, LMS & Online Courses 2.7.7, at vendor/wpfluent/framework/src/WPFluent/Foundation/ComponentBinder.php

480 lines 12.4 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 namespace FluentCommunity\Framework\Foundation;
4
5 use FluentCommunity\Framework\Support\Arr;
6 use FluentCommunity\Framework\View\View;
7 use FluentCommunity\Framework\Cache\Cache;
8 use FluentCommunity\Framework\Http\URL;
9 use FluentCommunity\Framework\Http\UrlGenerator;
10 use FluentCommunity\Framework\Support\Mail;
11 use FluentCommunity\Framework\Support\Pipeline;
12 use FluentCommunity\Framework\Http\Router;
13 use FluentCommunity\Framework\Http\Request\Request;
14 use FluentCommunity\Framework\Http\Response\Response;
15 use FluentCommunity\Framework\Events\Dispatcher;
16 use FluentCommunity\Framework\Encryption\Encrypter;
17 use FluentCommunity\Framework\Database\Orm\Model;
18 use FluentCommunity\Framework\Validator\Validator;
19 use FluentCommunity\Framework\Foundation\RequestGuard;
20 use FluentCommunity\Framework\Foundation\Exceptions\ExceptionHandler;
21 use FluentCommunity\Framework\Database\DatabaseManager;
22 use FluentCommunity\Framework\Database\DatabaseTransactionsManager;
23 use FluentCommunity\Framework\Database\ConnectionResolver;
24 use FluentCommunity\Framework\Database\Query\WPDBConnection;
25 use FluentCommunity\Framework\Pagination\AbstractCursorPaginator;
26 use FluentCommunity\Framework\Pagination\AbstractPaginator;
27 use FluentCommunity\Framework\Pagination\CursorPaginator;
28 use FluentCommunity\Framework\Pagination\Cursor;
29 use WpOrg\Requests\Exception\Http\Status401;
30
31 class ComponentBinder
32 {
33 use Concerns\DynamicFacadeTrait;
34
35 /**
36 * The application instance
37 * @var \FluentCommunity\Framework\Foundation\Application
38 */
39 protected $app = null;
40
41 /**
42 * List of bindings
43 * @var array
44 */
45 protected $bindables = [
46 'Cache',
47 'Request',
48 'Response',
49 'Validator',
50 'View',
51 'Events',
52 'Encrypter',
53 'DB',
54 'URL',
55 'Router',
56 'Mail',
57 'Paginator',
58 'Pipeline',
59 'ExceptionHandler',
60 ];
61
62 /**
63 * Construct the binder
64 * @param \FluentCommunity\Framework\Foundation\Application $app
65 */
66 public function __construct($app)
67 {
68 $this->registerFacadeResolver(
69 $this->app = $app
70 );
71 }
72
73 /**
74 * Bind all the components in to the container.
75 * @return null
76 */
77 public function bindComponents()
78 {
79 foreach ($this->bindables as $value) {
80 $method = "bind{$value}";
81 $this->{$method}();
82 }
83
84 $this->extendBindings($this->app);
85
86 $this->loadGlobalFunctions($this->app);
87
88 $this->registerResolvingEvent($this->app);
89 }
90
91 public function resolveDatabaseTransactionsManager()
92 {
93 if (!$this->app->bound('db.transactions')) {
94 $this->app->singleton('db.transactions', function ($app) {
95 return new DatabaseTransactionsManager;
96 });
97 }
98
99 return $this->app->make('db.transactions');
100 }
101
102 /**
103 * Register resolving event into the container.
104 * @param \FluentCommunity\Framework\Foundation\Application $app
105 * @return null
106 */
107 protected function registerResolvingEvent($app)
108 {
109 $app->resolving(RequestGuard::class, function($request) use ($app) {
110
111 $request->setRequestInstance($app->request);
112
113 if (method_exists($request, 'authorize')) {
114 if(!$request->authorize()) throw new Status401;
115 }
116
117 $request->merge((array) $request->beforeValidation());
118 $request->validate();
119 $request->merge((array) $request->afterValidation(
120 $request->getValidator()
121 ));
122 });
123 }
124
125 /**
126 * Bind the cache instance into the container.
127 * @return null
128 */
129 protected function bindCache()
130 {
131 $this->app->singleton(Cache::class, function ($app) {
132 return Cache::init();
133 });
134
135 $this->app->alias(Cache::class, 'cache');
136 }
137
138 /**
139 * Bind the request instance into the container.
140 * @return null
141 */
142 protected function bindRequest()
143 {
144 $method = $this->getBindingMethod('singleton');
145
146 $this->app->$method(Request::class, function ($app) {
147 return $this->resolveRequest($app);
148 });
149
150 $this->app->alias(Request::class, 'request');
151
152 $this->addBackwardCompatibleAlias(Request::class);
153 }
154
155 /**
156 * Bind the reesponse instance into the container.
157 * @return null
158 */
159 protected function bindResponse()
160 {
161 $method = $this->getBindingMethod('singleton');
162
163 $this->app->$method(Response::class, function($app) {
164 return new Response($app);
165 });
166
167 $this->app->alias(Response::class, 'response');
168
169 $this->addBackwardCompatibleAlias(Response::class);
170 }
171
172 /**
173 * Get the binding method to bind a component.
174 * In the testing environment, we use bind
175 * method instead of singleton method.
176 *
177 * @param string $original
178 * @return string
179 */
180 protected function getBindingMethod($original)
181 {
182 return str_starts_with(
183 $this->app->env(), 'testing'
184 ) ? 'bind' : $original;
185 }
186
187 /**
188 * Bind the request validator into the container.
189 * @return null
190 */
191 protected function bindValidator()
192 {
193 $this->app->bind(Validator::class, function($app) {
194 return new Validator;
195 });
196
197 $this->app->alias(Validator::class, 'validator');
198 }
199
200 /**
201 * Bind the view instance into the container.
202 * @return null
203 */
204 protected function bindView()
205 {
206 $this->app->bind(View::class, function($app) {
207 return new View($app);
208 });
209
210 $this->app->alias(View::class, 'view');
211 }
212
213 /**
214 * Bind the event dispatcher instance into the container.
215 * @return null
216 */
217 protected function bindEvents()
218 {
219 $this->app->singleton(Dispatcher::class, function($app) {
220 return (new Dispatcher($app))->setTransactionManagerResolver(
221 fn () => $this->resolveDatabaseTransactionsManager()
222 );
223 });
224
225 $this->app->alias(Dispatcher::class, 'events');
226 }
227
228 /**
229 * Bind the encrypter instance into the container.
230 * @return null
231 */
232 protected function bindEncrypter()
233 {
234 $this->app->singleton(Encrypter::class, function($app) {
235 return new Encrypter($app->config->get('app.key'));
236 });
237
238 $this->app->alias(Encrypter::class, 'encrypter');
239 $this->app->alias(Encrypter::class, 'crypt');
240 }
241
242 /**
243 * Bind the db (query builder) instance into the container.
244 * @return null
245 */
246 protected function bindDB()
247 {
248 $connection = new WPDBConnection($GLOBALS['wpdb']);
249
250 $resolver = new ConnectionResolver([
251 'mysql' => $connection,
252 'sqlite' => $connection,
253 ]);
254
255 $resolver->setDefaultConnection('mysql');
256
257 $resolver->connection()->setTransactionManager(
258 $this->resolveDatabaseTransactionsManager()
259 );
260
261 Model::setConnectionResolver($resolver);
262
263 Model::setEventDispatcher($this->app['events']);
264
265 $this->app->singletonIf('db', function($app) use ($resolver) {
266 return new DatabaseManager($resolver);
267 });
268 }
269
270 /**
271 * Bind the Url instance into the container.
272 * @return null
273 */
274 protected function bindUrl()
275 {
276 $this->app->bind(URL::class, function($app) {
277 return new URL('', new UrlGenerator($app));
278 });
279
280 $this->app->alias(URL::class, 'url');
281 }
282
283 /**
284 * Bind the router instance into the container.
285 * @return null
286 */
287 protected function bindRouter()
288 {
289 $this->app->singleton(Router::class, function($app) {
290 return new Router($app);
291 });
292
293 $this->app->alias(Router::class, 'router');
294 }
295
296 /**
297 * Bind the mail instance into the container.
298 * @return null
299 */
300 protected function bindMail()
301 {
302 $this->app->bind(Mail::class, function($app) {
303 return new Mail();
304 });
305
306 $this->app->alias(Mail::class, 'mail');
307 }
308
309 /**
310 * Bind the paginator instance into the container.
311 * @return null
312 */
313 protected function bindPaginator()
314 {
315 AbstractPaginator::currentPathResolver(function () {
316 return $this->app['request']->url();
317 });
318
319 AbstractPaginator::currentPageResolver(function ($pageName = 'page') {
320 $page = $this->app['request']->get($pageName);
321
322 if (filter_var($page, FILTER_VALIDATE_INT) !== false && (int) $page >= 1) {
323 return $page;
324 }
325
326 return 1;
327 });
328
329 AbstractPaginator::queryStringResolver(function () {
330 return $this->app['request']->query();
331 });
332
333 AbstractCursorPaginator::currentCursorResolver(function ($cursorName = 'cursor') {
334 return Cursor::fromEncoded($this->app['request']->get($cursorName));
335 });
336 }
337
338 /**
339 * Bind the pipeline instance into the container.
340 * @return null
341 */
342 protected function bindPipeline()
343 {
344 $this->app->bind(Pipeline::class, function ($app) {
345 return new Pipeline($app);
346 });
347
348 $this->app->alias(Pipeline::class, 'pipeline');
349 }
350
351 /**
352 * Bind the exception-handler registry into the container.
353 *
354 * Default is the bare `Foundation\Exceptions\ExceptionHandler` (no
355 * renderables registered). Plugins override by re-binding their own
356 * subclass to the same key from `boot/bindings.php` BEFORE the first
357 * request hits Route.
358 *
359 * @return null
360 */
361 protected function bindExceptionHandler()
362 {
363 $this->app->singleton(ExceptionHandler::class, function ($app) {
364 return new ExceptionHandler();
365 });
366
367 $this->app->alias(ExceptionHandler::class, 'exception.handler');
368 }
369
370 /**
371 * Load other bindings the developers might
372 * have added in the application level.
373 *
374 * @param \FluentCommunity\Framework\Foundation\Application $app
375 * @return null
376 */
377 protected function extendBindings($app)
378 {
379 $bindings = $app['path'] . 'boot/bindings.php';
380
381 if (is_readable($bindings)) {
382 require_once $bindings;
383 }
384 }
385
386 /**
387 * Load the plugin's global functions
388 * @param \FluentCommunity\Framework\Foundation\Application $app
389 * @return null
390 */
391 protected function loadGlobalFunctions($app)
392 {
393 $globals = $app['path'] . 'boot/globals.php';
394
395 if (is_readable($globals)) {
396 require_once $globals;
397 }
398 }
399
400 /**
401 * Adds new alias to maintain the backward compatibility.
402 *
403 * @param string $class
404 * @return void
405 */
406 protected function addBackwardCompatibleAlias($class)
407 {
408 $this->app->alias(
409 $class, $alias = $this->getAlias($class)
410 );
411
412 if (!class_exists($alias)) {
413 class_alias($class, $alias);
414 }
415 }
416
417 /**
418 * Resolves the backward compatible alias.
419 *
420 * @param string $class
421 * @return string New alias
422 */
423 protected function getAlias($class)
424 {
425 $pieces = explode('\\', $class);
426
427 if ($index = Arr::findPath($pieces, 'Http')) {
428 unset($pieces[$index]);
429 }
430
431 return implode('\\', $pieces);
432 }
433
434 /**
435 * Resolve the appropriate request instance.
436 *
437 * @param $app
438 * @return Request|object (Anonymous Class)
439 */
440 protected function resolveRequest($app)
441 {
442 return new Request($app, $_GET, $_POST);
443 }
444
445 /**
446 * Check if the request is of the plugin.
447 *
448 * @return boolean
449 */
450 protected function isRequestOfPlugin()
451 {
452 if (str_starts_with($this->app->env(), 'testing')) {
453 return true;
454 }
455
456 $slug = $this->app->config->get('app.slug');
457
458 if (get_option('permalink_structure')) {
459 $route = $_SERVER['REQUEST_URI'] ?? '';
460 } else {
461 $route = $_GET['rest_route'] ?? '';
462 }
463
464 $parsedUrl = parse_url($route);
465
466 $path = $parsedUrl['path'] ?? '';
467
468 $path = str_replace('/wp-json', '', $path);
469
470 if (is_admin()) {
471 $page = $_GET['page'] ?? '';
472 if ($slug === $page) {
473 $path = $page;
474 }
475 }
476
477 return str_starts_with(ltrim($path, '/'), $slug);
478 }
479 }
480