Document PSR-7 support
authorTim Düsterhus <duesterhus@woltlab.com>
Thu, 19 Aug 2021 10:55:28 +0000 (12:55 +0200)
committerTim Düsterhus <duesterhus@woltlab.com>
Thu, 19 Aug 2021 10:55:28 +0000 (12:55 +0200)
Resolves #214

docs/migration/wsc54/php.md

index 99634c0f77e752d9e72ed70c582d08810728324a..190b3b7256c3b2921463247a2c6d3879e7998266 100644 (file)
@@ -1,5 +1,144 @@
 # Migrating from WSC 5.4 - PHP
 
+## Initial PSR-7 support
+
+WoltLab Suite will *incrementally* add support for object oriented request/response handling based off the [PSR-7](https://www.php-fig.org/psr/psr-7/) and [PSR-15](https://www.php-fig.org/psr/psr-15/) standards in the upcoming versions.
+
+WoltLab Suite 5.5 adds initial support by allowing to define the response using objects implementing the PSR-7 `ResponseInterface`.
+If a controller returns such a response object from its `__run()` method, this response will automatically emitted to the client.
+
+Any PSR-7 implementation is supported, but WoltLab Suite 5.5 ships with [laminas-diactoros](https://docs.laminas.dev/laminas-diactoros/) as the recommended “batteries included” implementation of PSR-7.
+
+Support for PSR-7 requests and PSR-15 middlewares is expected to follow in future versions.
+
+See [WoltLab/WCF#4437](https://github.com/WoltLab/WCF/pull/4437) for details.
+
+### Recommended changes for WoltLab Suite 5.5
+
+With the current support in WoltLab Suite 5.5 it is recommended to migrate the `*Action` classes to make use of PSR-7 responses.
+Control and data flow is typically fairly simple in `*Action` classes with most requests ending up in either a redirect or a JSON response, commonly followed by a call to `exit;`.
+
+Experimental support for `*Page` and `*Form` is available.
+It is recommended to wait for a future version before migrating these types of controllers.
+
+#### Migrating Redirects
+
+Previously:
+
+{jinja{ codebox(
+    language="php",
+    title="lib/action/ExampleRedirectAction.class.php",
+    contents="""
+<?php
+
+namespace wcf\\action;
+
+use wcf\\system\\request\\LinkHandler;
+use wcf\\util\\HeaderUtil;
+
+final class ExampleRedirectAction extends AbstractAction
+{
+    public function execute()
+    {
+        parent::execute();
+
+        // Redirect to the landing page.
+        HeaderUtil::redirect(
+            LinkHandler::getInstance()->getLink()
+        );
+
+        exit;
+    }
+}
+"""
+) }}
+
+Now:
+
+{jinja{ codebox(
+    language="php",
+    title="lib/action/ExampleRedirectAction.class.php",
+    contents="""
+<?php
+
+namespace wcf\\action;
+
+use Laminas\\Diactoros\\Response\\RedirectResponse;
+use wcf\\system\\request\\LinkHandler;
+
+final class ExampleRedirectAction extends AbstractAction
+{
+    public function execute()
+    {
+        parent::execute();
+
+        // Redirect to the landing page.
+        return new RedirectResponse(
+            LinkHandler::getInstance()->getLink()
+        );
+    }
+}
+"""
+) }}
+
+#### Migrating JSON responses
+
+Previously:
+
+{jinja{ codebox(
+    language="php",
+    title="lib/action/ExampleJsonAction.class.php",
+    contents="""
+<?php
+
+namespace wcf\\action;
+
+use wcf\\util\\JSON;
+
+final class ExampleJsonAction extends AbstractAction
+{
+    public function execute()
+    {
+        parent::execute();
+
+        \header('Content-type: application/json; charset=UTF-8');
+
+        echo JSON::encode([
+            'foo' => 'bar',
+        ]);
+
+        exit;
+    }
+}
+"""
+) }}
+
+Now:
+
+{jinja{ codebox(
+    language="php",
+    title="lib/action/ExampleJsonAction.class.php",
+    contents="""
+<?php
+
+namespace wcf\\action;
+
+use Laminas\\Diactoros\\Response\\JsonResponse;
+
+final class ExampleJsonAction extends AbstractAction
+{
+    public function execute()
+    {
+        parent::execute();
+
+        return new JsonResponse([
+            'foo' => 'bar',
+        ]);
+    }
+}
+"""
+) }}
+
 ## Events
 
 Historically, events were tightly coupled with a single class, with the event object being an object of this class, expecting the event listener to consume public properties and method of the event object.