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

api-platform / core / 10014117656

19 Jul 2024 08:44PM UTC coverage: 7.856% (-56.3%) from 64.185%
10014117656

push

github

soyuka
Merge branch 'sf/remove-flag'

0 of 527 new or added lines in 83 files covered. (0.0%)

10505 existing lines in 362 files now uncovered.

12705 of 161727 relevant lines covered (7.86%)

26.85 hits per line

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

98.23
/src/Hydra/JsonSchema/SchemaFactory.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\Hydra\JsonSchema;
15

16
use ApiPlatform\JsonLd\ContextBuilder;
17
use ApiPlatform\JsonSchema\Schema;
18
use ApiPlatform\JsonSchema\SchemaFactoryAwareInterface;
19
use ApiPlatform\JsonSchema\SchemaFactoryInterface;
20
use ApiPlatform\Metadata\Operation;
21

22
/**
23
 * Decorator factory which adds Hydra properties to the JSON Schema document.
24
 *
25
 * @author Kévin Dunglas <dunglas@gmail.com>
26
 */
27
final class SchemaFactory implements SchemaFactoryInterface, SchemaFactoryAwareInterface
28
{
29
    private const BASE_PROP = [
30
        'type' => 'string',
31
    ];
32
    private const BASE_PROPS = [
33
        '@id' => self::BASE_PROP,
34
        '@type' => self::BASE_PROP,
35
    ];
36
    private const BASE_ROOT_PROPS = [
37
        '@context' => [
38
            'oneOf' => [
39
                ['type' => 'string'],
40
                [
41
                    'type' => 'object',
42
                    'properties' => [
43
                        '@vocab' => [
44
                            'type' => 'string',
45
                        ],
46
                        'hydra' => [
47
                            'type' => 'string',
48
                            'enum' => [ContextBuilder::HYDRA_NS],
49
                        ],
50
                    ],
51
                    'required' => ['@vocab', 'hydra'],
52
                    'additionalProperties' => true,
53
                ],
54
            ],
55
        ],
56
    ] + self::BASE_PROPS;
57

58
    public function __construct(private readonly SchemaFactoryInterface $schemaFactory)
59
    {
UNCOV
60
        if ($this->schemaFactory instanceof SchemaFactoryAwareInterface) {
2,243✔
UNCOV
61
            $this->schemaFactory->setSchemaFactory($this);
2,243✔
62
        }
63
    }
64

65
    /**
66
     * {@inheritdoc}
67
     */
68
    public function buildSchema(string $className, string $format = 'jsonld', string $type = Schema::TYPE_OUTPUT, ?Operation $operation = null, ?Schema $schema = null, ?array $serializerContext = null, bool $forceCollection = false): Schema
69
    {
UNCOV
70
        $schema = $this->schemaFactory->buildSchema($className, $format, $type, $operation, $schema, $serializerContext, $forceCollection);
174✔
UNCOV
71
        if ('jsonld' !== $format) {
174✔
UNCOV
72
            return $schema;
114✔
73
        }
74

UNCOV
75
        if (($key = $schema->getRootDefinitionKey() ?? $schema->getItemsDefinitionKey()) !== null) {
117✔
UNCOV
76
            $postfix = '.'.$type;
117✔
UNCOV
77
            $definitions = $schema->getDefinitions();
117✔
UNCOV
78
            $definitions[$key.$postfix] = $definitions[$key];
117✔
UNCOV
79
            unset($definitions[$key]);
117✔
80

UNCOV
81
            if (($schema['type'] ?? '') === 'array') {
117✔
UNCOV
82
                $schema['items']['$ref'] .= $postfix;
72✔
83
            } else {
UNCOV
84
                $schema['$ref'] .= $postfix;
114✔
85
            }
86
        }
87

UNCOV
88
        $definitions = $schema->getDefinitions();
117✔
UNCOV
89
        if ($key = $schema->getRootDefinitionKey()) {
117✔
UNCOV
90
            $definitions[$key]['properties'] = self::BASE_ROOT_PROPS + ($definitions[$key]['properties'] ?? []);
114✔
UNCOV
91
            if (Schema::TYPE_OUTPUT === $type) {
114✔
UNCOV
92
                foreach (array_keys(self::BASE_ROOT_PROPS) as $property) {
102✔
UNCOV
93
                    $definitions[$key]['required'] ??= [];
102✔
UNCOV
94
                    if (!\in_array($property, $definitions[$key]['required'], true)) {
102✔
UNCOV
95
                        $definitions[$key]['required'][] = $property;
102✔
96
                    }
97
                }
98
            }
99

UNCOV
100
            return $schema;
114✔
101
        }
UNCOV
102
        if ($key = $schema->getItemsDefinitionKey()) {
72✔
UNCOV
103
            $definitions[$key]['properties'] = self::BASE_PROPS + ($definitions[$key]['properties'] ?? []);
72✔
104
            if (Schema::TYPE_OUTPUT === $type) {
72✔
105
                foreach (array_keys(self::BASE_PROPS) as $property) {
72✔
UNCOV
106
                    $definitions[$key]['required'] ??= [];
72✔
UNCOV
107
                    if (!\in_array($property, $definitions[$key]['required'], true)) {
72✔
UNCOV
108
                        $definitions[$key]['required'][] = $property;
72✔
109
                    }
110
                }
111
            }
112
        }
113

UNCOV
114
        if (($schema['type'] ?? '') === 'array') {
72✔
115
            // hydra:collection
UNCOV
116
            $items = $schema['items'];
72✔
UNCOV
117
            unset($schema['items']);
72✔
118

UNCOV
119
            switch ($schema->getVersion()) {
72✔
120
                // JSON Schema + OpenAPI 3.1
UNCOV
121
                case Schema::VERSION_OPENAPI:
72✔
UNCOV
122
                case Schema::VERSION_JSON_SCHEMA:
15✔
UNCOV
123
                    $nullableStringDefinition = ['type' => ['string', 'null']];
72✔
UNCOV
124
                    break;
72✔
125
                    // Swagger
126
                default:
UNCOV
127
                    $nullableStringDefinition = ['type' => 'string'];
×
UNCOV
128
                    break;
×
129
            }
130

UNCOV
131
            $schema['type'] = 'object';
72✔
UNCOV
132
            $schema['properties'] = [
72✔
UNCOV
133
                'hydra:member' => [
72✔
UNCOV
134
                    'type' => 'array',
72✔
UNCOV
135
                    'items' => $items,
72✔
UNCOV
136
                ],
72✔
UNCOV
137
                'hydra:totalItems' => [
72✔
UNCOV
138
                    'type' => 'integer',
72✔
UNCOV
139
                    'minimum' => 0,
72✔
UNCOV
140
                ],
72✔
UNCOV
141
                'hydra:view' => [
72✔
UNCOV
142
                    'type' => 'object',
72✔
UNCOV
143
                    'properties' => [
72✔
UNCOV
144
                        '@id' => [
72✔
UNCOV
145
                            'type' => 'string',
72✔
UNCOV
146
                            'format' => 'iri-reference',
72✔
UNCOV
147
                        ],
72✔
UNCOV
148
                        '@type' => [
72✔
UNCOV
149
                            'type' => 'string',
72✔
UNCOV
150
                        ],
72✔
UNCOV
151
                        'hydra:first' => [
72✔
UNCOV
152
                            'type' => 'string',
72✔
UNCOV
153
                            'format' => 'iri-reference',
72✔
UNCOV
154
                        ],
72✔
UNCOV
155
                        'hydra:last' => [
72✔
UNCOV
156
                            'type' => 'string',
72✔
UNCOV
157
                            'format' => 'iri-reference',
72✔
UNCOV
158
                        ],
72✔
UNCOV
159
                        'hydra:previous' => [
72✔
UNCOV
160
                            'type' => 'string',
72✔
UNCOV
161
                            'format' => 'iri-reference',
72✔
UNCOV
162
                        ],
72✔
UNCOV
163
                        'hydra:next' => [
72✔
UNCOV
164
                            'type' => 'string',
72✔
UNCOV
165
                            'format' => 'iri-reference',
72✔
UNCOV
166
                        ],
72✔
UNCOV
167
                    ],
72✔
UNCOV
168
                    'example' => [
72✔
UNCOV
169
                        '@id' => 'string',
72✔
UNCOV
170
                        'type' => 'string',
72✔
UNCOV
171
                        'hydra:first' => 'string',
72✔
UNCOV
172
                        'hydra:last' => 'string',
72✔
UNCOV
173
                        'hydra:previous' => 'string',
72✔
UNCOV
174
                        'hydra:next' => 'string',
72✔
UNCOV
175
                    ],
72✔
UNCOV
176
                ],
72✔
UNCOV
177
                'hydra:search' => [
72✔
UNCOV
178
                    'type' => 'object',
72✔
UNCOV
179
                    'properties' => [
72✔
UNCOV
180
                        '@type' => ['type' => 'string'],
72✔
UNCOV
181
                        'hydra:template' => ['type' => 'string'],
72✔
UNCOV
182
                        'hydra:variableRepresentation' => ['type' => 'string'],
72✔
UNCOV
183
                        'hydra:mapping' => [
72✔
UNCOV
184
                            'type' => 'array',
72✔
UNCOV
185
                            'items' => [
72✔
UNCOV
186
                                'type' => 'object',
72✔
UNCOV
187
                                'properties' => [
72✔
UNCOV
188
                                    '@type' => ['type' => 'string'],
72✔
UNCOV
189
                                    'variable' => ['type' => 'string'],
72✔
UNCOV
190
                                    'property' => $nullableStringDefinition,
72✔
UNCOV
191
                                    'required' => ['type' => 'boolean'],
72✔
UNCOV
192
                                ],
72✔
UNCOV
193
                            ],
72✔
UNCOV
194
                        ],
72✔
UNCOV
195
                    ],
72✔
UNCOV
196
                ],
72✔
UNCOV
197
            ];
72✔
UNCOV
198
            $schema['required'] = [
72✔
UNCOV
199
                'hydra:member',
72✔
UNCOV
200
            ];
72✔
201

UNCOV
202
            return $schema;
72✔
203
        }
204

UNCOV
205
        return $schema;
36✔
206
    }
207

208
    public function setSchemaFactory(SchemaFactoryInterface $schemaFactory): void
209
    {
UNCOV
210
        if ($this->schemaFactory instanceof SchemaFactoryAwareInterface) {
2,243✔
UNCOV
211
            $this->schemaFactory->setSchemaFactory($schemaFactory);
2,243✔
212
        }
213
    }
214
}
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