• 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.87
/src/OpenApi/Serializer/OpenApiNormalizer.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\OpenApi\Serializer;
15

16
use ApiPlatform\OpenApi\Model\Paths;
17
use ApiPlatform\OpenApi\OpenApi;
18
use Symfony\Component\Serializer\Normalizer\AbstractNormalizer;
19
use Symfony\Component\Serializer\Normalizer\AbstractObjectNormalizer;
20
use Symfony\Component\Serializer\Normalizer\NormalizerInterface;
21

22
/**
23
 * Generates an OpenAPI v3 specification.
24
 */
25
final class OpenApiNormalizer implements NormalizerInterface
26
{
27
    public const FORMAT = 'json';
28
    public const JSON_FORMAT = 'jsonopenapi';
29
    public const YAML_FORMAT = 'yamlopenapi';
30
    private const EXTENSION_PROPERTIES_KEY = 'extensionProperties';
31

32
    public function __construct(private readonly NormalizerInterface $decorated)
33
    {
UNCOV
34
    }
950✔
35

36
    /**
37
     * {@inheritdoc}
38
     */
39
    public function normalize(mixed $object, ?string $format = null, array $context = []): array
40
    {
UNCOV
41
        $pathsCallback = $this->getPathsCallBack();
22✔
UNCOV
42
        $context[AbstractObjectNormalizer::PRESERVE_EMPTY_OBJECTS] = true;
22✔
UNCOV
43
        $context[AbstractObjectNormalizer::SKIP_NULL_VALUES] = true;
22✔
UNCOV
44
        $context[AbstractNormalizer::CALLBACKS] = [
22✔
UNCOV
45
            'paths' => $pathsCallback,
22✔
UNCOV
46
        ];
22✔
47

UNCOV
48
        return $this->recursiveClean($this->decorated->normalize($object, $format, $context));
22✔
49
    }
50

51
    private function recursiveClean(array $data): array
52
    {
UNCOV
53
        foreach ($data as $key => $value) {
22✔
UNCOV
54
            if (self::EXTENSION_PROPERTIES_KEY === $key) {
22✔
UNCOV
55
                foreach ($data[self::EXTENSION_PROPERTIES_KEY] as $extensionPropertyKey => $extensionPropertyValue) {
22✔
UNCOV
56
                    $data[$extensionPropertyKey] = $extensionPropertyValue;
19✔
57
                }
UNCOV
58
                continue;
22✔
59
            }
60

UNCOV
61
            if (\is_array($value)) {
22✔
UNCOV
62
                $data[$key] = $this->recursiveClean($value);
22✔
63
            }
64
        }
65

UNCOV
66
        unset($data[self::EXTENSION_PROPERTIES_KEY]);
22✔
67

UNCOV
68
        return $data;
22✔
69
    }
70

71
    /**
72
     * {@inheritdoc}
73
     */
74
    public function supportsNormalization(mixed $data, ?string $format = null, array $context = []): bool
75
    {
UNCOV
76
        return (self::FORMAT === $format || self::JSON_FORMAT === $format || self::YAML_FORMAT === $format) && $data instanceof OpenApi;
22✔
77
    }
78

79
    public function getSupportedTypes($format): array
80
    {
UNCOV
81
        return (self::FORMAT === $format || self::JSON_FORMAT === $format || self::YAML_FORMAT === $format) ? [OpenApi::class => true] : [];
912✔
82
    }
83

84
    private function getPathsCallBack(): \Closure
85
    {
UNCOV
86
        return static function ($decoratedObject): array {
22✔
UNCOV
87
            if ($decoratedObject instanceof Paths) {
22✔
UNCOV
88
                $paths = $decoratedObject->getPaths();
22✔
89

90
                // sort paths by tags, then by path for each tag
UNCOV
91
                uksort($paths, function ($keyA, $keyB) use ($paths) {
22✔
UNCOV
92
                    $a = $paths[$keyA];
21✔
UNCOV
93
                    $b = $paths[$keyB];
21✔
94

UNCOV
95
                    $tagsA = [
21✔
UNCOV
96
                        ...($a->getGet()?->getTags() ?? []),
21✔
UNCOV
97
                        ...($a->getPost()?->getTags() ?? []),
21✔
UNCOV
98
                        ...($a->getPatch()?->getTags() ?? []),
21✔
UNCOV
99
                        ...($a->getPut()?->getTags() ?? []),
21✔
UNCOV
100
                        ...($a->getDelete()?->getTags() ?? []),
21✔
UNCOV
101
                    ];
21✔
UNCOV
102
                    sort($tagsA);
21✔
103

UNCOV
104
                    $tagsB = [
21✔
UNCOV
105
                        ...($b->getGet()?->getTags() ?? []),
21✔
UNCOV
106
                        ...($b->getPost()?->getTags() ?? []),
21✔
UNCOV
107
                        ...($b->getPatch()?->getTags() ?? []),
21✔
UNCOV
108
                        ...($b->getPut()?->getTags() ?? []),
21✔
UNCOV
109
                        ...($b->getDelete()?->getTags() ?? []),
21✔
UNCOV
110
                    ];
21✔
UNCOV
111
                    sort($tagsB);
21✔
112

UNCOV
113
                    return match (true) {
UNCOV
114
                        current($tagsA) === current($tagsB) => $keyA <=> $keyB,
21✔
UNCOV
115
                        default => current($tagsA) <=> current($tagsB),
21✔
UNCOV
116
                    };
UNCOV
117
                });
22✔
118

UNCOV
119
                return $paths;
22✔
120
            }
121

122
            return [];
×
UNCOV
123
        };
22✔
124
    }
125
}
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