Completed
Push — master ( d88ff8...31f153 )
by Joschi
02:55
created

Server::getRouteAction()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 4
ccs 2
cts 2
cp 1
rs 10
cc 1
eloc 2
nc 1
nop 2
crap 1
1
<?php
2
3
/**
4
 * apparat-server
5
 *
6
 * @category    Apparat
7
 * @package     Apparat\Server
8
 * @subpackage  Apparat\Server\Infrastructure\Model
9
 * @author      Joschi Kuphal <[email protected]> / @jkphl
10
 * @copyright   Copyright © 2016 Joschi Kuphal <[email protected]> / @jkphl
11
 * @license     http://opensource.org/licenses/MIT The MIT License (MIT)
12
 */
13
14
/***********************************************************************************
15
 *  The MIT License (MIT)
16
 *
17
 *  Copyright © 2016 Joschi Kuphal <[email protected]> / @jkphl
18
 *
19
 *  Permission is hereby granted, free of charge, to any person obtaining a copy of
20
 *  this software and associated documentation files (the "Software"), to deal in
21
 *  the Software without restriction, including without limitation the rights to
22
 *  use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
23
 *  the Software, and to permit persons to whom the Software is furnished to do so,
24
 *  subject to the following conditions:
25
 *
26
 *  The above copyright notice and this permission notice shall be included in all
27
 *  copies or substantial portions of the Software.
28
 *
29
 *  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
30
 *  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
31
 *  FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
32
 *  COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
33
 *  IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
34
 *  CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
35
 ***********************************************************************************/
36
37
namespace Apparat\Server\Infrastructure\Model;
38
39
use Apparat\Object\Ports\Types\Object;
40
use Apparat\Server\Domain\Contract\ActionRouteInterface;
41
use Apparat\Server\Infrastructure\Action\DayAction;
42
use Apparat\Server\Infrastructure\Action\HourAction;
43
use Apparat\Server\Infrastructure\Action\MinuteAction;
44
use Apparat\Server\Infrastructure\Action\MonthAction;
45
use Apparat\Server\Infrastructure\Action\ObjectAction;
46
use Apparat\Server\Infrastructure\Action\SecondAction;
47
use Apparat\Server\Infrastructure\Action\TypeAction;
48
use Apparat\Server\Infrastructure\Action\YearAction;
49
use Apparat\Server\Ports\Action\ActionInterface;
50
use Apparat\Server\Ports\Route\Route;
51
use Psr\Http\Message\ResponseInterface;
52
use Psr\Http\Message\ServerRequestInterface;
53
54
/**
55
 * Server instance
56
 *
57
 * @package Apparat\Server
58
 * @subpackage Apparat\Server\Infrastructure
59
 */
