Skip to content

Commit 5d0140c

Browse files
committed
Replace Laminas\Json usage in the JsonModel. Possible BC break now that a DomainException is thrown if there is an encoding error
Signed-off-by: George Steel <george@net-glue.co.uk>
1 parent 5cbac9a commit 5d0140c

File tree

2 files changed

+48
-14
lines changed

2 files changed

+48
-14
lines changed

src/Model/JsonModel.php

+20-6
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,16 @@
88

99
namespace Laminas\View\Model;
1010

11-
use Laminas\Json\Json;
11+
use JsonException;
1212
use Laminas\Stdlib\ArrayUtils;
13+
use Laminas\View\Exception\DomainException;
1314
use Traversable;
1415

16+
use function json_encode;
17+
18+
use const JSON_PRETTY_PRINT;
19+
use const JSON_THROW_ON_ERROR;
20+
1521
class JsonModel extends ViewModel
1622
{
1723
/**
@@ -60,13 +66,21 @@ public function serialize()
6066
$variables = ArrayUtils::iteratorToArray($variables);
6167
}
6268

63-
$options = [
64-
'prettyPrint' => $this->getOption('prettyPrint'),
65-
];
69+
$options = (bool) $this->getOption('prettyPrint', false) ? JSON_PRETTY_PRINT : 0;
6670

6771
if (null !== $this->jsonpCallback) {
68-
return $this->jsonpCallback.'('.Json::encode($variables, false, $options).');';
72+
return $this->jsonpCallback.'('.$this->jsonEncode($variables, $options).');';
73+
}
74+
return $this->jsonEncode($variables, $options);
75+
}
76+
77+
/** @param mixed $data */
78+
private function jsonEncode($data, int $options): string
79+
{
80+
try {
81+
return json_encode($data, $options | JSON_THROW_ON_ERROR);
82+
} catch (JsonException $e) {
83+
throw new DomainException('Failed to encode Json', $e->getCode(), $e);
6984
}
70-
return Json::encode($variables, false, $options);
7185
}
7286
}

test/Model/JsonModelTest.php

+28-8
Original file line numberDiff line numberDiff line change
@@ -8,37 +8,46 @@
88

99
namespace LaminasTest\View\Model;
1010

11-
use Laminas\Json\Json;
11+
use Laminas\View\Exception\DomainException;
1212
use Laminas\View\Model\JsonModel;
1313
use Laminas\View\Variables;
1414
use PHPUnit\Framework\TestCase;
1515

16+
use function json_encode;
17+
18+
use const JSON_PRETTY_PRINT;
19+
use const JSON_THROW_ON_ERROR;
20+
1621
class JsonModelTest extends TestCase
1722
{
18-
public function testAllowsEmptyConstructor()
23+
public function testAllowsEmptyConstructor(): void
1924
{
2025
$model = new JsonModel();
2126
$this->assertInstanceOf(Variables::class, $model->getVariables());
2227
$this->assertEquals([], $model->getOptions());
2328
}
2429

25-
public function testCanSerializeVariablesToJson()
30+
public function testCanSerializeVariablesToJson(): void
2631
{
2732
$array = ['foo' => 'bar'];
2833
$model = new JsonModel($array);
2934
$this->assertEquals($array, $model->getVariables());
30-
$this->assertEquals(Json::encode($array), $model->serialize());
35+
$this->assertJsonStringEqualsJsonString(json_encode($array, JSON_THROW_ON_ERROR), $model->serialize());
3136
}
3237

33-
public function testCanSerializeWithJsonpCallback()
38+
public function testCanSerializeWithJsonpCallback(): void
3439
{
3540
$array = ['foo' => 'bar'];
3641
$model = new JsonModel($array);
3742
$model->setJsonpCallback('callback');
38-
$this->assertEquals('callback(' . Json::encode($array) . ');', $model->serialize());
43+
$expect = sprintf(
44+
'callback(%s);',
45+
json_encode($array, JSON_THROW_ON_ERROR)
46+
);
47+
$this->assertEquals($expect, $model->serialize());
3948
}
4049

41-
public function testPrettyPrint()
50+
public function testPrettyPrint(): void
4251
{
4352
$array = [
4453
'simple' => 'simple test string',
@@ -49,6 +58,17 @@ public function testPrettyPrint()
4958
]
5059
];
5160
$model = new JsonModel($array, ['prettyPrint' => true]);
52-
$this->assertEquals(Json::encode($array, false, ['prettyPrint' => true]), $model->serialize());
61+
$expect = json_encode($array, JSON_THROW_ON_ERROR | JSON_PRETTY_PRINT);
62+
$this->assertEquals($expect, $model->serialize());
63+
}
64+
65+
public function testThatAnExceptionIsThrownIfItIsNotPossibleToEncodeThePayload(): void
66+
{
67+
$malformedUtf8 = [
68+
'string' => "\x92",
69+
];
70+
$this->expectException(DomainException::class);
71+
$this->expectExceptionMessage('Failed to encode Json');
72+
(new JsonModel($malformedUtf8))->serialize();
5373
}
5474
}

0 commit comments

Comments
 (0)