Created
January 20, 2010 19:59
-
-
Save fritz0705/282181 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
namespace ActionController\Routing; | |
class Routes { | |
public static $map = null; | |
public static function draw(\Closure $lambda) { | |
$lambda->__invoke(self::$map); | |
} | |
public static function extract_params($path, $route = null) { | |
if ($route == null) { | |
$route = self::find_route($path); | |
} | |
$extracted_params = array(); | |
$route_path = self::normalize_path($route->path); | |
$route_path_parts = preg_split("/[".preg_quote(ACTION_CONTROLLER_ROUTING_PATH_SEPARATORS, "/")."]/", $route_path); | |
$route_options = $route->options; | |
$path = self::normalize_path($path); | |
$path_parts = preg_split("/[".preg_quote(ACTION_CONTROLLER_ROUTING_PATH_SEPARATORS, "/")."]/", $path); | |
foreach ($route_path_parts as $route_path_part_key => $route_path_part) { | |
$path_part = $path_parts[$route_path_part_key]; | |
if (substr($route_path_part, 0, 1) == ":") { | |
$route_path_part_name = substr($route_path_part, 1); | |
$extracted_params[$route_path_part_name] = $path_part; | |
} | |
} | |
foreach ($route_options as $route_option_key => $route_option) { | |
if (substr($route_option, 0, 1) != "/") { | |
$extracted_params[$route_option_key] = $route_option; | |
} | |
} | |
return $extracted_params; | |
} | |
public static function find_route($path) { | |
$path_separators_expr = preg_quote(ACTION_CONTROLLER_ROUTING_PATH_SEPARATORS, "/"); | |
$routes = self::$map->routes; | |
$path = self::normalize_path($path); | |
$path_parts_split_expr = "/[".$path_separators_expr."]/"; | |
$path_parts = preg_split($path_parts_split_expr, $path); | |
$path_part_separators = self::extract_separators($path); | |
foreach ($routes as $route) { | |
if (!strstr($route->path, ":") && $route->path == $path) { | |
return $route; | |
} | |
$route_options = $route->options; | |
$route_path = self::normalize_path($route->path); | |
$route_path_parts_split_expr = "/[".$path_separators_expr."]/"; | |
$route_path_parts = preg_split($route_path_parts_split_expr, $route_path); | |
$route_path_part_separators = self::extract_separators($route_path); | |
if (count($route_path_parts) != count($path_parts)) { | |
continue; | |
} | |
$matches = true; | |
foreach ($route_path_parts as $key => $route_path_part) { | |
if (array_key_exists($key, $path_part_separators)) { | |
if ($path_part_separators[$key] != $route_path_part_separators[$key]) { | |
$matches &= false; | |
break; | |
} | |
} | |
if (substr($route_path_part, 0, 1) == ":") { | |
$route_path_part_name = substr($route_path_part, 1); | |
if (array_key_exists($route_path_part_name, $route_options)) { | |
$route_path_part_option = $route_options[$route_path_part_name]; | |
if (substr($route_path_part_option, 0, 1) == "/") { | |
if (!preg_match($route_path_part_option, $path_parts[$key])) { | |
$matches = false; | |
break; | |
} else { | |
$matches &= true; | |
continue; | |
} | |
} else { | |
if ($route_path_part_option == $path_parts) { | |
$matches &= true; | |
continue; | |
} | |
} | |
} | |
$matches &= true; | |
} else { | |
if ($route_path_part == $path_parts[$key]) { | |
$matches &= true; | |
} else { | |
$matches &= false; | |
break; | |
} | |
} | |
} | |
if ($matches) { | |
return $route; | |
} | |
} | |
throw new Exception("No route found!"); | |
} | |
public static function generate($options = array()) { | |
foreach (self::$map->routes as $route) { | |
$route_options = $route->options; | |
$route_path = self::normalize_path($route->path); | |
foreach ($route_options as $key => $route_option) { | |
if (!array_key_exists($key, $options)) { | |
if (substr($route_option, 0, 1) == "/") { | |
continue 2; | |
} | |
} | |
if (substr($route_option, 0, 1) == "/") { | |
if (!preg_match($route_option, $options[$key])) { | |
continue 2; | |
} | |
} else if ($route_option != $options[$key]) { | |
continue 2; | |
} | |
} | |
$generated_route_path = $route_path; | |
foreach ($options as $key => $value) { | |
$generated_route_path = str_replace(":" . $key, $value, $generated_route_path); | |
} | |
return "/" . $generated_route_path; | |
} | |
$url_query = array(); | |
foreach ($options as $name => $option) { | |
$url_query[] = $name . "=" . $option; | |
} | |
return "/?" . implode("&", $url_query); | |
} | |
private static function normalize_path($path) { | |
$path = str_replace("//", "/", $path); | |
$path = substr($path, -1) == "/" ? substr($path, 0, strlen($path) - 1) : $path; | |
$path = substr($path, 0, 1) == "/" ? substr($path, 1) : $path; | |
$path = str_replace("::", ":", $path); | |
return $path; | |
} | |
private static function extract_separators($path) { | |
$result = array(); | |
$separators_array = str_split(ACTION_CONTROLLER_ROUTING_PATH_SEPARATORS); | |
foreach (str_split($path) as $char) { | |
if (in_array($char, $separators_array)) { | |
$result[] = $char; | |
} | |
} | |
return $result; | |
} | |
} | |
Routes::$map = new Map(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment