From 53801f62f8e4cc09f276eea6696706026369fcd9 Mon Sep 17 00:00:00 2001 From: ADmad Date: Sun, 27 Jan 2019 23:32:38 +0530 Subject: [PATCH] Update docs regarding PSR-15 support. Refs cakephp/cakephp#12907 --- en/appendices/4-0-migration-guide.rst | 3 ++ en/controllers/middleware.rst | 47 +++++++++++++-------------- 2 files changed, 26 insertions(+), 24 deletions(-) diff --git a/en/appendices/4-0-migration-guide.rst b/en/appendices/4-0-migration-guide.rst index 2172a0ec86..0817f697d4 100644 --- a/en/appendices/4-0-migration-guide.rst +++ b/en/appendices/4-0-migration-guide.rst @@ -146,6 +146,9 @@ Error Http ---- +* CakePHP now supports the `PSR-15: HTTP Server Request Handlers _` specification. + As a consequence the middlewares now implement ``Psr\Http\Server\MiddlewareInterface``. + CakePHP 3.x style invokable double pass middlewares are still supported for backwards compatibility. * ``Cake\Http\Client`` now follows `PSR-18: HTTP Client _` specifications. * ``Cake\Http\Client\Response::isSuccess()`` was added. This method returns true if the response status code is 2xx. diff --git a/en/controllers/middleware.rst b/en/controllers/middleware.rst index efbb070a0b..8269729aed 100644 --- a/en/controllers/middleware.rst +++ b/en/controllers/middleware.rst @@ -22,9 +22,9 @@ and have its action invoked, or an exception will be raised generating an error page. Middleware are part of the new HTTP stack in CakePHP that leverages the PSR-7 -request and response interfaces. Because CakePHP is leveraging the PSR-7 -standard you can use any PSR-7 compatible middleware available on `The Packagist -`__. +request and response interfaces. CakePHP also supports the PSR-15 standard for +server request handlers so you can use any PSR-15 compatible middleware available +on `The Packagist `__. Middleware in CakePHP ===================== @@ -225,40 +225,37 @@ Most often you'll be setting headers and response bodies on requests:: Creating Middleware =================== -Middleware can either be implemented as anonymous functions (Closures), or as -invokable classes. While Closures are suitable for smaller tasks they make -testing harder, and can create a complicated ``Application`` class. Middleware -classes in CakePHP have a few conventions: +Middleware can either be implemented as anonymous functions (Closures), or classes +which extend ``Psr\Http\Server\MiddlewareInterface``. While Closures are suitable +for smaller tasks they make testing harder, and can create a complicated +``Application`` class. Middleware classes in CakePHP have a few conventions: * Middleware class files should be put in **src/Middleware**. For example: **src/Middleware/CorsMiddleware.php** * Middleware classes should be suffixed with ``Middleware``. For example: ``LinkMiddleware``. -* Middleware are expected to implement the middleware protocol. +* Middleware must implement ``Psr\Http\Server\MiddlewareInterface``. -While not a formal interface (yet), Middleware do have a soft-interface or -'protocol'. The protocol is as follows: - -#. Middleware must implement ``__invoke($request, $response, $next)``. -#. Middleware must return an object implementing the PSR-7 ``ResponseInterface``. - -Middleware can return a response either by calling ``$next`` or by creating -their own response. We can see both options in our simple middleware:: +Middleware can return a response either by calling ``$handler->handle()`` or by +creating their own response. We can see both options in our simple middleware:: // In src/Middleware/TrackingCookieMiddleware.php namespace App\Middleware; + use Cake\I18n\Time; + use Psr\Http\Message\ResponseInterface; + use Psr\Http\Message\ServerRequestInterface; + use Psr\Http\Server\RequestHandlerInterface; + use Psr\Http\Server\MiddlewareInterface; - class TrackingCookieMiddleware + class TrackingCookieMiddleware implements MiddlewareInterface { - public function __invoke($request, $response, $next) + public function process(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface { - // Calling $next() delegates control to the *next* middleware + // Calling $handler->handle() delegates control to the *next* middleware // In your application's queue. - $response = $next($request, $response); + $response = $handler->handle($request); - // When modifying the response, you should do it - // *after* calling next. if (!$request->getCookie('landing_page')) { $expiry = new Time('+ 1 year'); $response = $response->withCookie('landing_page' ,[ @@ -266,6 +263,7 @@ their own response. We can see both options in our simple middleware:: 'expire' => $expiry->format('U'), ]); } + return $response; } } @@ -277,10 +275,11 @@ application:: namespace App; use App\Middleware\TrackingCookieMiddleware; + use Cake\Http\MiddlewareQueue; class Application { - public function middleware($middlewareQueue) + public function middleware(MiddlewareQueue $middlewareQueue): MiddlewareQueue { // Add your simple middleware onto the queue $middlewareQueue->add(new TrackingCookieMiddleware()); @@ -301,7 +300,7 @@ enable cached routes, provide the desired :ref:`cache configuration ` as a parameter:: // In Application.php - public function middleware($middlewareQueue) + public function middleware(MiddlewareQueue $middlewareQueue): MiddlewareQueue { // ... $middlewareQueue->add(new RoutingMiddleware($this, 'routing'));