Skip to content

Commit

Permalink
Merge pull request #125 from gsteel/remove-laminas-json
Browse files Browse the repository at this point in the history
Remove dependency on laminas-json
  • Loading branch information
Ocramius authored Jan 31, 2022
2 parents 9bf6259 + d55a676 commit e0d37bf
Show file tree
Hide file tree
Showing 9 changed files with 101 additions and 157 deletions.
1 change: 0 additions & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@
"php": "^7.4 || ~8.0.0 || ~8.1.0",
"ext-json": "*",
"laminas/laminas-eventmanager": "^3.4",
"laminas/laminas-json": "^3.3",
"laminas/laminas-stdlib": "^3.6"
},
"require-dev": {
Expand Down
63 changes: 1 addition & 62 deletions composer.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

26 changes: 0 additions & 26 deletions docs/book/helpers/json.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,29 +19,3 @@ determine how to handle the content.
```php
<?= $this->json($this->data) ?>
```

> WARNING: **Deprecated**
>
> ### Enabling encoding using Laminas\Json\Expr
>
> **This feature of the Json view helper has been deprecated in version 2.16 and will be removed in version 3.0.**
>
> The JSON helper accepts an array of options that will be passed to `Laminas\Json\Json::encode()` and
> used internally to encode data.
> `Laminas\Json\Json::encode` allows the encoding of native JSON expressions using `Laminas\Json\Expr`
> objects. This option is disabled by default. To enable this option, pass a boolean `true` to the
> `enableJsonExprFinder` key of the options array:
>
> ```php
> <?= $this->json($this->data, ['enableJsonExprFinder' => true]) ?>
> ``
>
> The JSON helper accepts an array of options that will be passed to `Laminas\Json\Json::encode()` and
> used internally to encode data.
> `Laminas\Json\Json::encode` allows the encoding of native JSON expressions using `Laminas\Json\Expr`
> objects. This option is disabled by default. To enable this option, pass a boolean `true` to the
> `enableJsonExprFinder` key of the options array:
>
> ```php
> <?= $this->json($this->data, ['enableJsonExprFinder' => true]) ?>
> ```
14 changes: 0 additions & 14 deletions psalm-baseline.xml
Original file line number Diff line number Diff line change
Expand Up @@ -760,17 +760,6 @@
<code>InlineScript</code>
</PropertyNotSetInConstructor>
</file>
<file src="src/Helper/Json.php">
<MissingConstructor occurrences="1">
<code>$response</code>
</MissingConstructor>
<NullArgument occurrences="1">
<code>null</code>
</NullArgument>
<RedundantConditionGivenDocblockType occurrences="1">
<code>$this-&gt;response instanceof Response</code>
</RedundantConditionGivenDocblockType>
</file>
<file src="src/Helper/Layout.php">
<DocblockTypeContradiction occurrences="1">
<code>null === $this-&gt;viewModelHelper</code>
Expand Down Expand Up @@ -1915,9 +1904,6 @@
</UndefinedInterfaceMethod>
</file>
<file src="src/Renderer/JsonRenderer.php">
<ImplementedReturnTypeMismatch occurrences="1">
<code>void</code>
</ImplementedReturnTypeMismatch>
<MissingConstructor occurrences="1">
<code>$jsonpCallback</code>
</MissingConstructor>
Expand Down
31 changes: 17 additions & 14 deletions src/Helper/Json.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,37 +5,30 @@
namespace Laminas\View\Helper;

use Laminas\Http\Response;
use Laminas\Json\Json as JsonFormatter;

use function trigger_error;
use function json_encode;

use const E_USER_DEPRECATED;
use const JSON_PRETTY_PRINT;
use const JSON_THROW_ON_ERROR;

/**
* Helper for simplifying JSON responses
*/
class Json extends AbstractHelper
{
/** @var Response */
/** @var Response|null */
protected $response;

/**
* Encode data as JSON and set response header
*
* @param mixed $data
* @param array $jsonOptions Options to pass to JsonFormatter::encode()
* @return string|void
* @param array{prettyPrint?: bool} $jsonOptions
* @return string
*/
public function __invoke($data, array $jsonOptions = [])
{
if (isset($jsonOptions['enableJsonExprFinder']) && $jsonOptions['enableJsonExprFinder'] === true) {
trigger_error(
'Json Expression functionality is deprecated and will be removed in laminas-view 3.0',
E_USER_DEPRECATED
);
}

$data = JsonFormatter::encode($data, null, $jsonOptions);
$data = json_encode($data, $this->optionsToFlags($jsonOptions));

if ($this->response instanceof Response) {
$headers = $this->response->getHeaders();
Expand All @@ -45,6 +38,16 @@ public function __invoke($data, array $jsonOptions = [])
return $data;
}

/** @param array{prettyPrint?: bool} $options */
private function optionsToFlags(array $options = []): int
{
$prettyPrint = $options['prettyPrint'] ?? false;
$flags = JSON_THROW_ON_ERROR;
$flags |= $prettyPrint ? 0 : JSON_PRETTY_PRINT;

return $flags;
}

/**
* Set the response object
*
Expand Down
26 changes: 20 additions & 6 deletions src/Model/JsonModel.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,16 @@

namespace Laminas\View\Model;

use Laminas\Json\Json;
use JsonException;
use Laminas\Stdlib\ArrayUtils;
use Laminas\View\Exception\DomainException;
use Traversable;

use function json_encode;

use const JSON_PRETTY_PRINT;
use const JSON_THROW_ON_ERROR;

class JsonModel extends ViewModel
{
/**
Expand Down Expand Up @@ -56,13 +62,21 @@ public function serialize()
$variables = ArrayUtils::iteratorToArray($variables);
}

$options = [
'prettyPrint' => $this->getOption('prettyPrint'),
];
$options = (bool) $this->getOption('prettyPrint', false) ? JSON_PRETTY_PRINT : 0;

if (null !== $this->jsonpCallback) {
return $this->jsonpCallback . '(' . Json::encode($variables, false, $options) . ');';
return $this->jsonpCallback . '(' . $this->jsonEncode($variables, $options) . ');';
}
return $this->jsonEncode($variables, $options);
}

/** @param mixed $data */
private function jsonEncode($data, int $options): string
{
try {
return json_encode($data, $options | JSON_THROW_ON_ERROR);
} catch (JsonException $e) {
throw new DomainException('Failed to encode Json', (int) $e->getCode(), $e);
}
return Json::encode($variables, false, $options);
}
}
36 changes: 25 additions & 11 deletions src/Renderer/JsonRenderer.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@
namespace Laminas\View\Renderer;

use ArrayAccess;
use JsonException;
use JsonSerializable;
use Laminas\Json\Json;
use Laminas\Stdlib\ArrayUtils;
use Laminas\View\Exception;
use Laminas\View\Model\JsonModel;
Expand All @@ -18,8 +18,11 @@
use function array_replace_recursive;
use function get_object_vars;
use function is_object;
use function json_encode;
use function sprintf;

use const JSON_THROW_ON_ERROR;

/**
* JSON renderer
*/
Expand Down Expand Up @@ -60,11 +63,13 @@ public function getEngine()
* Set the resolver used to map a template name to a resource the renderer may consume.
*
* @todo Determine use case for resolvers when rendering JSON
* @return void
* @return self
*/
public function setResolver(Resolver $resolver)
{
$this->resolver = $resolver;

return $this;
}

/**
Expand Down Expand Up @@ -131,28 +136,27 @@ public function render($nameOrModel, $values = null)
if ($nameOrModel instanceof JsonModel) {
$children = $this->recurseModel($nameOrModel, false);
$this->injectChildren($nameOrModel, $children);
$values = $nameOrModel->serialize();
$output = $nameOrModel->serialize();
} else {
$values = $this->recurseModel($nameOrModel);
$values = Json::encode($values);
$output = $this->recurseModel($nameOrModel);
$output = $this->jsonEncode($output);
}

if ($this->hasJsonpCallback()) {
$values = $this->jsonpCallback . '(' . $values . ');';
$output = $this->jsonpCallback . '(' . $output . ');';
}
return $values;
return $output;
}

// use case 2: $nameOrModel is populated, $values is not
// Serialize $nameOrModel
if (null === $values) {
if (! is_object($nameOrModel) || $nameOrModel instanceof JsonSerializable) {
$return = Json::encode($nameOrModel);
$return = $this->jsonEncode($nameOrModel);
} elseif ($nameOrModel instanceof Traversable) {
$nameOrModel = ArrayUtils::iteratorToArray($nameOrModel);
$return = Json::encode($nameOrModel);
$return = $this->jsonEncode(ArrayUtils::iteratorToArray($nameOrModel));
} else {
$return = Json::encode(get_object_vars($nameOrModel));
$return = $this->jsonEncode(get_object_vars($nameOrModel));
}

if ($this->hasJsonpCallback()) {
Expand Down Expand Up @@ -237,4 +241,14 @@ protected function injectChildren(Model $model, array $children): void
$model->setVariable($child, $value);
}
}

/** @param mixed $data */
private function jsonEncode($data): string
{
try {
return json_encode($data, JSON_THROW_ON_ERROR);
} catch (JsonException $e) {
throw new Exception\DomainException('Json encoding failed', (int) $e->getCode(), $e);
}
}
}
28 changes: 11 additions & 17 deletions test/Helper/JsonTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,13 @@

use Laminas\Http\Header\HeaderInterface;
use Laminas\Http\Response;
use Laminas\Json\Json as JsonFormatter;
use Laminas\View\Helper\Json as JsonHelper;
use PHPUnit\Framework\TestCase;

use function json_encode;

use const JSON_THROW_ON_ERROR;

/**
* Test class for Laminas\View\Helper\Json
*
Expand All @@ -34,7 +37,7 @@ protected function setUp(): void
$this->helper->setResponse($this->response);
}

public function verifyJsonHeader(): void
private function verifyJsonHeader(): void
{
$headers = $this->response->getHeaders();
$this->assertTrue($headers->has('Content-Type'));
Expand All @@ -51,20 +54,11 @@ public function testJsonHelperSetsResponseHeader(): void

public function testJsonHelperReturnsJsonEncodedString(): void
{
$data = $this->helper->__invoke('foobar');
$this->assertIsString($data);
$this->assertEquals('foobar', JsonFormatter::decode($data));
}

public function testThatADeprecationErrorIsTriggeredWhenExpressionFinderOptionIsUsed(): void
{
$this->expectDeprecation();
$this->helper->__invoke(['foo'], ['enableJsonExprFinder' => true]);
}

public function testThatADeprecationErrorIsNotTriggeredWhenExpressionFinderOptionIsNotUsed(): void
{
$this->expectNotToPerformAssertions();
$this->helper->__invoke(['foo'], ['enableJsonExprFinder' => 'anything other than true']);
$input = [
'dory' => 'blue',
'nemo' => 'orange',
];
$expect = json_encode($input, JSON_THROW_ON_ERROR);
self::assertJsonStringEqualsJsonString($expect, ($this->helper)($input));
}
}
Loading

0 comments on commit e0d37bf

Please sign in to comment.