• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

api-platform / core / 10729306835

05 Sep 2024 10:46PM UTC coverage: 7.655% (-0.01%) from 7.665%
10729306835

push

github

web-flow
Merge pull request #6586 from soyuka/merge-342

Merge 3.4

0 of 54 new or added lines in 12 files covered. (0.0%)

8760 existing lines in 277 files now uncovered.

12505 of 163357 relevant lines covered (7.66%)

22.84 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

95.65
/src/JsonLd/ContextBuilder.php
1
<?php
2

3
/*
4
 * This file is part of the API Platform project.
5
 *
6
 * (c) Kévin Dunglas <dunglas@gmail.com>
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\JsonLd;
15

16
use ApiPlatform\Metadata\Get;
17
use ApiPlatform\Metadata\HttpOperation;
18
use ApiPlatform\Metadata\IriConverterInterface;
19
use ApiPlatform\Metadata\Property\Factory\PropertyMetadataFactoryInterface;
20
use ApiPlatform\Metadata\Property\Factory\PropertyNameCollectionFactoryInterface;
21
use ApiPlatform\Metadata\Resource\Factory\ResourceMetadataCollectionFactoryInterface;
22
use ApiPlatform\Metadata\Resource\Factory\ResourceNameCollectionFactoryInterface;
23
use ApiPlatform\Metadata\UrlGeneratorInterface;
24
use ApiPlatform\Metadata\Util\ClassInfoTrait;
25
use Symfony\Component\Serializer\NameConverter\NameConverterInterface;
26

27
/**
28
 * {@inheritdoc}
29
 *
30
 * @author Kévin Dunglas <dunglas@gmail.com>
31
 */
