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

api-platform / core / 13203378522

07 Feb 2025 03:56PM UTC coverage: 8.501% (+0.7%) from 7.837%
13203378522

push

github

soyuka
Merge 4.1

111 of 490 new or added lines in 51 files covered. (22.65%)

5590 existing lines in 163 files now uncovered.

13345 of 156987 relevant lines covered (8.5%)

22.88 hits per line

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

0.0
/src/Metadata/Tests/Extractor/Adapter/XmlResourceAdapter.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\Metadata\Tests\Extractor\Adapter;
15

16
use ApiPlatform\Metadata\Tests\Extractor\ResourceMetadataCompatibilityTest;
17

18
/**
19
 * XML adapter for ResourceMetadataCompatibilityTest.
20
 *
21
 * @author Vincent Chalamon <vincentchalamon@gmail.com>
22
 */
23
final class XmlResourceAdapter implements ResourceAdapterInterface
24
{
25
    private const ATTRIBUTES = [
26
        'uriTemplate',
27
        'shortName',
28
        'description',
29
        'routePrefix',
30
        'stateless',
31
        'sunset',
32
        'class',
33
        'acceptPatch',
34
        'status',
35
        'host',
36
        'condition',
37
        'controller',
38
        'urlGenerationStrategy',
39
        'deprecationReason',
40
        'elasticsearch',
41
        'messenger',
42
        'input',
43
        'output',
44
        'fetchPartial',
45
        'forceEager',
46
        'paginationClientEnabled',
47
        'paginationClientItemsPerPage',
48
        'paginationClientPartial',
49
        'paginationEnabled',
50
        'paginationFetchJoinCollection',
51
        'paginationUseOutputWalkers',
52
        'paginationItemsPerPage',
53
        'paginationMaximumItemsPerPage',
54
        'paginationPartial',
55
        'paginationType',
56
        'processor',
57
        'provider',
58
        'security',
59
        'securityMessage',
60
        'securityPostDenormalize',
61
        'securityPostDenormalizeMessage',
62
        'securityPostValidation',
63
        'securityPostValidationMessage',
64
        'queryParameterValidationEnabled',
65
        'strictQueryParameterValidation',
66
        'hideHydraOperation',
67
        'stateOptions',
68
        'collectDenormalizationErrors',
69
        'links',
70
        'parameters',
71
    ];
72

73
    private const EXCLUDE = ['policy', 'middleware', 'rule'];
74

75
    /**
76
     * {@inheritdoc}
77
     */
78
    public function __invoke(string $resourceClass, array $parameters, array $fixtures): array
79
    {
UNCOV
80
        $xml = new \SimpleXMLElement(<<<XML_WRAP
×
81
<?xml version="1.0" encoding="UTF-8" ?>
82
<resources xmlns="https://api-platform.com/schema/metadata/resources-3.0"
83
           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
84
           xsi:schemaLocation="https://api-platform.com/schema/metadata/resources-3.0
85
           https://api-platform.com/schema/metadata/resources-3.0.xsd">
86
</resources>
UNCOV
87
XML_WRAP
×
88
        );
×
89

UNCOV
90
        foreach ($fixtures as $fixture) {
×
91
            $resource = $xml->addChild('resource');
×
92

93
            if (null === $fixture) {
×
UNCOV
94
                $resource->addAttribute('class', $resourceClass);
×
UNCOV
95
                continue;
×
96
            }
97

98
            $fixture['class'] = $resourceClass;
×
99
            foreach ($parameters as $parameter) {
×
100
                $parameterName = $parameter->getName();
×
UNCOV
101
                if (\in_array($parameterName, self::EXCLUDE, true)) {
×
UNCOV
102
                    continue;
×
103
                }
104

105
                $value = \array_key_exists($parameterName, $fixture) ? $fixture[$parameterName] : null;
×
106

UNCOV
107
                if ('compositeIdentifier' === $parameterName || 'provider' === $parameterName || 'processor' === $parameterName) {
×
UNCOV
108
                    continue;
×
109
                }
110

111
                if (method_exists($this, 'build'.ucfirst($parameterName))) {
×
UNCOV
112
                    $this->{'build'.ucfirst($parameterName)}($resource, $value);
×
UNCOV
113
                    continue;
×
114
                }
115

116
                if (\in_array($parameterName, self::ATTRIBUTES, true) && \is_scalar($value)) {
×
UNCOV
117
                    $resource->addAttribute($parameterName, $this->parse($value));
×
UNCOV
118
                    continue;
×
119
                }
120

UNCOV
121
                throw new \LogicException(\sprintf('Cannot adapt attribute or child "%s". Please add fixtures in '.ResourceMetadataCompatibilityTest::class.' and create a "%s" method in %s.', $parameterName, 'build'.ucfirst($parameterName), self::class));
×
122
            }
123
        }
124

UNCOV
125
        $filename = __DIR__.'/resources.xml';
×
126
        $xml->asXML($filename);
×
127

UNCOV
128
        return [$filename];
×
129
    }
130

131
    private function buildTypes(\SimpleXMLElement $resource, array $values): void
132
    {
133
        $node = $resource->addChild('types');
×
UNCOV
134
        foreach ($values as $value) {
×
UNCOV
135
            $node->addChild('type', $value);
×
136
        }
137
    }
138

139
    private function buildInputFormats(\SimpleXMLElement $resource, array $values): void
140
    {
UNCOV
141
        $this->buildFormats($resource, $values, 'inputFormats');
×
142
    }
143

144
    private function buildOutputFormats(\SimpleXMLElement $resource, array $values): void
145
    {
UNCOV
146
        $this->buildFormats($resource, $values, 'outputFormats');
×
147
    }
148

149
    private function buildUriVariables(\SimpleXMLElement $resource, array $values): void
150
    {
151
        $child = $resource->addChild('uriVariables');
×
152
        foreach ($values as $parameterName => $value) {
×
153
            $grandChild = $child->addChild('uriVariable');
×
154
            $grandChild->addAttribute('parameterName', $parameterName);
×
155
            if (!isset($value['fromClass'])) {
×
156
                $value['fromClass'] = $value[0];
×
UNCOV
157
                $value['fromProperty'] = $value[1];
×
158
                unset($value[0], $value[1]);
×
159
            }
UNCOV
160
            foreach ($value as $key => $data) {
×
UNCOV
161
                $grandChild->addAttribute($key, $this->parse($data));
×
162
            }
163
        }
164
    }
165

166
    private function buildDefaults(\SimpleXMLElement $resource, array $values): void
167
    {
UNCOV
168
        $this->buildValues($resource->addChild('defaults'), $values);
×
169
    }
170

171
    private function buildMercure(\SimpleXMLElement $resource, $values): void
172
    {
173
        $child = $resource->addChild('mercure');
×
174
        if (\is_array($values)) {
×
175
            foreach ($values as $key => $value) {
×
UNCOV
176
                if (\is_string($key)) {
×
UNCOV
177
                    $child->addAttribute($key, $this->parse($value));
×
178
                }
179
            }
180
        }
181
    }
182

183
    private function buildRequirements(\SimpleXMLElement $resource, array $values): void
184
    {
185
        $node = $resource->addChild('requirements');
×
UNCOV
186
        foreach ($values as $key => $value) {
×
UNCOV
187
            $node->addChild('requirement', $value)->addAttribute('property', $key);
×
188
        }
189
    }
190

191
    private function buildOptions(\SimpleXMLElement $resource, array $values): void
192
    {
UNCOV
193
        $this->buildValues($resource->addChild('options'), $values);
×
194
    }
195

196
    private function buildSchemes(\SimpleXMLElement $resource, array $values): void
197
    {
198
        $node = $resource->addChild('schemes');
×
UNCOV
199
        foreach ($values as $value) {
×
UNCOV
200
            $node->addChild('scheme', $value);
×
201
        }
202
    }
203

204
    private function buildCacheHeaders(\SimpleXMLElement $resource, array $values): void
205
    {
206
        $node = $resource->addChild('cacheHeaders');
×
207
        foreach ($values as $key => $value) {
×
208
            if (\is_array($value)) {
×
UNCOV
209
                $child = $node->addChild('cacheHeader');
×
210
                $this->buildValues($child, $value);
×
211
            } else {
212
                $child = $node->addChild('cacheHeader', $this->parse($value));
×
213
            }
UNCOV
214
            $child->addAttribute('name', $key);
×
215
        }
216
    }
217

218
    private function buildNormalizationContext(\SimpleXMLElement $resource, array $values): void
219
    {
UNCOV
220
        $this->buildValues($resource->addChild('normalizationContext'), $values);
×
221
    }
222

223
    private function buildDenormalizationContext(\SimpleXMLElement $resource, array $values): void
224
    {
UNCOV
225
        $this->buildValues($resource->addChild('denormalizationContext'), $values);
×
226
    }
227

228
    private function buildHydraContext(\SimpleXMLElement $resource, array $values): void
229
    {
UNCOV
230
        $this->buildValues($resource->addChild('hydraContext'), $values);
×
231
    }
232

233
    private function buildOpenapi(\SimpleXMLElement $resource, array $values): void
234
    {
235
        $node = $resource->openapi ?? $resource->addChild('openapi');
×
236

237
        if (isset($values['tags'])) {
×
238
            $tagsNode = $node->tags ?? $node->addChild('tags');
×
UNCOV
239
            foreach ($values['tags'] as $tag) {
×
UNCOV
240
                $tagsNode->addChild('tag', $tag);
×
241
            }
242
        }
243

244
        if (isset($values['responses'])) {
×
245
            $responsesNode = $node->responses ?? $node->addChild('responses');
×
246
            foreach ($values['responses'] as $status => $response) {
×
247
                $responseNode = $responsesNode->addChild('response');
×
248
                $responseNode->addAttribute('status', $status);
×
UNCOV
249
                if (isset($response['description'])) {
×
250
                    $responseNode->addAttribute('description', $response['description']);
×
251
                }
UNCOV
252
                if (isset($response['content'])) {
×
253
                    $this->buildValues($responseNode->addChild('content'), $response['content']);
×
254
                }
UNCOV
255
                if (isset($response['headers'])) {
×
256
                    $this->buildValues($responseNode->addChild('headers'), $response['headers']);
×
257
                }
UNCOV
258
                if (isset($response['links'])) {
×
UNCOV
259
                    $this->buildValues($responseNode->addChild('links'), $response['links']);
×
260
                }
261
            }
262
        }
263

264
        if (isset($values['externalDocs'])) {
×
265
            $externalDocsNode = $node->externalDocs ?? $node->addChild('externalDocs');
×
UNCOV
266
            if (isset($values['externalDocs']['description'])) {
×
267
                $externalDocsNode->addAttribute('description', $values['externalDocs']['description']);
×
268
            }
UNCOV
269
            if (isset($values['url']['description'])) {
×
UNCOV
270
                $externalDocsNode->addAttribute('url', $values['externalDocs']['url']);
×
271
            }
272
        }
273

274
        if (isset($values['parameters'])) {
×
275
            $parametersNode = $node->parameters ?? $node->addChild('parameters');
×
276
            foreach ($values['parameters'] as $name => $parameter) {
×
277
                $parameterNode = $parametersNode->addChild('parameter');
×
278
                $parameterNode->addAttribute('name', $name);
×
UNCOV
279
                if (isset($parameter['in'])) {
×
280
                    $parameterNode->addAttribute('in', $parameter['in']);
×
281
                }
UNCOV
282
                if (isset($parameter['description'])) {
×
283
                    $parameterNode->addAttribute('description', $parameter['description']);
×
284
                }
UNCOV
285
                if (isset($parameter['required'])) {
×
286
                    $parameterNode->addAttribute('required', $parameter['required']);
×
287
                }
UNCOV
288
                if (isset($parameter['deprecated'])) {
×
289
                    $parameterNode->addAttribute('deprecated', $parameter['deprecated']);
×
290
                }
UNCOV
291
                if (isset($parameter['allowEmptyValue'])) {
×
292
                    $parameterNode->addAttribute('allowEmptyValue', $parameter['allowEmptyValue']);
×
293
                }
UNCOV
294
                if (isset($parameter['style'])) {
×
295
                    $parameterNode->addAttribute('style', $parameter['style']);
×
296
                }
UNCOV
297
                if (isset($parameter['explode'])) {
×
298
                    $parameterNode->addAttribute('explode', $parameter['explode']);
×
299
                }
UNCOV
300
                if (isset($parameter['allowReserved'])) {
×
301
                    $parameterNode->addAttribute('allowReserved', $parameter['allowReserved']);
×
302
                }
UNCOV
303
                if (isset($parameter['example'])) {
×
304
                    $parameterNode->addAttribute('example', $parameter['example']);
×
305
                }
UNCOV
306
                if (isset($parameter['schema'])) {
×
307
                    $this->buildValues($parameterNode->addChild('schema'), $parameter['schema']);
×
308
                }
UNCOV
309
                if (isset($parameter['examples'])) {
×
310
                    $this->buildValues($parameterNode->addChild('examples'), $parameter['examples']);
×
311
                }
UNCOV
312
                if (isset($parameter['content'])) {
×
UNCOV
313
                    $this->buildValues($parameterNode->addChild('content'), $parameter['content']);
×
314
                }
315
            }
316
        }
317

318
        if (isset($values['requestBody'])) {
×
319
            $requestBodyNode = $node->requestBody ?? $node->addChild('requestBody');
×
UNCOV
320
            if (isset($values['requestBody']['content'])) {
×
321
                $this->buildValues($requestBodyNode->addChild('content'), $values['requestBody']['content']);
×
322
            }
UNCOV
323
            if (isset($values['requestBody']['description'])) {
×
324
                $requestBodyNode->addAttribute('description', $values['requestBody']['description']);
×
325
            }
UNCOV
326
            if (isset($values['requestBody']['required'])) {
×
UNCOV
327
                $requestBodyNode->addAttribute('required', $values['requestBody']['required']);
×
328
            }
329
        }
330

UNCOV
331
        if (isset($values['callbacks'])) {
×
UNCOV
332
            $this->buildValues($node->callbacks ?? $node->addChild('callbacks'), $values['callbacks']);
×
333
        }
334

UNCOV
335
        if (isset($values['security'])) {
×
UNCOV
336
            $this->buildValues($node->security ?? $node->addChild('security'), $values['security']);
×
337
        }
338

339
        if (isset($values['servers'])) {
×
340
            $serversNode = $node->servers ?? $node->addChild('servers');
×
341
            foreach ($values['servers'] as $server) {
×
342
                $serverNode = $serversNode->addChild('serverNode');
×
UNCOV
343
                if (isset($server['url'])) {
×
344
                    $serverNode->addAttribute('url', $server['url']);
×
345
                }
UNCOV
346
                if (isset($server['description'])) {
×
347
                    $serverNode->addAttribute('description', $server['description']);
×
348
                }
UNCOV
349
                if (isset($server['variables'])) {
×
UNCOV
350
                    $this->buildValues($serverNode->addChild('variables'), $server['variables']);
×
351
                }
352
            }
353
        }
354

UNCOV
355
        if (isset($values['extensionProperties'])) {
×
UNCOV
356
            $this->buildValues($node->extensionProperties ?? $node->addChild('extensionProperties'), $values['extensionProperties']);
×
357
        }
358
    }
359

360
    private function buildValidationContext(\SimpleXMLElement $resource, array $values): void
361
    {
UNCOV
362
        $this->buildValues($resource->addChild('validationContext'), $values);
×
363
    }
364

365
    private function buildFilters(\SimpleXMLElement $resource, array $values): void
366
    {
367
        $node = $resource->addChild('filters');
×
UNCOV
368
        foreach ($values as $value) {
×
UNCOV
369
            $node->addChild('filter', $value);
×
370
        }
371
    }
372

373
    private function buildOrder(\SimpleXMLElement $resource, array $values): void
374
    {
UNCOV
375
        $this->buildValues($resource->addChild('order'), $values);
×
376
    }
377

378
    private function buildPaginationViaCursor(\SimpleXMLElement $resource, array $values): void
379
    {
380
        $node = $resource->addChild('paginationViaCursor');
×
381
        foreach ($values as $key => $value) {
×
382
            $child = $node->addChild('paginationField');
×
UNCOV
383
            $child->addAttribute('field', $key);
×
UNCOV
384
            $child->addAttribute('direction', $value);
×
385
        }
386
    }
387

388
    private function buildExceptionToStatus(\SimpleXMLElement $resource, array $values): void
389
    {
390
        $node = $resource->addChild('exceptionToStatus');
×
391
        foreach ($values as $key => $value) {
×
392
            $child = $node->addChild('exception');
×
UNCOV
393
            $child->addAttribute('class', $key);
×
UNCOV
394
            $child->addAttribute('statusCode', $this->parse($value));
×
395
        }
396
    }
397

398
    private function buildExtraProperties(\SimpleXMLElement $resource, array $values): void
399
    {
UNCOV
400
        $this->buildValues($resource->addChild('extraProperties'), $values);
×
401
    }
402

403
    private function buildArgs(\SimpleXMLElement $resource, array $args): void
404
    {
405
        $child = $resource->addChild('args');
×
406
        foreach ($args as $id => $values) {
×
407
            $grandChild = $child->addChild('arg');
×
UNCOV
408
            $grandChild->addAttribute('id', $id);
×
UNCOV
409
            $this->buildValues($grandChild, $values);
×
410
        }
411
    }
412

413
    private function buildExtraArgs(\SimpleXMLElement $resource, array $args): void
414
    {
415
        $child = $resource->addChild('extraArgs');
×
416
        foreach ($args as $id => $values) {
×
417
            $grandChild = $child->addChild('arg');
×
UNCOV
418
            $grandChild->addAttribute('id', $id);
×
UNCOV
419
            $this->buildValues($grandChild, $values);
×
420
        }
421
    }
422

423
    private function buildGraphQlOperations(\SimpleXMLElement $resource, array $values): void
424
    {
425
        $node = $resource->addChild('graphQlOperations');
×
426
        foreach ($values as $value) {
×
427
            $child = $node->addChild('graphQlOperation');
×
428
            foreach ($value as $index => $data) {
×
429
                if (method_exists($this, 'build'.ucfirst($index))) {
×
UNCOV
430
                    $this->{'build'.ucfirst($index)}($child, $data);
×
UNCOV
431
                    continue;
×
432
                }
433

434
                if (\is_string($data) || null === $data || is_numeric($data) || \is_bool($data)) {
×
UNCOV
435
                    $child->addAttribute($index, $this->parse($data));
×
UNCOV
436
                    continue;
×
437
                }
438

UNCOV
439
                throw new \LogicException(\sprintf('Cannot adapt graphQlOperation attribute or child "%s". Please create a "%s" method in %s.', $index, 'build'.ucfirst($index), self::class));
×
440
            }
441
        }
442
    }
443

444
    private function buildOperations(\SimpleXMLElement $resource, array $values): void
445
    {
446
        $node = $resource->addChild('operations');
×
447
        foreach ($values as $value) {
×
448
            $child = $node->addChild('operation');
×
449
            foreach ($value as $index => $data) {
×
450
                if (method_exists($this, 'build'.ucfirst($index))) {
×
UNCOV
451
                    $this->{'build'.ucfirst($index)}($child, $data);
×
UNCOV
452
                    continue;
×
453
                }
454

455
                if (\is_string($data) || null === $data || is_numeric($data) || \is_bool($data)) {
×
UNCOV
456
                    $child->addAttribute($index, $this->parse($data));
×
UNCOV
457
                    continue;
×
458
                }
459

UNCOV
460
                throw new \LogicException(\sprintf('Cannot adapt operation attribute or child "%s". Please create a "%s" method in %s.', $index, 'build'.ucfirst($index), self::class));
×
461
            }
462
        }
463
    }
464

465
    private function buildFormats(\SimpleXMLElement $resource, array $values, string $name = 'formats'): void
466
    {
467
        $node = $resource->addChild($name);
×
UNCOV
468
        foreach ($values as $key => $value) {
×
UNCOV
469
            $node->addChild('format', $value)->addAttribute('name', $key);
×
470
        }
471
    }
472

473
    private function buildStateOptions(\SimpleXMLElement $resource, array $values): void
474
    {
475
        $node = $resource->addChild('stateOptions');
×
476
        $childNode = $node->addChild(array_key_first($values));
×
UNCOV
477
        $childNode->addAttribute('index', $values[array_key_first($values)]['index']);
×
UNCOV
478
        $childNode->addAttribute('type', $values[array_key_first($values)]['type']);
×
479
    }
480

481
    private function buildValues(\SimpleXMLElement $resource, array $values): void
482
    {
483
        $node = $resource->addChild('values');
×
484
        foreach ($values as $key => $value) {
×
485
            if (\is_array($value)) {
×
UNCOV
486
                $child = $node->addChild('value');
×
487
                $this->buildValues($child, $value);
×
488
            } else {
489
                $child = $node->addChild('value', $value);
×
490
            }
UNCOV
491
            if (\is_string($key)) {
×
UNCOV
492
                $child->addAttribute('name', $key);
×
493
            }
494
        }
495
    }
496

497
    private function buildLinks(\SimpleXMLElement $resource, ?array $values = null): void
498
    {
UNCOV
499
        if (!$values) {
×
UNCOV
500
            return;
×
501
        }
502

503
        $node = $resource->addChild('links');
×
504
        $childNode = $node->addChild('link');
×
UNCOV
505
        $childNode->addAttribute('rel', $values[0]['rel']);
×
UNCOV
506
        $childNode->addAttribute('href', $values[0]['href']);
×
507
    }
508

509
    private function buildRules(\SimpleXMLElement $resource, ?array $values = null): void
510
    {
UNCOV
511
    }
×
512

513
    private function buildHeaders(\SimpleXMLElement $resource, ?array $values = null): void
514
    {
UNCOV
515
        if (!$values) {
×
UNCOV
516
            return;
×
517
        }
518

519
        $node = $resource->addChild('headers');
×
520
        foreach ($values as $key => $value) {
×
521
            $childNode = $node->addChild('header');
×
UNCOV
522
            $childNode->addAttribute('key', $key);
×
UNCOV
523
            $childNode->addAttribute('value', $value);
×
524
        }
525
    }
526

527
    private function buildParameters(\SimpleXMLElement $resource, ?array $values = null): void
528
    {
UNCOV
529
        if (!$values) {
×
UNCOV
530
            return;
×
531
        }
532

533
        $node = $resource->addChild('parameters');
×
534
        foreach ($values as $key => $value) {
×
535
            $childNode = $node->addChild('parameter');
×
536
            $childNode->addAttribute('in', 'query');
×
537
            $childNode->addAttribute('key', $key);
×
538

UNCOV
539
            if (\array_key_exists('required', $value)) {
×
UNCOV
540
                $childNode->addAttribute('required', $this->parse($value['required']));
×
541
            }
542

543
            if (\array_key_exists('schema', $value)) {
×
544
                $this->buildValues($childNode->addChild('schema'), $value['schema']);
×
545
            }
546
        }
547
    }
548

549
    private function parse($value): ?string
550
    {
UNCOV
551
        if (null === $value) {
×
UNCOV
552
            return null;
×
553
        }
554

UNCOV
555
        return \is_bool($value) ? (true === $value ? 'true' : 'false') : (string) $value;
×
556
    }
557
}
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