Passed
Pull Request — master (#4)
by Justin
03:07
created

Framework::requestFromGlobals()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

Changes 0
Metric Value
dl 0
loc 4
ccs 2
cts 2
cp 1
rs 10
c 0
b 0
f 0
cc 1
nc 1
nop 0
crap 1
1
<?php
2
3
namespace Fermi;
4
5
use FastRoute\Dispatcher;
6
use League\Plates\Engine;
7
use FastRoute\RouteCollector;
8
use Psr\Http\Message\ResponseInterface;
9
use Zend\Diactoros\ServerRequestFactory;
10
use Psr\Http\Server\MiddlewareInterface;
11
use Psr\Http\Server\RequestHandlerInterface;
12
use Psr\Http\Message\ServerRequestInterface;
13
14
class Framework
15
{
16
    /**
17
     * Create a new request from the php globals environment.
18
     *
19
     * Note: If you want to use a different PSR-7 implementation this would be
20
     * the proper place to replace the stock implementation of zend\diactoros.
21
     *
22
     * @return Psr\Http\Message\ServerRequestInterface
23
     */
24 9
    public static function requestFromGlobals(): ServerRequestInterface
25
    {
26 9
        return ServerRequestFactory::fromGlobals();
27
    }
28
29
    /**
30
     * Returns the full middleware stack.
31
     *
32
     * @return array
33
     */
34 1
    public static function stack(): array
35
    {
36 1
        return static::config('middleware');
37
    }
38
39
    /**
40
     * Create a middleware stack that is resolvable by PSR-15.
41
     *
42
     * @param  array $stack array of callables or strings.
43
     * @return array
44
     */
45 2
    public static function middleware(array $stack): array
46
    {
47
        return array_map(function ($callable) {
48 2
            $callable = is_string($callable) ? static::lazy($callable) : $callable;
49 2
            return $callable;
50 2
        }, $stack);
51
    }
52
53
    /**
54
     * Returns a closure which, when called, will create an instance of the
55
     * class passed to it and then call __invoke() with middleware arguments.
56
     *
57
     * @param  string   $className fully-qualified name of a class
58
     * @return callable
59
     */
60 2
    public static function lazy(string $className): callable
61
    {
62
        return function (ServerRequestInterface $request, RequestHandlerInterface $handler) use ($className): ResponseInterface {
63 1
            $class = new $className();
64 1
            if ($class instanceof MiddlewareInterface) {
65 1
                return $class->process($request, $handler);
66
            } else {
67
                return $class($request, $handler);
68
            }
69 2
        };
70
    }
71
72
    /**
73
     * Use FastRouter\simpleDispatcher to collect the routes into a FastRoute\Dispatcher.
74
     *
75
     * @param  Psr\Http\Message\ServerRequestInterface $request
76
     * @param  string                                  $path
77
     * @return Psr\Http\Message\ResponseInterface
78
     */
79 2
    public static function router(ServerRequestInterface $request, string $path = null): ResponseInterface
80
    {
81 2
        $path = $path ?: __DIR__ . "/../app/routes.php";
82
        $dispatcher = \FastRoute\simpleDispatcher(function (RouteCollector $r) use ($path) {
83 2
            include $path;
84 2
        });
85 2
        $match = $dispatcher->dispatch($request->getMethod(), $request->getUri()->getPath());
86 2
        return static::resolve($request, $match);
87
    }
88
89
    /**
90
     * Resolve an HTTP request match.
91
     *
92
     * @param  Psr\Http\Message\ServerRequestInterface $request
93
     * @param  array                                   $match Route match. When using fast router will be array.
94
     * @return Psr\Http\Message\ResponseInterface
95
     */
96 3
    public static function resolve(ServerRequestInterface $request, array $match): ResponseInterface
97
    {
98 3
        switch ($match[0]) {
99 3
            case Dispatcher::FOUND:
100 1
                array_unshift($match[2], $request);
101 1
                return call_user_func_array($match[1], $match[2]);
102 2
            case Dispatcher::METHOD_NOT_ALLOWED:
103 1
                return Response::error405($request);
104
            default:
105 1
                return Response::error404($request);
106
        }
107
    }
108
109
    /**
110
     * Load a given configuration file or array.
111
     *
112
     * @param  string $name config file name
113
     * @param  string $dir  path to directory storing the config file
114
     * @return array
115
     */
116 4
    public static function config(string $name, string $dir = null): array
117
    {
118 4
        $dir = $dir ?: __DIR__ . "/../config";
119 4
        $location = rtrim($dir, "/") . "/" . ltrim($name, "/") . ".php";
120 4
        if (!file_exists($location)) {
121 1
            throw new \InvalidArgumentException('Requested configuration file does not exist: ' . $location);
122
        }
123 3
        $config = include $location;
124 3
        if (!is_array($config)) {
125 1
            throw new \InvalidArgumentException('Requested configuration file does not return an array: ' . $location);
126
        }
127 2
        return $config;
128
    }
129
130
    /**
131
     * Get the rendering engine.
132
     *
133
     * @return League\Plates\Engine
134
     */
135 1
    public static function engine(): Engine
136
    {
137 1
        return new Engine(__DIR__ . "/../views");
138
    }
139
140
    /**
141
     * Render a given view with our template engine.
142
     *
143
     * @param  string $view   name of the view
144
     * @param  array  $data   data to pass through to our template
145
     * @param  Engine $engine alternative rendering engine
146
     * @return string
147
     */
148 2
    public static function render(string $view, array $data, Engine $engine = null): string
149
    {
150 2
        $engine = ($engine instanceof Engine) ? $engine : static::engine();
151 2
        return $engine->render($view, $data);
152
    }
153
}
154