60
class Server extends \Apparat\Server\Domain\Model\Server
61
{
62
    /**
63
     * Asterisk regular expression
64
     *
65
     * @var string
66
     */
67
    const REGEX_ASTERISK = '(?:\%2A)';
68
    /**
69
     * Year route token
70
     *
71
     * @var array
72
     */
73
    protected static $TOKEN_YEAR = ['year' => self::REGEX_ASTERISK.'|(?:\d{4})'];
74
    /**
75
     * Month route token
76
     *
77
     * @var array
78
     */
79
    protected static $TOKEN_MONTH = ['month' => self::REGEX_ASTERISK.'|(?:0[1-9])|(?:1[0-2])'];
80
    /**
81
     * Day route token
82
     *
83
     * @var array
84
     */
85
    protected static $TOKEN_DAY = ['day' => self::REGEX_ASTERISK.'|(?:0[1-9])|(?:[1-2]\d)|(?:3[0-1])'];
86
    /**
87
     * Hour route token
88
     *
89
     * @var array
90
     */
91
    protected static $TOKEN_HOUR = ['hour' => self::REGEX_ASTERISK.'|(?:0[1-9])|(?:1[0-2])'];
92
    /**
93
     * Day route token
94
     *
95
     * @var array
96
     */
97
    protected static $TOKEN_MINUTE = ['minute' => self::REGEX_ASTERISK.'|(?:0[1-9])|(?:[1-4]\d)|(?:5[0-9])'];
98
    /**
99
     * Second route token
100
     *
101
     * @var array
102
     */
103
    protected static $TOKEN_SECOND = ['second' => self::REGEX_ASTERISK.'|(?:0[1-9])|(?:[1-4]\d)|(?:5[0-9])'];
104
105
    /**
106
     * Build and return the default date routes
107
     *
108
     * @param string $prefix Repository route prefix
109
     * @param int $precision Date precision
110
     * @return array Default date routes
111
     */
112 2
    protected function buildDefaultDateRoutes($prefix, $precision)
113
    {
114 1
        return array_slice(
115
            [
116 1
                Route::SECOND => [
117 1
                    $prefix.'/{year}/{month}/{day}/{hour}/{minute}/{second}',
118 1
                    self::$TOKEN_YEAR +
119 1
                    self::$TOKEN_MONTH +
120 1
                    self::$TOKEN_DAY +
121 1
                    self::$TOKEN_HOUR +
122 1
                    self::$TOKEN_MINUTE +
123 1
                    self::$TOKEN_SECOND,
124
                    SecondAction::class
125 1
                ],
126 1
                Route::MINUTE => [
127 1
                    $prefix.'/{year}/{month}/{day}/{hour}/{minute}',
128 1
                    self::$TOKEN_YEAR +
129 1
                    self::$TOKEN_MONTH +
130 1
                    self::$TOKEN_DAY +
131 1
                    self::$TOKEN_HOUR +
132 1
                    self::$TOKEN_MINUTE,
133
                    MinuteAction::class
134 1
                ],
135 2
                Route::HOUR => [
136 1
                    $prefix.'/{year}/{month}/{day}/{hour}',
137 1
                    self::$TOKEN_YEAR +
138 1
                    self::$TOKEN_MONTH +
139 1
                    self::$TOKEN_DAY +
140 2
                    self::$TOKEN_HOUR,
141
                    HourAction::class
142 1
                ],
143 1
                Route::DAY => [
144 1
                    $prefix.'/{year}/{month}/{day}',
145 1
                    self::$TOKEN_YEAR +
146 1
                    self::$TOKEN_MONTH +
147 1
                    self::$TOKEN_DAY,
148
                    DayAction::class
149 1
                ],
150 1
                Route::MONTH => [
151 1
                    $prefix.'/{year}/{month}',
152 1
                    self::$TOKEN_YEAR +
153 1
                    self::$TOKEN_MONTH,
154
                    MonthAction::class
155 1
                ],
156 1
                Route::YEAR => [
157 1
                    $prefix.'/{year}',
158 1
                    self::$TOKEN_YEAR,
159
                    YearAction::class
160 1
                ]
161 1
            ],
162
            6 - $precision
163 1
        );
164
    }
165
166
    /**
167
     * Build and return the default object routes
168
     *
169
     * @param string $prefix Repository route prefix
170
     * @param array $baseDateRoute Base date route
171
     * @param int $numDefaultRoutes Total number of date routes
172
     * @return array Default object routes
173
     */
174 1
    protected function buildDefaultObjectRoutes($prefix, $baseDateRoute, $numDefaultRoutes)
175
    {
176
        // Build a regular expression for all supported object types
177 1
        $enabledObjectTypes = '(?:-(?:(?:'.implode(')|(?:', array_map('preg_quote', Object::getSupportedTypes())).')))';
178 1
        $objectResourceExt = getenv('OBJECT_RESOURCE_EXTENSION');
179
180
        return [
181
            // Default object route
182 1
            Route::OBJECT => [
183 1
                $prefix.$baseDateRoute[0].'/{hidden}{id}{type}{draft}{revision}{format}',
184 1
                $baseDateRoute[1] + [
185 1
                    'hidden' => '\.?',
186 1
                    'id' => '\d+',
187 1
                    'type' => $enabledObjectTypes.'?',
188 1
                    'draft' => '(?:/(\.)?\\'.(2 + $numDefaultRoutes).')?',
189 1
                    'revision' => '(?('.(5 + $numDefaultRoutes).')|(?:-\d+)?)',
190 1
                    'format' => '(?('.(4 + $numDefaultRoutes).')(?:\.'.preg_quote($objectResourceExt).')?)',
191 1
                ],
192
                ObjectAction::class
193 1
            ],
194
            // Default type route
195 1
            Route::TYPE => [
196 1
                $baseDateRoute[0].'/{hidden}{id}{type}{draft}{revision}{format}',
197 1
                $baseDateRoute[1] + [
198 1
                    'hidden' => '\.?',
199 1
                    'id' => self::REGEX_ASTERISK,
200 1
                    'type' => $enabledObjectTypes.'?',
201 1
                    'draft' => '(?:/(\.)?'.self::REGEX_ASTERISK.')?',
202 1
                    'revision' => '(?('.(5 + $numDefaultRoutes).')|(?:-\d+)?)',
203 1
                    'format' => '(?('.(4 + $numDefaultRoutes).')(?:\.'.preg_quote($objectResourceExt).')?)',
204 1
                ],
205
                TypeAction::class
206 1
            ]
207 1
        ];
208
    }
209
210
    /**
211
     * Register the default routes for a particular repository
212
     *
213
     * @param string $repositoryPath Repository path
214
     * @param bool $enable Enable / disable default routes
215
     */
216 1
    public function registerRepositoryDefaultRoutes($repositoryPath = '', $enable = true)
0 ignored issues
show
Unused Code introduced by
The parameter $enable is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
217
    {
218
        // Repository route prefix
219 1
        $prefix = rtrim('/'.$repositoryPath, '/');
220
221
        // Build the list of default routes
222 1
        $defaultDateRoutes = $this->buildDefaultDateRoutes($prefix, getenv('OBJECT_DATE_PRECISION'));
223 1
        $baseDateRoute = count($defaultDateRoutes) ? current($defaultDateRoutes) : ['/', []];
224 1
        $defaultObjectRoutes = $this->buildDefaultObjectRoutes($prefix, $baseDateRoute, count($defaultDateRoutes));
225 1
        $defaultRoutes = $defaultObjectRoutes + $defaultDateRoutes;
226
227
        // Iterate through and register all base routes
228 1
        foreach ($defaultRoutes as $routeName => $routeConfig) {
229 1
            $route = new Route(Route::GET, $routeName, $routeConfig[0], $routeConfig[2], true);
230 1
            $this->registerRoute($route->setTokens($routeConfig[1]));
231 1
        }
232 1
    }
233
234
    /**
235
     * Prepare and return a route action
236
     *
237
     * @param ServerRequestInterface $request Request
238
     * @param ActionRouteInterface $route Route
239
     * @return ActionInterface|Callable $action Action
240
     */
241 2
    public function getRouteAction(ServerRequestInterface $request, ActionRouteInterface $route = null)
242
    {
243 2
        return $this->routerContainer->getRouteAction($request, $route);
0 ignored issues
show
Bug introduced by
It seems like $route defined by parameter $route on line 241 can be null; however, Apparat\Server\Domain\Co...rface::getRouteAction() does not accept null, maybe add an additional type check?

It seems like you allow that null is being passed for a parameter, however the function which is called does not seem to accept null.

We recommend to add an additional type check (or disallow null for the parameter):

function notNullable(stdClass $x) { }

// Unsafe
function withoutCheck(stdClass $x = null) {
    notNullable($x);
}

// Safe - Alternative 1: Adding Additional Type-Check
function withCheck(stdClass $x = null) {
    if ($x instanceof stdClass) {
        notNullable($x);
    }
}

// Safe - Alternative 2: Changing Parameter
function withNonNullableParam(stdClass $x) {
    notNullable($x);
}
Loading history...
244
    }
245
}
246