Middleware piped may be either callables or service names. Middleware
specified as services will be wrapped in a closure similar to the
following:
function ($request, $response, $next = null) use ($container, $middleware) {
$invokable = $container->get($middleware);
if (! is_callable($invokable)) {
throw new Exception\InvalidMiddlewareException(sprintf(
'Lazy-loaded middleware "%s" is not invokable',
$middleware
));
}
return $invokable($request, $response, $next);
};
This is done to delay fetching the middleware until it is actually used;
the upshot is that you will not be notified if the service is invalid to
use as middleware until runtime.
Middleware may also be passed as an array; each item in the array must
resolve to middleware eventually (i.e., callable or service name).
Finally, ensures that the route middleware is only ever registered
once. public static function setUpBeforeClass() { // Load configuration $config = (require __DIR__ . '/../config/config.php'); // Override config settings $config['debug'] = true; $config['config_cache_enabled'] = false; $dependencies = $config['dependencies']; $dependencies['services']['config'] = $config; // Build container self::$container = new ServiceManager($dependencies); // Get application from container self::$app = self::$container->get(Application::class); self::$app->raiseThrowables(); // Setup middleware self::$app->pipe(ServerUrlMiddleware::class); self::$app->pipe(ErrorHandler::class); self::$app->pipe(SessionMiddleware::class); self::$app->pipeRoutingMiddleware(); self::$app->pipe(UrlHelperMiddleware::class); self::$app->pipeDispatchMiddleware(); self::$app->pipe(NotFoundHandler::class); // Setup routes self::$app->route('/', Action\HomePageAction::class, ['GET'], 'home'); self::$app->route('/blog', Action\BlogIndexAction::class, ['GET'], 'blog'); self::$app->route('/blog/feed.xml', Action\BlogXmlFeedAction::class, ['GET'], 'feed'); self::$app->route('/blog/{id:[0-9a-zA-Z\\-]+}', Action\BlogPostAction::class, ['GET'], 'blog.post'); self::$app->route('/code', Action\CodeAction::class, ['GET'], 'code'); self::$app->route('/contact', Action\ContactAction::class, ['GET', 'POST'], 'contact'); }
/** * Given a collection of middleware specifications, pipe them to the application. * * @param array $collection * @param Application $app * @param ContainerInterface $container * @throws Exception\InvalidMiddlewareException for invalid middleware. */ private function injectMiddleware(array $collection, Application $app, ContainerInterface $container) { foreach ($collection as $spec) { if (!array_key_exists('middleware', $spec)) { continue; } $middleware = $spec['middleware']; if (!is_callable($middleware)) { $middleware = $this->marshalMiddleware($middleware, $container); } $path = isset($spec['path']) ? $spec['path'] : '/'; $app->pipe($path, $middleware); } }
/** * @group lazy-piping */ public function testAllowsPipingMiddlewareAsServiceNameWithPath() { $middleware = function ($req, $res, $next = null) { return 'invoked'; }; $container = $this->prophesize(ContainerInterface::class); $container->has('foo')->willReturn(true); $container->get('foo')->willReturn($middleware); $app = new Application($this->router->reveal(), $container->reveal()); $app->pipe('/foo', 'foo'); $r = new ReflectionProperty($app, 'pipeline'); $r->setAccessible(true); $pipeline = $r->getValue($app); $route = $pipeline->dequeue(); $this->assertInstanceOf('Zend\\Stratigility\\Route', $route); $handler = $route->handler; $this->assertEquals('invoked', $handler('foo', 'bar')); }
public function testFinalHandlerCreatedAtInvocationIsProvidedResponseInstance() { $routeResult = RouteResult::fromRouteFailure(); $this->router->match()->willReturn($routeResult); $app = new Application($this->router->reveal()); $finalResponse = $this->prophesize('Psr\\Http\\Message\\ResponseInterface'); $app->pipe(function ($req, $res, $next) use($finalResponse) { return $finalResponse->reveal(); }); $responseStream = $this->prophesize('Psr\\Http\\Message\\StreamInterface'); $responseStream->getSize()->willReturn(0); $request = new Request([], [], 'http://example.com/'); $response = $this->prophesize('Psr\\Http\\Message\\ResponseInterface'); $response->getBody()->willReturn($responseStream->reveal()); $test = $app($request, $response->reveal()); $finalHandler = $app->getFinalHandler(); $this->assertInstanceOf('Zend\\Stratigility\\FinalHandler', $finalHandler); $r = new ReflectionProperty($finalHandler, 'response'); $r->setAccessible(true); $handlerResponse = $r->getValue($finalHandler); $this->assertSame($response->reveal(), $handlerResponse); }
private function setupPipeFromDefinition(array $definition) { $this->app->pipe($definition['middleware']); }