32
final class ContextBuilder implements AnonymousContextBuilderInterface
33
{
34
    use ClassInfoTrait;
35

36
    public const FORMAT = 'jsonld';
37

38
    public function __construct(private readonly ResourceNameCollectionFactoryInterface $resourceNameCollectionFactory, private readonly ResourceMetadataCollectionFactoryInterface $resourceMetadataFactory, private readonly PropertyNameCollectionFactoryInterface $propertyNameCollectionFactory, private readonly PropertyMetadataFactoryInterface $propertyMetadataFactory, private readonly UrlGeneratorInterface $urlGenerator, private readonly ?IriConverterInterface $iriConverter = null, private readonly ?NameConverterInterface $nameConverter = null)
39
    {
UNCOV
40
    }
2,255✔
41

42
    /**
43
     * {@inheritdoc}
44
     */
45
    public function getBaseContext(int $referenceType = UrlGeneratorInterface::ABS_URL): array
46
    {
UNCOV
47
        return [
116✔
UNCOV
48
            '@vocab' => $this->urlGenerator->generate('api_doc', ['_format' => self::FORMAT], UrlGeneratorInterface::ABS_URL).'#',
116✔
UNCOV
49
            'hydra' => self::HYDRA_NS,
116✔
UNCOV
50
        ];
116✔
51
    }
52

53
    /**
54
     * {@inheritdoc}
55
     */
56
    public function getEntrypointContext(int $referenceType = UrlGeneratorInterface::ABS_PATH): array
57
    {
UNCOV
58
        $context = $this->getBaseContext($referenceType);
3✔
59

UNCOV
60
        foreach ($this->resourceNameCollectionFactory->create() as $resourceClass) {
3✔
UNCOV
61
            $shortName = $this->resourceMetadataFactory->create($resourceClass)[0]->getShortName();
3✔
UNCOV
62
            $resourceName = lcfirst($shortName);
3✔
63

UNCOV
64
            $context[$resourceName] = [
3✔
UNCOV
65
                '@id' => 'Entrypoint/'.$resourceName,
3✔
UNCOV
66
                '@type' => '@id',
3✔
UNCOV
67
            ];
3✔
68
        }
69

UNCOV
70
        return $context;
3✔
71
    }
72

73
    /**
74
     * {@inheritdoc}
75
     */
76
    public function getResourceContext(string $resourceClass, int $referenceType = UrlGeneratorInterface::ABS_PATH): array
77
    {
78
        /** @var HttpOperation $operation */
UNCOV
79
        $operation = $this->resourceMetadataFactory->create($resourceClass)->getOperation(null, false, true);
18✔
UNCOV
80
        if (null === $shortName = $operation->getShortName()) {
18✔
81
            return [];
×
82
        }
83

UNCOV
84
        if ($operation->getNormalizationContext()['iri_only'] ?? false) {
18✔
UNCOV
85
            $context = $this->getBaseContext($referenceType);
9✔
UNCOV
86
            $context['hydra:member']['@type'] = '@id';
9✔
87

UNCOV
88
            return $context;
9✔
89
        }
90

UNCOV
91
        return $this->getResourceContextWithShortname($resourceClass, $referenceType, $shortName, $operation);
9✔
92
    }
93

94
    /**
95
     * {@inheritdoc}
96
     */
97
    public function getResourceContextUri(string $resourceClass, ?int $referenceType = null): string
98
    {
UNCOV
99
        $resourceMetadata = $this->resourceMetadataFactory->create($resourceClass)[0];
1,256✔
UNCOV
100
        if (null === $referenceType) {
1,256✔
UNCOV
101
            $referenceType = $resourceMetadata->getUrlGenerationStrategy();
1,256✔
102
        }
103

UNCOV
104
        return $this->urlGenerator->generate('api_jsonld_context', ['shortName' => $resourceMetadata->getShortName()], $referenceType ?? UrlGeneratorInterface::ABS_PATH);
1,256✔
105
    }
106

107
    /**
108
     * {@inheritdoc}
109
     */
110
    public function getAnonymousResourceContext(object $object, array $context = [], int $referenceType = UrlGeneratorInterface::ABS_PATH): array
111
    {
UNCOV
112
        $outputClass = $this->getObjectClass($object);
95✔
UNCOV
113
        $operation = $context['operation'] ?? new Get(shortName: (new \ReflectionClass($outputClass))->getShortName());
95✔
UNCOV
114
        $shortName = $operation->getShortName();
95✔
115

UNCOV
116
        $jsonLdContext = [
95✔
UNCOV
117
            '@context' => $this->getResourceContextWithShortname(
95✔
UNCOV
118
                $outputClass,
95✔
UNCOV
119
                $referenceType,
95✔
UNCOV
120
                $shortName
95✔
UNCOV
121
            ),
95✔
UNCOV
122
            '@type' => $shortName,
95✔
UNCOV
123
        ];
95✔
124

UNCOV
125
        if (isset($context['iri'])) {
95✔
126
            $jsonLdContext['@id'] = $context['iri'];
×
UNCOV
127
        } elseif (true === ($context['gen_id'] ?? true) && $this->iriConverter) {
95✔
UNCOV
128
            $jsonLdContext['@id'] = $this->iriConverter->getIriFromResource($object);
91✔
129
        }
130

UNCOV
131
        if ($context['has_context'] ?? false) {
95✔
UNCOV
132
            unset($jsonLdContext['@context']);
80✔
133
        }
134

135
        // here the object can be different from the resource given by the $context['api_resource'] value
UNCOV
136
        if (isset($context['api_resource'])) {
95✔
137
            $jsonLdContext['@type'] = $this->resourceMetadataFactory->create($this->getObjectClass($context['api_resource']))[0]->getShortName();
×
138
        }
139

UNCOV
140
        return $jsonLdContext;
95✔
141
    }
142

143
    private function getResourceContextWithShortname(string $resourceClass, int $referenceType, string $shortName, ?HttpOperation $operation = null): array
144
    {
UNCOV
145
        $context = $this->getBaseContext($referenceType);
104✔
UNCOV
146
        $propertyContext = $operation ? ['normalization_groups' => $operation->getNormalizationContext()['groups'] ?? null, 'denormalization_groups' => $operation->getDenormalizationContext()['groups'] ?? null] : ['normalization_groups' => [], 'denormalization_groups' => []];
104✔
147

UNCOV
148
        foreach ($this->propertyNameCollectionFactory->create($resourceClass) as $propertyName) {
104✔
UNCOV
149
            $propertyMetadata = $this->propertyMetadataFactory->create($resourceClass, $propertyName, $propertyContext);
103✔
150

UNCOV
151
            if ($propertyMetadata->isIdentifier() && true !== $propertyMetadata->isWritable()) {
103✔
UNCOV
152
                continue;
35✔
153
            }
154

UNCOV
155
            $convertedName = $this->nameConverter ? $this->nameConverter->normalize($propertyName, $resourceClass, self::FORMAT) : $propertyName;
103✔
UNCOV
156
            $jsonldContext = $propertyMetadata->getJsonldContext() ?? [];
103✔
157

UNCOV
158
            if ($id = $propertyMetadata->getIris()) {
103✔
UNCOV
159
                $id = 1 === (is_countable($id) ? \count($id) : 0) ? $id[0] : $id;
3✔
160
            }
161

UNCOV
162
            if (!$id) {
103✔
UNCOV
163
                $id = \sprintf('%s/%s', $shortName, $convertedName);
103✔
164
            }
165

UNCOV
166
            if (false === $propertyMetadata->isReadableLink()) {
103✔
UNCOV
167
                $jsonldContext += [
3✔
UNCOV
168
                    '@id' => $id,
3✔
UNCOV
169
                    '@type' => '@id',
3✔
UNCOV
170
                ];
3✔
171
            }
172

UNCOV
173
            if (empty($jsonldContext)) {
103✔
UNCOV
174
                $context[$convertedName] = $id;
100✔
175
            } else {
UNCOV
176
                $context[$convertedName] = $jsonldContext + [
6✔
UNCOV
177
                    '@id' => $id,
6✔
UNCOV
178
                ];
6✔
179
            }
180
        }
181

UNCOV
182
        return $context;
104✔
183
    }
184
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc