1 | <?php |
||
2 | |||
3 | /* |
||
4 | * This file is part of the API Platform project. |
||
5 | * |
||
6 | * (c) Kévin Dunglas <[email protected]> |
||
7 | * |
||
8 | * For the full copyright and license information, please view the LICENSE |
||
9 | * file that was distributed with this source code. |
||
10 | */ |
||
11 | |||
12 | declare(strict_types=1); |
||
13 | |||
14 | namespace ApiPlatform\Core\JsonApi\Serializer; |
||
15 | |||
16 | use ApiPlatform\Core\Api\IriConverterInterface; |
||
17 | use ApiPlatform\Core\Api\ResourceClassResolverInterface; |
||
18 | use ApiPlatform\Core\Metadata\Resource\Factory\ResourceMetadataFactoryInterface; |
||
19 | use ApiPlatform\Core\Util\ClassInfoTrait; |
||
20 | use Symfony\Component\Serializer\Normalizer\CacheableSupportsMethodInterface; |
||
21 | use Symfony\Component\Serializer\Normalizer\NormalizerInterface; |
||
22 | |||
23 | /** |
||
24 | * Decorates the output with JSON API metadata when appropriate, but otherwise |
||
25 | * just passes through to the decorated normalizer. |
||
26 | */ |
||
27 | final class ObjectNormalizer implements NormalizerInterface, CacheableSupportsMethodInterface |
||
28 | { |
||
29 | use ClassInfoTrait; |
||
30 | |||
31 | public const FORMAT = 'jsonapi'; |
||
32 | |||
33 | private $decorated; |
||
34 | private $iriConverter; |
||
35 | private $resourceClassResolver; |
||
36 | private $resourceMetadataFactory; |
||
37 | |||
38 | public function __construct(NormalizerInterface $decorated, IriConverterInterface $iriConverter, ResourceClassResolverInterface $resourceClassResolver, ResourceMetadataFactoryInterface $resourceMetadataFactory) |
||
39 | { |
||
40 | $this->decorated = $decorated; |
||
41 | $this->iriConverter = $iriConverter; |
||
42 | $this->resourceClassResolver = $resourceClassResolver; |
||
43 | $this->resourceMetadataFactory = $resourceMetadataFactory; |
||
44 | } |
||
45 | |||
46 | /** |
||
47 | * {@inheritdoc} |
||
48 | */ |
||
49 | public function supportsNormalization($data, $format = null, array $context = []): bool |
||
50 | { |
||
51 | return self::FORMAT === $format && $this->decorated->supportsNormalization($data, $format, $context); |
||
52 | } |
||
53 | |||
54 | /** |
||
55 | * {@inheritdoc} |
||
56 | */ |
||
57 | public function hasCacheableSupportsMethod(): bool |
||
58 | { |
||
59 | return $this->decorated instanceof CacheableSupportsMethodInterface && $this->decorated->hasCacheableSupportsMethod(); |
||
60 | } |
||
61 | |||
62 | /** |
||
63 | * {@inheritdoc} |
||
64 | */ |
||
65 | public function normalize($object, $format = null, array $context = []) |
||
66 | { |
||
67 | if (isset($context['api_resource'])) { |
||
68 | $originalResource = $context['api_resource']; |
||
69 | unset($context['api_resource']); |
||
70 | } |
||
71 | |||
72 | $data = $this->decorated->normalize($object, $format, $context); |
||
73 | if (!\is_array($data) || isset($context['api_attribute'])) { |
||
74 | return $data; |
||
75 | } |
||
76 | |||
77 | if (isset($originalResource)) { |
||
78 | $resourceClass = $this->resourceClassResolver->getResourceClass($originalResource); |
||
79 | $resourceMetadata = $this->resourceMetadataFactory->create($resourceClass); |
||
80 | |||
81 | $resourceData = [ |
||
82 | 'id' => $this->iriConverter->getIriFromItem($originalResource), |
||
83 | 'type' => $resourceMetadata->getShortName(), |
||
84 | ]; |
||
85 | } else { |
||
86 | $resourceData = [ |
||
87 | 'id' => \function_exists('spl_object_id') ? spl_object_id($object) : spl_object_hash($object), |
||
88 | 'type' => (new \ReflectionClass($this->getObjectClass($object)))->getShortName(), |
||
89 | ]; |
||
90 | } |
||
91 | |||
92 | if ($data) { |
||
0 ignored issues
–
show
|
|||
93 | $resourceData['attributes'] = $data; |
||
94 | } |
||
95 | |||
96 | return ['data' => $resourceData]; |
||
97 | } |
||
98 | } |
||
99 |
This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.
Consider making the comparison explicit by using
empty(..)
or! empty(...)
instead.