Table   A
last analyzed

Complexity

Total Complexity 33

Size/Duplication

Total Lines 242
Duplicated Lines 0 %

Test Coverage

Coverage 57.6%

Importance

Changes 0
Metric Value
wmc 33
eloc 76
dl 0
loc 242
c 0
b 0
f 0
ccs 53
cts 92
cp 0.576
rs 9.76

13 Methods

Rating   Name   Duplication   Size   Complexity  
A count() 0 3 1
A defaultRoute() 0 3 1
A getRoutes() 0 3 1
A dumpCache() 0 10 3
A readCache() 0 17 3
A __construct() 0 12 1
A registerRoute() 0 20 1
B updateRoute() 0 13 7
A add() 0 36 5
A remove() 0 17 2
A get() 0 9 2
A load() 0 21 5
A regex() 0 5 1
1
<?php namespace Comodojo\Dispatcher\Router;
2
3
use \Comodojo\Foundation\Base\Configuration;
4
use \Comodojo\Dispatcher\Components\AbstractModel;
5
use \Comodojo\Dispatcher\Cache\RouterCache;
6
use \Comodojo\Dispatcher\Request\Model as Request;
7
use \Comodojo\Dispatcher\Router\Parser;
8
use \Comodojo\Dispatcher\Router\Route;
9
use \Comodojo\Dispatcher\Router\Model as Router;
10
use \Comodojo\SimpleCache\Manager as SimpleCacheManager;
11
use \Comodojo\Exception\DispatcherException;
12
use \Psr\Log\LoggerInterface;
13
use \Countable;
14
use \Exception;
15
16
/**
17
 * @package     Comodojo Dispatcher
18
 * @author      Marco Giovinazzi <[email protected]>
19
 * @author      Marco Castiello <[email protected]>
20
 * @license     MIT
21
 *
22
 * LICENSE:
23
 *
24
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
25
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
26
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
27
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
28
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
29
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
30
 * THE SOFTWARE.
31
 */
