Completed
Pull Request — master (#75)
by Vladimir
02:16
created

DevServer   A

Complexity

Total Complexity 12

Size/Duplication

Total Lines 93
Duplicated Lines 0 %

Coupling/Cohesion

Components 0
Dependencies 9

Importance

Changes 0
Metric Value
wmc 12
lcom 0
cbo 9
dl 0
loc 93
rs 10
c 0
b 0
f 0

4 Methods

Rating   Name   Duplication   Size   Complexity  
A searchAsset() 0 25 4
B create() 0 37 6
A return200() 0 4 1
A return404() 0 4 1
1
<?php
2
3
/**
4
 * @copyright 2018 Vladimir Jimenez
5
 * @license   https://github.com/stakx-io/stakx/blob/master/LICENSE.md MIT
6
 */
7
8
namespace allejo\stakx\Server;
9
10
use allejo\stakx\Compiler;
11
use allejo\stakx\Filesystem\File;
12
use allejo\stakx\Filesystem\FilesystemPath;
13
use allejo\stakx\Service;
14
use Psr\Http\Message\ServerRequestInterface;
15
use React\Http\Response;
16
use React\Http\Server;
17
use Symfony\Component\Filesystem\Exception\FileNotFoundException;
18
19
class DevServer
20
{
21
    private static function searchAsset($url, $continueNesting = true)
0 ignored issues
show
Documentation introduced by
The return type could not be reliably inferred; please add a @return annotation.

Our type inference engine in quite powerful, but sometimes the code does not provide enough clues to go by. In these cases we request you to add a @return annotation as described here.

Loading history...
22
    {
23
        $preparedPath = substr($url, 0, 1) === '/' ? substr($url, 1) : $url;
24
        $path = new FilesystemPath($preparedPath);
25
26
        try
27
        {
28
            $file = new File($path);
29
            $mime = MimeDetector::getMimeType($file->getExtension());
30
31
            return new Response(200, ['Content-Type' => $mime], $file->getContents());
32
        }
33
        catch (FileNotFoundException $e)
34
        {
35
            if (!$continueNesting)
36
            {
37
                return null;
38
            }
39
40
            $theme = Service::getOption('theme');
41
            $themeFile = "_themes/${theme}/" . $url;
42
43
            return self::searchAsset($themeFile, false);
44
        }
45
    }
46
47
    public static function create(PageViewRouter $router, Compiler $compiler)
48
    {
49
        $dispatcher = RouteDispatcher::create($router, $compiler);
50
51
        return new Server(function (ServerRequestInterface $request) use ($router, $dispatcher) {
52
            $httpMethod = $request->getMethod();
53
            $urlPath = RouteDispatcher::normalizeUrl($request->getUri()->getPath());
54
55
            if ($httpMethod !== 'GET')
56
            {
57
                return new Response(406, ['Content-Type' => 'text/plain'], 'Method not allowed');
58
            }
59
60
            $routeInfo = $dispatcher->dispatch($httpMethod, $urlPath);
61
62
            switch ($routeInfo[0])
63
            {
64
                case \FastRoute\Dispatcher::FOUND:
65
                    $params = isset($routeInfo[2]) ? $routeInfo[2] : [];
66
                    return $routeInfo[1]($request, ...array_values($params));
67
68
                case \FastRoute\Dispatcher::NOT_FOUND:
69
                    $response = DevServer::return404();
70
                    $guessFile = self::searchAsset($urlPath);
71
72
                    if ($guessFile !== null)
73
                    {
74
                        $response = $guessFile;
75
                    }
76
77
                    return $response;
78
79
                default:
80
                    return DevServer::return404();
81
            }
82
        });
83
    }
84
85
    /**
86
     * Return a 200 HTML Response.
87
     *
88
     * This is just a utility function available.
89
     *
90
     * @param string $content
91
     * @param mixed  $mimeType
92
     *
93
     * @return Response
94
     */
95
    public static function return200($content, $mimeType = 'text/html')
96
    {
97
        return new Response(200, ['Content-Type' => $mimeType], $content);
98
    }
99
100
    /**
101
     * Return a 404 Response.
102
     *
103
     * This is just a utility function available.
104
     *
105
     * @return Response
106
     */
107
    public static function return404()
108
    {
109
        return new Response(404, ['Content-Type' => 'text/plain'], '404: Page not found');
110
    }
111
}
112