• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In
Build has been canceled!

api-platform / core / 21001095414

14 Jan 2026 04:10PM UTC coverage: 0.0% (-29.1%) from 29.095%
21001095414

Pull #7595

github

web-flow
Merge 620cc601d into 73402fc61
Pull Request #7595: feat: mcp bundle tool integration

0 of 476 new or added lines in 16 files covered. (0.0%)

15042 existing lines in 491 files now uncovered.

0 of 58241 relevant lines covered (0.0%)

0.0 hits per line

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

0.0
/src/GraphQl/Serializer/SerializerContextBuilder.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\GraphQl\Serializer;
15

16
use ApiPlatform\Metadata\GraphQl\Mutation;
17
use ApiPlatform\Metadata\GraphQl\Operation;
18
use ApiPlatform\Metadata\GraphQl\Subscription;
19
use GraphQL\Type\Definition\ResolveInfo;
20
use Symfony\Component\Serializer\NameConverter\NameConverterInterface;
21
use Symfony\Component\Serializer\Normalizer\AbstractObjectNormalizer;
22

23
/**
24
 * Builds the context used by the Symfony Serializer.
25
 *
26
 * @author Alan Poulain <contact@alanpoulain.eu>
27
 */
28
final class SerializerContextBuilder implements SerializerContextBuilderInterface
29
{
30
    public function __construct(private readonly ?NameConverterInterface $nameConverter)
31
    {
UNCOV
32
    }
×
33

34
    public function create(?string $resourceClass, Operation $operation, array $resolverContext, bool $normalization): array
35
    {
UNCOV
36
        $context = ['resource_class' => $resourceClass, 'operation_name' => $operation->getName(), 'graphql_operation_name' => $operation->getName()];
×
37

UNCOV
38
        if (isset($resolverContext['fields'])) {
×
39
            $context['no_resolver_data'] = true;
×
40
        }
41

UNCOV
42
        $context['operation'] = $operation;
×
UNCOV
43
        if ($operation->getInput()) {
×
44
            $context['input'] = $operation->getInput();
×
45
        }
UNCOV
46
        if ($operation->getOutput()) {
×
47
            $context['output'] = $operation->getOutput();
×
48
        }
UNCOV
49
        $context = $normalization ? array_merge($operation->getNormalizationContext() ?? [], $context) : array_merge($operation->getDenormalizationContext() ?? [], $context);
×
50

UNCOV
51
        if ($normalization) {
×
UNCOV
52
            $context['attributes'] = $this->fieldsToAttributes($resourceClass, $operation, $resolverContext, $context);
×
53
        }
54

55
        // to keep the cache computation smaller, we have "operation_name" and "iri" anyways
UNCOV
56
        $context[AbstractObjectNormalizer::EXCLUDE_FROM_CACHE_KEY][] = 'root_operation';
×
UNCOV
57
        $context[AbstractObjectNormalizer::EXCLUDE_FROM_CACHE_KEY][] = 'operation';
×
UNCOV
58
        $context[AbstractObjectNormalizer::EXCLUDE_FROM_CACHE_KEY][] = 'object';
×
UNCOV
59
        $context[AbstractObjectNormalizer::EXCLUDE_FROM_CACHE_KEY][] = 'data';
×
UNCOV
60
        $context[AbstractObjectNormalizer::EXCLUDE_FROM_CACHE_KEY][] = 'property_metadata';
×
UNCOV
61
        $context[AbstractObjectNormalizer::EXCLUDE_FROM_CACHE_KEY][] = 'circular_reference_limit_counters';
×
UNCOV
62
        $context[AbstractObjectNormalizer::EXCLUDE_FROM_CACHE_KEY][] = 'debug_trace_id';
×
63

UNCOV
64
        return $context;
×
65
    }
66

67
    /**
68
     * Retrieves fields, recursively replaces the "_id" key (the raw id) by "id" (the name of the property expected by the Serializer) and flattens edge and node structures (pagination).
69
     */
70
    private function fieldsToAttributes(?string $resourceClass, Operation $operation, array $resolverContext, array $context): array
71
    {
UNCOV
72
        if (isset($resolverContext['fields'])) {
×
73
            $fields = $resolverContext['fields'];
×
74
        } else {
75
            /** @var ResolveInfo $info */
UNCOV
76
            $info = $resolverContext['info'];
×
UNCOV
77
            $fields = $info->getFieldSelection(\PHP_INT_MAX);
×
78
        }
79

UNCOV
80
        $attributes = $this->replaceIdKeys($fields['edges']['node'] ?? $fields['collection'] ?? $fields, $resourceClass, $context);
×
81

UNCOV
82
        if ($operation instanceof Subscription || $operation instanceof Mutation) {
×
UNCOV
83
            $wrapFieldName = lcfirst($operation->getShortName());
×
84

UNCOV
85
            return $attributes[$wrapFieldName] ?? [];
×
86
        }
87

UNCOV
88
        return $attributes;
×
89
    }
90

91
    private function replaceIdKeys(array $fields, ?string $resourceClass, array $context): array
92
    {
UNCOV
93
        $denormalizedFields = [];
×
94

UNCOV
95
        foreach ($fields as $key => $value) {
×
UNCOV
96
            if ('_id' === $key) {
×
97
                $denormalizedFields['id'] = $fields['_id'];
×
98

99
                continue;
×
100
            }
101

UNCOV
102
            $denormalizedFields[$this->denormalizePropertyName((string) $key, $resourceClass, $context)] = \is_array($value) ? $this->replaceIdKeys($value, $resourceClass, $context) : $value;
×
103
        }
104

UNCOV
105
        return $denormalizedFields;
×
106
    }
107

108
    private function denormalizePropertyName(string $property, ?string $resourceClass, array $context): string
109
    {
UNCOV
110
        if (null === $this->nameConverter) {
×
111
            return $property;
×
112
        }
113

UNCOV
114
        return $this->nameConverter->denormalize($property, $resourceClass, null, $context);
×
115
    }
116
}
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