Route.class.php 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355
  1. <?php
  2. /**
  3. * This class will be a container for routes generated from link strings.
  4. *
  5. * @author Ironpilot
  6. * @copyright Copywrite (c) 2011, STAPLE CODE
  7. *
  8. * This file is part of the STAPLE Framework.
  9. *
  10. * The STAPLE Framework is free software: you can redistribute it and/or modify
  11. * it under the terms of the GNU Lesser General Public License as published by the
  12. * Free Software Foundation, either version 3 of the License, or (at your option)
  13. * any later version.
  14. *
  15. * The STAPLE Framework is distributed in the hope that it will be useful,
  16. * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
  17. * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
  18. * more details.
  19. *
  20. * You should have received a copy of the GNU Lesser General Public License
  21. * along with the STAPLE Framework. If not, see <http://www.gnu.org/licenses/>.
  22. */
  23. class Staple_Route
  24. {
  25. const ROUTE_MVC = 1;
  26. const ROUTE_SCRIPT = 2;
  27. const CONTROLLER_SUFFIX = "Controller";
  28. /**
  29. * The name of the controller being executed.
  30. * @var string
  31. */
  32. protected $controller;
  33. /**
  34. * Name of the action being executed.
  35. * @var string
  36. */
  37. protected $action;
  38. /**
  39. * The parameters that are being sent to the action
  40. * @var array[mixed]
  41. */
  42. protected $params = array();
  43. /**
  44. * The script route string.
  45. * @var string
  46. */
  47. protected $script;
  48. /**
  49. * Type of route: MVC route or script route.
  50. * @var int
  51. */
  52. protected $type;
  53. public function __construct($link = NULL)
  54. {
  55. if(isset($link))
  56. {
  57. if(is_array($link))
  58. {
  59. $this->processArrayRoute($link);
  60. }
  61. else
  62. {
  63. $this->processStringRoute($link);
  64. }
  65. }
  66. }
  67. /**
  68. * Returns the route as a link.
  69. */
  70. public function __toString()
  71. {
  72. //Website Base
  73. //$link = Staple_Config::getValue('application', 'public_location');
  74. //Add Controller
  75. $link = Staple_Link::urlCase($this->getController()).'/';
  76. //Add Action
  77. $link .= Staple_Link::urlCase($this->getAction());
  78. //Add Parameters
  79. if(count($this->params) >= 1)
  80. {
  81. $link .= '/'.implode('/', $this->params);
  82. }
  83. return $link;
  84. }
  85. /**
  86. * Returns the currently executing route. This is processed direct from the PATH_INFO php variable.
  87. * Returns a Staple_Route object.
  88. * @return Staple_Route
  89. */
  90. public static function GetCurrentRoute()
  91. {
  92. $route = new static();
  93. //First determine which routing information to use
  94. if(array_key_exists('PATH_INFO', $_SERVER)) //Use the URI route
  95. {
  96. $routeString = $_SERVER['PATH_INFO'];
  97. $routeString = urldecode($routeString); //URL decode any special characters
  98. }
  99. elseif(array_key_exists('REQUEST_URI', $_SERVER)) //Use the URI route
  100. {
  101. $routeString = $_SERVER['REQUEST_URI'];
  102. $routeString = urldecode($routeString); //URL decode any special characters
  103. }
  104. else //Use the default route
  105. {
  106. $routeString = 'index/index';
  107. }
  108. $route->processStringRoute($routeString);
  109. return $route;
  110. }
  111. /**
  112. * Dispatch the route
  113. */
  114. public function Execute()
  115. {
  116. //@todo incomplete method
  117. }
  118. /**
  119. * Redirect to the route location.
  120. */
  121. public function Redirect()
  122. {
  123. $base = Staple_Config::getValue('application', 'public_location');
  124. header('Location: '.$base.$this);
  125. exit(0);
  126. }
  127. /**
  128. * @return the $controller
  129. */
  130. public function getController()
  131. {
  132. return $this->controller;
  133. }
  134. /**
  135. * @return the $action
  136. */
  137. public function getAction()
  138. {
  139. return $this->action;
  140. }
  141. /**
  142. * @return the $params
  143. */
  144. public function getParams()
  145. {
  146. return $this->params;
  147. }
  148. /**
  149. * @return the $script
  150. */
  151. public function getScript()
  152. {
  153. return $this->script;
  154. }
  155. /**
  156. * @return the $type
  157. */
  158. public function getType()
  159. {
  160. return $this->type;
  161. }
  162. /**
  163. * @param number $type
  164. */
  165. public function setType($type)
  166. {
  167. switch($type)
  168. {
  169. case self::ROUTE_MVC:
  170. case self::ROUTE_SCRIPT:
  171. $this->type = (int)$type;
  172. break;
  173. }
  174. return $this;
  175. }
  176. /**
  177. * @param string $script
  178. */
  179. public function setScript($script)
  180. {
  181. $this->script = (string)$script;
  182. return $this;
  183. }
  184. /**
  185. * @param string $controller
  186. */
  187. public function setController($controller)
  188. {
  189. $this->controller = $controller;
  190. return $this;
  191. }
  192. /**
  193. * @param string $action
  194. */
  195. public function setAction($action)
  196. {
  197. $this->action = $action;
  198. return $this;
  199. }
  200. /**
  201. * @param array[mixed] $params
  202. */
  203. public function setParams(array $params)
  204. {
  205. $this->params = $params;
  206. return $this;
  207. }
  208. /**
  209. * Process an array route
  210. * @param array $route
  211. */
  212. protected function processArrayRoute(array $route)
  213. {
  214. //Set the Controller
  215. if(array_key_exists(0, $route))
  216. {
  217. $this->setController($route[0]);
  218. unset($route[0]);
  219. }
  220. else
  221. {
  222. $this->setController('index');
  223. }
  224. //Set the Action
  225. if(array_key_exists(1, $route))
  226. {
  227. $this->setAction($route[1]);
  228. unset($route[1]);
  229. }
  230. else
  231. {
  232. $this->setAction('index');
  233. }
  234. //Set Parameters
  235. if(count($route) >= 1)
  236. {
  237. $this->setParams($route);
  238. }
  239. }
  240. protected function processStringRoute($route)
  241. {
  242. //Run some route cleaning operations.
  243. $route = str_replace('\\','/',$route); //Convert backslashes to forward slashes
  244. //Remove a starting forward slash
  245. if(substr($route, 0, 1) == '/') $route = substr($route, 1, strlen($route)-1);
  246. //Remove trailing forward slash
  247. if(substr($route, (strlen($route)-1), 1) == '/') $route = substr($route, 0, strlen($route)-1);
  248. //End routing information on the first "." occurance
  249. if(($end = strpos($route,'.')) !== false)
  250. {
  251. $route = substr($route, 0, $end);
  252. }
  253. //Check to see if a script exists with that route.
  254. $scriptRoute = SCRIPT_ROOT.$route.'.php';
  255. if(file_exists($scriptRoute))
  256. {
  257. //Check for valid path information
  258. if(ctype_alnum(str_replace(array('/','_','-'),'',$route)))
  259. {
  260. $this->setScript($route)
  261. ->setType(self::ROUTE_SCRIPT);
  262. }
  263. }
  264. else
  265. {
  266. //No Script found, routing to controller/action
  267. //Split the route into it's component elements.
  268. $splitRoute = explode('/',$route);
  269. $routeCount = count($splitRoute);
  270. //If the route only contains a controller add the index action
  271. if($routeCount == 0)
  272. {
  273. array_push($splitRoute, 'index');
  274. array_push($splitRoute, 'index');
  275. }
  276. elseif($routeCount == 1)
  277. {
  278. array_push($splitRoute, 'index');
  279. }
  280. elseif($routeCount >= 2)
  281. {
  282. //If the action is numeric, it is not the action. Insert the index action into the route.
  283. if(is_numeric($splitRoute[1]))
  284. {
  285. $shift = array_shift($splitRoute);
  286. array_unshift($splitRoute, $shift, 'index');
  287. }
  288. }
  289. //Check the Controller value and Set a valid value
  290. $controller = array_shift($splitRoute);
  291. if(ctype_alnum(str_replace('-', '', $controller)) && ctype_alpha(substr($controller, 0, 1)))
  292. {
  293. $this->setController(Staple_Link::methodCase($controller));
  294. }
  295. else
  296. {
  297. //Bad info in the route, error out.
  298. throw new Exception('Invalid Route', Staple_Error::PAGE_NOT_FOUND);
  299. }
  300. //Check the Action Value and Set a valid value
  301. $action = array_shift($splitRoute);
  302. if(ctype_alnum(str_replace('-', '', $action)) && ctype_alpha(substr($action, 0, 1)))
  303. {
  304. $this->setAction(Staple_Link::methodCase($action));
  305. }
  306. else
  307. {
  308. //Bad info in the route, error out.
  309. throw new Exception('Invalid Route', Staple_Error::PAGE_NOT_FOUND);
  310. }
  311. $this
  312. ->setParams($splitRoute)
  313. ->setType(self::ROUTE_MVC);
  314. }
  315. }
  316. }
  317. ?>