From e99c8a7dca900094b42cbaee78dcf560aee240ab Mon Sep 17 00:00:00 2001 From: Jason Varga Date: Wed, 6 Mar 2024 15:11:07 -0500 Subject: [PATCH 1/4] wip --- src/Contracts/Data/Augmentable.php | 2 +- src/Data/HasAugmentedInstance.php | 5 +++++ src/Fields/Value.php | 7 ++++++- src/Modifiers/CoreModifiers.php | 15 +++++++-------- 4 files changed, 19 insertions(+), 10 deletions(-) diff --git a/src/Contracts/Data/Augmentable.php b/src/Contracts/Data/Augmentable.php index 3ef410e154..6fb1766f4d 100644 --- a/src/Contracts/Data/Augmentable.php +++ b/src/Contracts/Data/Augmentable.php @@ -2,7 +2,7 @@ namespace Statamic\Contracts\Data; -interface Augmentable +interface Augmentable extends \JsonSerializable { public function augmentedValue($key); diff --git a/src/Data/HasAugmentedInstance.php b/src/Data/HasAugmentedInstance.php index 41d1fb1f01..9aa148a87b 100644 --- a/src/Data/HasAugmentedInstance.php +++ b/src/Data/HasAugmentedInstance.php @@ -83,6 +83,11 @@ public function toArray() return $this->toEvaluatedAugmentedArray(); } + public function jsonSerialize(): mixed + { + return $this->toArray(); + } + public function __get($key) { $value = $this->augmentedValue($key); diff --git a/src/Fields/Value.php b/src/Fields/Value.php index 0ddd7b024b..b51ff8097f 100644 --- a/src/Fields/Value.php +++ b/src/Fields/Value.php @@ -8,6 +8,7 @@ use JsonSerializable; use Statamic\Contracts\Data\Augmentable; use Statamic\Contracts\View\Antlers\Parser; +use Statamic\Facades\Compare; use Statamic\Support\Str; use Statamic\View\Antlers\Language\Parser\DocumentTransformer; @@ -60,8 +61,12 @@ public function jsonSerialize($options = 0) { $value = $this->value(); + if (Compare::isQueryBuilder($value)) { + $value = $value->get(); + } + if ($value instanceof Augmentable || $value instanceof Collection) { - $value = $value->toAugmentedArray(); + $value = $value->toArray(); } return $value; diff --git a/src/Modifiers/CoreModifiers.php b/src/Modifiers/CoreModifiers.php index 937e2230e7..a0897c16e1 100644 --- a/src/Modifiers/CoreModifiers.php +++ b/src/Modifiers/CoreModifiers.php @@ -2542,14 +2542,13 @@ public function toBool($value, $params) public function toJson($value, $params) { $options = Arr::get($params, 0) === 'pretty' ? JSON_PRETTY_PRINT : 0; - - if (Compare::isQueryBuilder($value)) { - $value = $value->get(); - } - - if ($value instanceof Collection || $value instanceof Augmentable) { - $value = $value->toAugmentedArray(); - } +// if (Compare::isQueryBuilder($value)) { +// $value = $value->get(); +// } +// +// if ($value instanceof Collection || $value instanceof Augmentable) { +// $value = $value->toAugmentedArray(); +// } return json_encode($value, $options); } From 934b8aca527e9793786cc8039dd6acb960fba69e Mon Sep 17 00:00:00 2001 From: jasonvarga Date: Wed, 6 Mar 2024 20:14:36 +0000 Subject: [PATCH 2/4] Fix styling --- src/Modifiers/CoreModifiers.php | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/Modifiers/CoreModifiers.php b/src/Modifiers/CoreModifiers.php index a0897c16e1..3c4399cc6f 100644 --- a/src/Modifiers/CoreModifiers.php +++ b/src/Modifiers/CoreModifiers.php @@ -2542,13 +2542,13 @@ public function toBool($value, $params) public function toJson($value, $params) { $options = Arr::get($params, 0) === 'pretty' ? JSON_PRETTY_PRINT : 0; -// if (Compare::isQueryBuilder($value)) { -// $value = $value->get(); -// } -// -// if ($value instanceof Collection || $value instanceof Augmentable) { -// $value = $value->toAugmentedArray(); -// } + // if (Compare::isQueryBuilder($value)) { + // $value = $value->get(); + // } + // + // if ($value instanceof Collection || $value instanceof Augmentable) { + // $value = $value->toAugmentedArray(); + // } return json_encode($value, $options); } From 7737d841317cd8c77533cb73f61b6419adbd3e0a Mon Sep 17 00:00:00 2001 From: Jason Varga Date: Fri, 12 Apr 2024 11:45:59 -0400 Subject: [PATCH 3/4] add to_json modifier tests and bring back handling for query builders --- src/Modifiers/CoreModifiers.php | 11 ++-- tests/Modifiers/ToJsonTest.php | 89 +++++++++++++++++++++++++++++++++ 2 files changed, 93 insertions(+), 7 deletions(-) create mode 100644 tests/Modifiers/ToJsonTest.php diff --git a/src/Modifiers/CoreModifiers.php b/src/Modifiers/CoreModifiers.php index f1cdfe48ed..d2efb0417f 100644 --- a/src/Modifiers/CoreModifiers.php +++ b/src/Modifiers/CoreModifiers.php @@ -2540,13 +2540,10 @@ public function toBool($value, $params) public function toJson($value, $params) { $options = Arr::get($params, 0) === 'pretty' ? JSON_PRETTY_PRINT : 0; - // if (Compare::isQueryBuilder($value)) { - // $value = $value->get(); - // } - // - // if ($value instanceof Collection || $value instanceof Augmentable) { - // $value = $value->toAugmentedArray(); - // } + + if (Compare::isQueryBuilder($value)) { + $value = $value->get(); + } return json_encode($value, $options); } diff --git a/tests/Modifiers/ToJsonTest.php b/tests/Modifiers/ToJsonTest.php new file mode 100644 index 0000000000..14d2d2f3fd --- /dev/null +++ b/tests/Modifiers/ToJsonTest.php @@ -0,0 +1,89 @@ +modify(value($input)); + + $this->assertEquals($expected, $modified); + } + + /** + * @test + * + * @dataProvider bourneJsonBourneProvider + */ + public function it_pretty_prints($input, $expected): void + { + $modified = $this->modify(value($input), ['pretty']); + + $this->assertEquals(json_encode(json_decode($expected, true), JSON_PRETTY_PRINT), $modified); + } + + private function modify($value, $options = []) + { + return Modify::value($value)->toJson($options)->fetch(); + } + + public static function bourneJsonBourneProvider(): array + { + return [ + 'empty array' => [[], '[]'], + 'array' => [['book' => 'All The Places You\'ll Go'], '{"book":"All The Places You\'ll Go"}'], + 'string' => ['foo bar baz', '"foo bar baz"'], + 'null' => [null, 'null'], + 'collection' => [collect(['book' => 'All The Places You\'ll Go']), '{"book":"All The Places You\'ll Go"}'], + 'collection with JsonSerializables' => [ + collect([ + new class implements \JsonSerializable + { + public function jsonSerialize(): array + { + return ['book' => 'All The Places You\'ll Go']; + } + }, + new class implements \JsonSerializable + { + public function jsonSerialize(): array + { + return ['book' => 'Oh, The Places You\'ll Go']; + } + }, + ]), '[{"book":"All The Places You\'ll Go"},{"book":"Oh, The Places You\'ll Go"}]', + ], + 'JsonSerializable object' => [ + new class implements \JsonSerializable + { + public function jsonSerialize(): array + { + return ['book' => 'All The Places You\'ll Go']; + } + }, '{"book":"All The Places You\'ll Go"}', + ], + 'query builder' => [ + function () { + EntryFactory::collection('blog')->data(['title' => 'Post One'])->create(); + EntryFactory::collection('blog')->data(['title' => 'Post Two'])->create(); + + return Entry::query()->get(['title']); + }, '[{"title":"Post One"},{"title":"Post Two"}]', + ], + ]; + } +} From 4b7c50bb57052643f15bc6dcc60f6cbec1a1ad7b Mon Sep 17 00:00:00 2001 From: Jason Varga Date: Fri, 12 Apr 2024 16:07:10 -0400 Subject: [PATCH 4/4] prevent infinite recursion when values or data methods arent provided when augmentedArrayData is not overridden --- src/Data/HasAugmentedData.php | 10 +++++++++- tests/Data/AugmentedCollectionTest.php | 23 ++++++++++++++--------- 2 files changed, 23 insertions(+), 10 deletions(-) diff --git a/src/Data/HasAugmentedData.php b/src/Data/HasAugmentedData.php index d1ba21606b..4fb055ea97 100644 --- a/src/Data/HasAugmentedData.php +++ b/src/Data/HasAugmentedData.php @@ -15,6 +15,14 @@ public function newAugmentedInstance(): Augmented public function augmentedArrayData() { - return method_exists($this, 'values') ? $this->values() : $this->data(); + if (method_exists($this, 'values')) { + return $this->values(); + } + + if (method_exists($this, 'data')) { + return $this->data(); + } + + throw new \Exception('Augmentable object must have a values() or data() method, or override the augmentedArrayData() method.'); } } diff --git a/tests/Data/AugmentedCollectionTest.php b/tests/Data/AugmentedCollectionTest.php index c600791f0b..50271578bf 100644 --- a/tests/Data/AugmentedCollectionTest.php +++ b/tests/Data/AugmentedCollectionTest.php @@ -7,20 +7,15 @@ use Illuminate\Database\Query\Builder as LaravelQueryBuilder; use JsonSerializable; use Mockery as m; -use PHPUnit\Framework\TestCase; use Statamic\Contracts\Data\Augmentable; use Statamic\Contracts\Query\Builder as StatamicQueryBuilder; use Statamic\Data\AugmentedCollection; use Statamic\Data\HasAugmentedData; use Statamic\Fields\Value; +use Tests\TestCase; class AugmentedCollectionTest extends TestCase { - public function tearDown(): void - { - m::close(); - } - /** @test */ public function it_calls_toArray_on_each_item() { @@ -147,7 +142,7 @@ public function it_json_serializes() new TestArrayableObject, new TestJsonableObject, new TestJsonSerializeObject, - $augmentable = new TestAugmentableObject, + $augmentable = new TestAugmentableObject(['foo' => 'bar']), 'baz', $value, ]); @@ -156,7 +151,7 @@ public function it_json_serializes() ['foo' => 'bar'], ['foo' => 'bar'], ['foo' => 'bar'], - $augmentable, + ['foo' => 'bar'], 'baz', 'value json serialized', ], $c->jsonSerialize()); @@ -172,7 +167,7 @@ public function augmentables_get_shallow_augmented_when_json_serializing_with_fl new TestArrayableObject, new TestJsonableObject, new TestJsonSerializeObject, - new TestAugmentableObject, + new TestAugmentableObject(['foo' => 'bar']), 'baz', $value, ]); @@ -217,6 +212,16 @@ class TestAugmentableObject implements Augmentable { use HasAugmentedData; + public function __construct(private $data) + { + + } + + public function augmentedArrayData() + { + return $this->data; + } + public function toShallowAugmentedArray() { return ['shallow augmented augmentable'];