Skip to content
Permalink
Browse files

Merge branch 'psr-15-request-handler2' into 4.x

  • Loading branch information...
akrabat committed Nov 18, 2018
2 parents a86f05d + ac2bbac commit e13f367c8a3f156299838c190bca7390a4d9d050
@@ -5,6 +5,7 @@

### Added

- [#2497](https://github.com/slimphp/Slim/pull/2497) PSR-15 RequestHandlers can now be used as route callables
- [#2496](https://github.com/slimphp/Slim/pull/2496) A Slim App can now be used as PSR-15 Request Handler
- [#2405](https://github.com/slimphp/Slim/pull/2405) RoutingMiddleware now adds the `routingResults` request attribute to hold the results of routing
- [#2404](https://github.com/slimphp/Slim/pull/2404) Slim 4 requires PHP 7.0 or higher
@@ -12,6 +12,7 @@
namespace Slim;
use Psr\Container\ContainerInterface;
use Psr\Http\Server\RequestHandlerInterface;
use RuntimeException;
use Slim\Interfaces\CallableResolverInterface;
@@ -70,6 +71,11 @@ public function resolve($toResolve): callable
}
$resolved = [new $class($this->container), $method];
}
// For a class that implements RequestHandlerInterface, we will call handle()
if ($resolved[0] instanceof RequestHandlerInterface) {
$resolved[1] = 'handle';
}
}
if (!is_callable($resolved)) {
@@ -0,0 +1,39 @@
<?php
/**
* Slim Framework (https://slimframework.com)
*
* @link https://github.com/slimphp/Slim
* @copyright Copyright (c) 2011-2018 Josh Lockhart
* @license https://github.com/slimphp/Slim/blob/4.x/LICENSE.md (MIT License)
*/
declare(strict_types=1);
namespace Slim\Handlers\Strategies;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;
use Slim\Interfaces\InvocationStrategyInterface;
/**
* Default route callback strategy with route parameters as an array of arguments.
*/
class RequestHandler implements InvocationStrategyInterface
{
/**
* Invoke a route callable that implments RequestHandlerInterface
*
* @param callable $callable
* @param ServerRequestInterface $request
*
* @return ResponseInterface
*/
public function __invoke(
callable $callable,
ServerRequestInterface $request,
ResponseInterface $response,
array $routeArguments
): ResponseInterface {
return $callable($request);
}
}
@@ -13,6 +13,8 @@
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;
use Psr\Http\Server\RequestHandlerInterface;
use Slim\Handlers\Strategies\RequestHandler;
use Slim\Handlers\Strategies\RequestResponse;
use Slim\Interfaces\InvocationStrategyInterface;
use Slim\Interfaces\RouteInterface;
@@ -316,14 +318,13 @@ public function __invoke(ServerRequestInterface $request, ResponseInterface $res
$callable = $this->callableResolver->resolve($callable);
}
/** @var InvocationStrategyInterface $handler */
$handler = $this->routeInvocationStrategy;
$routeResponse = $handler($callable, $request, $response, $this->arguments);
if (! $routeResponse instanceof ResponseInterface) {
throw new \RuntimeException('Route handler must return instance of \Psr\Http\Message\ResponseInterface');
if (is_array($callable) && $callable[0] instanceof RequestHandlerInterface) {
// callables that implement RequestHandlerInterface use the RequestHandler strategy
$handler = new RequestHandler();
}
return $routeResponse;
// invoke route callable via invokation strategy handler
return $handler($callable, $request, $response, $this->arguments);
}
}
@@ -14,6 +14,8 @@
use Slim\CallableResolver;
use Slim\Tests\Mocks\CallableTest;
use Slim\Tests\Mocks\InvokableTest;
use Slim\Tests\Mocks\RequestHandlerTest;
use Slim\Http\Request;
class CallableResolverTest extends TestCase
{
@@ -116,6 +118,15 @@ public function testResolutionToAnInvokableClass()
$this->assertEquals(1, InvokableTest::$CalledCount);
}
public function testResolutionToAPsrRequestHandlerClass()
{
$request = $this->getMockBuilder(Request::class)->disableOriginalConstructor()->getMock();
$resolver = new CallableResolver(); // No container injected
$callable = $resolver->resolve(RequestHandlerTest::class);
$callable($request);
$this->assertEquals(1, RequestHandlerTest::$CalledCount);
}
/**
* @expectedException \RuntimeException
*/
@@ -0,0 +1,40 @@
<?php
/**
* Slim Framework (https://slimframework.com)
*
* @link https://github.com/slimphp/Slim
* @copyright Copyright (c) 2011-2018 Josh Lockhart
* @license https://github.com/slimphp/Slim/blob/4.x/LICENSE.md (MIT License)
*/
namespace Slim\Tests\Mocks;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;
use Psr\Http\Server\RequestHandlerInterface;
use Slim\Http\Response;
/**
* Mock object for Slim\Tests\CallableResolverTest
*/
class RequestHandlerTest implements RequestHandlerInterface
{
public static $CalledCount = 0;
public static $strategy = '';
public function handle(ServerRequestInterface $request) : ResponseInterface
{
static::$CalledCount++;
// store the strategy that was used to call this handler - it's in the back trace
$trace = debug_backtrace();
if (isset($trace[1])) {
static::$strategy = $trace[1]['class'];
}
$response = new Response();
$response = $response->withHeader('Content-Type', 'text/plain');
$response->write(static::$CalledCount);
return $response;
}
}
@@ -23,6 +23,7 @@
use Slim\Tests\Mocks\CallableTest;
use Slim\Tests\Mocks\InvocationStrategyTest;
use Slim\Tests\Mocks\MiddlewareStub;
use Slim\Tests\Mocks\RequestHandlerTest;
class RouteTest extends TestCase
{
@@ -414,6 +415,25 @@ public function testInvokeDeferredCallableWithContainer()
$this->assertEquals([new CallableTest(), 'toCall'], InvocationStrategyTest::$LastCalledFor);
}
public function testInvokeUsesRequestHandlerStrategyForRequestHandlers()
{
$pimple = new Pimple();
$pimple[RequestHandlerTest::class] = new RequestHandlerTest();
$resolver = new CallableResolver(new Psr11Container($pimple));
$route = new Route(['GET'], '/', RequestHandlerTest::class);
$route->setCallableResolver($resolver);
$uri = Uri::createFromString('https://example.com:80');
$body = new Body(fopen('php://temp', 'r+'));
$request = new Request('GET', $uri, new Headers(), [], Environment::mock(), $body);
$result = $route->callMiddlewareStack($request, new Response);
$strategy = $pimple[RequestHandlerTest::class]::$strategy;
$this->assertEquals('Slim\Handlers\Strategies\RequestHandler', $strategy);
}
/**
* Ensure that the pattern can be dynamically changed
*/

0 comments on commit e13f367

Please sign in to comment.
You can’t perform that action at this time.