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 function DI\add;
|
||||
use function DI\autowire;
|
||||
use function DI\get;
|
||||
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;
|
||||
}
|
||||
|
||||
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);
|
||||
});
|
||||
}
|
||||
}
|
||||
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