Completed
Push — master ( c695c6...742385 )
by Jean-Christophe
01:48
created

Router::path()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 3
rs 10
c 0
b 0
f 0
cc 1
eloc 2
nc 1
nop 2
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)) {
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(!isset($routeDetails["name"])){
94
				foreach ($routeDetails as $methodRouteDetail){
0 ignored issues
show
Unused Code introduced by
This foreach statement is empty and can be removed.

This check looks for foreach loops that have no statements or where all statements have been commented out. This may be the result of changes for debugging or the code may simply be obsolete.

Consider removing the loop.

Loading history...
95
96
				}
97
			}
98
			if (self::checkRouteName($routeDetails, $name)) {
99
				if(\sizeof($parameters)>0)
100
					$routePath=self::_getURL($routePath, $parameters);
101
				if ($absolute)
102
					return RequestUtils::getUrl($routePath);
103
				else
104
					return $routePath;
105
			}
106
		}
107
		return false;
108
	}
109
110
	public static function path($name,$parameters=[]){
111
		return self::getRouteByName($name,$parameters,false);
112
	}
113
114
	public static function url($name,$parameters=[]){
115
		return self::getRouteByName($name,$parameters,true);
116
	}
117
	protected static function _getURL($routePath,$params){
118
		return \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...
119
			return array_shift($params);
120
		}, $routePath);
121
	}
122
123
	protected static function checkRouteName($routeDetails,$name){
124
		if(!isset($routeDetails["name"])){
125
			foreach ($routeDetails as $methodRouteDetail){
126
				if(isset($methodRouteDetail["name"]) && $methodRouteDetail==$name)
127
					return true;
128
			}
129
		}
130
		return isset($routeDetails["name"]) && $routeDetails["name"] == $name;
131
	}
132
133
	public static function getRouteUrlParts($routeArray, $params, $cached=false, $duration=NULL,$cachedResponse=true) {
134
		$params=\array_slice($params, 1);
135
		$ctrl=str_replace("\\\\", "\\", $routeArray["details"]["controller"]);
136
		$result=[ $ctrl,$routeArray["details"]["action"] ];
137
		$paramsOrder=$routeArray["details"]["parameters"];
138
		$index=0;
139
		foreach ( $paramsOrder as $order ) {
140 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...
141
				if(isset($params[$index]))
142
					$result=\array_merge($result,\array_diff(\explode("/", $params[$index]),[""]));
143
				break;
144
			}
145
			if(\substr($order, 0,1)==="~"){
146
				$order=\intval(\substr($order,1,1));
147 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...
148
					$result=\array_merge($result,\array_diff(\explode("/", $params[$order]),[""]));
149
					break;
150
				}
151
			}
152
			$result[]=self::cleanParam($params[$order]);
153
			unset($params[$order]);
154
			$index++;
155
		}
156
		if ($cached === true && $cachedResponse===true) {
157
			return CacheManager::getRouteCache($result, $duration);
158
		}
159
		return $result;
160
	}
161
162
	private static function cleanParam($param){
163
		if(StrUtils::endswith($param, "/"))
164
			return \substr($param, 0,-1);
165
		return $param;
166
	}
167
168
	/**
169
	 * Déclare une route comme étant expirée ou non
170
	 * @param string $routePath
171
	 * @param boolean $expired
172
	 */
173
	public static function setExpired($routePath, $expired=true) {
174
		CacheManager::setExpired($routePath, $expired);
175
	}
176
177
	/**
178
	 *
179
	 * @param string $path
180
	 * @param string $controller
181
	 * @param string $action
182
	 * @param array|null $methods
183
	 * @param string $name
184
	 * @param boolean $cache
185
	 * @param int $duration
186
	 */
187
	public static function addRoute($path, $controller, $action="index", $methods=null, $name="", $cache=false, $duration=null) {
188
		self::addRouteToRoutes(self::$routes, $path, $controller, $action, $methods, $name, $cache, $duration);
189
	}
190
191
	public static function addRouteToRoutes(&$routesArray, $path, $controller, $action="index", $methods=null, $name="", $cache=false, $duration=null) {
192
		$result=[ ];
193
		if(\class_exists($controller)){
194
			$method=new \ReflectionMethod($controller, $action);
195
			ControllerParser::parseRouteArray($result, $controller, [ "path" => $path,"methods" => $methods,"name" => $name,"cache" => $cache,"duration" => $duration ], $method, $action);
196
			foreach ( $result as $k => $v ) {
197
				$routesArray[$k]=$v;
198
			}
199
		}
200
	}
201
}
202