Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- <?php
- namespace Recman\Core\Http;
- use Exception;
- use Recman\Core\Controller;
- use Recman\Core\Database\Model;
- use Recman\Core\Entities\Entity;
- use Recman\Core\Entities\Route;
- use ReflectionMethod;
- use ReflectionParameter;
- /**
- * Class Dispatcher
- * @package Recman\Core\Http
- */
- class Dispatcher
- {
- /**
- * @var Dispatcher
- */
- protected static $instance;
- /**
- * @var Controller
- */
- private $controller;
- /**
- * @var Request
- */
- private $request;
- /**
- * @var Router
- */
- private $router;
- /**
- * @return mixed
- * @throws Exception
- * @throws \Psr\SimpleCache\InvalidArgumentException
- */
- public static function dispatch()
- {
- if (!self::$instance instanceof Dispatcher) {
- self::$instance = new Dispatcher();
- }
- self::$instance->router = Router::router();
- self::$instance->request = new Request();
- return self::$instance->invoke();
- }
- /**
- * @param $reflection
- * @param bool $isModel
- * @return mixed
- */
- private function reflectModel($reflection, $isModel = false)
- {
- preg_match_all('/(\w+)/', get_class($reflection), $match);
- $model = "Recman\Core\Models\\" . end($match[1]) . ($isModel ? '' : "Model");
- /** @var Model $model */
- return new $model($model);
- }
- /**
- * @throws \Exception
- * @throws \Psr\SimpleCache\InvalidArgumentException
- */
- private function invoke()
- {
- $request = self::$instance->request;
- $route = $this->router->match($request->path(), $request->is());
- $this->runMiddlewares($route);
- $controller = $route->getController($request);
- if (!$this->checkMethodExistence($route, $controller)) {
- throw new Exception("Method [{$route->method}] doesn't exists in the [{$route->controller}]");
- }
- $reflector = new ReflectionMethod($controller, $route->method);
- $params = [];
- /** @var ReflectionParameter $parameter */
- foreach ($reflector->getParameters() as $parameter) {
- $reflectionClass = !$parameter->hasType() ? null : $parameter->getType()->getName();
- if ($reflectionClass) {
- $reflection = new $reflectionClass;
- if (is_object($reflection)) {
- if ($reflection instanceof Entity) {
- $params[$parameter->getName()] = $this->reflectModel($reflection)
- ->get($route->getArgs()[$parameter->getName()]);
- }
- if ($reflection instanceof Model) {
- $params[$parameter->getName()] = $this->reflectModel($reflection, true);
- }
- }
- } else {
- $params[$parameter->getName()] = $route->getArgs()[$parameter->getName()];
- }
- }
- $route->setArgs($params);
- if ($route->isApi) {
- Response::setType('json');
- }
- return $controller->__invoke($route->method, $route->getArgs());
- }
- /**
- * @param Route $route
- * @throws Exception
- * @return void
- */
- private function runMiddlewares(Route $route)
- {
- if ($route->middlewares) {
- $middlewares = is_array($route->middlewares) ? $route->middlewares :
- [$route->middlewares];
- foreach ($middlewares as $mlw) {
- if (!Middleware::checkMiddleware($mlw)) {
- throw new Exception("Middleware [{$mlw}] does not exists", 404);
- }
- $middlewareClass = Middleware::$middlewares[$mlw];
- /** @var Middleware $middleware */
- $middleware = new $middlewareClass();
- $middleware->handle(Request::instance(), Response::instance());
- }
- }
- }
- /**
- * @param Route $route
- * @param Controller $controller
- * @return bool
- * @throws Exception
- */
- private function checkMethodExistence(Route $route, Controller $controller)
- {
- if (!$controller || !$route->method) {
- throw new Exception("Controller [{$route->controller}] or method [{$route->method}] doesn't exist or equals to NULL", 400);
- }
- return in_array($route->method, get_class_methods($controller));
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement