Passed
Push — 2.3 ( 6a30bd...80ff05 )
by Kévin
05:10 queued 01:39
created

CollectionNormalizer::normalize()   C

Complexity

Conditions 12
Paths 15

Size

Total Lines 41
Code Lines 25

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 25
dl 0
loc 41
rs 6.9666
c 0
b 0
f 0
cc 12
nc 15
nop 3

How to fix   Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

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\Hydra\Serializer;
15
16
use ApiPlatform\Core\Api\IriConverterInterface;
17
use ApiPlatform\Core\Api\OperationType;
18
use ApiPlatform\Core\Api\ResourceClassResolverInterface;
19
use ApiPlatform\Core\DataProvider\PaginatorInterface;
20
use ApiPlatform\Core\DataProvider\PartialPaginatorInterface;
21
use ApiPlatform\Core\Exception\InvalidArgumentException;
22
use ApiPlatform\Core\JsonLd\ContextBuilderInterface;
23
use ApiPlatform\Core\JsonLd\Serializer\JsonLdContextTrait;
24
use ApiPlatform\Core\Serializer\ContextTrait;
25
use Symfony\Component\Serializer\Normalizer\CacheableSupportsMethodInterface;
26
use Symfony\Component\Serializer\Normalizer\NormalizerAwareInterface;
27
use Symfony\Component\Serializer\Normalizer\NormalizerAwareTrait;
28
use Symfony\Component\Serializer\Normalizer\NormalizerInterface;
29
30
/**
31
 * This normalizer handles collections.
32
 *
33
 * @author Kevin Dunglas <[email protected]>
34
 * @author Samuel ROZE <[email protected]>
35
 */
36
final class CollectionNormalizer implements NormalizerInterface, NormalizerAwareInterface, CacheableSupportsMethodInterface
37
{
38
    use ContextTrait;
39
    use JsonLdContextTrait;
40
    use NormalizerAwareTrait;
41
42
    const FORMAT = 'jsonld';
43
44
    private $contextBuilder;
45
    private $resourceClassResolver;
46
    private $iriConverter;
47
48
    public function __construct(ContextBuilderInterface $contextBuilder, ResourceClassResolverInterface $resourceClassResolver, IriConverterInterface $iriConverter)
49
    {
50
        $this->contextBuilder = $contextBuilder;
51
        $this->resourceClassResolver = $resourceClassResolver;
52
        $this->iriConverter = $iriConverter;
53
    }
54
55
    /**
56
     * {@inheritdoc}
57
     */
58
    public function supportsNormalization($data, $format = null)
59
    {
60
        return self::FORMAT === $format && is_iterable($data);
61
    }
62
63
    /**
64
     * {@inheritdoc}
65
     */
66
    public function normalize($object, $format = null, array $context = [])
67
    {
68
        if (isset($context['api_sub_level'])) {
69
            return $this->normalizeRawCollection($object, $format, $context);
70
        }
71
72
        try {
73
            $resourceClass = $this->resourceClassResolver->getResourceClass($object, $context['resource_class'] ?? null, true);
74
        } catch (InvalidArgumentException $e) {
75
            if (!isset($context['resource_class'])) {
76
                return $this->normalizeRawCollection($object, $format, $context);
77
            }
78
79
            throw $e;
80
        }
81
        $data = $this->addJsonLdContext($this->contextBuilder, $resourceClass, $context);
82
        $context = $this->initContext($resourceClass, $context);
83
84
        if (isset($context['operation_type']) && OperationType::SUBRESOURCE === $context['operation_type']) {
85
            $data['@id'] = $this->iriConverter->getSubresourceIriFromResourceClass($resourceClass, $context);
86
        } else {
87
            $data['@id'] = $this->iriConverter->getIriFromResourceClass($resourceClass);
88
        }
89
90
        $data['@type'] = 'hydra:Collection';
91
92
        $data['hydra:member'] = [];
93
        foreach ($object as $obj) {
94
            $data['hydra:member'][] = $this->normalizer->normalize($obj, $format, $context);
95
        }
96
97
        $paginated = null;
98
        if (
99
            \is_array($object) ||
100
            ($paginated = $object instanceof PaginatorInterface) ||
101
            $object instanceof \Countable && !$object instanceof PartialPaginatorInterface
102
        ) {
103
            $data['hydra:totalItems'] = $paginated ? $object->getTotalItems() : \count($object);
0 ignored issues
show
introduced by
$paginated is of type null, thus it always evaluated to false.
Loading history...
104
        }
105
106
        return $data;
107
    }
108
109
    /**
110
     * {@inheritdoc}
111
     */
112
    public function hasCacheableSupportsMethod(): bool
113
    {
114
        return true;
115
    }
116
117
    /**
118
     * Normalizes a raw collection (not API resources).
119
     */
120
    private function normalizeRawCollection($object, $format = null, array $context = []): array
121
    {
122
        $data = [];
123
        foreach ($object as $index => $obj) {
124
            $data[$index] = $this->normalizer->normalize($obj, $format, $context);
125
        }
126
127
        return $data;
128
    }
129
}
130