Skip to content

Commit 6a6b9ad

Browse files
committed
[JsonStreamer] Allow to access current object when writing
1 parent 79cd71d commit 6a6b9ad

File tree

4 files changed

+42
-5
lines changed

4 files changed

+42
-5
lines changed

src/Symfony/Component/JsonStreamer/CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ CHANGELOG
55
---
66

77
* Remove `nikic/php-parser` dependency
8+
* Add `_current_object` to the context passed to value transformers during write operations
89

910
7.3
1011
---

src/Symfony/Component/JsonStreamer/Tests/Fixtures/stream_writer/object_with_value_transformer.php

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,13 @@
66
return static function (mixed $data, \Psr\Container\ContainerInterface $valueTransformers, array $options): \Traversable {
77
try {
88
yield '{"id":';
9-
yield \json_encode($valueTransformers->get('Symfony\Component\JsonStreamer\Tests\Fixtures\ValueTransformer\DoubleIntAndCastToStringValueTransformer')->transform($data->id, $options), \JSON_THROW_ON_ERROR, 511);
9+
yield \json_encode($valueTransformers->get('Symfony\Component\JsonStreamer\Tests\Fixtures\ValueTransformer\DoubleIntAndCastToStringValueTransformer')->transform($data->id, $options + ['_current_object' => $data]), \JSON_THROW_ON_ERROR, 511);
1010
yield ',"active":';
11-
yield \json_encode($valueTransformers->get('Symfony\Component\JsonStreamer\Tests\Fixtures\ValueTransformer\BooleanToStringValueTransformer')->transform($data->active, $options), \JSON_THROW_ON_ERROR, 511);
11+
yield \json_encode($valueTransformers->get('Symfony\Component\JsonStreamer\Tests\Fixtures\ValueTransformer\BooleanToStringValueTransformer')->transform($data->active, $options + ['_current_object' => $data]), \JSON_THROW_ON_ERROR, 511);
1212
yield ',"name":';
1313
yield \json_encode(strtolower($data->name), \JSON_THROW_ON_ERROR, 511);
1414
yield ',"range":';
15-
yield \json_encode(Symfony\Component\JsonStreamer\Tests\Fixtures\Model\DummyWithValueTransformerAttributes::concatRange($data->range, $options), \JSON_THROW_ON_ERROR, 511);
15+
yield \json_encode(Symfony\Component\JsonStreamer\Tests\Fixtures\Model\DummyWithValueTransformerAttributes::concatRange($data->range, $options + ['_current_object' => $data]), \JSON_THROW_ON_ERROR, 511);
1616
yield '}';
1717
} catch (\JsonException $e) {
1818
throw new \Symfony\Component\JsonStreamer\Exception\NotEncodableValueException($e->getMessage(), 0, $e);

src/Symfony/Component/JsonStreamer/Tests/JsonStreamWriterTest.php

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -157,6 +157,42 @@ public function testWriteObjectWithValueTransformer()
157157
);
158158
}
159159

160+
public function testValueTransformerHasAccessToCurrentObject()
161+
{
162+
$dummy = new DummyWithValueTransformerAttributes();
163+
$dummy->id = 10;
164+
$dummy->active = true;
165+
166+
$this->assertWritten(
167+
'{"id":"20","active":"true","name":"dummy","range":"10..20"}',
168+
$dummy,
169+
Type::object(DummyWithValueTransformerAttributes::class),
170+
options: ['scale' => 1],
171+
valueTransformers: [
172+
BooleanToStringValueTransformer::class => new class($this) implements ValueTransformerInterface {
173+
public function __construct(
174+
private JsonStreamWriterTest $test,
175+
) {
176+
}
177+
178+
public function transform(mixed $value, array $options = []): mixed
179+
{
180+
$this->test->assertArrayHasKey('_current_object', $options);
181+
$this->test->assertInstanceof(DummyWithValueTransformerAttributes::class, $options['_current_object']);
182+
183+
return (new BooleanToStringValueTransformer())->transform($value, $options);
184+
}
185+
186+
public static function getStreamValueType(): Type
187+
{
188+
return BooleanToStringValueTransformer::getStreamValueType();
189+
}
190+
},
191+
DoubleIntAndCastToStringValueTransformer::class => new DoubleIntAndCastToStringValueTransformer(),
192+
],
193+
);
194+
}
195+
160196
public function testWriteObjectWithPhpDoc()
161197
{
162198
$dummy = new DummyWithPhpDoc();

src/Symfony/Component/JsonStreamer/Write/StreamWriterGenerator.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -138,7 +138,7 @@ private function createDataModel(Type $type, string $accessor, array $options =
138138
foreach ($propertyMetadata->getNativeToStreamValueTransformer() as $valueTransformer) {
139139
if (\is_string($valueTransformer)) {
140140
$valueTransformerServiceAccessor = "\$valueTransformers->get('$valueTransformer')";
141-
$propertyAccessor = "{$valueTransformerServiceAccessor}->transform($propertyAccessor, \$options)";
141+
$propertyAccessor = "{$valueTransformerServiceAccessor}->transform($propertyAccessor, \$options + ['_current_object' => $accessor])";
142142

143143
continue;
144144
}
@@ -152,7 +152,7 @@ private function createDataModel(Type $type, string $accessor, array $options =
152152
$functionName = !$functionReflection->getClosureCalledClass()
153153
? $functionReflection->getName()
154154
: \sprintf('%s::%s', $functionReflection->getClosureCalledClass()->getName(), $functionReflection->getName());
155-
$arguments = $functionReflection->isUserDefined() ? "$propertyAccessor, \$options" : $propertyAccessor;
155+
$arguments = $functionReflection->isUserDefined() ? "$propertyAccessor, \$options + ['_current_object' => $accessor]" : $propertyAccessor;
156156

157157
$propertyAccessor = "$functionName($arguments)";
158158
}

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy