Passed
Push — main ( c5612c...d21d40 )
by Thomas
02:40
created

App::addRoute()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

Changes 0
Metric Value
eloc 1
dl 0
loc 3
ccs 2
cts 2
cp 1
rs 10
c 0
b 0
f 0
cc 1
nc 1
nop 1
crap 1
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Conia\Chuck;
6
7
use Closure;
8
use Throwable;
9
use Conia\Chuck\Exception\RuntimeException;
10
use Conia\Chuck\MiddlewareInterface;
11
use Conia\Chuck\ResponseFactory;
12
use Conia\Chuck\Entry;
13
use Conia\Chuck\Registry;
14
use Conia\Chuck\Routing\{Route, Group, Router, AddsRoutes};
15
use Psr\Http\Message\ResponseFactoryInterface;
16
use Psr\Http\Message\ServerRequestInterface;
17
use Psr\Http\Message\StreamFactoryInterface;
18
use Psr\Container\ContainerInterface;
19
20
/** @psalm-consistent-constructor */
21
class App
22
{
23
    use AddsRoutes;
24
25 22
    public function __construct(
26
        protected Config $config,
27
        protected Router $router,
28
        protected Registry $registry,
29
    ) {
30 22
        $this->initializeRegistry();
31
    }
32
33 20
    public static function create(Config $config, ?ContainerInterface $container = null): static
34
    {
35 20
        $registry = new Registry($container);
36 20
        $router = new Router();
37
38 20
        $errorHandler = new ErrorHandler($config, $registry);
0 ignored issues
show
Bug introduced by
The type Conia\Chuck\ErrorHandler was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
39 20
        $errorHandler->setup();
40
41 20
        return new static($config, $router, $registry);
42
    }
43
44 13
    public function router(): Router
45
    {
46 13
        return $this->router;
47
    }
48
49 1
    public function config(): Config
50
    {
51 1
        return $this->config;
52
    }
53
54 2
    public function registry(): Registry
55
    {
56 2
        return $this->registry;
57
    }
58
59 14
    public function addRoute(Route $route): void
60
    {
61 14
        $this->router->addRoute($route);
62
    }
63
64 1
    public function addGroup(Group $group): void
65
    {
66 1
        $this->router->addGroup($group);
67
    }
68
69 1
    public function group(
70
        string $patternPrefix,
71
        Closure $createClosure,
72
        ?string $namePrefix = null,
73
    ): Group {
74 1
        $group = new Group($patternPrefix, $createClosure, $namePrefix);
75 1
        $this->router->addGroup($group);
76
77 1
        return $group;
78
    }
79
80 1
    public function staticRoute(
81
        string $prefix,
82
        string $path,
83
        ?string $name = null,
84
    ): void {
85 1
        $this->router->addStatic($prefix, $path, $name);
86
    }
87
88
    /**
89
     * @param MiddlewareInterface|callable(
90
     *     Request,
91
     *     callable
92
     * ):\Conia\Chuck\Response $middleware
93
     *
94
     * TODO: Why can't we import the custom psalm type MiddlewareCallable from MiddlewareInterface
95
     */
96 5
    public function middleware(MiddlewareInterface|callable ...$middleware): void
97
    {
98 5
        $this->router->middleware(...$middleware);
99
    }
100
101
    /**
102
     * @param non-empty-string $key
0 ignored issues
show
Documentation Bug introduced by
The doc comment non-empty-string at position 0 could not be parsed: Unknown type name 'non-empty-string' at position 0 in non-empty-string.
Loading history...
103
     * @param object|class-string $value
104
     * */
105 2
    public function register(string $key, object|string $value): Entry
106
    {
107 2
        return $this->registry->add($key, $value);
108
    }
109
110 22
    protected function initializeRegistry(): void
111
    {
112 22
        $registry = $this->registry;
113
114 22
        $registry->addAnyway(Config::class, $this->config);
115 22
        $registry->addAnyway($this->config::class, $this->config);
116 22
        $registry->addAnyway(Router::class, $this->router);
117 22
        $registry->addAnyway($this->router::class, $this->router);
118 22
        $registry->addAnyway(App::class, $this);
119
120 22
        $registry->addAnyway(ResponseFactoryInterface::class, \Nyholm\Psr7\Factory\Psr17Factory::class);
121 22
        $registry->addAnyway(StreamFactoryInterface::class, \Nyholm\Psr7\Factory\Psr17Factory::class);
122 22
        $registry->addAnyway(ResponseFactory::class, new ResponseFactory($this->registry));
123 22
        $registry->addAnyway(ServerRequestInterface::class, function (): ServerRequestInterface {
124
            try {
125 5
                $psr17Factory = new \Nyholm\Psr7\Factory\Psr17Factory();
126 5
                $creator = new \Nyholm\Psr7Server\ServerRequestCreator(
127 5
                    $psr17Factory, // ServerRequestFactory
128 5
                    $psr17Factory, // UriFactory
129 5
                    $psr17Factory, // UploadedFileFactory
130 5
                    $psr17Factory  // StreamFactory
131 5
                );
132 5
                return $creator->fromGlobals();
133
                // @codeCoverageIgnoreStart
134
            } catch (Throwable) {
135
                throw new RuntimeException('Install nyholm/psr7-server');
136
                // @codeCoverageIgnoreEnd
137
            }
138 22
        });
139
    }
140
141 5
    public function run(): Response
142
    {
143 5
        $serverRequest = $this->registry->get(ServerRequestInterface::class);
144 5
        assert($serverRequest instanceof ServerRequestInterface);
145 5
        $request = new Request($serverRequest);
146 5
        $this->registry->addAnyway(Request::class, $request);
147
148 5
        $response = $this->router->dispatch($request, $this->config, $this->registry);
149
150 5
        (new Emitter())->emit($response->psr7());
151
152 5
        return $response;
153
    }
154
}
155