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

api-platform / core / 15133993414

20 May 2025 09:30AM UTC coverage: 26.313% (-1.2%) from 27.493%
15133993414

Pull #7161

github

web-flow
Merge e2c03d45f into 5459ba375
Pull Request #7161: fix(metadata): infer parameter string type from schema

0 of 2 new or added lines in 1 file covered. (0.0%)

11019 existing lines in 363 files now uncovered.

12898 of 49018 relevant lines covered (26.31%)

34.33 hits per line

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

97.96
/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\JsonLd\Serializer\HydraPrefixTrait;
18
use ApiPlatform\JsonSchema\Schema;
19
use ApiPlatform\JsonSchema\SchemaFactoryAwareInterface;
20
use ApiPlatform\JsonSchema\SchemaFactoryInterface;
21
use ApiPlatform\Metadata\Operation;
22

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

62
    public function __construct(private readonly SchemaFactoryInterface $schemaFactory, private readonly array $defaultContext = [])
63
    {
UNCOV
64
        if ($this->schemaFactory instanceof SchemaFactoryAwareInterface) {
828✔
UNCOV
65
            $this->schemaFactory->setSchemaFactory($this);
828✔
66
        }
67
    }
68

69
    /**
70
     * {@inheritdoc}
71
     */
72
    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
