Passed
Push — master ( 8bd912...d93388 )
by Alan
06:58 queued 02:20
created

src/Hydra/Serializer/CollectionNormalizer.php (1 issue)

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