Completed
Push — master ( 4779d9...563222 )
by Harm
07:06
created

DocsController::getFilePath()   B

Complexity

Conditions 6
Paths 7

Size

Total Lines 23

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 10
CRAP Score 6.1666

Importance

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

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For string values, the empty string '' is a special case, in particular the following results might be unexpected:

''   == false // true
''   == null  // true
'ab' == false // false
'ab' == null  // false

// It is often better to use strict comparison
'' === false // false
'' === null  // false
Loading history...
154 3
            $parameters['configUrl'] = $this->generateUrl(
155 3
                'hb_swagger_ui_swagger_file',
156 3
                ['fileName' => $this->configFile],
157 3
                UrlGeneratorInterface::ABSOLUTE_PATH
158
            );
159
        }
160
161 3
        return $this->generateUrl('hb_swagger_ui_default', $parameters);
162
    }
163
}
164