PluginProbe
FluentBoards – Project Management, Task Management, Goal Tracking, Kanban Board, and, Team Collaboration / 1.91.6
FluentBoards – Project Management, Task Management, Goal Tracking, Kanban Board, and, Team Collaboration v1.91.6
2.1.0 2.0.15 2.0.12 2.0.10 2.0.4 2.0.1 2.0.0 1.95.3 1.95.2 1.95 1.91.6 trunk 1.11 1.12 1.13 1.20 1.21 1.22 1.23 1.30 1.31 1.32 1.35 1.40 1.41 All 42 releases
fluent-boards / vendor / wpfluent / framework / src / WPFluent / Foundation / ComponentBinder.php

ComponentBinder.php in FluentBoards – Project Management, Task Management, Goal Tracking, Kanban Board, and, Team Collaboration 1.91.6, at vendor/wpfluent/framework/src/WPFluent/Foundation/ComponentBinder.php

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