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

api-platform / core / 5939488801

22 Aug 2023 01:27PM UTC coverage: 58.818% (-0.02%) from 58.84%
5939488801

push

github

web-flow
refactor(serializer): child definition context creation

Also fixes the item_uri_template usage

* fix(symfony): fix Symfony IriConverter with item_uri_template

Co-authored-by: soyuka <soyuka@users.noreply.github.com>

22 of 22 new or added lines in 5 files covered. (100.0%)

10839 of 18428 relevant lines covered (58.82%)

19.76 hits per line

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

91.18
/src/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\Serializer;
15

16
use ApiPlatform\Exception\RuntimeException;
17
use ApiPlatform\Metadata\CollectionOperationInterface;
18
use ApiPlatform\Metadata\Resource\Factory\ResourceMetadataCollectionFactoryInterface;
19
use ApiPlatform\Util\RequestAttributesExtractor;
20
use Symfony\Component\HttpFoundation\Request;
21
use Symfony\Component\Serializer\Encoder\CsvEncoder;
22
use Symfony\Component\Serializer\Normalizer\AbstractObjectNormalizer;
23
use Symfony\Component\Serializer\Normalizer\DenormalizerInterface;
24

25
/**
26
 * {@inheritdoc}
27
 *
28
 * @author Kévin Dunglas <dunglas@gmail.com>
29
 */
30
final class SerializerContextBuilder implements SerializerContextBuilderInterface
31
{
32
    public function __construct(private readonly ResourceMetadataCollectionFactoryInterface $resourceMetadataFactory)
33
    {
34
    }
60✔
35

36
    /**
37
     * {@inheritdoc}
38
     */
39
    public function createFromRequest(Request $request, bool $normalization, array $attributes = null): array
40
    {
41
        if (null === $attributes && !$attributes = RequestAttributesExtractor::extractAttributes($request)) {
40✔
42
            throw new RuntimeException('Request attributes are not valid.');
2✔
43
        }
44

45
        $operation = $attributes['operation'] ?? $this->resourceMetadataFactory->create($attributes['resource_class'])->getOperation($attributes['operation_name']);
38✔
46
        $context = $normalization ? ($operation->getNormalizationContext() ?? []) : ($operation->getDenormalizationContext() ?? []);
38✔
47
        $context['operation_name'] = $operation->getName();
38✔
48
        $context['operation'] = $operation;
38✔
49
        $context['resource_class'] = $attributes['resource_class'];
38✔
50
        $context['skip_null_values'] ??= true;
38✔
51
        $context['iri_only'] ??= false;
38✔
52
        $context['request_uri'] = $request->getRequestUri();
38✔
53
        $context['uri'] = $request->getUri();
38✔
54
        $context['input'] = $operation->getInput();
38✔
55
        $context['output'] = $operation->getOutput();
38✔
56

57
        // Special case as this is usually handled by our OperationContextTrait, here we want to force the IRI in the response
58
        if (!$operation instanceof CollectionOperationInterface && method_exists($operation, 'getItemUriTemplate') && $operation->getItemUriTemplate()) {
38✔
59
            $context['item_uri_template'] = $operation->getItemUriTemplate();
×
60
        }
61

62
        if ($operation->getTypes()) {
38✔
63
            $context['types'] = $operation->getTypes();
×
64
        }
65

66
        if ($operation->getUriVariables()) {
38✔
67
            $context['uri_variables'] = [];
8✔
68

69
            foreach (array_keys($operation->getUriVariables()) as $parameterName) {
8✔
70
                $context['uri_variables'][$parameterName] = $request->attributes->get($parameterName);
8✔
71
            }
72
        }
73

74
        if (!$normalization) {
38✔
75
            if (!isset($context['api_allow_update'])) {
16✔
76
                $context['api_allow_update'] = \in_array($method = $request->getMethod(), ['PUT', 'PATCH'], true);
16✔
77

78
                if ($context['api_allow_update'] && 'PATCH' === $method) {
16✔
79
                    $context['deep_object_to_populate'] ??= true;
2✔
80
                }
81
            }
82

83
            if ('csv' === (method_exists(Request::class, 'getContentTypeFormat') ? $request->getContentTypeFormat() : $request->getContentType())) {
16✔
84
                $context[CsvEncoder::AS_COLLECTION_KEY] = false;
×
85
            }
86
        }
87
        if ($operation->getCollectDenormalizationErrors() ?? false) {
38✔
88
            $context[DenormalizerInterface::COLLECT_DENORMALIZATION_ERRORS] = true;
2✔
89
        }
90

91
        // to keep the cache computation smaller, we have "operation_name" and "iri" anyways
92
        $context[AbstractObjectNormalizer::EXCLUDE_FROM_CACHE_KEY][] = 'root_operation';
38✔
93
        $context[AbstractObjectNormalizer::EXCLUDE_FROM_CACHE_KEY][] = 'operation';
38✔
94

95
        return $context;
38✔
96
    }
97
}
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