PageRenderTime 44ms CodeModel.GetById 15ms RepoModel.GetById 0ms app.codeStats 0ms

/ROUTER.php

https://bitbucket.org/vodolaz095/trivia_core
PHP | 284 lines | 209 code | 23 blank | 52 comment | 20 complexity | 433798a452fdab380db1a98b6ab50ef6 MD5 | raw file
  1. <?php
  2. class RouterException extends Exception
  3. {
  4. }
  5. class ROUTER
  6. {
  7. protected static $instance;
  8. private $assigns = array();
  9. private $current_dir;
  10. private $path;
  11. private $args = array();
  12. private $is_deployed = false;
  13. private static function init()
  14. {
  15. if (is_null(self::$instance))
  16. {
  17. self::$instance = new ROUTER();
  18. }
  19. return self::$instance;
  20. }
  21. private function __construct()
  22. {
  23. }
  24. /**
  25. * Sets the current directory for project, where controllers and folder for modules are placed
  26. * @param string $current_dir - directory, where the BOOTLOADER.php file and main controllers are placed
  27. * @throws RouterException
  28. */
  29. public static function setCurrentDir($current_dir)
  30. {
  31. if(is_dir($current_dir))
  32. {
  33. $router=ROUTER::init();
  34. $router->current_dir=$current_dir;
  35. }
  36. else
  37. {
  38. throw new RouterException('Router can not set '.$currendDir.' as Current Directory for project!');
  39. }
  40. }
  41. /**
  42. * @return string - directory
  43. */
  44. public static function getCurrentDir()
  45. {
  46. $router=ROUTER::init();
  47. return($router->current_dir);
  48. }
  49. /**
  50. * Assign module action for route
  51. * @param string-regex $route - route to be assigned -
  52. * @param string $module - module name (consists only from letters, _ and digits) - in folder `modules` subfolder `indx` is a module name
  53. * @param string $action - action name (consists only from letters, _ and digits) - in folder `indx` `indx.action.php` is a action name
  54. * @throws RouterException - when something is wrong
  55. */
  56. public static function assign($route, $module, $action)
  57. {
  58. $router = ROUTER::init();
  59. if($router->current_dir)
  60. {
  61. if (preg_match('~^[a-z0-9_]+$~i', $module) and preg_match('~^[a-z0-9_]+$~i', $action))
  62. {
  63. $path = $router->current_dir . '/modules/' . $module . '/' . $action . '.action.php';
  64. if (is_readable($path))
  65. {
  66. //*
  67. if(isset($router->assigns[$route]))
  68. {
  69. throw new RouterException('Route '.$route.' is already assignet to '.$module.'-'.$action.' via path '.$router->assigns[$module.'-'.$action]['path']);
  70. }
  71. else
  72. {
  73. $router->assigns[$route] = array(
  74. 'route' => $route,
  75. 'module' => $module,
  76. 'action' => $action,
  77. 'path' => $path
  78. );
  79. }
  80. //*/
  81. /*
  82. $router->assigns[$route] = array(
  83. 'route' => $route,
  84. 'module' => $module,
  85. 'action' => $action,
  86. 'path' => $path
  87. );
  88. //*/
  89. }
  90. else
  91. {
  92. throw new RouterException('File "' . $path . '" does\'t exists!');
  93. }
  94. }
  95. else
  96. {
  97. throw new RouterException('Bad Folder and Module names!');
  98. }
  99. }
  100. else
  101. {
  102. throw new RouterException('Set the current directory from bootloader via command ROUTER::setCurrentDir(__DIR__)!!!');
  103. }
  104. }
  105. /**
  106. * Assign callback function to be executed when route matches the pattern
  107. * @param string-regex $route
  108. * @param $closure - function
  109. * @throws RouterException - when something is wrong
  110. */
  111. public static function assignFunction($route, $closure)
  112. {
  113. $router = ROUTER::init();
  114. if($router->current_dir)
  115. {
  116. if (is_callable($closure))
  117. {
  118. $router->assigns[] = array(
  119. 'route' => $route,
  120. 'function' => $closure
  121. );
  122. }
  123. else
  124. {
  125. throw new RouterException('Wrong object type for closure');
  126. }
  127. }
  128. else
  129. {
  130. throw new RouterException('Set the current directory from bootloader via command ROUTER::setCurrentDir(__DIR__)!!!');
  131. }
  132. }
  133. /**
  134. * Sets the module as a default module - server route. So, request with pattern example.com example/dosmth example/list
  135. * goes to actions index.action.php, dosmth.action.php and list.action.php of a module, defined as ServerRoute
  136. * @param $dirname
  137. * @throws RouterException
  138. */
  139. public static function setServerRoot($module_name)
  140. {
  141. $router = ROUTER::init();
  142. if($router->current_dir)
  143. {
  144. if(preg_match('~^[0-9a-z_]+$~i',$module_name))
  145. {
  146. if(is_dir($router->current_dir . '/modules/' . $module_name))
  147. {
  148. $path = $router->current_dir . '/modules/' . $module_name . '/*.action.php';
  149. foreach (glob($path) as $filename)
  150. {
  151. $name=basename($filename,'.action.php');
  152. if($name=='index')
  153. $router->assign('~^/$~',$module_name,'index');
  154. else
  155. $router->assign('~^/'.$name.'/?$~',$module_name,$name);
  156. }
  157. }
  158. else
  159. {
  160. throw new RouterException('Wrong directory name!');
  161. }
  162. }
  163. else
  164. {
  165. throw new RouterException('Wrong directory name!');
  166. }
  167. }
  168. else
  169. {
  170. throw new RouterException('Set the current directory from bootloader via command ROUTER::setCurrentDir(__DIR__)!!!');
  171. }
  172. }
  173. /**
  174. * Get array of all assigned routes
  175. * @return array
  176. */
  177. public static function getRoutes()
  178. {
  179. $a = array();
  180. $router = ROUTER::init();
  181. foreach ($router->assigns as $ass)
  182. {
  183. if (isset($ass['module']) and isset($ass['action']))
  184. {
  185. $a[] = array('route' => $ass['route'], 'execute' => $router->current_dir . '/' . $ass['module'] . '/' . $ass['action'] . '.action.php');
  186. }
  187. elseif (isset($ass['function']))
  188. {
  189. $a[] = array('route' => $ass['route'], 'function' => $ass['function']);
  190. }
  191. else
  192. {
  193. /*do nothing*/;
  194. }
  195. }
  196. return $a;
  197. }
  198. /**
  199. * Returns the route parameters
  200. * @param $number_of_argument - if assignet,returns the number of argument in query string
  201. * @return array
  202. */
  203. public static function getParameters($number_of_argument=false)
  204. {
  205. $router = ROUTER::init();
  206. if($number_of_argument)
  207. {
  208. return isset($router->args[$number_of_argument]) ? $router->args[$number_of_argument] : false;
  209. }
  210. else return $router->args;
  211. }
  212. /**
  213. * The main function for router!!!
  214. * @param string $override_request_uri - string to override URL of pages from cli enviroment
  215. * @return true on success, false on errors (no action to route et cetera)
  216. * @throws RouterException
  217. */
  218. public static function deploy($override_request_uri = false)
  219. {
  220. $unknown_route = true;
  221. $router = ROUTER::init();
  222. if ($router->is_deployed === false)
  223. {
  224. $router->is_deployed = true;
  225. if (PHP_SAPI == 'cli' and $override_request_uri)
  226. {
  227. $router->path = $override_request_uri;
  228. }
  229. else
  230. {
  231. $router->path = parse_url('http://' . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'], PHP_URL_PATH);
  232. }
  233. foreach ($router->assigns as $assign)
  234. {
  235. if (preg_match($assign['route'], $router->path, $router->args))
  236. {
  237. $unknown_route = false;
  238. if (isset($assign['path']))
  239. {
  240. require_once $assign['path'];
  241. }
  242. elseif(isset($assign['function']))
  243. {
  244. $a = $assign['function'];
  245. $a($router->args);
  246. }
  247. else
  248. {
  249. throw new RouterException('Wrong type of route?');
  250. }
  251. break;
  252. }
  253. }
  254. return (!$unknown_route);
  255. }
  256. else
  257. {
  258. throw new RouterException('Router Already Deployed!');
  259. }
  260. }
  261. }