Passed
Push — master ( 4d0f3d...b95030 )
by Jean-Christophe
02:31
created

Router::checkRouteName()   A

Complexity

Conditions 6
Paths 5

Size

Total Lines 8
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 42

Importance

Changes 0
Metric Value
cc 6
eloc 5
nc 5
nop 2
dl 0
loc 8
ccs 0
cts 6
cp 0
crap 42
rs 9.2222
c 0
b 0
f 0
1
<?php
2
3
namespace Ubiquity\controllers;
4
5
use Ubiquity\cache\CacheManager;
6
use Ubiquity\utils\http\URequest;
7
use Ubiquity\utils\base\UString;
8
use Ubiquity\log\Logger;
9
use Ubiquity\controllers\traits\RouterModifierTrait;
10
use Ubiquity\controllers\traits\RouterAdminTrait;
11
12
/**
13
 * Router manager
14
 * @author jcheron <[email protected]>
15
 * @version 1.0.3
16
 */
17
class Router {
18
	use RouterModifierTrait,RouterAdminTrait;
19
	
20
	protected static $routes;
21
22
	/**
23
	 * Starts the router by loading normal routes (not rest)
24
	 */
25 2
	public static function start() {
26 2
		self::$routes = CacheManager::getControllerCache ();
27 2
	}
28
29
	/**
30
	 * Starts the router by loading rest routes (not normal routes)
31
	 */
32
	public static function startRest() {
33
		self::$routes = CacheManager::getControllerCache ( true );
34
	}
35
	
36
	/**
37
	 * Starts the router by loading all routes (normal + rest routes)
38
	 */
39
	public static function startAll() {
40
		self::$routes = array_merge(CacheManager::getControllerCache (),CacheManager::getControllerCache(true));
41
	}
42
43
	/**
44
	 * Returns the route corresponding to a path
45
	 * @param string $path
46
	 * @param boolean $cachedResponse
47
	 * @return boolean|mixed[]|string
48
	 */
49 2
	public static function getRoute($path, $cachedResponse = true) {
50 2
		$path = self::slashPath ( $path );
51 2
		if(isset(self::$routes[$path])){
52
			return self::getRoute_(self::$routes[$path], $path, [$path], $cachedResponse);
53
		}
54 2
		foreach ( self::$routes as $routePath => $routeDetails ) {
55
			if (preg_match ( "@^" . $routePath . "$@s", $path, $matches )) {
56
				return self::getRoute_($routeDetails, $routePath, $matches, $cachedResponse);
57
			}
58
		}
59 2
		Logger::warn("Router", "No route found for {$path}","getRoute");
60 2
		return false;
61
	}
62
	
63
	private static function getRoute_(&$routeDetails,$routePath,$matches,$cachedResponse){
64
		if (! isset ( $routeDetails ["controller"] )) {
65
			$method = URequest::getMethod ();
66
			if (isset ( $routeDetails [$method] )){
67
				$routeDetailsMethod=$routeDetails [$method];
68
				return self::getRouteUrlParts ( [ "path" => $routePath,"details" => $routeDetailsMethod ], $matches, $routeDetailsMethod ["cache"]??false, $routeDetailsMethod["duration"]??null, $cachedResponse );
69
			}
70
		} else{
71
			return self::getRouteUrlParts ( [ "path" => $routePath,"details" => $routeDetails ], $matches, $routeDetails ["cache"]??false, $routeDetails ["duration"]??null, $cachedResponse );
72
		}
73
		return false;
74
	}
75
76
	/**
77
	 * Returns the generated path from a route
78
	 *
79
	 * @param string $name
80
	 *        	name of the route
81
	 * @param array $parameters
82
	 *        	array of the route parameters. default : []
83
	 * @param boolean $absolute
84
	 */
85
	public static function getRouteByName($name, $parameters = [], $absolute = true) {
86
		foreach ( self::$routes as $routePath => $routeDetails ) {
87
			if (self::checkRouteName ( $routeDetails, $name )) {
88
				if (\sizeof ( $parameters ) > 0)
89
					$routePath = self::_getURL ( $routePath, $parameters );
90
				if (! $absolute)
91
					return \ltrim ( $routePath, '/' );
92
				else
93
					return $routePath;
94
			}
95
		}
96
		return false;
97
	}
98
99
	/**
100
	 * Returns the generated path from a route
101
	 *
102
	 * @param string $name
103
	 *        	the route name
104
	 * @param array $parameters
105
	 *        	default: []
106
	 * @param boolean $absolute
107
	 *        	true if the path is absolute (/ at first)
108
	 * @return boolean|string|array|mixed the generated path (/path/to/route)
109
	 */
110
	public static function path($name, $parameters = [], $absolute = false) {
111
		return self::getRouteByName ( $name, $parameters, $absolute );
112
	}
113
114
	/**
115
	 * Returns the generated url from a route
116
	 *
117
	 * @param string $name
118
	 *        	the route name
119
	 * @param array $parameters
120
	 *        	default: []
121
	 * @return string the generated url (http://myApp/path/to/route)
122
	 */
123
	public static function url($name, $parameters = []) {
124
		return URequest::getUrl ( self::getRouteByName ( $name, $parameters, false ) );
125
	}
126
127
	protected static function _getURL($routePath, $params) {
128
		$result = \preg_replace_callback ( '~\((.*?)\)~', function () use (&$params) {
129
			return array_shift ( $params );
130
		}, $routePath );
131
		if (\sizeof ( $params ) > 0) {
132
			$result = \rtrim ( $result, '/' ) . '/' . \implode ( '/', $params );
133
		}
134
		return $result;
135
	}
136
137
	protected static function checkRouteName($routeDetails, $name) {
138
		if (! isset ( $routeDetails ["name"] )) {
139
			foreach ( $routeDetails as $methodRouteDetail ) {
140
				if (isset ( $methodRouteDetail ["name"] ) && $methodRouteDetail == $name)
141
					return true;
142
			}
143
		}
144
		return isset ( $routeDetails ["name"] ) && $routeDetails ["name"] == $name;
145
	}
146
147
	public static function getRouteUrlParts($routeArray, $params, $cached = false, $duration = NULL, $cachedResponse = true) {
148
		\array_shift($params);
149
		$routeDetails=$routeArray ["details"];
150
		$result = [ str_replace ( "\\\\", "\\", $routeDetails["controller"] ),$routeDetails["action"] ];
151
		if(($paramsOrder = $routeDetails["parameters"]) && (sizeof($paramsOrder)>0)){
152
			self::setParamsInOrder($result, $paramsOrder, $params);
153
		}
154
		if(!$cached || !$cachedResponse){
155
			Logger::info('Router', sprintf('Route found for %s : %s',$routeArray["path"],implode("/", $result)),'getRouteUrlParts');
156
			return $result;
157
		}
158
		Logger::info('Router', sprintf('Route found for %s (from cache) : %s',$routeArray["path"],implode("/", $result)),'getRouteUrlParts');
159
		return CacheManager::getRouteCache ( $result, $duration );
160
	}
161
	
162
	protected static function setParamsInOrder(&$routeUrlParts,$paramsOrder,$params){
163
		$index = 0;
164
		foreach ( $paramsOrder as $order ) {
165
			if ($order === '*') {
166
				if (isset ( $params [$index] ))
167
					$routeUrlParts = \array_merge ( $routeUrlParts, \array_diff ( \explode ( "/", $params [$index] ), [ "" ] ) );
168
					break;
169
			}
170
			if ($order[0] === '~') {
171
				$order = \intval ( \substr ( $order, 1, 1 ) );
172
				if (isset ( $params [$order] )) {
173
					$routeUrlParts = \array_merge ( $routeUrlParts, \array_diff ( \explode ( "/", $params [$order] ), [ "" ] ) );
174
					break;
175
				}
176
			}
177
			$routeUrlParts [] = self::cleanParam ( $params [$order] );
178
			unset ( $params [$order] );
179
			$index ++;
180
		}
181
	}
182
183
	private static function cleanParam($param) {
184
		if (UString::endswith ( $param, "/" ))
185
			return \substr ( $param, 0, - 1 );
186
		return $param;
187
	}
188
	
189 2
	protected static function slashPath($path) {
190 2
		if (UString::startswith ( $path, "/" ) === false)
191 2
			$path = "/" . $path;
192 2
		if (! UString::endswith ( $path, "/" ))
193 2
			$path = $path . "/";
194 2
		return $path;
195
	}
196
	
197
	/**
198
	 * Declare a route as expired or not
199
	 *
200
	 * @param string $routePath
201
	 * @param boolean $expired
202
	 */
203
	public static function setExpired($routePath, $expired = true) {
204
		CacheManager::setExpired ( $routePath, $expired );
205
	}
206
}
207