Fix some things
This commit is contained in:
parent
91d17f713a
commit
9d8ab04348
5 changed files with 90 additions and 49 deletions
|
|
@ -1,6 +1,5 @@
|
|||
{
|
||||
"name": "bitcommunism/http",
|
||||
"version": "1.0.1",
|
||||
"license": "MIT",
|
||||
"require": {
|
||||
"nikic/fast-route": "^1.2",
|
||||
|
|
@ -10,6 +9,7 @@
|
|||
"autoload": {
|
||||
"psr-4": {
|
||||
"BitCommunism\\Http\\": "src/"
|
||||
}
|
||||
},
|
||||
"files": ["src/functions.php"]
|
||||
}
|
||||
}
|
||||
|
|
@ -2,24 +2,23 @@
|
|||
|
||||
namespace BitCommunism\Http;
|
||||
|
||||
use BitCommunism\Marx\Instance;
|
||||
use function DI\add;
|
||||
use function DI\autowire;
|
||||
use function DI\get;
|
||||
use function DI\object;
|
||||
use function DI\value;
|
||||
|
||||
return [
|
||||
'marx.calls' => add([
|
||||
'http' => function(Server $server) {
|
||||
'http' => value(function(Server $server) {
|
||||
return $server;
|
||||
}
|
||||
})
|
||||
]),
|
||||
|
||||
'marx.loaders' => add([
|
||||
function(Server $server) {
|
||||
value(function(Server $server) {
|
||||
$server->buildRoutes();
|
||||
}
|
||||
})
|
||||
]),
|
||||
|
||||
Server::class => object()->constructorParameter('routes', get('routes')),
|
||||
Server::class => autowire()->constructorParameter('routes', get('routes')),
|
||||
];
|
||||
|
|
@ -7,7 +7,7 @@ use Psr\Http\Message\RequestInterface;
|
|||
use Psr\Http\Message\ResponseInterface;
|
||||
use Psr\Http\Message\ServerRequestInterface;
|
||||
|
||||
class Context
|
||||
class Context implements \ArrayAccess
|
||||
{
|
||||
/**
|
||||
* @var ServerRequestInterface
|
||||
|
|
@ -112,29 +112,37 @@ class Context
|
|||
return $this->settings;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $settings
|
||||
*/
|
||||
public function setSettings(array $settings): void
|
||||
{
|
||||
$this->settings = $settings;
|
||||
}
|
||||
|
||||
public function redirect($to, $status = 302): void {
|
||||
$this->withResponse(function (ResponseInterface $response) use ($to, $status) {
|
||||
return $response->withStatus($status)->withHeader('Location', $to);
|
||||
});
|
||||
}
|
||||
|
||||
public function __get($name)
|
||||
public function offsetExists($offset)
|
||||
{
|
||||
return $this->context[$name];
|
||||
return isset($this->context[$offset]);
|
||||
}
|
||||
|
||||
public function __set($name, $value)
|
||||
public function offsetGet($offset)
|
||||
{
|
||||
$this->context[$name] = $value;
|
||||
return $this->context[$offset];
|
||||
}
|
||||
|
||||
public function __isset($name)
|
||||
public function offsetSet($offset, $value)
|
||||
{
|
||||
return isset($this->context[$name]);
|
||||
$this->context[$offset] = $value;
|
||||
}
|
||||
|
||||
public function __unset($name)
|
||||
public function offsetUnset($offset)
|
||||
{
|
||||
unset($this->context[$name]);
|
||||
unset($this->context[$offset]);
|
||||
}
|
||||
}
|
||||
|
|
@ -4,23 +4,31 @@ namespace BitCommunism\Http;
|
|||
|
||||
|
||||
use DI\Container;
|
||||
use DI\ContainerBuilder;
|
||||
use function DI\value;
|
||||
use FastRoute\Dispatcher;
|
||||
use FastRoute\RouteCollector;
|
||||
use function FastRoute\simpleDispatcher;
|
||||
use function GuzzleHttp\Psr7\copy_to_stream;
|
||||
use GuzzleHttp\Psr7\Response;
|
||||
use GuzzleHttp\Psr7\ServerRequest;
|
||||
use function GuzzleHttp\Psr7\stream_for;
|
||||
use Psr\Http\Message\RequestInterface;
|
||||
use Invoker\Invoker;
|
||||
use Invoker\ParameterResolver\AssociativeArrayResolver;
|
||||
use Invoker\ParameterResolver\Container\TypeHintContainerResolver;
|
||||
use Invoker\ParameterResolver\DefaultValueResolver;
|
||||
use Invoker\ParameterResolver\NumericArrayResolver;
|
||||
use Invoker\ParameterResolver\ResolverChain;
|
||||
use Invoker\ParameterResolver\TypeHintResolver;
|
||||
use Psr\Http\Message\ResponseInterface;
|
||||
use Psr\Http\Message\ServerRequestInterface;
|
||||
use function FastRoute\simpleDispatcher;
|
||||
use function GuzzleHttp\Psr7\copy_to_stream;
|
||||
use function GuzzleHttp\Psr7\stream_for;
|
||||
|
||||
class Server
|
||||
{
|
||||
private $routes = [];
|
||||
private $container;
|
||||
/**
|
||||
* @var Invoker
|
||||
*/
|
||||
private $invoker;
|
||||
|
||||
/**
|
||||
* @var Dispatcher
|
||||
|
|
@ -31,6 +39,7 @@ class Server
|
|||
{
|
||||
$this->routes = $routes;
|
||||
$this->container = $container;
|
||||
$this->invoker = $this->createDefaultInvoker();
|
||||
}
|
||||
|
||||
private function iterateRoutes()
|
||||
|
|
@ -40,17 +49,26 @@ class Server
|
|||
|
||||
private function iterateRoutesFromArray($routeArr, $prefix = '', $known = [], $middleware = [])
|
||||
{
|
||||
foreach ($routeArr as $key => $route) {
|
||||
if ($key === 'middleware') {
|
||||
$middleware = array_merge($middleware, $route);
|
||||
$route = $routeArr['middleware'] ?? [];
|
||||
$middleware = array_merge($middleware, array_map(function ($route) {
|
||||
if (!$route instanceof Handle) {
|
||||
return new Handle($route);
|
||||
}
|
||||
|
||||
if (is_array($route) && !(isset($route[0]) && isset($route[1]))) {
|
||||
yield from $this->iterateRoutesFromArray($route, $prefix . $key, $known);
|
||||
return $route;
|
||||
}, (array)$route));
|
||||
|
||||
foreach ($routeArr as $key => $route) {
|
||||
if ($key === 'middleware') {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (is_array($route) || is_string($route)) {
|
||||
if (is_array($route) && !(isset($route[0]) && isset($route[1]))) {
|
||||
yield from $this->iterateRoutesFromArray($route, $prefix . $key, $known, $middleware);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!$route instanceof Handle) {
|
||||
$route = new Handle($route);
|
||||
}
|
||||
|
||||
|
|
@ -123,6 +141,16 @@ class Server
|
|||
return $response;
|
||||
}
|
||||
|
||||
private function createDefaultInvoker() {
|
||||
return new Invoker(new ResolverChain(array(
|
||||
new NumericArrayResolver(),
|
||||
new AssociativeArrayResolver(),
|
||||
new DefaultValueResolver(),
|
||||
new TypeHintResolver(),
|
||||
new TypeHintContainerResolver($this->container),
|
||||
)), $this->container);
|
||||
}
|
||||
|
||||
public function handleHttp(ServerRequestInterface $request, Handle $handler, array $vars, ResponseInterface $response = null): ResponseInterface
|
||||
{
|
||||
$middlewareArray = $handler->getMiddleware();
|
||||
|
|
@ -134,29 +162,33 @@ class Server
|
|||
$response = new Response(200, [], stream_for('Empty response'));
|
||||
}
|
||||
|
||||
$context = new Context($request, $response);
|
||||
$context = new Context($request, $response, $vars);
|
||||
|
||||
$next = function (Context $context) use ($handler, $middlewareArray, &$middlewarePointer, &$next) {
|
||||
$output = null;
|
||||
|
||||
if (count($middlewareArray) >= $middlewarePointer) {
|
||||
$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);
|
||||
$call = [$middleware, $func];
|
||||
if (count($middlewareArray) > $middlewarePointer) {
|
||||
$handler = $middlewareArray[$middlewarePointer++];
|
||||
}
|
||||
|
||||
$output = $this->container->call($call, [
|
||||
$call = $handler->getCall();
|
||||
if (is_array($call)) {
|
||||
$obj = $this->container->get($call[0]);
|
||||
$call = [$obj, $call[1]];
|
||||
}
|
||||
|
||||
$context->setSettings($handler->getSettings());
|
||||
|
||||
$output = $this->invoker->call($call, [
|
||||
'request' => $context->getRequest(),
|
||||
ServerRequestInterface::class => $context->getRequest(),
|
||||
'response' => $context->getResponse(),
|
||||
ResponseInterface::class => $context->getResponse(),
|
||||
'context' => $context,
|
||||
Context::class => $context,
|
||||
'vars' => $context->getVars(),
|
||||
'settings' => $context->getSettings(),
|
||||
'next' => $next,
|
||||
]);
|
||||
|
||||
$this->normalizeResponse($output, $context);
|
||||
|
|
@ -169,6 +201,10 @@ class Server
|
|||
|
||||
private function normalizeResponse($response, Context $context)
|
||||
{
|
||||
if ($response === null) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ($response instanceof ResponseInterface) {
|
||||
$context->setResponse($response);
|
||||
return;
|
||||
|
|
|
|||
|
|
@ -2,20 +2,18 @@
|
|||
|
||||
namespace BitCommunism\Http;
|
||||
|
||||
use Psr\Http\Message\ResponseInterface;
|
||||
|
||||
if (function_exists(__NAMESPACE__ . '\\handle')) {
|
||||
function handle($call, $settings = [])
|
||||
if (!function_exists(__NAMESPACE__ . '\\handle')) {
|
||||
function handle($call, $settings = []): Handle
|
||||
{
|
||||
return new Handle($call, $settings);
|
||||
}
|
||||
}
|
||||
|
||||
if (function_exists(__NAMESPACE__ . '\\redirect')) {
|
||||
if (!function_exists(__NAMESPACE__ . '\\redirect')) {
|
||||
function redirect($to, $status = 302)
|
||||
{
|
||||
return function (Context $c) use ($to, $status) {
|
||||
return handle(function (Context $c) use ($to, $status) {
|
||||
$c->redirect($to, $status);
|
||||
};
|
||||
});
|
||||
}
|
||||
}
|
||||
Loading…
Reference in a new issue