32
33
class Table extends AbstractModel implements Countable {
34
35
    /**
36
     * Types of route that this table will accept
37
     * @var array
38
     */
39
    const ALLOWED_ROUTES = [ "ROUTE", "REDIRECT", "ERROR" ];
0 ignored issues
show
Coding Style Comprehensibility introduced by
The string literal ROUTE does not require double quotes, as per coding-style, please use single quotes.

PHP provides two ways to mark string literals. Either with single quotes 'literal' or with double quotes "literal". The difference between these is that string literals in double quotes may contain variables with are evaluated at run-time as well as escape sequences.

String literals in single quotes on the other hand are evaluated very literally and the only two characters that needs escaping in the literal are the single quote itself (\') and the backslash (\\). Every other character is displayed as is.

Double quoted string literals may contain other variables or more complex escape sequences.

<?php

$singleQuoted = 'Value';
$doubleQuoted = "\tSingle is $singleQuoted";

print $doubleQuoted;

will print an indented: Single is Value

If your string literal does not contain variables or escape sequences, it should be defined using single quotes to make that fact clear.

For more information on PHP string literals and available escape sequences see the PHP core documentation.

Loading history...
Coding Style Comprehensibility introduced by
The string literal REDIRECT does not require double quotes, as per coding-style, please use single quotes.

PHP provides two ways to mark string literals. Either with single quotes 'literal' or with double quotes "literal". The difference between these is that string literals in double quotes may contain variables with are evaluated at run-time as well as escape sequences.

String literals in single quotes on the other hand are evaluated very literally and the only two characters that needs escaping in the literal are the single quote itself (\') and the backslash (\\). Every other character is displayed as is.

Double quoted string literals may contain other variables or more complex escape sequences.

<?php

$singleQuoted = 'Value';
$doubleQuoted = "\tSingle is $singleQuoted";

print $doubleQuoted;

will print an indented: Single is Value

If your string literal does not contain variables or escape sequences, it should be defined using single quotes to make that fact clear.

For more information on PHP string literals and available escape sequences see the PHP core documentation.

Loading history...
Coding Style Comprehensibility introduced by
The string literal ERROR does not require double quotes, as per coding-style, please use single quotes.

PHP provides two ways to mark string literals. Either with single quotes 'literal' or with double quotes "literal". The difference between these is that string literals in double quotes may contain variables with are evaluated at run-time as well as escape sequences.

String literals in single quotes on the other hand are evaluated very literally and the only two characters that needs escaping in the literal are the single quote itself (\') and the backslash (\\). Every other character is displayed as is.

Double quoted string literals may contain other variables or more complex escape sequences.

<?php

$singleQuoted = 'Value';
$doubleQuoted = "\tSingle is $singleQuoted";

print $doubleQuoted;

will print an indented: Single is Value

If your string literal does not contain variables or escape sequences, it should be defined using single quotes to make that fact clear.

For more information on PHP string literals and available escape sequences see the PHP core documentation.

Loading history...
40
41
    /**
42
     * Current repository of routes
43
     * @var array
44
     */
45
    protected $routes = [];
46
47
    /**
48
     * @var Parser
49
     */
50
    protected $parser;
51
52
    /**
53
     * @var RouterCache
54
     */
55
    protected $cache;
56
57
    /**
58
     * Table constructor
59
     *
60
     * @param Configuration $configuration
61
     * @param LoggerInterface $logger
62
     * @param SimpleCacheManager $cache
63
     */
64 1
    public function __construct(
65
        Configuration $configuration,
66
        LoggerInterface $logger,
67
        SimpleCacheManager $cache
68
    ) {
69
70 1
        parent::__construct($configuration, $logger);
71
72 1
        $this->parser = new Parser($logger);
73 1
        $this->cache = new RouterCache($cache);
74
75 1
        $this->readCache();
76
77 1
    }
78
79 1
    public function add(
80
        $route,
81
        $type,
82
        $class = null,
83
        array $parameters = []
84
    ) {
85
86 1
        $type = strtoupper($type);
87
88 1
        if ( !in_array($type, self::ALLOWED_ROUTES) ) {
89
90
            $this->getLogger()->error("Invalid route definition - unknown type $type for route $route)");
0 ignored issues
show
Coding Style Best Practice introduced by
As per coding-style, please use concatenation or sprintf for the variable $type instead of interpolation.

It is generally a best practice as it is often more readable to use concatenation instead of interpolation for variables inside strings.

// Instead of
$x = "foo $bar $baz";

// Better use either
$x = "foo " . $bar . " " . $baz;
$x = sprintf("foo %s %s", $bar, $baz);
Loading history...
Coding Style Best Practice introduced by
As per coding-style, please use concatenation or sprintf for the variable $route instead of interpolation.

It is generally a best practice as it is often more readable to use concatenation instead of interpolation for variables inside strings.

// Instead of
$x = "foo $bar $baz";

// Better use either
$x = "foo " . $bar . " " . $baz;
$x = sprintf("foo %s %s", $bar, $baz);
Loading history...
91
92 1
        } else if ( $type == 'ROUTE' && empty($class) ) {
0 ignored issues
show
Coding Style introduced by
Operator == prohibited; use === instead
Loading history...
93
94
            $this->getLogger()->error("Invalid route definition - missing class for route $route)");
0 ignored issues
show
Coding Style Best Practice introduced by
As per coding-style, please use concatenation or sprintf for the variable $route instead of interpolation.

It is generally a best practice as it is often more readable to use concatenation instead of interpolation for variables inside strings.

// Instead of
$x = "foo $bar $baz";

// Better use either
$x = "foo " . $bar . " " . $baz;
$x = sprintf("foo %s %s", $bar, $baz);
Loading history...
95
96
        } else {
97
98 1
            $routeData = $this->get($route);
99
100 1
            if ( !is_null($routeData) ) {
101
102
                $this->updateRoute($routeData, $type, $class, $parameters);
103
104
            } else {
105
106 1
                $folders = explode("/", $route);
0 ignored issues
show
Coding Style Comprehensibility introduced by
The string literal / does not require double quotes, as per coding-style, please use single quotes.

PHP provides two ways to mark string literals. Either with single quotes 'literal' or with double quotes "literal". The difference between these is that string literals in double quotes may contain variables with are evaluated at run-time as well as escape sequences.

String literals in single quotes on the other hand are evaluated very literally and the only two characters that needs escaping in the literal are the single quote itself (\') and the backslash (\\). Every other character is displayed as is.

Double quoted string literals may contain other variables or more complex escape sequences.

<?php

$singleQuoted = 'Value';
$doubleQuoted = "\tSingle is $singleQuoted";

print $doubleQuoted;

will print an indented: Single is Value

If your string literal does not contain variables or escape sequences, it should be defined using single quotes to make that fact clear.

For more information on PHP string literals and available escape sequences see the PHP core documentation.

Loading history...
107
108 1
                $this->registerRoute($folders, $type, $class, $parameters);
109
110
            }
111
112
        }
113
114 1
        return $this;
115
116
    }
117
118
    /**
119
     * Get registered routes count
120
     *
121
     * @return int
122
     */
123
    public function count() {
124
125
        return count($this->routes);
126
127
    }
128
129 1
    public function getRoutes() {
130
131 1
        return $this->routes;
132
133
    }
134
135 1
    public function get($route) {
136
137 1
        $regex = $this->regex($route);
138
139 1
        if (isset($this->routes[$regex])) {
140 1
            return $this->routes[$regex];
141
        }
142
143 1
        return null;
144
145
    }
146
147 1
    public function regex($route) {
148
149 1
        $folders = explode("/", $route);
0 ignored issues
show
Coding Style Comprehensibility introduced by
The string literal / does not require double quotes, as per coding-style, please use single quotes.

PHP provides two ways to mark string literals. Either with single quotes 'literal' or with double quotes "literal". The difference between these is that string literals in double quotes may contain variables with are evaluated at run-time as well as escape sequences.

String literals in single quotes on the other hand are evaluated very literally and the only two characters that needs escaping in the literal are the single quote itself (\') and the backslash (\\). Every other character is displayed as is.

Double quoted string literals may contain other variables or more complex escape sequences.

<?php

$singleQuoted = 'Value';
$doubleQuoted = "\tSingle is $singleQuoted";

print $doubleQuoted;

will print an indented: Single is Value

If your string literal does not contain variables or escape sequences, it should be defined using single quotes to make that fact clear.

For more information on PHP string literals and available escape sequences see the PHP core documentation.

Loading history...
150
151 1
        return $this->parser->read($folders);
152
153
    }
154
155 1
    public function remove($route) {
156
157 1
        $regex = $this->regex($route);
158
159 1
        $routes = $this->routes;
160
161 1
        if (isset($routes[$regex])) {
162
163 1
            unset($routes[$regex]);
164
165 1
            $this->routes = $routes;
166
167 1
            return true;
168
169
        }
170
171
        return false;
172
173
    }
174
175
    public function defaultRoute() {
176
177
        return $this->get('/');
178
179
    }
180
181
    public function load(array $routes) {
182
183
        if (!empty($routes)) {
184
185
            foreach ($routes as $name => $route) {
186
187
                $this->add(
188
                    $route['route'],
189
                    $route['type'],
190
                    empty($route['class']) ? null : $route['class'],
191
                    empty($route['parameters']) ? [] : $route['parameters']
192
                );
193
194
            }
195
196
        }
197
198
        $count = $this->count();
199
        $this->logger->debug("$count routes loaded in routing table");
0 ignored issues
show
Coding Style Best Practice introduced by
As per coding-style, please use concatenation or sprintf for the variable $count instead of interpolation.

It is generally a best practice as it is often more readable to use concatenation instead of interpolation for variables inside strings.

// Instead of
$x = "foo $bar $baz";

// Better use either
$x = "foo " . $bar . " " . $baz;
$x = sprintf("foo %s %s", $bar, $baz);
Loading history...
200
201
        $this->dumpCache();
202
203
    }
204
205
    // This method add a route to the supported list
206 1
    private function registerRoute($folders, $type, $class = null, array $parameters = []) {
207
208
        // The values associated with a route are as follows:
209
        // $route = new Route($this->router);
0 ignored issues
show
Unused Code Comprehensibility introduced by
50% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
210 1
        $route = new Route();
211
212 1
        $this->updateRoute($route, $type, $class, $parameters);
213
214
        // $route->setType($type) // Type of route
0 ignored issues
show
Unused Code Comprehensibility introduced by
63% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
215
        //     ->setClassName($class) // Class to be invoked
0 ignored issues
show
Unused Code Comprehensibility introduced by
58% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
216
        //     ->setParameters($parameters); // Parameters passed via the composer.json configuration (cache, ttl, etc...)
0 ignored issues
show
Unused Code Comprehensibility introduced by
63% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
217
218 1
        $this->logger->debug("Route table - route: ".implode("/", $folders));
0 ignored issues
show
Coding Style Comprehensibility introduced by
The string literal Route table - route: does not require double quotes, as per coding-style, please use single quotes.

PHP provides two ways to mark string literals. Either with single quotes 'literal' or with double quotes "literal". The difference between these is that string literals in double quotes may contain variables with are evaluated at run-time as well as escape sequences.

String literals in single quotes on the other hand are evaluated very literally and the only two characters that needs escaping in the literal are the single quote itself (\') and the backslash (\\). Every other character is displayed as is.

Double quoted string literals may contain other variables or more complex escape sequences.

<?php

$singleQuoted = 'Value';
$doubleQuoted = "\tSingle is $singleQuoted";

print $doubleQuoted;

will print an indented: Single is Value

If your string literal does not contain variables or escape sequences, it should be defined using single quotes to make that fact clear.

For more information on PHP string literals and available escape sequences see the PHP core documentation.

Loading history...
Coding Style Comprehensibility introduced by
The string literal / does not require double quotes, as per coding-style, please use single quotes.

PHP provides two ways to mark string literals. Either with single quotes 'literal' or with double quotes "literal". The difference between these is that string literals in double quotes may contain variables with are evaluated at run-time as well as escape sequences.

String literals in single quotes on the other hand are evaluated very literally and the only two characters that needs escaping in the literal are the single quote itself (\') and the backslash (\\). Every other character is displayed as is.

Double quoted string literals may contain other variables or more complex escape sequences.

<?php

$singleQuoted = 'Value';
$doubleQuoted = "\tSingle is $singleQuoted";

print $doubleQuoted;

will print an indented: Single is Value

If your string literal does not contain variables or escape sequences, it should be defined using single quotes to make that fact clear.

For more information on PHP string literals and available escape sequences see the PHP core documentation.

Loading history...
219
220
        // This method generate a global regular expression which will be able to match all the URI supported by the route
221 1
        $regex = $this->parser->read($folders, $route);
222
223 1
        $this->logger->debug("Route table - route regex: $regex");
0 ignored issues
show
Coding Style Best Practice introduced by
As per coding-style, please use concatenation or sprintf for the variable $regex instead of interpolation.

It is generally a best practice as it is often more readable to use concatenation instead of interpolation for variables inside strings.

// Instead of
$x = "foo $bar $baz";

// Better use either
$x = "foo " . $bar . " " . $baz;
$x = sprintf("foo %s %s", $bar, $baz);
Loading history...
224
225 1
        $this->routes = array_merge($this->routes, [$regex => $route]);
226
227 1
    }
228
229 1
    private function updateRoute(Route $route, $type, $class = null, array $parameters = []) {
230
231 1
        $route->setType($type)
232 1
            ->setClassName($class)
233 1
            ->setParameters($parameters);
234
235 1
        if ( !empty($parameters['redirect-code']) ) $route->setRedirectCode($parameters['redirect-code']);
236 1
        if ( !empty($parameters['redirect-location']) ) $route->setRedirectLocation($parameters['redirect-location']);
237 1
        if ( !empty($parameters['redirect-message']) ) $route->setRedirectLocation($parameters['redirect-message']);
238 1
        if ( !empty($parameters['redirect-type']) ) $route->setRedirectType($parameters['redirect-type']);
239
240 1
        if ( !empty($parameters['error-code']) ) $route->setErrorCode($parameters['error-code']);
241 1
        if ( !empty($parameters['error-message']) ) $route->setErrorMessage($parameters['error-message']);
242
243 1
    }
244
245 1
    private function readCache() {
246
247 1
        if ($this->configuration->get('routing-table-cache') !== true) return;
248
249
        $data = $this->cache->read();
250
251
        if (is_null($data)) {
0 ignored issues
show
introduced by
The condition is_null($data) is always false.
Loading history...
252
253
            $this->routes = [];
254
255
            return;
256
257
        }
258
259
        $this->routes = $data;
260
261
        $this->logger->debug("Routing table loaded from cache");
0 ignored issues
show
Coding Style Comprehensibility introduced by
The string literal Routing table loaded from cache does not require double quotes, as per coding-style, please use single quotes.

PHP provides two ways to mark string literals. Either with single quotes 'literal' or with double quotes "literal". The difference between these is that string literals in double quotes may contain variables with are evaluated at run-time as well as escape sequences.

String literals in single quotes on the other hand are evaluated very literally and the only two characters that needs escaping in the literal are the single quote itself (\') and the backslash (\\). Every other character is displayed as is.

Double quoted string literals may contain other variables or more complex escape sequences.

<?php

$singleQuoted = 'Value';
$doubleQuoted = "\tSingle is $singleQuoted";

print $doubleQuoted;

will print an indented: Single is Value

If your string literal does not contain variables or escape sequences, it should be defined using single quotes to make that fact clear.

For more information on PHP string literals and available escape sequences see the PHP core documentation.

Loading history...
262
263
    }
264
265
    private function dumpCache() {
266
267
        if ($this->configuration->get('routing-table-cache') !== true) return;
268
269
        $ttl = $this->configuration->get('routing-table-ttl');
270
271
        if ($this->cache->dump($this->routes, $ttl)) {
272
            $this->logger->debug("Routing table saved to cache");
0 ignored issues
show
Coding Style Comprehensibility introduced by
The string literal Routing table saved to cache does not require double quotes, as per coding-style, please use single quotes.

PHP provides two ways to mark string literals. Either with single quotes 'literal' or with double quotes "literal". The difference between these is that string literals in double quotes may contain variables with are evaluated at run-time as well as escape sequences.

String literals in single quotes on the other hand are evaluated very literally and the only two characters that needs escaping in the literal are the single quote itself (\') and the backslash (\\). Every other character is displayed as is.

Double quoted string literals may contain other variables or more complex escape sequences.

<?php

$singleQuoted = 'Value';
$doubleQuoted = "\tSingle is $singleQuoted";

print $doubleQuoted;

will print an indented: Single is Value

If your string literal does not contain variables or escape sequences, it should be defined using single quotes to make that fact clear.

For more information on PHP string literals and available escape sequences see the PHP core documentation.

Loading history...
273
        } else {
274
            $this->logger->warning("Cannot save routing table to cache");
0 ignored issues
show
Coding Style Comprehensibility introduced by
The string literal Cannot save routing table to cache does not require double quotes, as per coding-style, please use single quotes.

PHP provides two ways to mark string literals. Either with single quotes 'literal' or with double quotes "literal". The difference between these is that string literals in double quotes may contain variables with are evaluated at run-time as well as escape sequences.

String literals in single quotes on the other hand are evaluated very literally and the only two characters that needs escaping in the literal are the single quote itself (\') and the backslash (\\). Every other character is displayed as is.

Double quoted string literals may contain other variables or more complex escape sequences.

<?php

$singleQuoted = 'Value';
$doubleQuoted = "\tSingle is $singleQuoted";

print $doubleQuoted;

will print an indented: Single is Value

If your string literal does not contain variables or escape sequences, it should be defined using single quotes to make that fact clear.

For more information on PHP string literals and available escape sequences see the PHP core documentation.

Loading history...
275
        }
276
277
    }
278
279
}
280