Use context object with settings
This commit is contained in:
parent
231ff5161f
commit
34c2939d14
6 changed files with 236 additions and 34 deletions
|
@ -4,6 +4,7 @@ namespace BitCommunism\Http;
|
||||||
|
|
||||||
use BitCommunism\Marx\Instance;
|
use BitCommunism\Marx\Instance;
|
||||||
use function DI\add;
|
use function DI\add;
|
||||||
|
use function DI\autowire;
|
||||||
use function DI\get;
|
use function DI\get;
|
||||||
use function DI\object;
|
use function DI\object;
|
||||||
|
|
||||||
|
|
116
src/Context.php
Normal file
116
src/Context.php
Normal file
|
@ -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]);
|
||||||
|
}
|
||||||
|
}
|
76
src/Handle.php
Normal file
76
src/Handle.php
Normal file
|
@ -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;
|
$this->container = $container;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function get($name, $default = null) {
|
protected function get($name, $default = null)
|
||||||
|
{
|
||||||
if (!$this->container->has($name)) {
|
if (!$this->container->has($name)) {
|
||||||
return $default;
|
return $default;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,15 +1,11 @@
|
||||||
<?php
|
<?php
|
||||||
/**
|
|
||||||
* Created by PhpStorm.
|
|
||||||
* User: eater
|
|
||||||
* Date: 1/17/18
|
|
||||||
* Time: 11:54 AM
|
|
||||||
*/
|
|
||||||
|
|
||||||
namespace BitCommunism\Http;
|
namespace BitCommunism\Http;
|
||||||
|
|
||||||
|
|
||||||
use DI\Container;
|
use DI\Container;
|
||||||
|
use DI\ContainerBuilder;
|
||||||
|
use function DI\value;
|
||||||
use FastRoute\Dispatcher;
|
use FastRoute\Dispatcher;
|
||||||
use FastRoute\RouteCollector;
|
use FastRoute\RouteCollector;
|
||||||
use function FastRoute\simpleDispatcher;
|
use function FastRoute\simpleDispatcher;
|
||||||
|
@ -54,11 +50,11 @@ class Server
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (is_string($route)) {
|
if (is_array($route) || is_string($route)) {
|
||||||
$route = [$route, 'handle', []];
|
$route = new Handle($route);
|
||||||
}
|
}
|
||||||
|
|
||||||
$route[2] = array_merge($middleware, $route[2] ?? []);
|
$route = $route->withPrependedMiddleware($middleware);
|
||||||
|
|
||||||
if ($key[0] !== '/') {
|
if ($key[0] !== '/') {
|
||||||
yield [$key, $prefix, $route];
|
yield [$key, $prefix, $route];
|
||||||
|
@ -70,7 +66,6 @@ class Server
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public function buildRoutes()
|
public function buildRoutes()
|
||||||
{
|
{
|
||||||
$this->router = simpleDispatcher(function (RouteCollector $collector) {
|
$this->router = simpleDispatcher(function (RouteCollector $collector) {
|
||||||
|
@ -121,30 +116,35 @@ class Server
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($response === null) {
|
if ($response === null) {
|
||||||
// todo: Error page
|
$response = (new Response())
|
||||||
|
->withStatus(200);
|
||||||
}
|
}
|
||||||
|
|
||||||
return $response;
|
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;
|
$middlewarePointer = 0;
|
||||||
|
|
||||||
$next = null;
|
$next = null;
|
||||||
|
|
||||||
if ($response === 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;
|
$output = null;
|
||||||
|
|
||||||
if (count($middlewareArray) >= $middlewarePointer) {
|
if (count($middlewareArray) >= $middlewarePointer) {
|
||||||
$obj = $this->container->get($handler[0]);
|
$call = $handler->getCall();
|
||||||
$call = [$obj, $handler[1]];
|
if (is_array($call)) {
|
||||||
|
$obj = $this->container->get($call[0]);
|
||||||
|
$call = [$obj, $call[1]];
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
[$name, $func] = $middlewareArray[$middlewarePointer++];
|
[$name, $func] = $middlewareArray[$middlewarePointer++];
|
||||||
$middleware = $this->container->get($name);
|
$middleware = $this->container->get($name);
|
||||||
|
@ -152,31 +152,29 @@ class Server
|
||||||
}
|
}
|
||||||
|
|
||||||
$output = $this->container->call($call, [
|
$output = $this->container->call($call, [
|
||||||
RequestInterface::class => $request,
|
'request' => $context->getRequest(),
|
||||||
ResponseInterface::class => $response,
|
'response' => $context->getResponse(),
|
||||||
'request' => $request,
|
'context' => $context,
|
||||||
'response' => $response,
|
|
||||||
'vars' => $vars,
|
|
||||||
]);
|
]);
|
||||||
|
|
||||||
|
$this->normalizeResponse($output, $context);
|
||||||
return $this->normalizeResponse($output, $response);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
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) {
|
if ($response instanceof ResponseInterface) {
|
||||||
return $response;
|
$context->setResponse($response);
|
||||||
}
|
return;
|
||||||
|
|
||||||
if (!$response) {
|
|
||||||
return $previousResponse;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
$body = stream_for($response);
|
$body = stream_for($response);
|
||||||
return $previousResponse->withBody($body);
|
$context->withResponse(function (ResponseInterface $response) use ($body) {
|
||||||
|
return $response->withBody($body);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
10
src/functions.php
Normal file
10
src/functions.php
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace BitCommunism\Http;
|
||||||
|
|
||||||
|
if (function_exists(__NAMESPACE__ . '\\handle')) {
|
||||||
|
function handle($call, $settings = [])
|
||||||
|
{
|
||||||
|
return new Handle($call, $settings);
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in a new issue