| Total Complexity | 42 |
| Total Lines | 187 |
| Duplicated Lines | 0 % |
| Changes | 0 | ||
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.
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 |
||
| 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() { |
||
| 41 | } |
||
| 42 | |||
| 43 | /** |
||
| 44 | * Returns the route corresponding to a path |
||
| 45 | * @param string $path |
||
| 46 | * @param boolean $cachedResponse |
||
| 47 | * @return boolean|mixed[]|mixed |
||
| 48 | */ |
||
| 49 | public static function getRoute($path, $cachedResponse = true) { |
||
| 50 | $path = self::slashPath ( $path ); |
||
| 51 | if(isset(self::$routes[$path])){ |
||
| 52 | return self::getRoute_(self::$routes[$path], $path, [$path], $cachedResponse); |
||
| 53 | } |
||
| 54 | 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 | Logger::warn("Router", "No route found for {$path}","getRoute"); |
||
| 60 | 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 | return self::getRouteUrlParts ( [ "path" => $routePath,"details" => $routeDetails [$method] ], $matches, @$routeDetails [$method] ["cache"], @$routeDetails [$method] ["duration"], $cachedResponse ); |
||
| 68 | } |
||
| 69 | } else{ |
||
| 70 | return self::getRouteUrlParts ( [ "path" => $routePath,"details" => $routeDetails ], $matches, @$routeDetails ["cache"], @$routeDetails ["duration"], $cachedResponse ); |
||
| 71 | } |
||
| 72 | return false; |
||
| 73 | } |
||
| 74 | |||
| 75 | /** |
||
| 76 | * Returns the generated path from a route |
||
| 77 | * |
||
| 78 | * @param string $name |
||
| 79 | * name of the route |
||
| 80 | * @param array $parameters |
||
| 81 | * array of the route parameters. default : [] |
||
| 82 | * @param boolean $absolute |
||
| 83 | */ |
||
| 84 | public static function getRouteByName($name, $parameters = [], $absolute = true) { |
||
| 85 | foreach ( self::$routes as $routePath => $routeDetails ) { |
||
| 86 | if (self::checkRouteName ( $routeDetails, $name )) { |
||
| 87 | if (\sizeof ( $parameters ) > 0) |
||
| 88 | $routePath = self::_getURL ( $routePath, $parameters ); |
||
| 89 | if (! $absolute) |
||
| 90 | return \ltrim ( $routePath, '/' ); |
||
| 91 | else |
||
| 92 | return $routePath; |
||
| 93 | } |
||
| 94 | } |
||
| 95 | return false; |
||
| 96 | } |
||
| 97 | |||
| 98 | /** |
||
| 99 | * Returns the generated path from a route |
||
| 100 | * |
||
| 101 | * @param string $name |
||
| 102 | * the route name |
||
| 103 | * @param array $parameters |
||
| 104 | * default: [] |
||
| 105 | * @param boolean $absolute |
||
| 106 | * true if the path is absolute (/ at first) |
||
| 107 | * @return boolean|string|array|mixed the generated path (/path/to/route) |
||
| 108 | */ |
||
| 109 | public static function path($name, $parameters = [], $absolute = false) { |
||
| 110 | return self::getRouteByName ( $name, $parameters, $absolute ); |
||
| 111 | } |
||
| 112 | |||
| 113 | /** |
||
| 114 | * Returns the generated url from a route |
||
| 115 | * |
||
| 116 | * @param string $name |
||
| 117 | * the route name |
||
| 118 | * @param array $parameters |
||
| 119 | * default: [] |
||
| 120 | * @return string the generated url (http://myApp/path/to/route) |
||
| 121 | */ |
||
| 122 | public static function url($name, $parameters = []) { |
||
| 123 | return URequest::getUrl ( self::getRouteByName ( $name, $parameters, false ) ); |
||
| 124 | } |
||
| 125 | |||
| 126 | protected static function _getURL($routePath, $params) { |
||
| 127 | $result = \preg_replace_callback ( '~\((.*?)\)~', function () use (&$params) { |
||
| 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 | if(($paramsOrder = @$routeArray ["details"] ["parameters"]) && (sizeof($paramsOrder)>0)){ |
||
| 151 | self::setParamsInOrder($result, $paramsOrder, $params); |
||
| 152 | } |
||
| 153 | if ($cached === true && $cachedResponse === true) { |
||
| 154 | Logger::info("Router", "Route found for {$routeArray["path"]} (from cache) : ".implode("/", $result),"getRouteUrlParts"); |
||
| 155 | return CacheManager::getRouteCache ( $result, $duration ); |
||
| 156 | } |
||
| 157 | Logger::info("Router", "Route found for {$routeArray["path"]} : ".implode("/", $result),"getRouteUrlParts"); |
||
| 158 | return $result; |
||
| 159 | } |
||
| 160 | |||
| 161 | protected static function setParamsInOrder(&$routeUrlParts,$paramsOrder,$params){ |
||
| 162 | $index = 0; |
||
| 163 | foreach ( $paramsOrder as $order ) { |
||
| 164 | if ($order === "*") { |
||
| 165 | if (isset ( $params [$index] )) |
||
| 166 | $routeUrlParts = \array_merge ( $routeUrlParts, \array_diff ( \explode ( "/", $params [$index] ), [ "" ] ) ); |
||
| 167 | break; |
||
| 168 | } |
||
| 169 | if (\substr ( $order, 0, 1 ) === "~") { |
||
| 170 | $order = \intval ( \substr ( $order, 1, 1 ) ); |
||
| 171 | if (isset ( $params [$order] )) { |
||
| 172 | $routeUrlParts = \array_merge ( $routeUrlParts, \array_diff ( \explode ( "/", $params [$order] ), [ "" ] ) ); |
||
| 173 | break; |
||
| 174 | } |
||
| 175 | } |
||
| 176 | $routeUrlParts [] = self::cleanParam ( $params [$order] ); |
||
| 177 | unset ( $params [$order] ); |
||
| 178 | $index ++; |
||
| 179 | } |
||
| 180 | } |
||
| 181 | |||
| 182 | private static function cleanParam($param) { |
||
| 186 | } |
||
| 187 | |||
| 188 | protected static function slashPath($path) { |
||
| 189 | if (UString::startswith ( $path, "/" ) === false) |
||
| 190 | $path = "/" . $path; |
||
| 191 | if (! UString::endswith ( $path, "/" )) |
||
| 192 | $path = $path . "/"; |
||
| 193 | return $path; |
||
| 194 | } |
||
| 195 | |||
| 196 | /** |
||
| 197 | * Declare a route as expired or not |
||
| 198 | * |
||
| 199 | * @param string $routePath |
||
| 200 | * @param boolean $expired |
||
| 201 | */ |
||
| 202 | public static function setExpired($routePath, $expired = true) { |
||
| 204 | } |
||
| 205 | } |
||
| 206 |