PageRenderTime 55ms CodeModel.GetById 25ms RepoModel.GetById 0ms app.codeStats 1ms

/lib/core/dispatcher/Mapper.php

https://github.com/anderson631/spaghettiphp
PHP | 218 lines | 209 code | 9 blank | 0 comment | 38 complexity | 284ae3eeeb02d09c516d165227643108 MD5 | raw file
  1. <?php
  2. class Mapper {
  3. protected $prefixes = array();
  4. protected $routes = array();
  5. protected $base;
  6. protected $here = '/';
  7. protected $domain = 'http://localhost';
  8. protected $root;
  9. protected static $instance;
  10. public function __construct() {
  11. $this->base = dirname($_SERVER['PHP_SELF']);
  12. if(basename($this->base) == 'public'):
  13. $this->base = dirname($this->base);
  14. if($this->base == DIRECTORY_SEPARATOR || $this->base == '.'):
  15. $this->base = '/';
  16. endif;
  17. endif;
  18. if(array_key_exists('REQUEST_URI', $_SERVER) && array_key_exists('HTTP_HOST', $_SERVER)):
  19. $start = strlen($this->base);
  20. $this->here = self::normalize(substr($_SERVER['REQUEST_URI'], $start));
  21. $this->domain = 'http' . (isset($_SERVER['HTTPS']) ? 's' : '') . '://' . $_SERVER['HTTP_HOST'];
  22. endif;
  23. }
  24. public static function instance() {
  25. if(!isset(self::$instance)):
  26. $c = __CLASS__;
  27. self::$instance = new $c;
  28. endif;
  29. return self::$instance;
  30. }
  31. public static function here() {
  32. $self = self::instance();
  33. return $self->here;
  34. }
  35. public static function base() {
  36. $self = self::instance();
  37. return $self->base;
  38. }
  39. public static function domain() {
  40. $self = self::instance();
  41. return $self->domain;
  42. }
  43. public static function normalize($url) {
  44. if(!preg_match('/^[a-z]+:/i', $url)):
  45. $url = '/' . $url;
  46. while(strpos($url, '//') !== false):
  47. $url = str_replace('//', '/', $url);
  48. endwhile;
  49. $url = rtrim($url, '/');
  50. if(empty($url)):
  51. $url = '/';
  52. endif;
  53. endif;
  54. return $url;
  55. }
  56. public static function root($controller) {
  57. $self = self::instance();
  58. $self->root = $controller;
  59. return true;
  60. }
  61. public static function getRoot() {
  62. $self = self::instance();
  63. return $self->root;
  64. }
  65. public static function prefix($prefix) {
  66. $self = self::instance();
  67. if(is_array($prefix)) $prefixes = $prefix;
  68. else $prefixes = func_get_args();
  69. foreach($prefixes as $prefix):
  70. $self->prefixes []= $prefix;
  71. endforeach;
  72. return true;
  73. }
  74. public static function unsetPrefix($prefix) {
  75. $self = self::instance();
  76. unset($self->prefixes[$prefix]);
  77. return true;
  78. }
  79. public static function getPrefixes() {
  80. $self = self::instance();
  81. return $self->prefixes;
  82. }
  83. public static function connect($url = null, $route = null) {
  84. if(is_array($url)):
  85. foreach($url as $key => $value):
  86. self::connect($key, $value);
  87. endforeach;
  88. elseif(!is_null($url)):
  89. $self = self::instance();
  90. $url = self::normalize($url);
  91. $self->routes[$url] = rtrim($route, '/');
  92. endif;
  93. return true;
  94. }
  95. public static function disconnect($url) {
  96. $self = self::instance();
  97. $url = rtrim($url, '/');
  98. unset($self->routes[$url]);
  99. return true;
  100. }
  101. public static function match($check, $url = null) {
  102. if(is_null($url)):
  103. $url = self::here();
  104. endif;
  105. $check = '%^' . str_replace(array(':any', ':fragment', ':num'), array('(.+)', '([^\/]+)', '([0-9]+)'), $check) . '/?$%';
  106. return preg_match($check, $url);
  107. }
  108. public static function getRoute($url) {
  109. $self = self::instance();
  110. foreach($self->routes as $map => $route):
  111. if(self::match($map, $url)):
  112. $map = '%^' . str_replace(array(':any', ':fragment', ':num'), array('(.+)', '([^\/]+)', '([0-9]+)'), $map) . '/?$%';
  113. $url = preg_replace($map, $route, $url);
  114. break;
  115. endif;
  116. endforeach;
  117. return self::normalize($url);
  118. }
  119. public static function parse($url = null) {
  120. $here = self::normalize(is_null($url) ? self::here() : $url);
  121. $url = self::getRoute($here);
  122. $prefixes = join('|', self::getPrefixes());
  123. $path = array();
  124. $parts = array('here', 'prefix', 'controller', 'action', 'extension', 'params', 'queryString');
  125. preg_match('/^\/(?:(' . $prefixes . ')(?:\/|(?!\w)))?(?:([a-z_-]*)\/?)?(?:([a-z_-]*)\/?)?(?:\.([\w]+))?(?:\/?([^?]+))?(?:\?(.*))?/i', $url, $reg);
  126. foreach($parts as $k => $key):
  127. $path[$key] = isset($reg[$k]) ? $reg[$k] : null;
  128. endforeach;
  129. $path['named'] = $path['params'] = array();
  130. if(isset($reg[5])):
  131. foreach(explode('/', $reg[5]) as $param):
  132. if(preg_match('/([^:]*):([^:]*)/', $param, $reg)):
  133. $path['named'][$reg[1]] = urldecode($reg[2]);
  134. elseif($param != ''):
  135. $path['params'] []= urldecode($param);
  136. endif;
  137. endforeach;
  138. endif;
  139. $path['here'] = $here;
  140. if(empty($path['controller'])) $path['controller'] = self::getRoot();
  141. if(empty($path['action'])) $path['action'] = 'index';
  142. if($filtered = self::filterAction($path['action'])):
  143. $path['prefix'] = $filtered['prefix'];
  144. $path['action'] = $filtered['action'];
  145. endif;
  146. if(!empty($path['prefix'])):
  147. $path['action'] = $path['prefix'] . '_' . $path['action'];
  148. endif;
  149. if(empty($path['id'])) $path['id'] = null;
  150. if(empty($path['extension'])) $path['extension'] = 'htm';
  151. if(!empty($path['queryString'])):
  152. parse_str($path['queryString'], $queryString);
  153. $path['named'] = array_merge($path['named'], $queryString);
  154. endif;
  155. return $path;
  156. }
  157. public static function url($path, $full = false) {
  158. if(is_array($path)):
  159. $here = self::parse();
  160. $params = $here['named'];
  161. $path = array_merge(array(
  162. 'prefix' => $here['prefix'],
  163. 'controller' => $here['controller'],
  164. 'action' => $here['action'],
  165. 'params' => $here['params']
  166. ), $params, $path);
  167. $nonParams = array('prefix', 'controller', 'action', 'params');
  168. $url = '';
  169. foreach($path as $key => $value):
  170. if(!in_array($key, $nonParams)):
  171. $url .= '/' . $key . ':' . $value;
  172. elseif(!is_null($value)):
  173. if($key == 'action' && $filtered = self::filterAction($value)):
  174. $value = $filtered['action'];
  175. elseif($key == 'params'):
  176. $value = join('/', $value);
  177. endif;
  178. $url .= '/' . $value;
  179. endif;
  180. endforeach;
  181. else:
  182. if(preg_match('/^[a-z]+:/', $path)):
  183. return $path;
  184. elseif(substr($path, 0, 1) == '/'):
  185. $url = $path;
  186. else:
  187. if(substr($path, 0, 1) != '#'):
  188. $path = '/' . $path;
  189. endif;
  190. $url = self::here() . $path;
  191. endif;
  192. endif;
  193. $url = self::normalize(self::base() . $url);
  194. return $full ? self::domain() . $url : $url;
  195. }
  196. public static function filterAction($action) {
  197. if(strpos($action, '_') !== false):
  198. foreach(self::getPrefixes() as $prefix):
  199. if(strpos($action, $prefix) === 0):
  200. return array(
  201. 'action' => substr($action, strlen($prefix) + 1),
  202. 'prefix' => $prefix
  203. );
  204. endif;
  205. endforeach;
  206. endif;
  207. return false;
  208. }
  209. }