73
    {
UNCOV
74
        $schema = $this->schemaFactory->buildSchema($className, $format, $type, $operation, $schema, $serializerContext, $forceCollection);
65✔
UNCOV
75
        if ('jsonld' !== $format) {
65✔
UNCOV
76
            return $schema;
41✔
77
        }
78

UNCOV
79
        if ('input' === $type) {
46✔
UNCOV
80
            return $schema;
24✔
81
        }
82

UNCOV
83
        $definitions = $schema->getDefinitions();
42✔
UNCOV
84
        if ($key = $schema->getRootDefinitionKey()) {
42✔
UNCOV
85
            $definitions[$key]['properties'] = self::BASE_ROOT_PROPS + ($definitions[$key]['properties'] ?? []);
39✔
86

UNCOV
87
            return $schema;
39✔
88
        }
UNCOV
89
        if ($key = $schema->getItemsDefinitionKey()) {
28✔
UNCOV
90
            $definitions[$key]['properties'] = self::BASE_PROPS + ($definitions[$key]['properties'] ?? []);
28✔
91
        }
92

UNCOV
93
        if (($schema['type'] ?? '') === 'array') {
28✔
94
            // hydra:collection
UNCOV
95
            $items = $schema['items'];
28✔
UNCOV
96
            unset($schema['items']);
28✔
97

UNCOV
98
            switch ($schema->getVersion()) {
28✔
99
                // JSON Schema + OpenAPI 3.1
UNCOV
100
                case Schema::VERSION_OPENAPI:
28✔
UNCOV
101
                case Schema::VERSION_JSON_SCHEMA:
6✔
UNCOV
102
                    $nullableStringDefinition = ['type' => ['string', 'null']];
28✔
UNCOV
103
                    break;
28✔
104
                    // Swagger
105
                default:
106
                    $nullableStringDefinition = ['type' => 'string'];
×
107
                    break;
×
108
            }
109

UNCOV
110
            $hydraPrefix = $this->getHydraPrefix(($serializerContext ?? []) + $this->defaultContext);
28✔
UNCOV
111
            $schema['type'] = 'object';
28✔
UNCOV
112
            $schema['properties'] = [
28✔
UNCOV
113
                $hydraPrefix.'member' => [
28✔
UNCOV
114
                    'type' => 'array',
28✔
UNCOV
115
                    'items' => $items,
28✔
UNCOV
116
                ],
28✔
UNCOV
117
                $hydraPrefix.'totalItems' => [
28✔
UNCOV
118
                    'type' => 'integer',
28✔
UNCOV
119
                    'minimum' => 0,
28✔
UNCOV
120
                ],
28✔
UNCOV
121
                $hydraPrefix.'view' => [
28✔
UNCOV
122
                    'type' => 'object',
28✔
UNCOV
123
                    'properties' => [
28✔
UNCOV
124
                        '@id' => [
28✔
UNCOV
125
                            'type' => 'string',
28✔
UNCOV
126
                            'format' => 'iri-reference',
28✔
UNCOV
127
                        ],
28✔
UNCOV
128
                        '@type' => [
28✔
UNCOV
129
                            'type' => 'string',
28✔
UNCOV
130
                        ],
28✔
UNCOV
131
                        $hydraPrefix.'first' => [
28✔
UNCOV
132
                            'type' => 'string',
28✔
UNCOV
133
                            'format' => 'iri-reference',
28✔
UNCOV
134
                        ],
28✔
UNCOV
135
                        $hydraPrefix.'last' => [
28✔
UNCOV
136
                            'type' => 'string',
28✔
UNCOV
137
                            'format' => 'iri-reference',
28✔
UNCOV
138
                        ],
28✔
UNCOV
139
                        $hydraPrefix.'previous' => [
28✔
UNCOV
140
                            'type' => 'string',
28✔
UNCOV
141
                            'format' => 'iri-reference',
28✔
UNCOV
142
                        ],
28✔
UNCOV
143
                        $hydraPrefix.'next' => [
28✔
UNCOV
144
                            'type' => 'string',
28✔
UNCOV
145
                            'format' => 'iri-reference',
28✔
UNCOV
146
                        ],
28✔
UNCOV
147
                    ],
28✔
UNCOV
148
                    'example' => [
28✔
UNCOV
149
                        '@id' => 'string',
28✔
UNCOV
150
                        'type' => 'string',
28✔
UNCOV
151
                        $hydraPrefix.'first' => 'string',
28✔
UNCOV
152
                        $hydraPrefix.'last' => 'string',
28✔
UNCOV
153
                        $hydraPrefix.'previous' => 'string',
28✔
UNCOV
154
                        $hydraPrefix.'next' => 'string',
28✔
UNCOV
155
                    ],
28✔
UNCOV
156
                ],
28✔
UNCOV
157
                $hydraPrefix.'search' => [
28✔
UNCOV
158
                    'type' => 'object',
28✔
UNCOV
159
                    'properties' => [
28✔
UNCOV
160
                        '@type' => ['type' => 'string'],
28✔
UNCOV
161
                        $hydraPrefix.'template' => ['type' => 'string'],
28✔
UNCOV
162
                        $hydraPrefix.'variableRepresentation' => ['type' => 'string'],
28✔
UNCOV
163
                        $hydraPrefix.'mapping' => [
28✔
UNCOV
164
                            'type' => 'array',
28✔
UNCOV
165
                            'items' => [
28✔
UNCOV
166
                                'type' => 'object',
28✔
UNCOV
167
                                'properties' => [
28✔
UNCOV
168
                                    '@type' => ['type' => 'string'],
28✔
UNCOV
169
                                    'variable' => ['type' => 'string'],
28✔
UNCOV
170
                                    'property' => $nullableStringDefinition,
28✔
UNCOV
171
                                    'required' => ['type' => 'boolean'],
28✔
UNCOV
172
                                ],
28✔
UNCOV
173
                            ],
28✔
UNCOV
174
                        ],
28✔
UNCOV
175
                    ],
28✔
UNCOV
176
                ],
28✔
UNCOV
177
            ];
28✔
UNCOV
178
            $schema['required'] = [
28✔
UNCOV
179
                $hydraPrefix.'member',
28✔
UNCOV
180
            ];
28✔
181

UNCOV
182
            return $schema;
28✔
183
        }
184

185
        return $schema;
12✔
186
    }
187

188
    public function setSchemaFactory(SchemaFactoryInterface $schemaFactory): void
189
    {
UNCOV
190
        if ($this->schemaFactory instanceof SchemaFactoryAwareInterface) {
828✔
UNCOV
191
            $this->schemaFactory->setSchemaFactory($schemaFactory);
828✔
192
        }
193
    }
194
}
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

© 2025 Coveralls, Inc