Passed
Push — master ( ccc9fa...bee35f )
by Gabor
03:14
created

ServiceAdapter::match()   B

Complexity

Conditions 6
Paths 6

Size

Total Lines 31
Code Lines 17

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 17
CRAP Score 6

Importance

Changes 0
Metric Value
dl 0
loc 31
ccs 17
cts 17
cp 1
rs 8.439
c 0
b 0
f 0
cc 6
eloc 17
nc 6
nop 1
crap 6
1
<?php
2
/**
3
 * WebHemi
4
 *
5
 * PHP version 7.1
6
 *
7
 * @copyright 2012 - 2017 Gixx-web (http://www.gixx-web.com)
8
 * @license   https://opensource.org/licenses/MIT The MIT License (MIT)
9
 * @link      http://www.gixx-web.com
10
 */
11
declare(strict_types = 1);
12
13
namespace WebHemi\Router\ServiceAdapter\Base;
14
15
use WebHemi\Configuration\ServiceInterface as ConfigurationInterface;
16
use WebHemi\Environment\ServiceInterface as EnvironmentInterface;
17
use WebHemi\Http\ServerRequestInterface;
18
use WebHemi\Router\ProxyInterface;
19
use WebHemi\Router\Result\Result;
20
use WebHemi\Router\ServiceInterface;
21
22
/**
23
 * Class ServiceAdapter.
24
 */
25
class ServiceAdapter implements ServiceInterface
26
{
27
    /** @var Result */
28
    private $result;
29
    /** @var array */
30
    private $routes;
31
    /** @var string */
32
    private $module;
33
    /** @var string */
34
    private $application;
35
    /** @var string */
36
    private $applicationPath;
37
    /** @var ProxyInterface */
38
    private $proxy;
39
40
    /**
41
     * ServiceAdapter constructor.
42
     *
43
     * @param ConfigurationInterface $configuration
44
     * @param EnvironmentInterface   $environmentManager
45
     * @param Result                 $routeResult
46
     * @param null|ProxyInterface    $routerProxy
47
     */
48 10
    public function __construct(
49
        ConfigurationInterface $configuration,
50
        EnvironmentInterface $environmentManager,
51
        Result $routeResult,
52
        ? ProxyInterface $routerProxy = null
53
    ) {
54 10
        $module = $environmentManager->getSelectedModule();
55 10
        $this->routes = $configuration->getData('router/'.$module);
56 10
        $this->proxy = $routerProxy;
57 10
        $this->result = $routeResult;
58 10
        $this->module = $environmentManager->getSelectedModule();
59 10
        $this->application = $environmentManager->getSelectedApplication();
60 10
        $this->applicationPath = $environmentManager->getSelectedApplicationUri();
61 10
    }
62
63
    /**
64
     * Processes the Request and give a Result.
65
     *
66
     * @param ServerRequestInterface $request
67
     * @return Result
68
     */
69 8
    public function match(ServerRequestInterface $request) : Result
70
    {
71 8
        $httpMethod = $request->getMethod();
72 8
        $uri        = $this->getApplicationRouteUri($request);
73
74 8
        $result = clone $this->result;
75 8
        $routeDefinition = $this->findRouteDefinition($uri);
76
77 8
        if (empty($routeDefinition)) {
78 3
            return $result->setStatus(Result::CODE_NOT_FOUND);
79
        }
80
81 7
        if (!in_array($httpMethod, $routeDefinition['allowed_methods'])) {
82 3
            return $result->setStatus(Result::CODE_BAD_METHOD);
83
        }
84
85 6
        $result->setParameters($routeDefinition['parameters'])
86 6
            ->setResource($routeDefinition['resource'])
87 6
            ->setMatchedMiddleware($routeDefinition['middleware']);
88
89
        // Check if we marked the middleware to be resolved by the proxy
90 6
        if ($routeDefinition['middleware'] === 'proxy' && $this->proxy instanceof ProxyInterface) {
91 1
            $this->proxy->resolveMiddleware($this->application, $result);
92
        }
93
94 6
        if (empty($result->getMatchedMiddleware())) {
95 1
            return $result->setStatus(Result::CODE_NOT_FOUND);
96
        }
97
98 6
        return $result->setStatus(Result::CODE_FOUND);
99
    }
100
101
    /**
102
     * According to the application path, determines the route uri
103
     *
104
     * @param ServerRequestInterface $request
105
     * @return string
106
     */
107 9
    private function getApplicationRouteUri(ServerRequestInterface $request) : string
108
    {
109 9
        $uri = $request->getUri()->getPath();
110
111 9
        if ($this->applicationPath != '/' && strpos($uri, $this->applicationPath) === 0) {
112 2
            $uri = substr($uri, strlen($this->applicationPath));
113
        }
114
115 9
        return empty($uri) ? '/' : $uri;
116
    }
117
118
    /**
119
     * Searches definition and returns data is found. First find, first served.
120
     *
121
     * @param string $uri
122
     * @return array|null
123
     */
124 8
    private function findRouteDefinition(string $uri) : ? array
125
    {
126 8
        $routeDefinition = [];
127 8
        $matches = [];
128
129 8
        foreach ($this->routes as $resource => $routeData) {
130 8
            $pattern = '#'.$routeData['path'].'#';
131
132 8
            if (preg_match_all($pattern, $uri, $matches, PREG_SET_ORDER, 0)) {
133 7
                $parameters = $this->getMatchParameters($matches);
134
135
                $routeDefinition = [
136 7
                    'uri'             => $uri,
137 7
                    'middleware'      => $routeData['middleware'],
138 7
                    'parameters'      => $parameters,
139 7
                    'resource'        => $resource,
140 7
                    'allowed_methods' => $routeData['allowed_methods']
141
                ];
142
143 8
                break;
144
            }
145
        }
146 8
        return $routeDefinition;
147
    }
148
149
    /**
150
     * Gets the paramters from the route pattern match result.
151
     *
152
     * @param array $matches
153
     * @return array
154
     */
155 7
    private function getMatchParameters(array $matches) : array
156
    {
157 7
        $parameters = [];
158
159 7
        foreach ($matches[0] as $index => $value) {
160 7
            if (!is_numeric($index)) {
161 7
                $parameters[$index] = $value;
162
            }
163
        }
164
165 7
        if ($this->module == 'Website') {
166 6
            $parameters['path'] = !empty($matches[0]['path']) ? $matches[0]['path'] : '/';
167 6
            $parameters['basename'] = !empty($matches[0]['basename']) ? $matches[0]['basename'] : 'index.html';
168
        }
169
170 7
        return $parameters;
171
    }
172
}
173