Passed
Push — master ( ce7fff...9920f1 )
by Alan
04:04
created

ObjectNormalizer::normalize()   B

Complexity

Conditions 7
Paths 14

Size

Total Lines 32
Code Lines 19

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 7
eloc 19
c 1
b 0
f 0
nc 14
nop 3
dl 0
loc 32
rs 8.8333
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);
0 ignored issues
show
Unused Code introduced by
The call to Symfony\Component\Serial...supportsNormalization() has too many arguments starting with $context. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

51
        return self::FORMAT === $format && $this->decorated->/** @scrutinizer ignore-call */ supportsNormalization($data, $format, $context);

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress. Please note the @ignore annotation hint above.

Loading history...
52
    }
53
54
    /**
55
     * {@inheritdoc}
56
     */
57
    public function hasCacheableSupportsMethod(): bool
58
    {
59
        return $this->decorated instanceof CacheableSupportsMethodInterface && $this->decorated->hasCacheableSupportsMethod();
0 ignored issues
show
Bug introduced by
The method hasCacheableSupportsMethod() does not exist on Symfony\Component\Serial...zer\NormalizerInterface. It seems like you code against a sub-type of said class. However, the method does not exist in ApiPlatform\Core\GraphQl...HttpExceptionNormalizer or Symfony\Component\Serial...er\SerializerNormalizer or ApiPlatform\Core\GraphQl...ception\ErrorNormalizer or ApiPlatform\Core\Tests\F...DocumentationNormalizer or Symfony\Component\Serial...rmalizer\TestNormalizer or Symfony\Component\Serial...sonSerializerNormalizer or ApiPlatform\Core\GraphQl...tionExceptionNormalizer or Symfony\Component\Serial...wareNormalizerInterface or Symfony\Component\Serial...ectSerializerNormalizer or ApiPlatform\Core\GraphQl...timeExceptionNormalizer or Symfony\Component\Serializer\Serializer. Are you sure you never get one of those? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

59
        return $this->decorated instanceof CacheableSupportsMethodInterface && $this->decorated->/** @scrutinizer ignore-call */ hasCacheableSupportsMethod();
Loading history...
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
Bug Best Practice introduced by
The expression $data of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using ! empty($expr) instead to make it clear that you intend to check for an array without elements.

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.

Loading history...
93
            $resourceData['attributes'] = $data;
94
        }
95
96
        return ['data' => $resourceData];
97
    }
98
}
99