From 4cd899627776b2098b130e2c1ee58de01bdbda97 Mon Sep 17 00:00:00 2001 From: George Steel Date: Thu, 25 Jan 2024 13:15:15 +0000 Subject: [PATCH 1/4] Re-work the JSON view helper resolving deprecations and updating documentation Signed-off-by: George Steel --- docs/book/v2/migration/preparing-for-v3.md | 2 +- docs/book/v3/helpers/json.md | 19 +++----- docs/book/v3/migration/v2-to-v3.md | 7 +++ src/Helper/Json.php | 53 ++++------------------ src/Renderer/PhpRenderer.php | 2 +- test/Helper/JsonTest.php | 33 +++++--------- 6 files changed, 36 insertions(+), 80 deletions(-) diff --git a/docs/book/v2/migration/preparing-for-v3.md b/docs/book/v2/migration/preparing-for-v3.md index 6787e769c..284ac670f 100644 --- a/docs/book/v2/migration/preparing-for-v3.md +++ b/docs/book/v2/migration/preparing-for-v3.md @@ -30,7 +30,7 @@ try { } ``` -## Deprecations +## Deprecations ### Undocumented Behaviour diff --git a/docs/book/v3/helpers/json.md b/docs/book/v3/helpers/json.md index 655a9f788..913e07b0e 100644 --- a/docs/book/v3/helpers/json.md +++ b/docs/book/v3/helpers/json.md @@ -1,21 +1,16 @@ # Json -When creating views that return JSON, it's important to also set the appropriate -response header. The JSON view helper does exactly that. In addition, by -default, it disables layouts (if currently enabled), as layouts generally aren't -used with JSON responses. +This view helper simply encodes its argument to JSON. -The JSON helper sets the following header: +## Basic Usage -```http -Content-Type: application/json +```php +json(['example' => 'payload']) ?> ``` -Most XmlHttpRequest libraries look for this header when parsing responses to -determine how to handle the content. - -## Basic Usage +The helper accepts a second argument `$jsonOptions`, an associative array with one possible key: `prettyPrint`. +Providing the value `['prettyPrint' => true]` will pretty-print the encoded data. ```php -json($this->data) ?> +json($data, ['prettyPrint' => true]) ?> ``` diff --git a/docs/book/v3/migration/v2-to-v3.md b/docs/book/v3/migration/v2-to-v3.md index 25b17c54f..646f2239d 100644 --- a/docs/book/v3/migration/v2-to-v3.md +++ b/docs/book/v3/migration/v2-to-v3.md @@ -27,6 +27,10 @@ The method of configuring the resource map remains unchanged. The deprecated runtime retrieval and modification of the underlying authentication service has been removed and the service must be injected into the helper constructor. Specifically, the methods `Laminas\View\Helper\Identity::setAuthenticationService()` and `Laminas\View\Helper\Identity::getAuthenticationService()` have been removed. +#### Json Helper + +The JSON view helper is now final and has no inheritance hierarchy. + ## Removed Features ### Stream Wrapper Functionality @@ -53,6 +57,9 @@ The encoding defaults to UTF-8 as it has always done but can be overridden in co In previous versions of laminas-view the [Json View Helper](helpers/json.md) made use of the [laminas-json](https://docs.laminas.dev/laminas-json/) library which enabled encoding of [JSON Expressions](https://docs.laminas.dev/laminas-json/advanced/#json-expressions). Support for this library and the expression finder feature has been removed. +In an MVC context, it was possible, in version 2, to provide a response object to the helper. +Invoking the helper would set the appropriate response headers for a JSON payload. This is no longer possible and the method `setResponse` has been removed. + ## Removed Class and Traits ### Removed Helpers diff --git a/src/Helper/Json.php b/src/Helper/Json.php index 542119922..80ae0e641 100644 --- a/src/Helper/Json.php +++ b/src/Helper/Json.php @@ -4,8 +4,6 @@ namespace Laminas\View\Helper; -use Laminas\Http\Response; - use function json_encode; use const JSON_PRETTY_PRINT; @@ -13,38 +11,19 @@ /** * Helper for simplifying JSON responses - * - * @psalm-suppress DeprecatedProperty - * @final */ -class Json extends AbstractHelper +final class Json { - use DeprecatedAbstractHelperHierarchyTrait; - - /** - * @deprecated since >= 2.20.0 - * - * @var Response|null - */ - protected $response; - /** - * Encode data as JSON and set response header + * Encode data as JSON * - * @param mixed $data - * @param array{prettyPrint?: bool} $jsonOptions Options to pass to JsonFormatter::encode() - * @return string + * @param array{prettyPrint?: bool} $jsonOptions + * @return non-empty-string */ - public function __invoke($data, array $jsonOptions = []) + public function __invoke(mixed $data, array $jsonOptions = []): string { - $data = json_encode($data, $this->optionsToFlags($jsonOptions)); - - if ($this->response instanceof Response) { - $headers = $this->response->getHeaders(); - $headers->addHeaderLine('Content-Type', 'application/json'); - } - - return $data; + /** @psalm-var non-empty-string */ + return json_encode($data, $this->optionsToFlags($jsonOptions)); } /** @param array{prettyPrint?: bool} $options */ @@ -52,24 +31,8 @@ private function optionsToFlags(array $options = []): int { $prettyPrint = $options['prettyPrint'] ?? false; $flags = JSON_THROW_ON_ERROR; - $flags |= $prettyPrint ? 0 : JSON_PRETTY_PRINT; + $flags |= $prettyPrint === false ? 0 : JSON_PRETTY_PRINT; return $flags; } - - /** - * Set the response object - * - * @deprecated since >= 2.20.0. If you need to set response headers, use the methods available in - * the framework. For example in Laminas MVC this can be achieved in the controller or in - * Mezzio, you can change response headers in Middleware. This method will be removed in 3.0 - * without replacement functionality. - * - * @return Json - */ - public function setResponse(Response $response) - { - $this->response = $response; - return $this; - } } diff --git a/src/Renderer/PhpRenderer.php b/src/Renderer/PhpRenderer.php index 271cf33da..ea1d37582 100644 --- a/src/Renderer/PhpRenderer.php +++ b/src/Renderer/PhpRenderer.php @@ -69,7 +69,7 @@ * @method string htmlPage($data, array $attribs = array(), array $params = array(), $content = null) * @method mixed|null identity() * @method \Laminas\View\Helper\InlineScript inlineScript($mode = \Laminas\View\Helper\HeadScript::FILE, $spec = null, $placement = 'APPEND', array $attrs = array(), $type = 'text/javascript') - * @method string|void json($data, array $jsonOptions = array()) + * @method string json(mixed $data, array $jsonOptions = []) * @method \Laminas\View\Helper\Layout layout($template = null) * @method \Laminas\View\Helper\Navigation navigation($container = null) * @method string paginationControl(\Laminas\Paginator\Paginator $paginator = null, $scrollingStyle = null, $partial = null, $params = null) diff --git a/test/Helper/JsonTest.php b/test/Helper/JsonTest.php index b829abf73..5550b51a2 100644 --- a/test/Helper/JsonTest.php +++ b/test/Helper/JsonTest.php @@ -4,18 +4,16 @@ namespace LaminasTest\View\Helper; -use Laminas\Http\Header\HeaderInterface; -use Laminas\Http\Response; use Laminas\View\Helper\Json as JsonHelper; use PHPUnit\Framework\TestCase; use function json_encode; +use const JSON_PRETTY_PRINT; use const JSON_THROW_ON_ERROR; class JsonTest extends TestCase { - private Response $response; private JsonHelper $helper; /** @@ -24,33 +22,26 @@ class JsonTest extends TestCase */ protected function setUp(): void { - $this->response = new Response(); - $this->helper = new JsonHelper(); - $this->helper->setResponse($this->response); + $this->helper = new JsonHelper(); } - private function verifyJsonHeader(): void - { - $headers = $this->response->getHeaders(); - $this->assertTrue($headers->has('Content-Type')); - $header = $headers->get('Content-Type'); - self::assertInstanceOf(HeaderInterface::class, $header); - $this->assertEquals('application/json', $header->getFieldValue()); - } - - public function testJsonHelperSetsResponseHeader(): void + public function testJsonHelperReturnsJsonEncodedString(): void { - $this->helper->__invoke('foobar'); - $this->verifyJsonHeader(); + $input = [ + 'dory' => 'blue', + 'nemo' => 'orange', + ]; + $expect = json_encode($input, JSON_THROW_ON_ERROR); + self::assertJsonStringEqualsJsonString($expect, ($this->helper)->__invoke($input)); } - public function testJsonHelperReturnsJsonEncodedString(): void + public function testTheHelperWillPrettyPrintWhenRequired(): void { $input = [ 'dory' => 'blue', 'nemo' => 'orange', ]; - $expect = json_encode($input, JSON_THROW_ON_ERROR); - self::assertJsonStringEqualsJsonString($expect, ($this->helper)($input)); + $expect = json_encode($input, JSON_THROW_ON_ERROR | JSON_PRETTY_PRINT); + self::assertSame($expect, ($this->helper)->__invoke($input, ['prettyPrint' => true])); } } From 930c31c26c57112d76ec97e42135a28f799e5304 Mon Sep 17 00:00:00 2001 From: George Steel Date: Fri, 26 Jan 2024 09:59:05 +0000 Subject: [PATCH 2/4] Remove the Json view helper entirely Signed-off-by: George Steel --- docs/book/v3/helpers/json.md | 16 ---------- docs/book/v3/migration/v2-to-v3.md | 17 ++++------- mkdocs.yml | 2 -- src/Helper/Json.php | 38 ------------------------ src/HelperPluginManager.php | 4 --- src/Renderer/PhpRenderer.php | 1 - test/Helper/JsonTest.php | 47 ------------------------------ 7 files changed, 5 insertions(+), 120 deletions(-) delete mode 100644 docs/book/v3/helpers/json.md delete mode 100644 src/Helper/Json.php delete mode 100644 test/Helper/JsonTest.php diff --git a/docs/book/v3/helpers/json.md b/docs/book/v3/helpers/json.md deleted file mode 100644 index 913e07b0e..000000000 --- a/docs/book/v3/helpers/json.md +++ /dev/null @@ -1,16 +0,0 @@ -# Json - -This view helper simply encodes its argument to JSON. - -## Basic Usage - -```php -json(['example' => 'payload']) ?> -``` - -The helper accepts a second argument `$jsonOptions`, an associative array with one possible key: `prettyPrint`. -Providing the value `['prettyPrint' => true]` will pretty-print the encoded data. - -```php -json($data, ['prettyPrint' => true]) ?> -``` diff --git a/docs/book/v3/migration/v2-to-v3.md b/docs/book/v3/migration/v2-to-v3.md index 646f2239d..2ac042c51 100644 --- a/docs/book/v3/migration/v2-to-v3.md +++ b/docs/book/v3/migration/v2-to-v3.md @@ -27,10 +27,6 @@ The method of configuring the resource map remains unchanged. The deprecated runtime retrieval and modification of the underlying authentication service has been removed and the service must be injected into the helper constructor. Specifically, the methods `Laminas\View\Helper\Identity::setAuthenticationService()` and `Laminas\View\Helper\Identity::getAuthenticationService()` have been removed. -#### Json Helper - -The JSON view helper is now final and has no inheritance hierarchy. - ## Removed Features ### Stream Wrapper Functionality @@ -52,14 +48,6 @@ These helpers now have constructors that expect an [Escaper](https://docs.lamina The encoding defaults to UTF-8 as it has always done but can be overridden in configuration by setting `view_manager.encoding` to your preferred value. -#### Json View Helper - -In previous versions of laminas-view the [Json View Helper](helpers/json.md) made use of the [laminas-json](https://docs.laminas.dev/laminas-json/) library which enabled encoding of [JSON Expressions](https://docs.laminas.dev/laminas-json/advanced/#json-expressions). -Support for this library and the expression finder feature has been removed. - -In an MVC context, it was possible, in version 2, to provide a response object to the helper. -Invoking the helper would set the appropriate response headers for a JSON payload. This is no longer possible and the method `setResponse` has been removed. - ## Removed Class and Traits ### Removed Helpers @@ -105,3 +93,8 @@ function gravatarImage( string $rating = 'g' ); ``` + +#### Json + +The deprecated Json view helper has been removed. +To encode data to Json for output in a view, you can call [`json_encode`](https://www.php.net/json_encode) directly. diff --git a/mkdocs.yml b/mkdocs.yml index d0f255355..52687be90 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -65,7 +65,6 @@ nav: - HtmlTag: v3/helpers/html-tag.md - Identity: v3/helpers/identity.md - InlineScript: v3/helpers/inline-script.md - - Json: v3/helpers/json.md - Layout: v3/helpers/layout.md - Partial: v3/helpers/partial.md - Placeholder: v3/helpers/placeholder.md @@ -115,7 +114,6 @@ plugins: helpers/html-tag.md: v3/helpers/html-tag.md helpers/identity.md: v3/helpers/identity.md helpers/inline-script.md: v3/helpers/inline-script.md - helpers/json.md: v3/helpers/json.md helpers/layout.md: v3/helpers/layout.md helpers/partial.md: v3/helpers/partial.md helpers/placeholder.md: v3/helpers/placeholder.md diff --git a/src/Helper/Json.php b/src/Helper/Json.php deleted file mode 100644 index 80ae0e641..000000000 --- a/src/Helper/Json.php +++ /dev/null @@ -1,38 +0,0 @@ -optionsToFlags($jsonOptions)); - } - - /** @param array{prettyPrint?: bool} $options */ - private function optionsToFlags(array $options = []): int - { - $prettyPrint = $options['prettyPrint'] ?? false; - $flags = JSON_THROW_ON_ERROR; - $flags |= $prettyPrint === false ? 0 : JSON_PRETTY_PRINT; - - return $flags; - } -} diff --git a/src/HelperPluginManager.php b/src/HelperPluginManager.php index bbadf35a4..7a01f7f70 100644 --- a/src/HelperPluginManager.php +++ b/src/HelperPluginManager.php @@ -111,8 +111,6 @@ class HelperPluginManager extends AbstractPluginManager 'inlinescript' => Helper\InlineScript::class, 'inlineScript' => Helper\InlineScript::class, 'InlineScript' => Helper\InlineScript::class, - 'json' => Helper\Json::class, - 'Json' => Helper\Json::class, 'layout' => Helper\Layout::class, 'Layout' => Helper\Layout::class, 'paginationcontrol' => Helper\PaginationControl::class, @@ -181,7 +179,6 @@ class HelperPluginManager extends AbstractPluginManager Helper\HtmlObject::class => InvokableFactory::class, Helper\HtmlPage::class => InvokableFactory::class, Helper\InlineScript::class => InvokableFactory::class, - Helper\Json::class => InvokableFactory::class, Helper\Layout::class => InvokableFactory::class, Helper\PaginationControl::class => InvokableFactory::class, Helper\PartialLoop::class => InvokableFactory::class, @@ -217,7 +214,6 @@ class HelperPluginManager extends AbstractPluginManager 'laminasviewhelperhtmlobject' => InvokableFactory::class, 'laminasviewhelperhtmlpage' => InvokableFactory::class, 'laminasviewhelperinlinescript' => InvokableFactory::class, - 'laminasviewhelperjson' => InvokableFactory::class, 'laminasviewhelperlayout' => InvokableFactory::class, 'laminasviewhelperpaginationcontrol' => InvokableFactory::class, 'laminasviewhelperpartialloop' => InvokableFactory::class, diff --git a/src/Renderer/PhpRenderer.php b/src/Renderer/PhpRenderer.php index ea1d37582..050dc29bf 100644 --- a/src/Renderer/PhpRenderer.php +++ b/src/Renderer/PhpRenderer.php @@ -69,7 +69,6 @@ * @method string htmlPage($data, array $attribs = array(), array $params = array(), $content = null) * @method mixed|null identity() * @method \Laminas\View\Helper\InlineScript inlineScript($mode = \Laminas\View\Helper\HeadScript::FILE, $spec = null, $placement = 'APPEND', array $attrs = array(), $type = 'text/javascript') - * @method string json(mixed $data, array $jsonOptions = []) * @method \Laminas\View\Helper\Layout layout($template = null) * @method \Laminas\View\Helper\Navigation navigation($container = null) * @method string paginationControl(\Laminas\Paginator\Paginator $paginator = null, $scrollingStyle = null, $partial = null, $params = null) diff --git a/test/Helper/JsonTest.php b/test/Helper/JsonTest.php deleted file mode 100644 index 5550b51a2..000000000 --- a/test/Helper/JsonTest.php +++ /dev/null @@ -1,47 +0,0 @@ -helper = new JsonHelper(); - } - - public function testJsonHelperReturnsJsonEncodedString(): void - { - $input = [ - 'dory' => 'blue', - 'nemo' => 'orange', - ]; - $expect = json_encode($input, JSON_THROW_ON_ERROR); - self::assertJsonStringEqualsJsonString($expect, ($this->helper)->__invoke($input)); - } - - public function testTheHelperWillPrettyPrintWhenRequired(): void - { - $input = [ - 'dory' => 'blue', - 'nemo' => 'orange', - ]; - $expect = json_encode($input, JSON_THROW_ON_ERROR | JSON_PRETTY_PRINT); - self::assertSame($expect, ($this->helper)->__invoke($input, ['prettyPrint' => true])); - } -} From 590a0c50f169221b8c27a664406ace3360726a69 Mon Sep 17 00:00:00 2001 From: George Steel Date: Fri, 26 Jan 2024 10:12:33 +0000 Subject: [PATCH 3/4] Additional guidance on json_encode for v3 migration Signed-off-by: George Steel --- docs/book/v3/migration/v2-to-v3.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/docs/book/v3/migration/v2-to-v3.md b/docs/book/v3/migration/v2-to-v3.md index 2ac042c51..94fd41f6b 100644 --- a/docs/book/v3/migration/v2-to-v3.md +++ b/docs/book/v3/migration/v2-to-v3.md @@ -98,3 +98,6 @@ function gravatarImage( The deprecated Json view helper has been removed. To encode data to Json for output in a view, you can call [`json_encode`](https://www.php.net/json_encode) directly. + +If you were relying on behaviour that was previously available via `laminas-json`, for example, calling object methods `toArray` or `toJson` prior to encoding, you should make the relevant objects implement `JsonSerializable`. +You can find documentation on the `JsonSerializable` interface [on the PHP website](https://www.php.net/manual/en/class.jsonserializable.php). From d202ab9c76693b4b9d9174694241222f7a8f13c8 Mon Sep 17 00:00:00 2001 From: George Steel Date: Mon, 5 Feb 2024 12:48:18 +0000 Subject: [PATCH 4/4] Use language-less links to the PHP docs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Frank Brückner Signed-off-by: George Steel --- docs/book/v3/migration/v2-to-v3.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/book/v3/migration/v2-to-v3.md b/docs/book/v3/migration/v2-to-v3.md index 94fd41f6b..c6eae30ec 100644 --- a/docs/book/v3/migration/v2-to-v3.md +++ b/docs/book/v3/migration/v2-to-v3.md @@ -100,4 +100,4 @@ The deprecated Json view helper has been removed. To encode data to Json for output in a view, you can call [`json_encode`](https://www.php.net/json_encode) directly. If you were relying on behaviour that was previously available via `laminas-json`, for example, calling object methods `toArray` or `toJson` prior to encoding, you should make the relevant objects implement `JsonSerializable`. -You can find documentation on the `JsonSerializable` interface [on the PHP website](https://www.php.net/manual/en/class.jsonserializable.php). +You can find documentation on the `JsonSerializable` interface [on the PHP website](https://www.php.net/manual/class.jsonserializable.php).