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

DevServer::create()   B

Complexity

Conditions 6
Paths 1

Size

Total Lines 37

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 37
rs 8.7057
c 0
b 0
f 0
cc 6
nc 1
nop 2
1
<?php
2
3
namespace allejo\stakx\Server;
4
5
use allejo\stakx\Compiler;
6
use allejo\stakx\Filesystem\File;
7
use allejo\stakx\Filesystem\FilesystemPath;
8
use allejo\stakx\Service;
9
use Psr\Http\Message\ServerRequestInterface;
10
use React\Http\Response;
11
use React\Http\Server;
12
use Symfony\Component\Filesystem\Exception\FileNotFoundException;
13
14
class DevServer
15
{
16
    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...
17
    {
18
        $preparedPath = substr($url, 0, 1) === '/' ? substr($url, 1) : $url;
19
        $path = new FilesystemPath($preparedPath);
20
21
        try
22
        {
23
            $file = new File($path);
24
            $mime = MimeDetector::getMimeType($file->getExtension());
25
26
            return new Response(200, ['Content-Type' => $mime], $file->getContents());
27
        }
28
        catch (FileNotFoundException $e)
29
        {
30
            if (!$continueNesting)
31
            {
32
                return null;
33
            }
34
35
            $theme = Service::getOption('theme');
36
            $themeFile = "_themes/${theme}/" . $url;
37
38
            return self::searchAsset($themeFile, false);
39
        }
40
    }
41
42
    public static function create(PageViewRouter $router, Compiler $compiler)
43
    {
44
        $dispatcher = RouteDispatcher::create($router, $compiler);
45
46
        return new Server(function (ServerRequestInterface $request) use ($router, $dispatcher) {
47
            $httpMethod = $request->getMethod();
48
            $urlPath = RouteDispatcher::normalizeUrl($request->getUri()->getPath());
49
50
            if ($httpMethod !== 'GET')
51
            {
52
                return new Response(406, ['Content-Type' => 'text/plain'], 'Method not allowed');
53
            }
54
55
            $routeInfo = $dispatcher->dispatch($httpMethod, $urlPath);
56
57
            switch ($routeInfo[0])
58
            {
59
                case \FastRoute\Dispatcher::FOUND:
60
                    $params = isset($routeInfo[2]) ? $routeInfo[2] : [];
61
                    return $routeInfo[1]($request, ...array_values($params));
62
63
                case \FastRoute\Dispatcher::NOT_FOUND:
64
                    $response = DevServer::return404();
65
                    $guessFile = self::searchAsset($urlPath);
66
67
                    if ($guessFile !== null)
68
                    {
69
                        $response = $guessFile;
70
                    }
71
72
                    return $response;
73
74
                default:
75
                    return DevServer::return404();
76
            }
77
        });
78
    }
79
80
    /**
81
     * Return a 200 HTML Response.
82
     *
83
     * This is just a utility function available.
84
     *
85
     * @param string $content
86
     *
87
     * @return Response
88
     */
89
    public static function return200($content, $mimeType = 'text/html')
90
    {
91
        return new Response(200, ['Content-Type' => $mimeType], $content);
92
    }
93
94
    /**
95
     * Return a 404 Response.
96
     *
97
     * This is just a utility function available.
98
     *
99
     * @return Response
100
     */
101
    public static function return404()
102
    {
103
        return new Response(404, ['Content-Type' => 'text/plain'], '404: Page not found');
104
    }
105
}