Completed
Push — master ( 19e0e1...4e6ea7 )
by Jean-Christophe
05:46
created

Router::getRouteInfo()   B

Complexity

Conditions 5
Paths 4

Size

Total Lines 12
Code Lines 9

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 12
rs 8.8571
c 0
b 0
f 0
cc 5
eloc 9
nc 4
nop 1
1
<?php
2
3
namespace Ubiquity\controllers;
4
5
use Ubiquity\cache\CacheManager;
6
use Ubiquity\utils\RequestUtils;
7
use Ubiquity\cache\parser\ControllerParser;
8
use Ubiquity\utils\StrUtils;
9
10
/**
11
 * Router
12
 * @author jc
13
 * @version 1.0.0.2
14
 */
15
class Router {
16
	private static $routes;
17
18
	public static function slashPath($path){
19
		if(StrUtils::startswith($path,"/")===false)
20
			$path="/" . $path;
21
		if(!StrUtils::endswith($path, "/"))
22
			$path=$path."/";
23
		return $path;
24
	}
25
26
	public static function start() {
27
		self::$routes=CacheManager::getControllerCache();
28
	}
29
30
	public static function startRest() {
31
		self::$routes=CacheManager::getControllerCache(true);
32
	}
33
34
	public static function getRoute($path,$cachedResponse=true) {
35
		$path=self::slashPath($path);
36
		foreach ( self::$routes as $routePath => $routeDetails ) {
37
			if (preg_match("@^" . $routePath . "$@s", $path, $matches)) {
38
				if (!isset($routeDetails["controller"])) {
39
					$method=RequestUtils::getMethod();
40
					if (isset($routeDetails[$method]))
41
						return self::getRouteUrlParts([ "path" => $routePath,"details" => $routeDetails[$method] ], $matches, $routeDetails[$method]["cache"], $routeDetails[$method]["duration"],$cachedResponse);
42
				} else
43
					return self::getRouteUrlParts([ "path" => $routePath,"details" => $routeDetails ], $matches, $routeDetails["cache"], $routeDetails["duration"],$cachedResponse);
44
			}
45
		}
46
		return false;
47
	}
48
49
	public static function filterRoutes($path) {
50
		$path=self::slashPath($path);
51
		$result=[];
52
		foreach ( self::$routes as $routePath => $routeDetails ) {
53
			if (preg_match("@^" . $routePath . ".*?$@s", $path, $matches)) {
54
				$result[$routePath]=$routeDetails;
55
			}
56
		}
57
		return $result;
58
	}
59
60
	public static function getRouteInfo($path){
61
		$path=self::slashPath($path);
62
		foreach ( self::$routes as $routePath => $routeDetails ) {
63
			if (preg_match("@^" . $routePath . "$@s", $path, $matches)|| \stripslashes($routePath)==$path) {
64
				if (!isset($routeDetails["controller"])) {
65
						return \reset($routeDetails);
66
				} else
67
					return $routeDetails;
68
			}
69
		}
70
		return false;
71
	}
72
73
	public static function getAnnotations($controllerName,$actionName){
74
		$result=[];
75
		foreach ( self::$routes as $routePath => $routeDetails ) {
76
			if (!isset($routeDetails["controller"])) {
77
				$routeDetails=\reset($routeDetails);
78
			}
79
			if($routeDetails["controller"]===$controllerName && $routeDetails["action"]===$actionName)
80
				$result[$routePath]=$routeDetails;
81
		}
82
		return $result;
83
	}
84
85
	/**
86
	 * Returns the generated path from a route
87
	 * @param string $name name of the route
88
	 * @param array $parameters array of the route parameters. default : []
89
	 * @param boolean $absolute
90
	 */
91
	public static function getRouteByName($name, $parameters=[],$absolute=true) {
92
		foreach ( self::$routes as $routePath => $routeDetails ) {
93
			if (self::checkRouteName($routeDetails, $name)) {
94
				if(\sizeof($parameters)>0)
95
					$routePath=self::_getURL($routePath, $parameters);
96
				if (!$absolute)
97
					return \ltrim($routePath,'/');
98
				else
99
					return $routePath;
100
			}
101
		}
102
		return false;
103
	}
104
105
	/**
106
	 * Returns the generated path from a route
107
	 * @param string $name the route name
108
	 * @param array $parameters default: []
109
	 * @param boolean $absolute true if the path is absolute (/ at first)
110
	 * @return boolean|string|array|mixed the generated path (/path/to/route)
111
	 */
112
	public static function path($name,$parameters=[],$absolute=false){
113
		return self::getRouteByName($name,$parameters,$absolute);
114
	}
115
116
	/**
117
	 * Returns the generated url from a route
118
	 * @param string $name the route name
119
	 * @param array $parameters default: []
120
	 * @return string the generated url (http://myApp/path/to/route)
121
	 */
122
	public static function url($name,$parameters=[]){
123
		return RequestUtils::getUrl(self::getRouteByName($name,$parameters,false));
124
	}
125
126
	protected static function _getURL($routePath,$params){
127
		$result= \preg_replace_callback('~\((.*?)\)~', function($matches) use (&$params) {
0 ignored issues
show
Unused Code introduced by
The parameter $matches 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...
128
			return array_shift($params);
129
		}, $routePath);
130
		if(\sizeof($params)>0){
131
			$result=\rtrim($result,'/').'/'.\implode('/', $params);
132
		}
133
		return $result;
134
	}
135
136
	protected static function checkRouteName($routeDetails,$name){
137
		if(!isset($routeDetails["name"])){
138
			foreach ($routeDetails as $methodRouteDetail){
139
				if(isset($methodRouteDetail["name"]) && $methodRouteDetail==$name)
140
					return true;
141
			}
142
		}
143
		return isset($routeDetails["name"]) && $routeDetails["name"] == $name;
144
	}
145
146
	public static function getRouteUrlParts($routeArray, $params, $cached=false, $duration=NULL,$cachedResponse=true) {
147
		$params=\array_slice($params, 1);
148
		$ctrl=str_replace("\\\\", "\\", $routeArray["details"]["controller"]);
149
		$result=[ $ctrl,$routeArray["details"]["action"] ];
150
		$paramsOrder=$routeArray["details"]["parameters"];
151
		$index=0;
152
		foreach ( $paramsOrder as $order ) {
153 View Code Duplication
			if($order==="*"){
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
154
				if(isset($params[$index]))
155
					$result=\array_merge($result,\array_diff(\explode("/", $params[$index]),[""]));
156
				break;
157
			}
158
			if(\substr($order, 0,1)==="~"){
159
				$order=\intval(\substr($order,1,1));
160 View Code Duplication
				if(isset($params[$order])){
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
161
					$result=\array_merge($result,\array_diff(\explode("/", $params[$order]),[""]));
162
					break;
163
				}
164
			}
165
			$result[]=self::cleanParam($params[$order]);
166
			unset($params[$order]);
167
			$index++;
168
		}
169
		if ($cached === true && $cachedResponse===true) {
170
			return CacheManager::getRouteCache($result, $duration);
171
		}
172
		return $result;
173
	}
174
175
	private static function cleanParam($param){
176
		if(StrUtils::endswith($param, "/"))
177
			return \substr($param, 0,-1);
178
		return $param;
179
	}
180
181
	/**
182
	 * Déclare une route comme étant expirée ou non
183
	 * @param string $routePath
184
	 * @param boolean $expired
185
	 */
186
	public static function setExpired($routePath, $expired=true) {
187
		CacheManager::setExpired($routePath, $expired);
188
	}
189
190
	/**
191
	 *
192
	 * @param string $path
193
	 * @param string $controller
194
	 * @param string $action
195
	 * @param array|null $methods
196
	 * @param string $name
197
	 * @param boolean $cache
198
	 * @param int $duration
199
	 * @param array $requirements
200
	 */
201
	public static function addRoute($path, $controller, $action="index", $methods=null, $name="", $cache=false, $duration=null,$requirements=[]) {
202
		self::addRouteToRoutes(self::$routes, $path, $controller, $action, $methods, $name, $cache, $duration,$requirements);
203
	}
204
205
	public static function addRouteToRoutes(&$routesArray, $path, $controller, $action="index", $methods=null, $name="", $cache=false, $duration=null,$requirements=[]) {
206
		$result=[ ];
207
		if(\class_exists($controller)){
208
			$method=new \ReflectionMethod($controller, $action);
209
			ControllerParser::parseRouteArray($result, $controller, [ "path" => $path,"methods" => $methods,"name" => $name,"cache" => $cache,"duration" => $duration,"requirements"=>$requirements ], $method, $action);
210
			foreach ( $result as $k => $v ) {
211
				$routesArray[$k]=$v;
212
			}
213
		}
214
	}
215
}
216