Passed
Push — 2.5 ( f50b5e...b47cce )
by Kévin
04:21
created

SerializerContextBuilder::createFromRequest()   F

Complexity

Conditions 17
Paths 481

Size

Total Lines 71
Code Lines 43

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 17
eloc 43
nc 481
nop 3
dl 0
loc 71
rs 1.7708
c 1
b 0
f 0

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

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\Exception\RuntimeException;
18
use ApiPlatform\Core\Metadata\Resource\Factory\ResourceMetadataFactoryInterface;
19
use ApiPlatform\Core\Swagger\Serializer\DocumentationNormalizer;
20
use ApiPlatform\Core\Util\RequestAttributesExtractor;
21
use Symfony\Component\HttpFoundation\Request;
22
use Symfony\Component\Serializer\Encoder\CsvEncoder;
23
24
/**
25
 * {@inheritdoc}
26
 *
27
 * @author Kévin Dunglas <[email protected]>
28
 */
29
final class SerializerContextBuilder implements SerializerContextBuilderInterface
30
{
31
    private $resourceMetadataFactory;
32
33
    public function __construct(ResourceMetadataFactoryInterface $resourceMetadataFactory)
34
    {
35
        $this->resourceMetadataFactory = $resourceMetadataFactory;
36
    }
37
38
    /**
39
     * {@inheritdoc}
40
     */
41
    public function createFromRequest(Request $request, bool $normalization, array $attributes = null): array
42
    {
43
        if (null === $attributes && !$attributes = RequestAttributesExtractor::extractAttributes($request)) {
44
            throw new RuntimeException('Request attributes are not valid.');
45
        }
46
47
        $resourceMetadata = $this->resourceMetadataFactory->create($attributes['resource_class']);
48
        $key = $normalization ? 'normalization_context' : 'denormalization_context';
49
        if (isset($attributes['collection_operation_name'])) {
50
            $operationKey = 'collection_operation_name';
51
            $operationType = OperationType::COLLECTION;
52
        } elseif (isset($attributes['item_operation_name'])) {
53
            $operationKey = 'item_operation_name';
54
            $operationType = OperationType::ITEM;
55
        } else {
56
            $operationKey = 'subresource_operation_name';
57
            $operationType = OperationType::SUBRESOURCE;
58
        }
59
60
        $context = $resourceMetadata->getTypedOperationAttribute($operationType, $attributes[$operationKey], $key, [], true);
61
        $context['operation_type'] = $operationType;
62
        $context[$operationKey] = $attributes[$operationKey];
63
64
        if (!$normalization) {
65
            if (!isset($context['api_allow_update'])) {
66
                $context['api_allow_update'] = \in_array($request->getMethod(), ['PUT', 'PATCH'], true);
67
            }
68
69
            if ('csv' === $request->getContentType()) {
70
                $context[CsvEncoder::AS_COLLECTION_KEY] = false;
71
            }
72
        }
73
74
        $context['resource_class'] = $attributes['resource_class'];
75
        $context['input'] = $resourceMetadata->getTypedOperationAttribute($operationType, $attributes[$operationKey], 'input', null, true);
76
        $context['output'] = $resourceMetadata->getTypedOperationAttribute($operationType, $attributes[$operationKey], 'output', null, true);
77
        $context['request_uri'] = $request->getRequestUri();
78
        $context['uri'] = $request->getUri();
79
80
        if (isset($attributes['subresource_context'])) {
81
            $context['subresource_identifiers'] = [];
82
83
            foreach ($attributes['subresource_context']['identifiers'] as $key => [$id, $resourceClass]) {
84
                if (!isset($context['subresource_resources'][$resourceClass])) {
85
                    $context['subresource_resources'][$resourceClass] = [];
86
                }
87
88
                $context['subresource_identifiers'][$id] = $context['subresource_resources'][$resourceClass][$id] = $request->attributes->get($id);
89
            }
90
        }
91
92
        if (isset($attributes['subresource_property'])) {
93
            $context['subresource_property'] = $attributes['subresource_property'];
94
            $context['subresource_resource_class'] = $attributes['subresource_resource_class'] ?? null;
95
        }
96
97
        unset($context[DocumentationNormalizer::SWAGGER_DEFINITION_NAME]);
98
99
        if (isset($context['skip_null_values'])) {
100
            return $context;
101
        }
102
103
        foreach ($resourceMetadata->getItemOperations() as $operation) {
104
            if ('PATCH' === ($operation['method'] ?? '') && \in_array('application/merge-patch+json', $operation['input_formats']['json'] ?? [], true)) {
105
                $context['skip_null_values'] = true;
106
107
                break;
108
            }
109
        }
110
111
        return $context;
112
    }
113
}
114