File Manager

Current Directory: /home/astoriaah/www/templates/yootheme-BK/vendor/yootheme/framework/modules/app/src
Viewing File: /home/astoriaah/www/templates/yootheme-BK/vendor/yootheme/framework/modules/app/src/Kernel.php
<?php namespace YOOtheme; use Psr\Http\Message\ResponseInterface; use Psr\Http\Message\ServerRequestInterface; class Kernel { use ContainerTrait; const FOUND = 1; const NOT_FOUND = 0; const METHOD_NOT_ALLOWED = 2; /** * @var \SplStack */ protected $stack; /** * @var boolean */ protected $locked; /** * Constructor. */ public function __construct() { $this->stack = new \SplStack(); $this->stack->push($this); } /** * Dispatches router with request and response. * * @param ServerRequestInterface $request * @param ResponseInterface $response * @return ResponseInterface */ public function __invoke(ServerRequestInterface $request, ResponseInterface $response) { try { $route = $request->getAttribute('route'); $routeInfo = $request->getAttribute('routeInfo'); if ($routeInfo[0] === static::FOUND) { $response = $this->handleFound($request, $response, array_map('urldecode', $routeInfo[2])); } elseif ($routeInfo[0] === static::METHOD_NOT_ALLOWED) { throw new Http\Exception(405); } else { throw new Http\Exception(404); } } catch (\Exception $e) { $response = $this->handleException($e, $request, $response); } return $response; } /** * Aborts a request with an exception. * * @param int $code * @param string $message * @throws Http\Exception */ public function abort($code, $message = '') { throw new Http\Exception($code, $message); } /** * Handles a request and converts it to a response. * * @param ServerRequestInterface $request * @param ResponseInterface $response * @param boolean $send * @return ResponseInterface */ public function handle(ServerRequestInterface $request, ResponseInterface $response, $send = true) { try { $start = $this->stack->top(); $this->locked = true; $response = $start($this->app['router']->dispatch($request), $response); $this->locked = false; } catch (\Exception $e) { $response = $this->handleException($e, $request, $response); } return $send ? $response->send() : $response; } /** * Handles a found route. * * @param ServerRequestInterface $request * @param ResponseInterface $response * @param array $params * @return ResponseInterface */ public function handleFound(ServerRequestInterface $request, ResponseInterface $response, array $params = []) { $args = []; $params = array_replace(compact('request', 'response'), $params); $callable = $this->resolveCallable($request->getAttribute('route')->getCallable()); foreach ($this->resolveParameters($callable) as $param) { $name = $param->getName(); if (isset($params[$name])) { $args[] = $params[$name]; continue; } if ($request->getParam($name) !== null) { $args[] = $request->getParam($name); continue; } if ($param->isDefaultValueAvailable()) { $args[] = $param->getDefaultValue(); continue; } if (is_array($callable)) { $handler = sprintf('%s::%s()', get_class($callable[0]), $callable[1]); } elseif (is_object($callable)) { $handler = get_class($callable); } else { $handler = $callable; } throw new \RuntimeException("Handler '{$handler}' requires that you provide a value for the '{$name}' argument"); } $result = call_user_func_array($callable, $args); if ($result instanceof ResponseInterface) { $response = $result; } elseif (is_string($result) || (is_object($result) && method_exists($result, '__toString'))) { $response->write((string) $result); } return $response; } /** * Handles an exception. * * @param \Exception $e * @param ServerRequestInterface $request * @param ResponseInterface $response * @return Response */ protected function handleException(\Exception $e, ServerRequestInterface $request, ResponseInterface $response) { $event = $this->app->trigger('error', [$request, $response, $e]); if ($event->result instanceof ResponseInterface) { return $event->result; } if ($e instanceof Http\Exception) { return $response->withStatus($e->getCode(), $e->getMessage()); } return $response->withStatus(500, $e->getMessage()); } /** * Adds a middleware callable. * * @param callable $callable * @return self */ public function addMiddleware(callable $callable) { if ($this->locked) { throw new \RuntimeException('Middleware can’t be added once the stack is dequeuing'); } $next = $this->stack->top(); $this->stack->push(function (ServerRequestInterface $request, ResponseInterface $response) use ($callable, $next) { $result = $callable($request, $response, $next); if (!$result instanceof ResponseInterface) { throw new \UnexpectedValueException('Middleware must return instance of Psr\Http\Message\ResponseInterface'); } return $result; }); return $this; } /** * Resolves a string to a callable that can be dispatched. * * @param callable|string $callable * @return callable */ public function resolveCallable($callable) { $pattern = '!^([^\:]+)\:([a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*)$!'; if (is_callable($callable)) { return $callable; } if (is_string($callable) && preg_match($pattern, $callable, $matches)) { list(, $class, $method) = $matches; if (isset($this->app[$class])) { return [$this->app[$class], $method]; } if (class_exists($class)) { return [new $class, $method]; } } throw new \RuntimeException("Route callable is not resolvable"); } /** * Resolves method parameters from a callable. * * @param callable $callable * @return array */ public function resolveParameters(callable $callable) { if (is_array($callable)) { $refl = new \ReflectionMethod($callable[0], $callable[1]); } elseif (is_object($callable) && !$callable instanceof \Closure) { $refl = (new \ReflectionObject($callable))->getMethod('__invoke'); } else { $refl = new \ReflectionFunction($callable); } return $refl->getParameters(); } }