Passed
Push — master ( f07946...439a7d )
by Jean-Christophe
01:33
created

Router::getRouteInfo()   A

Complexity

Conditions 5
Paths 4

Size

Total Lines 11
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 5
eloc 8
nc 4
nop 1
dl 0
loc 11
rs 9.6111
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.2
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
	public static function start() {
26
		self::$routes = CacheManager::getControllerCache ();
27
	}
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
	public static function getRoute($path, $cachedResponse = true) {
44
		$path = self::slashPath ( $path );
45
		foreach ( self::$routes as $routePath => $routeDetails ) {
46
			if (preg_match ( "@^" . $routePath . "$@s", $path, $matches )) {
47
				if (! isset ( $routeDetails ["controller"] )) {
48
					$method = URequest::getMethod ();
49
					if (isset ( $routeDetails [$method] ))
50
						return self::getRouteUrlParts ( [ "path" => $routePath,"details" => $routeDetails [$method] ], $matches, $routeDetails [$method] ["cache"], $routeDetails [$method] ["duration"], $cachedResponse );
51
				} else
52
					return self::getRouteUrlParts ( [ "path" => $routePath,"details" => $routeDetails ], $matches, $routeDetails ["cache"], $routeDetails ["duration"], $cachedResponse );
53
			}
54
		}
55
		Logger::warn("Router", "No route found for {$path}","getRoute");
56
		return false;
57
	}
58
59
	/**
60
	 * Returns the generated path from a route
61
	 *
62
	 * @param string $name
63
	 *        	name of the route
64
	 * @param array $parameters
65
	 *        	array of the route parameters. default : []
66
	 * @param boolean $absolute
67
	 */
68
	public static function getRouteByName($name, $parameters = [], $absolute = true) {
69
		foreach ( self::$routes as $routePath => $routeDetails ) {
70
			if (self::checkRouteName ( $routeDetails, $name )) {
71
				if (\sizeof ( $parameters ) > 0)
72
					$routePath = self::_getURL ( $routePath, $parameters );
73
				if (! $absolute)
74
					return \ltrim ( $routePath, '/' );
75
				else
76
					return $routePath;
77
			}
78
		}
79
		return false;
80
	}
81
82
	/**
83
	 * Returns the generated path from a route
84
	 *
85
	 * @param string $name
86
	 *        	the route name
87
	 * @param array $parameters
88
	 *        	default: []
89
	 * @param boolean $absolute
90
	 *        	true if the path is absolute (/ at first)
91
	 * @return boolean|string|array|mixed the generated path (/path/to/route)
92
	 */
93
	public static function path($name, $parameters = [], $absolute = false) {
94
		return self::getRouteByName ( $name, $parameters, $absolute );
95
	}
96
97
	/**
98
	 * Returns the generated url from a route
99
	 *
100
	 * @param string $name
101
	 *        	the route name
102
	 * @param array $parameters
103
	 *        	default: []
104
	 * @return string the generated url (http://myApp/path/to/route)
105
	 */
106
	public static function url($name, $parameters = []) {
107
		return URequest::getUrl ( self::getRouteByName ( $name, $parameters, false ) );
108
	}
109
110
	protected static function _getURL($routePath, $params) {
111
		$result = \preg_replace_callback ( '~\((.*?)\)~', function () use (&$params) {
112
			return array_shift ( $params );
113
		}, $routePath );
114
		if (\sizeof ( $params ) > 0) {
115
			$result = \rtrim ( $result, '/' ) . '/' . \implode ( '/', $params );
116
		}
117
		return $result;
118
	}
119
120
	protected static function checkRouteName($routeDetails, $name) {
121
		if (! isset ( $routeDetails ["name"] )) {
122
			foreach ( $routeDetails as $methodRouteDetail ) {
123
				if (isset ( $methodRouteDetail ["name"] ) && $methodRouteDetail == $name)
124
					return true;
125
			}
126
		}
127
		return isset ( $routeDetails ["name"] ) && $routeDetails ["name"] == $name;
128
	}
129
130
	public static function getRouteUrlParts($routeArray, $params, $cached = false, $duration = NULL, $cachedResponse = true) {
131
		$params = \array_slice ( $params, 1 );
132
		$ctrl = str_replace ( "\\\\", "\\", $routeArray ["details"] ["controller"] );
133
		$result = [ $ctrl,$routeArray ["details"] ["action"] ];
134
		$paramsOrder = $routeArray ["details"] ["parameters"];
135
		if(sizeof($paramsOrder)>0){
136
			self::setParamsInOrder($result, $paramsOrder, $params);
137
		}
138
		if ($cached === true && $cachedResponse === true) {
139
			Logger::info("Router", "Route found for {$routeArray["path"]} (from cache) : ".implode("/", $result),"getRouteUrlParts");
140
			return CacheManager::getRouteCache ( $result, $duration );
141
		}
142
		Logger::info("Router", "Route found for {$routeArray["path"]} : ".implode("/", $result),"getRouteUrlParts");
143
		return $result;
144
	}
145
	
146
	protected static function setParamsInOrder(&$routeUrlParts,$paramsOrder,$params){
147
		$index = 0;
148
		foreach ( $paramsOrder as $order ) {
149
			if ($order === "*") {
150
				if (isset ( $params [$index] ))
151
					$routeUrlParts = \array_merge ( $routeUrlParts, \array_diff ( \explode ( "/", $params [$index] ), [ "" ] ) );
152
					break;
153
			}
154
			if (\substr ( $order, 0, 1 ) === "~") {
155
				$order = \intval ( \substr ( $order, 1, 1 ) );
156
				if (isset ( $params [$order] )) {
157
					$routeUrlParts = \array_merge ( $routeUrlParts, \array_diff ( \explode ( "/", $params [$order] ), [ "" ] ) );
158
					break;
159
				}
160
			}
161
			$routeUrlParts [] = self::cleanParam ( $params [$order] );
162
			unset ( $params [$order] );
163
			$index ++;
164
		}
165
	}
166
167
	private static function cleanParam($param) {
168
		if (UString::endswith ( $param, "/" ))
169
			return \substr ( $param, 0, - 1 );
170
		return $param;
171
	}
172
	
173
	protected static function slashPath($path) {
174
		if (UString::startswith ( $path, "/" ) === false)
175
			$path = "/" . $path;
176
		if (! UString::endswith ( $path, "/" ))
177
			$path = $path . "/";
178
		return $path;
179
	}
180
	
181
	/**
182
	 * Declare a route as expired or not
183
	 *
184
	 * @param string $routePath
185
	 * @param boolean $expired
186
	 */
187
	public static function setExpired($routePath, $expired = true) {
188
		CacheManager::setExpired ( $routePath, $expired );
189
	}
190
}
191