1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121
|
<?php
/**
* Slim Framework (https://slimframework.com)
*
* @license https://github.com/slimphp/Slim/blob/3.x/LICENSE.md (MIT License)
*/
namespace Slim;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;
use RuntimeException;
use UnexpectedValueException;
/**
* Middleware
*
* This is an internal class that enables concentric middleware layers. This
* class is an implementation detail and is used only inside of the Slim
* application; it is not visible to—and should not be used by—end users.
*/
trait MiddlewareAwareTrait
{
/**
* Tip of the middleware call stack
*
* @var callable
*/
protected $tip;
/**
* Middleware stack lock
*
* @var bool
*/
protected $middlewareLock = false;
/**
* Add middleware
*
* This method prepends new middleware to the application middleware stack.
*
* @param callable $callable Any callable that accepts three arguments:
* 1. A Request object
* 2. A Response object
* 3. A "next" middleware callable
*
* @return static
*
* @throws RuntimeException If middleware is added while the stack is dequeuing
* @throws UnexpectedValueException If the middleware doesn't return a Psr\Http\Message\ResponseInterface
*/
protected function addMiddleware(callable $callable)
{
if ($this->middlewareLock) {
throw new RuntimeException('Middleware can’t be added once the stack is dequeuing');
}
if (is_null($this->tip)) {
$this->seedMiddlewareStack();
}
$next = $this->tip;
$this->tip = function (
ServerRequestInterface $request,
ResponseInterface $response
) use (
$callable,
$next
) {
$result = call_user_func($callable, $request, $response, $next);
if ($result instanceof ResponseInterface === false) {
throw new UnexpectedValueException(
'Middleware must return instance of \Psr\Http\Message\ResponseInterface'
);
}
return $result;
};
return $this;
}
/**
* Seed middleware stack with first callable
*
* @param callable $kernel The last item to run as middleware
*
* @throws RuntimeException if the stack is seeded more than once
*/
protected function seedMiddlewareStack(callable $kernel = null)
{
if (!is_null($this->tip)) {
throw new RuntimeException('MiddlewareStack can only be seeded once.');
}
if ($kernel === null) {
$kernel = $this;
}
$this->tip = $kernel;
}
/**
* Call middleware stack
*
* @param ServerRequestInterface $request A request object
* @param ResponseInterface $response A response object
*
* @return ResponseInterface
*/
public function callMiddlewareStack(ServerRequestInterface $request, ResponseInterface $response)
{
if (is_null($this->tip)) {
$this->seedMiddlewareStack();
}
/** @var callable $start */
$start = $this->tip;
$this->middlewareLock = true;
$response = $start($request, $response);
$this->middlewareLock = false;
return $response;
}
}
|