Skip to content

Commit 9ce38f3

Browse files
committed
Include extended JsonLD data if DTO outputs original object
In `ApiPlatform\Core\DataTransformer\DataTransformerInterface` there is a comment that states that DTOs should be allowed to return the same original object if no transformation is done. This resulted in missing LD data. (No @id, @context etc.). ```php /** * Transforms the given object to something else, usually another object. * This must return the original object if no transformation has been done. * * @param object $object * * @return object */ public function transform($object, string $to, array $context = []); ``` This update checks if the output class is the same as the original, and if so populated the extended metadata in the JsonLd\ItemNormalizer as it would not be added using the JsonLd\ObjectNormalizer
1 parent 3c49506 commit 9ce38f3

File tree

3 files changed

+22
-8
lines changed

3 files changed

+22
-8
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
* GraphQL: Do not allow empty cursor values on `before` or `after`
66
* Filter: Improve the RangeFilter query in case the values are equals using the between operator
7+
* Bug fix: Allow Data Transformers to return the original class if no transformation has been made, or the transformation was to the original object
78

89
## 2.5.4
910

src/JsonLd/Serializer/ItemNormalizer.php

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,9 @@ public function supportsNormalization($data, $format = null): bool
6565
*/
6666
public function normalize($object, $format = null, array $context = [])
6767
{
68-
if (null !== $this->getOutputClass($this->getObjectClass($object), $context)) {
68+
$objectClass = $this->getObjectClass($object);
69+
$outputClass = $this->getOutputClass($objectClass, $context);
70+
if (null !== $outputClass && !isset($context[self::IS_TRANSFORMED_TO_SAME_CLASS_CONTEXT_KEY])) {
6971
return parent::normalize($object, $format, $context);
7072
}
7173

src/Serializer/AbstractItemNormalizer.php

Lines changed: 18 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,8 @@ abstract class AbstractItemNormalizer extends AbstractObjectNormalizer
5151
use ContextTrait;
5252
use InputOutputMetadataTrait;
5353

54+
public const IS_TRANSFORMED_TO_SAME_CLASS_CONTEXT_KEY = 'is_transformed_to_same_class';
55+
5456
protected $propertyNameCollectionFactory;
5557
protected $propertyMetadataFactory;
5658
protected $iriConverter;
@@ -112,18 +114,24 @@ public function hasCacheableSupportsMethod(): bool
112114
*/
113115
public function normalize($object, $format = null, array $context = [])
114116
{
115-
if ($object !== $transformed = $this->transformOutput($object, $context)) {
117+
if (!($isTransformed = isset($context[self::IS_TRANSFORMED_TO_SAME_CLASS_CONTEXT_KEY])) && $outputClass = $this->getOutputClass($this->getObjectClass($object), $context)) {
116118
if (!$this->serializer instanceof NormalizerInterface) {
117119
throw new LogicException('Cannot normalize the output because the injected serializer is not a normalizer');
118120
}
119121

120-
$context['api_normalize'] = true;
121-
$context['api_resource'] = $object;
122-
unset($context['output']);
123-
unset($context['resource_class']);
122+
if ($object !== $transformed = $this->transformOutput($object, $context, $outputClass)) {
123+
$context['api_normalize'] = true;
124+
$context['api_resource'] = $object;
125+
unset($context['output'], $context['resource_class']);
126+
} else {
127+
$context[self::IS_TRANSFORMED_TO_SAME_CLASS_CONTEXT_KEY] = true;
128+
}
124129

125130
return $this->serializer->normalize($transformed, $format, $context);
126131
}
132+
if ($isTransformed) {
133+
unset($context[self::IS_TRANSFORMED_TO_SAME_CLASS_CONTEXT_KEY]);
134+
}
127135

128136
$resourceClass = $this->resourceClassResolver->getResourceClass($object, $context['resource_class'] ?? null);
129137
$context = $this->initContext($resourceClass, $context);
@@ -637,9 +645,12 @@ protected function getDataTransformer($data, string $to, array $context = []): ?
637645
* For a given resource, it returns an output representation if any
638646
* If not, the resource is returned.
639647
*/
640-
protected function transformOutput($object, array $context = [])
648+
protected function transformOutput($object, array $context = [], string $outputClass = null)
641649
{
642-
$outputClass = $this->getOutputClass($this->getObjectClass($object), $context);
650+
if (null === $outputClass) {
651+
$outputClass = $this->getOutputClass($this->getObjectClass($object), $context);
652+
}
653+
643654
if (null !== $outputClass && null !== $dataTransformer = $this->getDataTransformer($object, $outputClass, $context)) {
644655
return $dataTransformer->transform($object, $outputClass, $context);
645656
}

0 commit comments

Comments
 (0)