Completed
Push — upgrade_swaggerui ( c47a93...8528ad )
by Kévin
05:49
created

SwaggerUiAction::getContext()   B

Complexity

Conditions 5
Paths 4

Size

Total Lines 42
Code Lines 28

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 42
rs 8.439
c 0
b 0
f 0
cc 5
eloc 28
nc 4
nop 2
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\Bridge\Symfony\Bundle\Action;
15
16
use ApiPlatform\Core\Documentation\Documentation;
17
use ApiPlatform\Core\Exception\RuntimeException;
18
use ApiPlatform\Core\Metadata\Resource\Factory\ResourceMetadataFactoryInterface;
19
use ApiPlatform\Core\Metadata\Resource\Factory\ResourceNameCollectionFactoryInterface;
20
use Symfony\Component\HttpFoundation\Request;
21
use Symfony\Component\HttpFoundation\Response;
22
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
23
use Symfony\Component\Serializer\Normalizer\NormalizerInterface;
24
25
/**
26
 * Displays the documentation in Swagger UI.
27
 *
28
 * @author Kévin Dunglas <[email protected]>
29
 */
30
final class SwaggerUiAction
31
{
32
    private $resourceNameCollectionFactory;
33
    private $resourceMetadataFactory;
34
    private $normalizer;
35
    private $twig;
36
    private $urlGenerator;
37
    private $title;
38
    private $description;
39
    private $version;
40
    private $formats = [];
41
    private $oauthEnabled;
42
    private $oauthClientId;
43
    private $oauthClientSecret;
44
    private $oauthType;
45
    private $oauthFlow;
46
    private $oauthTokenUrl;
47
    private $oauthAuthorizationUrl;
48
    private $oauthScopes;
49
50
    public function __construct(ResourceNameCollectionFactoryInterface $resourceNameCollectionFactory, ResourceMetadataFactoryInterface $resourceMetadataFactory, NormalizerInterface $normalizer, \Twig_Environment $twig, UrlGeneratorInterface $urlGenerator, string $title = '', string $description = '', string $version = '', array $formats = [], $oauthEnabled = false, $oauthClientId = '', $oauthClientSecret = '', $oauthType = '', $oauthFlow = '', $oauthTokenUrl = '', $oauthAuthorizationUrl = '', $oauthScopes = [])
51
    {
52
        $this->resourceNameCollectionFactory = $resourceNameCollectionFactory;
53
        $this->resourceMetadataFactory = $resourceMetadataFactory;
54
        $this->normalizer = $normalizer;
55
        $this->twig = $twig;
56
        $this->urlGenerator = $urlGenerator;
57
        $this->title = $title;
58
        $this->description = $description;
59
        $this->version = $version;
60
        $this->formats = $formats;
61
        $this->oauthEnabled = $oauthEnabled;
62
        $this->oauthClientId = $oauthClientId;
63
        $this->oauthClientSecret = $oauthClientSecret;
64
        $this->oauthType = $oauthType;
65
        $this->oauthFlow = $oauthFlow;
66
        $this->oauthTokenUrl = $oauthTokenUrl;
67
        $this->oauthAuthorizationUrl = $oauthAuthorizationUrl;
68
        $this->oauthScopes = $oauthScopes;
69
    }
70
71
    public function __invoke(Request $request)
72
    {
73
        $documentation = new Documentation($this->resourceNameCollectionFactory->create(), $this->title, $this->description, $this->version, $this->formats);
74
75
        return new Response($this->twig->render('@ApiPlatform/SwaggerUi/index.html.twig', $this->getContext($request, $documentation)));
76
    }
77
78
    /**
79
     * Gets the base Twig context.
80
     *
81
     * @param Request $request
82
     *
83
     * @return array
84
     */
85
    private function getContext(Request $request, Documentation $documentation): array
86
    {
87
        $context = [
88
            'title' => $this->title,
89
            'description' => $this->description,
90
            'formats' => $this->formats,
91
        ];
92
93
        $swaggerData = [
94
            'url' => $this->urlGenerator->generate('api_doc', ['format' => 'json']),
95
            'spec' => $this->normalizer->normalize($documentation, 'json'),
96
        ];
97
98
        $swaggerData['oauth'] = [
99
            'enabled' => $this->oauthEnabled,
100
            'clientId' => $this->oauthClientId,
101
            'clientSecret' => $this->oauthClientSecret,
102
            'type' => $this->oauthType,
103
            'flow' => $this->oauthFlow,
104
            'tokenUrl' => $this->oauthTokenUrl,
105
            'authorizationUrl' => $this->oauthAuthorizationUrl,
106
            'scopes' => $this->oauthScopes,
107
        ];
108
109
        if ($request->isMethodSafe(false) && null !== $resourceClass = $request->attributes->get('_api_resource_class')) {
110
            $swaggerData['id'] = $request->attributes->get('id');
111
            $swaggerData['queryParameters'] = $request->query->all();
112
113
            $metadata = $this->resourceMetadataFactory->create($resourceClass);
114
            $swaggerData['shortName'] = $metadata->getShortName();
115
116
            if (null !== $collectionOperationName = $request->attributes->get('_api_collection_operation_name')) {
117
                $swaggerData['operationId'] = sprintf('%s%sCollection', $collectionOperationName, $swaggerData['shortName']);
118
            } elseif (null !== $itemOperationName = $request->attributes->get('_api_item_operation_name')) {
119
                $swaggerData['operationId'] = sprintf('%s%sItem', $itemOperationName, $swaggerData['shortName']);
120
            }
121
122
            list($swaggerData['path'], $swaggerData['method']) = $this->getPathAndMethod($swaggerData);
123
        }
124
125
        return $context + ['swagger_data' => $swaggerData];
126
    }
127
128
    private function getPathAndMethod(array $swaggerData): array
129
    {
130
        foreach ($swaggerData['spec']['paths'] as $path => $operations) {
131
            foreach ($operations as $method => $operation) {
132
                if ($operation['operationId'] === $swaggerData['operationId']) {
133
                    return [$path, $method];
134
                }
135
            }
136
        }
137
138
        throw new RuntimeException(sprintf('The operation "%s" cannot be found in the Swagger specification.', $swaggerData['operationId']));
139
    }
140
}
141