Use context object with settings

master
eater 6 years ago
parent 231ff5161f
commit 34c2939d14
Signed by: eater
GPG Key ID: AD2560A0F84F0759

@ -4,6 +4,7 @@ namespace BitCommunism\Http;
use BitCommunism\Marx\Instance;
use function DI\add;
use function DI\autowire;
use function DI\get;
use function DI\object;

@ -0,0 +1,116 @@
<?php
namespace BitCommunism\Http;
use Psr\Http\Message\RequestInterface;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;
class Context
{
/**
* @var ServerRequestInterface
*/
private $request;
/**
* @var ResponseInterface
*/
private $response;
/**
* @var array
*/
private $context = [];
/**
* @var array
*/
private $vars;
/**
* @var array
*/
private $settings;
/**
* Context constructor.
* @param ServerRequestInterface $request
* @param ResponseInterface $response
* @param array $vars
* @param array $settings
*/
public function __construct(ServerRequestInterface $request, ResponseInterface $response, array $vars = [], array $settings = [])
{
$this->request = $request;
$this->response = $response;
$this->vars = $vars;
$this->settings = $settings;
}
/**
* @return ServerRequestInterface
*/
public function getRequest(): ServerRequestInterface
{
return $this->request;
}
/**
* @param ServerRequestInterface $request
*/
public function setRequest(ServerRequestInterface $request): void
{
$this->request = $request;
}
/**
* @return ResponseInterface
*/
public function getResponse(): ResponseInterface
{
return $this->response;
}
/**
* @param ResponseInterface $response
*/
public function setResponse(ResponseInterface $response): void
{
$this->response = $response;
}
public function withResponse($fn)
{
$this->setResponse($fn($this->getResponse()));
}
public function getSetting($name, $default = null) {
return $this->settings[$name] ?? $default;
}
public function getVar($name, $default = null) {
return $this->settings[$name] ?? $default;
}
public function __get($name)
{
return $this->context[$name];
}
public function __set($name, $value)
{
$this->context[$name] = $value;
}
public function __isset($name)
{
return isset($this->context[$name]);
}
public function __unset($name)
{
unset($this->context[$name]);
}
}

@ -0,0 +1,76 @@
<?php
namespace BitCommunism\Http;
class Handle
{
/**
* @var callable
*/
private $call;
/**
* @var array
*/
private $settings = [];
/**
* @var
*/
private $middleware = [];
public function __construct($call, $settings = [], $middleware = [])
{
if (is_string($call)) {
$call = [$call, 'handle'];
}
$this->call = $call;
$this->settings = $settings;
$this->middleware = $middleware;
}
/**
* @return callable
*/
public function getCall(): callable
{
return $this->call;
}
/**
* @return array
*/
public function getSettings(): array
{
return $this->settings;
}
/**
* @return mixed
*/
public function getMiddleware()
{
return $this->middleware;
}
public function withMiddleware($middleware): Handle
{
return new static($this->call, $this->settings, array_merge($this->middleware, [$middleware]));
}
public function mergeWithSettings($settings): Handle
{
return new static($this->call, array_merge($this->settings, $settings), $this->middleware);
}
public function withSettings($settings): Handle
{
return new static($this->call, $settings, $this->middleware);
}
public function withPrependedMiddleware($middlewares): Handle
{
return new static($this->call, $this->settings, array_merge($middlewares, $this->middleware));
}
}

@ -20,7 +20,8 @@ class Handler
$this->container = $container;
}
protected function get($name, $default = null) {
protected function get($name, $default = null)
{
if (!$this->container->has($name)) {
return $default;
}

@ -1,15 +1,11 @@
<?php
/**
* Created by PhpStorm.
* User: eater
* Date: 1/17/18
* Time: 11:54 AM
*/
namespace BitCommunism\Http;
use DI\Container;
use DI\ContainerBuilder;
use function DI\value;
use FastRoute\Dispatcher;
use FastRoute\RouteCollector;
use function FastRoute\simpleDispatcher;
@ -54,11 +50,11 @@ class Server
continue;
}
if (is_string($route)) {
$route = [$route, 'handle', []];
if (is_array($route) || is_string($route)) {
$route = new Handle($route);
}
$route[2] = array_merge($middleware, $route[2] ?? []);
$route = $route->withPrependedMiddleware($middleware);
if ($key[0] !== '/') {
yield [$key, $prefix, $route];
@ -70,7 +66,6 @@ class Server
}
}
public function buildRoutes()
{
$this->router = simpleDispatcher(function (RouteCollector $collector) {
@ -121,30 +116,35 @@ class Server
}
if ($response === null) {
// todo: Error page
$response = (new Response())
->withStatus(200);
}
return $response;
}
public function handleHttp(ServerRequestInterface $request, array $handler, array $vars, ResponseInterface $response = null): ResponseInterface
public function handleHttp(ServerRequestInterface $request, Handle $handler, array $vars, ResponseInterface $response = null): ResponseInterface
{
[$_, $_, $middlewareArray] = $handler;
$middlewareArray = $handler->getMiddleware();
$middlewarePointer = 0;
$next = null;
if ($response === null) {
$response = new Response(200, [], stream_for('No answer'));
$response = new Response(200, [], stream_for('Empty response'));
}
$next = function ($request, $response, $vars) use ($handler, $middlewareArray, &$middlewarePointer, &$next) {
$context = new Context($request, $response);
$next = function (Context $context) use ($handler, $middlewareArray, &$middlewarePointer, &$next) {
$output = null;
if (count($middlewareArray) >= $middlewarePointer) {
$obj = $this->container->get($handler[0]);
$call = [$obj, $handler[1]];
$call = $handler->getCall();
if (is_array($call)) {
$obj = $this->container->get($call[0]);
$call = [$obj, $call[1]];
}
} else {
[$name, $func] = $middlewareArray[$middlewarePointer++];
$middleware = $this->container->get($name);
@ -152,31 +152,29 @@ class Server
}
$output = $this->container->call($call, [
RequestInterface::class => $request,
ResponseInterface::class => $response,
'request' => $request,
'response' => $response,
'vars' => $vars,
'request' => $context->getRequest(),
'response' => $context->getResponse(),
'context' => $context,
]);
return $this->normalizeResponse($output, $response);
$this->normalizeResponse($output, $context);
};
return $next($request, $response, $vars);
$next($context);
return $context->getResponse();
}
private function normalizeResponse($response, ResponseInterface $previousResponse)
private function normalizeResponse($response, Context $context)
{
if ($response instanceof ResponseInterface) {
return $response;
}
if (!$response) {
return $previousResponse;
$context->setResponse($response);
return;
}
$body = stream_for($response);
return $previousResponse->withBody($body);
$context->withResponse(function (ResponseInterface $response) use ($body) {
return $response->withBody($body);
});
}
}

@ -0,0 +1,10 @@
<?php
namespace BitCommunism\Http;
if (function_exists(__NAMESPACE__ . '\\handle')) {
function handle($call, $settings = [])
{
return new Handle($call, $settings);
}
}
Loading…
Cancel
Save