Completed
Pull Request — master (#24)
by
unknown
02:07
created

DocsController::swaggerFileAction()   A

Complexity

Conditions 4
Paths 3

Size

Total Lines 23

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 13
CRAP Score 4

Importance

Changes 0
Metric Value
dl 0
loc 23
ccs 13
cts 13
cp 1
rs 9.552
c 0
b 0
f 0
cc 4
nc 3
nop 1
crap 4
1
<?php
2
3
namespace HarmBandstra\SwaggerUiBundle\Controller;
4
5
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
6
use Symfony\Component\Filesystem\Exception\FileNotFoundException;
7
use Symfony\Component\HttpFoundation\JsonResponse;
8
use Symfony\Component\HttpFoundation\RedirectResponse;
9
use Symfony\Component\HttpFoundation\Request;
10
use Symfony\Component\HttpFoundation\Response;
11
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
12
use Symfony\Component\Yaml\Yaml;
13
14
class DocsController extends AbstractController
15
{
16
    /** @var string */
17
    private $projectDir;
18
19
    /** @var array */
20
    private $swaggerFiles;
21
22
    /** @var string */
23
    private $directory;
24
25
    /** @var string */
26
    private $assetUrlPath;
27
28
    /** @var string */
29
    private $configFile;
30
31 6
    public function __construct($projectDir, $swaggerFiles, $directory, $assetUrlPath, $configFile)
32
    {
33 6
        $this->projectDir = $projectDir;
34 6
        $this->swaggerFiles = $swaggerFiles;
35 6
        $this->directory = $directory;
36 6
        $this->assetUrlPath = $assetUrlPath;
37 6
        $this->configFile = $configFile;
38 6
    }
39
40
    /**
41
     * @param Request $request
42
     *
43
     * @return Response
44
     */
45 1
    public function indexAction(Request $request)
46
    {
47 1
        if (!$request->get('url') || (!$request->get('configUrl') && $this->configFile)) {
48
            // if there is no ?url=... parameter, redirect to the default one
49 1
            $specFile = reset($this->swaggerFiles);
50
51 1
            return $this->redirect($this->getRedirectUrlToSpec($specFile, $request->get('url')));
52
        }
53
        $contents = @file_get_contents(__DIR__ . '/../Resources/public/index.html');
54
        if ($contents === false) {
55
            throw new \RuntimeException('Unable to load [Resources/public/index.html]. Did [ScriptHandler::linkAssets] run correctly?');
56
        }
57
58
        return new Response($contents);
59
    }
60
61
    /**
62
     * @param string $fileName
63
     *
64
     * @return RedirectResponse
65
     */
66 1
    public function redirectAction($fileName)
67
    {
68
        // redirect to swagger file if that's what we're looking for
69 1
        if (in_array($fileName, $this->swaggerFiles, true)) {
70 1
            return $this->redirect($this->getRedirectUrlToSpec($fileName));
71
        }
72
73
        // redirect to the assets dir so that relative links work
74
        return $this->redirect($this->assetUrlPath . $fileName);
75
    }
76
77
    /**
78
     * @param string $fileName
79
     *
80
     * @return JsonResponse|Response
81
     */
82 4
    public function swaggerFileAction($fileName)
83
    {
84
        try {
85 4
            $filePath = $this->getFilePath($fileName);
86 2
        } catch (\Exception $e) {
87 2
            return new JsonResponse($e->getMessage(), Response::HTTP_NOT_FOUND);
88
        }
89
90 2
        $extension = strtolower(pathinfo($filePath, PATHINFO_EXTENSION));
91 2
        if ($extension === 'yml' || $extension === 'yaml') {
92 1
            $fileContents = Yaml::parse(file_get_contents($filePath));
93
94 1
            return new JsonResponse($fileContents);
95
        }
96
97 1
        $fileContents = file_get_contents($filePath);
98
99 1
        return new Response(
100 1
            $fileContents,
101 1
            Response::HTTP_OK,
102 1
            ['Content-Type' => 'application/json']
103
        );
104
    }
105
106
    /**
107
     * @param string $fileName
108
     *
109
     * @return string
110
     */
111 4
    private function getFilePath($fileName = '')
112
    {
113 4
        if ($fileName !== '' && !in_array($fileName, $this->swaggerFiles)) {
114 1
            throw new \RuntimeException(
115 1
                sprintf('File [%s] not defined under [hb_swagger_ui.files] in config.yml.', $fileName)
116
            );
117
        }
118
119 3
        if ($this->directory === '') {
120
            throw new \RuntimeException(
121
                'Directory [hb_swagger_ui.directory] not defined or empty in config.yml.'
122
            );
123
        }
124
125 3
        $filePath = realpath($this->directory . DIRECTORY_SEPARATOR . $fileName);
126 3
        if (!is_file($filePath)) {
127 1
            throw new FileNotFoundException(sprintf('File [%s] not found.', $fileName));
128
        }
129
130 2
        return $filePath;
131
    }
132
133
    /**
134
     * @param string $fileName
135
     *
136
     * @return string
137
     */
138 2
    private function getRedirectUrlToSpec($fileName, $url = null)
139
    {
140 2
        if ($url) {
141
            $specUrl = $url;
142
        } else {
143 2
            if (strpos($fileName, '/') === 0 || preg_match('#http[s]?://#', $fileName)) {
144
                // if absolute path or URL use it raw
145
                $specUrl = $fileName;
146
            } else {
147 2
                $specUrl = $this->generateUrl(
148 2
                    'hb_swagger_ui_swagger_file',
149 2
                    ['fileName' => $fileName],
150 2
                    UrlGeneratorInterface::ABSOLUTE_PATH
151
                );
152
            }
153
        }
154
155 2
        $parameters = ['url' => $specUrl];
156
157 2
        if ($this->configFile) {
158 2
            $parameters['configUrl'] = $this->configFile;
159
        }
160
161 2
        return $this->generateUrl('hb_swagger_ui_default', $parameters);
162
    }
163
}
164