Advertisement
Romanovich095

DIspatcher.php

Dec 11th, 2018
212
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
PHP 4.46 KB | None | 0 0
  1. <?php
  2.  
  3. namespace Recman\Core\Http;
  4.  
  5. use Exception;
  6. use Recman\Core\Controller;
  7. use Recman\Core\Database\Model;
  8. use Recman\Core\Entities\Entity;
  9. use Recman\Core\Entities\Route;
  10. use ReflectionMethod;
  11. use ReflectionParameter;
  12.  
  13. /**
  14.  * Class Dispatcher
  15.  * @package Recman\Core\Http
  16.  */
  17. class Dispatcher
  18. {
  19.  
  20.     /**
  21.      * @var Dispatcher
  22.      */
  23.     protected static $instance;
  24.  
  25.     /**
  26.      * @var Controller
  27.      */
  28.     private $controller;
  29.  
  30.     /**
  31.      * @var Request
  32.      */
  33.     private $request;
  34.  
  35.     /**
  36.      * @var Router
  37.      */
  38.     private $router;
  39.  
  40.     /**
  41.      * @return mixed
  42.      * @throws Exception
  43.      * @throws \Psr\SimpleCache\InvalidArgumentException
  44.      */
  45.     public static function dispatch()
  46.     {
  47.  
  48.         if (!self::$instance instanceof Dispatcher) {
  49.             self::$instance = new Dispatcher();
  50.         }
  51.  
  52.         self::$instance->router = Router::router();
  53.         self::$instance->request = new Request();
  54.  
  55.         return self::$instance->invoke();
  56.     }
  57.  
  58.     /**
  59.      * @param $reflection
  60.      * @param bool $isModel
  61.      * @return mixed
  62.      */
  63.     private function reflectModel($reflection, $isModel = false)
  64.     {
  65.         preg_match_all('/(\w+)/', get_class($reflection), $match);
  66.  
  67.         $model = "Recman\Core\Models\\" . end($match[1]) . ($isModel ? '' : "Model");
  68.  
  69.         /** @var Model $model */
  70.         return new $model($model);
  71.     }
  72.  
  73.     /**
  74.      * @throws \Exception
  75.      * @throws \Psr\SimpleCache\InvalidArgumentException
  76.      */
  77.     private function invoke()
  78.     {
  79.         $request = self::$instance->request;
  80.         $route = $this->router->match($request->path(), $request->is());
  81.  
  82.         $this->runMiddlewares($route);
  83.  
  84.         $controller = $route->getController($request);
  85.  
  86.         if (!$this->checkMethodExistence($route, $controller)) {
  87.             throw new Exception("Method [{$route->method}] doesn't exists in the [{$route->controller}]");
  88.         }
  89.  
  90.         $reflector = new ReflectionMethod($controller, $route->method);
  91.         $params = [];
  92.  
  93.         /** @var ReflectionParameter $parameter */
  94.         foreach ($reflector->getParameters() as $parameter) {
  95.             $reflectionClass = !$parameter->hasType() ? null : $parameter->getType()->getName();
  96.  
  97.             if ($reflectionClass) {
  98.                 $reflection = new $reflectionClass;
  99.                 if (is_object($reflection)) {
  100.                     if ($reflection instanceof Entity) {
  101.                         $params[$parameter->getName()] = $this->reflectModel($reflection)
  102.                             ->get($route->getArgs()[$parameter->getName()]);
  103.                     }
  104.  
  105.                     if ($reflection instanceof Model) {
  106.                         $params[$parameter->getName()] = $this->reflectModel($reflection, true);
  107.                     }
  108.  
  109.                 }
  110.             } else {
  111.                 $params[$parameter->getName()] = $route->getArgs()[$parameter->getName()];
  112.             }
  113.  
  114.         }
  115.  
  116.         $route->setArgs($params);
  117.  
  118.         if ($route->isApi) {
  119.             Response::setType('json');
  120.         }
  121.  
  122.         return $controller->__invoke($route->method, $route->getArgs());
  123.     }
  124.  
  125.     /**
  126.      * @param Route $route
  127.      * @throws Exception
  128.      * @return void
  129.      */
  130.     private function runMiddlewares(Route $route)
  131.     {
  132.         if ($route->middlewares) {
  133.             $middlewares = is_array($route->middlewares) ? $route->middlewares :
  134.                 [$route->middlewares];
  135.  
  136.             foreach ($middlewares as $mlw) {
  137.  
  138.                 if (!Middleware::checkMiddleware($mlw)) {
  139.                     throw new Exception("Middleware [{$mlw}] does not exists", 404);
  140.                 }
  141.  
  142.                 $middlewareClass = Middleware::$middlewares[$mlw];
  143.                 /** @var Middleware $middleware */
  144.                 $middleware = new $middlewareClass();
  145.                 $middleware->handle(Request::instance(), Response::instance());
  146.             }
  147.         }
  148.     }
  149.  
  150.     /**
  151.      * @param Route $route
  152.      * @param Controller $controller
  153.      * @return bool
  154.      * @throws Exception
  155.      */
  156.     private function checkMethodExistence(Route $route, Controller $controller)
  157.     {
  158.         if (!$controller || !$route->method) {
  159.             throw new Exception("Controller [{$route->controller}] or method [{$route->method}] doesn't exist or equals to NULL", 400);
  160.         }
  161.  
  162.         return in_array($route->method, get_class_methods($controller));
  163.     }
  164. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement