Test Failed
Pull Request — master (#16)
by Divine Niiquaye
02:47
created

RouteHandler   A

Complexity

Total Complexity 13

Size/Duplication

Total Lines 67
Duplicated Lines 0 %

Test Coverage

Coverage 100%

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 31
dl 0
loc 67
ccs 20
cts 20
cp 1
rs 10
c 1
b 0
f 0
wmc 13

2 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 4 1
C handle() 0 46 12
1
<?php
2
3
declare(strict_types=1);
4
5
/*
6
 * This file is part of Flight Routing.
7
 *
8
 * PHP version 7.1 and above required
9
 *
10
 * @author    Divine Niiquaye Ibok <[email protected]>
11
 * @copyright 2019 Biurad Group (https://biurad.com/)
12
 * @license   https://opensource.org/licenses/BSD-3-Clause License
13
 *
14
 * For the full copyright and license information, please view the LICENSE
15
 * file that was distributed with this source code.
16
 */
17
18
namespace Flight\Routing\Handlers;
19
20
use Flight\Routing\{Exceptions\RouteNotFoundException, Route};
21
use Psr\Http\Message\{ResponseFactoryInterface, ResponseInterface, ServerRequestInterface};
22
use Psr\Http\Server\RequestHandlerInterface;
23
24
/**
25
 * Default routing request handler.
26
 *
27
 * if route is found in request attribute, dispatch the route handler's
28
 * response to the browser and provides ability to detect right response content-type.
29
 *
30
 * @author Divine Niiquaye Ibok <[email protected]>
31
 */
32
final class RouteHandler implements RequestHandlerInterface
33
{
34
    public const CONTENT_TYPE = 'Content-Type';
35
36
    /** @var ResponseFactoryInterface */
37
    private $responseFactory;
38
39
    /** @var null|callable(mixed,array) */
40
    private $handlerResolver = null;
41
42
    public function __construct(ResponseFactoryInterface $responseFactory, callable $handlerResolver = null)
43
    {
44 39
        $this->handlerResolver = $handlerResolver;
45
        $this->responseFactory = $responseFactory;
46 39
    }
47 39
48 39
    /**
49
     * {@inheritdoc}
50
     *
51
     * @throws RouteNotFoundException
52
     */
53
    public function handle(ServerRequestInterface $request): ResponseInterface
54
    {
55 37
        $route = $request->getAttribute(Route::class);
56
57 37
        if (!$route instanceof Route) {
58
            throw new RouteNotFoundException(\sprintf('Unable to find the controller for path "%s". The route is wrongly configured.', $request->getUri()->getPath()));
59 37
        }
60
61 37
        // Resolve route handler arguments ...
62 37
        if (null !== $handlerResolver = $this->handlerResolver) {
63
            $route->arguments([\get_class($request) => $request, \get_class($this->responseFactory) => $this->responseFactory]);
64
        } else {
65 37
            foreach ([$request, $this->responseFactory] as $psr7) {
66 3
                foreach (@\class_implements($psr7) ?: [] as $psr7Interface) {
67 3
                    $route->argument($psr7Interface, $psr7);
68
                }
69 3
70
                $route->argument(\get_class($psr7), $psr7);
71
            }
72 34
        }
73
74
        $response = $route($request, $handlerResolver);
75
76
        if (!$response instanceof ResponseInterface) {
77
            ($result = $this->responseFactory->createResponse())->getBody()->write($response);
78
            $response = $result;
79
        }
80
81
        if ($response->hasHeader(self::CONTENT_TYPE)) {
82
            return $response;
83
        }
84
85 34
        $contents = (string) $response->getBody();
86
        $matched = \preg_match('#(?|\"\w\"\:.*?\,?\}|^\<\?(xml).*|[^>]+\>.*?\<\/(\w+)\>)$#ms', $contents, $matches);
87
88 34
        if (!$matchedType = $matches[2] ?? $matches[1] ?? 0 !== $matched) {
89 24
            return $response->withHeader(self::CONTENT_TYPE, '{' === @$contents[0] ? 'application/json' : 'text/plain; charset=utf-8');
90
        }
91
92 10
        if ('svg' === $matchedType) {
93 1
            $xmlResponse = $response->withHeader(self::CONTENT_TYPE, 'image/svg+xml');
94
        } elseif ('xml' === $matchedType) {
95
            $xmlResponse = $response->withHeader(self::CONTENT_TYPE, 'application/xml; charset=utf-8');
96
        }
97 10
98
        return $xmlResponse ?? $response->withHeader(self::CONTENT_TYPE, 'text/html; charset=utf-8');
99
    }
100
}
101