Completed
Pull Request — master (#3367)
by Alan
05:13
created

SerializerContextProvider   A

Complexity

Total Complexity 17

Size/Duplication

Total Lines 80
Duplicated Lines 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 46
dl 0
loc 80
rs 10
c 1
b 0
f 0
wmc 17

2 Methods

Rating   Name   Duplication   Size   Complexity  
F create() 0 68 16
A __construct() 0 3 1
1
<?php
2
3
/*
4
 * This file is part of the API Platform project.
5
 *
6
 * (c) Kévin Dunglas <[email protected]>
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\Core\Serializer;
15
16
use ApiPlatform\Core\Api\OperationType;
17
use ApiPlatform\Core\Metadata\Resource\Factory\ResourceMetadataFactoryInterface;
18
use Symfony\Component\Serializer\Encoder\CsvEncoder;
19
20
/**
21
 * {@inheritdoc}
22
 *
23
 * @author Alan Poulain <[email protected]>
24
 */
25
final class SerializerContextProvider implements SerializerContextProviderInterface
26
{
27
    private $resourceMetadataFactory;
28
29
    public function __construct(ResourceMetadataFactoryInterface $resourceMetadataFactory)
30
    {
31
        $this->resourceMetadataFactory = $resourceMetadataFactory;
32
    }
33
34
    /**
35
     * {@inheritdoc}
36
     */
37
    public function create(string $resourceClass, string $operationName, bool $normalization, array $context): array
38
    {
39
        $resourceMetadata = $this->resourceMetadataFactory->create($resourceClass);
40
        $key = $normalization ? 'normalization_context' : 'denormalization_context';
41
        if (isset($context['collection_operation_name'])) {
42
            $operationNameKey = 'collection_operation_name';
43
            $operationType = OperationType::COLLECTION;
44
        } elseif (isset($context['item_operation_name'])) {
45
            $operationNameKey = 'item_operation_name';
46
            $operationType = OperationType::ITEM;
47
        } elseif (isset($context['resource_operation_name'])) {
48
            $operationNameKey = 'resource_operation_name';
49
            $operationType = OperationType::RESOURCE;
50
        } else {
51
            $operationNameKey = 'subresource_operation_name';
52
            $operationType = OperationType::SUBRESOURCE;
53
        }
54
55
        $serializerContext = $resourceMetadata->getTypedOperationAttribute($operationType, $context[$operationNameKey], $key, [], true);
56
        $serializerContext['operation_type'] = $operationType;
57
        $serializerContext[$operationNameKey] = $context[$operationNameKey];
58
59
        if (!$normalization) {
60
            if (!isset($serializerContext['api_allow_update'])) {
61
                $serializerContext['api_allow_update'] = \in_array($context['request_method'] ?? null, ['PUT', 'PATCH'], true);
62
            }
63
64
            if ('csv' === ($context['request_content_type'] ?? null)) {
65
                $serializerContext[CsvEncoder::AS_COLLECTION_KEY] = false;
66
            }
67
        }
68
69
        $serializerContext['resource_class'] = $resourceClass;
70
        $serializerContext['input'] = $resourceMetadata->getTypedOperationAttribute($operationType, $context[$operationNameKey], 'input', null, true);
71
        $serializerContext['output'] = $resourceMetadata->getTypedOperationAttribute($operationType, $context[$operationNameKey], 'output', null, true);
72
        $serializerContext['request_uri'] = $context['request_request_uri'] ?? null;
73
        $serializerContext['uri'] = $context['request_uri'] ?? null;
74
75
        if (isset($context['subresource_context'])) {
76
            $serializerContext['subresource_identifiers'] = [];
77
78
            foreach ($context['subresource_context']['identifiers'] as $key => [$id, $subResourceClass]) {
79
                if (!isset($serializerContext['subresource_resources'][$subResourceClass])) {
80
                    $serializerContext['subresource_resources'][$subResourceClass] = [];
81
                }
82
83
                $serializerContext['subresource_identifiers'][$id] = $serializerContext['subresource_resources'][$subResourceClass][$id] = $context['request_attributes'][$id] ?? null;
84
            }
85
        }
86
87
        if (isset($context['subresource_property'])) {
88
            $serializerContext['subresource_property'] = $context['subresource_property'];
89
            $serializerContext['subresource_resource_class'] = $context['subresource_resource_class'] ?? null;
90
        }
91
92
        if (isset($serializerContext['skip_null_values'])) {
93
            return $serializerContext;
94
        }
95
96
        foreach ($resourceMetadata->getItemOperations() ?? [] as $operation) {
97
            if ('PATCH' === ($operation['method'] ?? '') && \in_array('application/merge-patch+json', $operation['input_formats']['json'] ?? [], true)) {
98
                $serializerContext['skip_null_values'] = true;
99
100
                break;
101
            }
102
        }
103
104
        return $serializerContext;
105
    }
106
}
107