Completed
Push — master ( 0feaa6...f4afa6 )
by Jean-Christophe
01:33
created

Router   B

Complexity

Total Complexity 40

Size/Duplication

Total Lines 153
Duplicated Lines 5.88 %

Coupling/Cohesion

Components 1
Dependencies 4

Importance

Changes 1
Bugs 0 Features 0
Metric Value
wmc 40
c 1
b 0
f 0
lcom 1
cbo 4
dl 9
loc 153
rs 8.2608

13 Methods

Rating   Name   Duplication   Size   Complexity  
A slashPath() 0 7 3
A start() 0 3 1
A startRest() 0 3 1
B getRoute() 0 14 5
A filterRoutes() 0 10 3
A getRouteInfo() 0 12 4
B getAnnotations() 0 11 5
A getRouteByName() 0 11 4
C getRouteUrlParts() 9 28 8
A cleanParam() 0 5 2
A setExpired() 0 3 1
A addRoute() 0 3 1
A addRouteToRoutes() 0 8 2

How to fix   Duplicated Code    Complexity   

Duplicated Code

Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.

Common duplication problems, and corresponding solutions are:

Complex Class

 Tip:   Before tackling complexity, make sure that you eliminate any duplication first. This often can reduce the size of classes significantly.

Complex classes like Router often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes. You can also have a look at the cohesion graph to spot any un-connected, or weakly-connected components.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use Router, and based on these observations, apply Extract Interface, too.

1
<?php
2
3
namespace micro\controllers;
4
5
use micro\cache\CacheManager;
6
use micro\utils\RequestUtils;
7
use micro\cache\parser\ControllerParser;
8
use micro\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
	 * Retourne le chemin d'une route par son nom
87
	 * @param string $name nom de la route
88
	 */
89
	public static function getRouteByName($name, $absolute=true) {
90
		foreach ( self::$routes as $routePath => $routeDetails ) {
91
			if ($routeDetails["name"] == $name) {
92
				if ($absolute)
93
					return RequestUtils::getUrl($routePath);
94
				else
95
					return $routePath;
96
			}
97
		}
98
		return false;
99
	}
100
101
	public static function getRouteUrlParts($routeArray, $params, $cached=false, $duration=NULL,$cachedResponse=true) {
102
		$params=\array_slice($params, 1);
103
		$ctrl=str_replace("\\\\", "\\", $routeArray["details"]["controller"]);
104
		$result=[ $ctrl,$routeArray["details"]["action"] ];
105
		$paramsOrder=$routeArray["details"]["parameters"];
106
		$index=0;
107
		foreach ( $paramsOrder as $order ) {
108 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...
109
				if(isset($params[$index]))
110
					$result=\array_merge($result,\array_diff(\explode("/", $params[$index]),[""]));
111
				break;
112
			}
113
			if(\substr($order, 0,1)==="~"){
114
				$order=\intval(\substr($order,1,1));
115 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...
116
					$result=\array_merge($result,\array_diff(\explode("/", $params[$order]),[""]));
117
					break;
118
				}
119
			}
120
			$result[]=self::cleanParam($params[$order]);
121
			unset($params[$order]);
122
			$index++;
123
		}
124
		if ($cached === true && $cachedResponse===true) {
125
			return CacheManager::getRouteCache($result, $duration);
126
		}
127
		return $result;
128
	}
129
130
	private static function cleanParam($param){
131
		if(StrUtils::endswith($param, "/"))
132
			return \substr($param, 0,-1);
133
		return $param;
134
	}
135
136
	/**
137
	 * Déclare une route comme étant expirée ou non
138
	 * @param string $routePath
139
	 * @param boolean $expired
140
	 */
141
	public static function setExpired($routePath, $expired=true) {
142
		CacheManager::setExpired($routePath, $expired);
143
	}
144
145
	/**
146
	 *
147
	 * @param string $path
148
	 * @param string $controller
149
	 * @param string $action
150
	 * @param array|null $methods
151
	 * @param string $name
152
	 * @param boolean $cache
153
	 * @param int $duration
154
	 */
155
	public static function addRoute($path, $controller, $action="index", $methods=null, $name="", $cache=false, $duration=null) {
156
		self::addRouteToRoutes(self::$routes, $path, $controller, $action, $methods, $name, $cache, $duration);
157
	}
158
159
	public static function addRouteToRoutes(&$routesArray, $path, $controller, $action="index", $methods=null, $name="", $cache=false, $duration=null) {
160
		$result=[ ];
161
		$method=new \ReflectionMethod($controller, $action);
162
		ControllerParser::parseRouteArray($result, $controller, [ "path" => $path,"methods" => $methods,"name" => $name,"cache" => $cache,"duration" => $duration ], $method, $action);
163
		foreach ( $result as $k => $v ) {
164
			$routesArray[$k]=$v;
165
		}
166
	}
167
}
168