Completed
Push — master ( 796f61...125dec )
by Han Hui
30s queued 13s
created

ReadListener::onKernelRequest()   F

Complexity

Conditions 16
Paths 277

Size

Total Lines 57
Code Lines 32

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 16
eloc 32
nc 277
nop 1
dl 0
loc 57
rs 3.7708
c 0
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\EventListener;
15
16
use ApiPlatform\Core\DataProvider\CollectionDataProviderInterface;
17
use ApiPlatform\Core\DataProvider\ItemDataProviderInterface;
18
use ApiPlatform\Core\DataProvider\OperationDataProviderTrait;
19
use ApiPlatform\Core\DataProvider\SubresourceDataProviderInterface;
20
use ApiPlatform\Core\Exception\InvalidIdentifierException;
21
use ApiPlatform\Core\Exception\RuntimeException;
22
use ApiPlatform\Core\Identifier\IdentifierConverterInterface;
23
use ApiPlatform\Core\Serializer\SerializerContextBuilderInterface;
24
use ApiPlatform\Core\Util\RequestAttributesExtractor;
25
use ApiPlatform\Core\Util\RequestParser;
26
use Symfony\Component\HttpKernel\Event\GetResponseEvent;
27
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
28
29
/**
30
 * Retrieves data from the applicable data provider and sets it as a request parameter called data.
31
 *
32
 * @author Kévin Dunglas <[email protected]>
33
 */
34
final class ReadListener
35
{
36
    use OperationDataProviderTrait;
37
38
    private $serializerContextBuilder;
39
40
    public function __construct(CollectionDataProviderInterface $collectionDataProvider, ItemDataProviderInterface $itemDataProvider, SubresourceDataProviderInterface $subresourceDataProvider = null, SerializerContextBuilderInterface $serializerContextBuilder = null, IdentifierConverterInterface $identifierConverter = null)
41
    {
42
        $this->collectionDataProvider = $collectionDataProvider;
43
        $this->itemDataProvider = $itemDataProvider;
44
        $this->subresourceDataProvider = $subresourceDataProvider;
45
        $this->serializerContextBuilder = $serializerContextBuilder;
46
        $this->identifierConverter = $identifierConverter;
47
    }
48
49
    /**
50
     * Calls the data provider and sets the data attribute.
51
     *
52
     * @throws NotFoundHttpException
53
     */
54
    public function onKernelRequest(GetResponseEvent $event): void
55
    {
56
        $request = $event->getRequest();
57
        if (
58
            !($attributes = RequestAttributesExtractor::extractAttributes($request))
59
            || !$attributes['receive']
60
        ) {
61
            return;
62
        }
63
64
        if (null === $filters = $request->attributes->get('_api_filters')) {
65
            $queryString = RequestParser::getQueryString($request);
66
            $filters = $queryString ? RequestParser::parseRequestParams($queryString) : null;
67
        }
68
69
        $context = null === $filters ? [] : ['filters' => $filters];
70
        if ($this->serializerContextBuilder) {
71
            // Builtin data providers are able to use the serialization context to automatically add join clauses
72
            $context += $normalizationContext = $this->serializerContextBuilder->createFromRequest($request, true, $attributes);
73
            $request->attributes->set('_api_normalization_context', $normalizationContext);
74
        }
75
76
        if (isset($attributes['collection_operation_name'])) {
77
            $request->attributes->set('data', $request->isMethod('POST') ? null : $this->getCollectionData($attributes, $context));
78
79
            return;
80
        }
81
82
        $data = [];
83
84
        if ($this->identifierConverter) {
85
            $context[IdentifierConverterInterface::HAS_IDENTIFIER_CONVERTER] = true;
86
        }
87
88
        try {
89
            $identifiers = $this->extractIdentifiers($request->attributes->all(), $attributes);
90
91
            if (isset($attributes['item_operation_name'])) {
92
                $data = $this->getItemData($identifiers, $attributes, $context);
93
            } elseif (isset($attributes['subresource_operation_name'])) {
94
                // Legacy
95
                if (null === $this->subresourceDataProvider) {
96
                    throw new RuntimeException('No subresource data provider.');
97
                }
98
99
                $data = $this->getSubresourceData($identifiers, $attributes, $context);
100
            }
101
        } catch (InvalidIdentifierException $e) {
102
            throw new NotFoundHttpException('Not found, because of an invalid identifier configuration', $e);
103
        }
104
105
        if (null === $data) {
106
            throw new NotFoundHttpException('Not Found');
107
        }
108
109
        $request->attributes->set('data', $data);
110
        $request->attributes->set('previous_data', \is_object($data) ? clone $data : $data);
111
    }
112
}
113