PageRenderTime 61ms CodeModel.GetById 34ms RepoModel.GetById 1ms app.codeStats 0ms

/libraries/joomla/application/router.php

https://github.com/joebushi/joomla
PHP | 359 lines | 172 code | 49 blank | 138 comment | 27 complexity | c3ad19fbc97d02db8649675028e78313 MD5 | raw file
Possible License(s): LGPL-2.1, Apache-2.0
  1. <?php
  2. /**
  3. * @version $Id:router.php 8876 2007-09-13 22:54:03Z jinx $
  4. * @package Joomla.Framework
  5. * @subpackage Application
  6. * @copyright Copyright (C) 2005 - 2010 Open Source Matters, Inc. All rights reserved.
  7. * @license GNU General Public License version 2 or later; see LICENSE.txt
  8. */
  9. // No direct access
  10. defined('JPATH_BASE') or die;
  11. /**
  12. * Set the available masks for the routing mode
  13. */
  14. define('JROUTER_MODE_RAW', 0);
  15. define('JROUTER_MODE_SEF', 1);
  16. /**
  17. * Class to create and parse routes
  18. *
  19. * @package Joomla.Framework
  20. * @subpackage Application
  21. * @since 1.5
  22. */
  23. class JRouter extends JObject
  24. {
  25. /**
  26. * The rewrite mode
  27. *
  28. * @var integer
  29. */
  30. protected $_mode = null;
  31. /**
  32. * An array of variables
  33. *
  34. * @var array
  35. */
  36. protected $_vars = array();
  37. /**
  38. * An array of rules
  39. *
  40. * @var array
  41. */
  42. protected $_rules = array(
  43. 'build' => array(),
  44. 'parse' => array()
  45. );
  46. /**
  47. * Class constructor
  48. */
  49. public function __construct($options = array())
  50. {
  51. if (array_key_exists('mode', $options)) {
  52. $this->_mode = $options['mode'];
  53. } else {
  54. $this->_mode = JROUTER_MODE_RAW;
  55. }
  56. }
  57. /**
  58. * Returns the global JRouter object, only creating it if it
  59. * doesn't already exist.
  60. *
  61. * @param string The name of the client
  62. * @param array An associative array of options
  63. * @return JRouter A router object.
  64. */
  65. public static function getInstance($client, $options = array())
  66. {
  67. static $instances;
  68. if (!isset($instances)) {
  69. $instances = array();
  70. }
  71. if (empty($instances[$client])) {
  72. //Load the router object
  73. $info = &JApplicationHelper::getClientInfo($client, true);
  74. $path = $info->path.DS.'includes'.DS.'router.php';
  75. if (file_exists($path)) {
  76. require_once $path;
  77. // Create a JRouter object
  78. $classname = 'JRouter'.ucfirst($client);
  79. $instance = new $classname($options);
  80. } else {
  81. $error = JError::raiseError(500, 'Unable to load router: '.$client);
  82. return $error;
  83. }
  84. $instances[$client] = & $instance;
  85. }
  86. return $instances[$client];
  87. }
  88. /**
  89. * Function to convert a route to an internal URI
  90. */
  91. public function parse(&$uri)
  92. {
  93. $vars = array();
  94. // Process the parsed variables based on custom defined rules
  95. $vars = $this->_processParseRules($uri);
  96. // Parse RAW URL
  97. if ($this->_mode == JROUTER_MODE_RAW) {
  98. $vars += $this->_parseRawRoute($uri);
  99. }
  100. // Parse SEF URL
  101. if ($this->_mode == JROUTER_MODE_SEF) {
  102. $vars += $vars + $this->_parseSefRoute($uri);
  103. }
  104. return array_merge($this->getVars(), $vars);
  105. }
  106. /**
  107. * Function to convert an internal URI to a route
  108. *
  109. * @param string The internal URL
  110. * @return string The absolute search engine friendly URL
  111. */
  112. public function build($url)
  113. {
  114. //Create the URI object
  115. $uri = &$this->_createURI($url);
  116. //Process the uri information based on custom defined rules
  117. $this->_processBuildRules($uri);
  118. // Build RAW URL
  119. if ($this->_mode == JROUTER_MODE_RAW) {
  120. $this->_buildRawRoute($uri);
  121. }
  122. // Build SEF URL : mysite/route/index.php?var=x
  123. if ($this->_mode == JROUTER_MODE_SEF) {
  124. $this->_buildSefRoute($uri);
  125. }
  126. return $uri;
  127. }
  128. /**
  129. * Get the router mode
  130. */
  131. public function getMode()
  132. {
  133. return $this->_mode;
  134. }
  135. /**
  136. * Get the router mode
  137. */
  138. public function setMode($mode)
  139. {
  140. $this->_mode = $mode;
  141. }
  142. /**
  143. * Set a router variable, creating it if it doesn't exist
  144. *
  145. * @param string The name of the variable
  146. * @param mixed The value of the variable
  147. * @param boolean If True, the variable will be created if it doesn't exist yet
  148. */
  149. public function setVar($key, $value, $create = true)
  150. {
  151. if (!$create && array_key_exists($key, $this->_vars)) {
  152. $this->_vars[$key] = $value;
  153. } else {
  154. $this->_vars[$key] = $value;
  155. }
  156. }
  157. /**
  158. * Set the router variable array
  159. *
  160. * @param array An associative array with variables
  161. * @param boolean If True, the array will be merged instead of overwritten
  162. */
  163. public function setVars($vars = array(), $merge = true)
  164. {
  165. if ($merge) {
  166. $this->_vars = array_merge($this->_vars, $vars);
  167. } else {
  168. $this->_vars = $vars;
  169. }
  170. }
  171. /**
  172. * Get a router variable
  173. *
  174. * @param string The name of the variable
  175. * @return mixed Value of the variable
  176. */
  177. public function getVar($key)
  178. {
  179. $result = null;
  180. if (isset($this->_vars[$key])) {
  181. $result = $this->_vars[$key];
  182. }
  183. return $result;
  184. }
  185. /**
  186. * Get the router variable array
  187. *
  188. * @return array An associative array of router variables
  189. */
  190. public function getVars()
  191. {
  192. return $this->_vars;
  193. }
  194. /**
  195. * Attach a build rule
  196. *
  197. * @param callback The function to be called.
  198. */
  199. public function attachBuildRule($callback)
  200. {
  201. $this->_rules['build'][] = $callback;
  202. }
  203. /**
  204. * Attach a parse rule
  205. *
  206. * @param callback The function to be called.
  207. */
  208. public function attachParseRule($callback)
  209. {
  210. $this->_rules['parse'][] = $callback;
  211. }
  212. /**
  213. * Function to convert a raw route to an internal URI
  214. */
  215. protected function _parseRawRoute(&$uri)
  216. {
  217. return false;
  218. }
  219. /**
  220. * Function to convert a sef route to an internal URI
  221. */
  222. protected function _parseSefRoute(&$uri)
  223. {
  224. return false;
  225. }
  226. /**
  227. * Function to build a raw route
  228. */
  229. protected function _buildRawRoute(&$uri)
  230. {
  231. }
  232. /**
  233. * Function to build a sef route
  234. */
  235. protected function _buildSefRoute(&$uri)
  236. {
  237. }
  238. /**
  239. * Process the parsed router variables based on custom defined rules
  240. */
  241. protected function _processParseRules(&$uri)
  242. {
  243. $vars = array();
  244. foreach($this->_rules['parse'] as $rule) {
  245. $vars = call_user_func_array($rule, array(&$this, &$uri));
  246. }
  247. return $vars;
  248. }
  249. /**
  250. * Process the build uri query data based on custom defined rules
  251. */
  252. protected function _processBuildRules(&$uri)
  253. {
  254. foreach($this->_rules['build'] as $rule) {
  255. call_user_func_array($rule, array(&$this, &$uri));
  256. }
  257. }
  258. /**
  259. * Create a uri based on a full or partial url string
  260. * @return JURI A JURI object
  261. */
  262. protected function _createURI($url)
  263. {
  264. // Create full URL if we are only appending variables to it
  265. if (substr($url, 0, 1) == '&') {
  266. $vars = array();
  267. if (strpos($url, '&amp;') !== false) {
  268. $url = str_replace('&amp;','&',$url);
  269. }
  270. parse_str($url, $vars);
  271. $vars = array_merge($this->getVars(), $vars);
  272. foreach($vars as $key => $var) {
  273. if ($var == "") {
  274. unset($vars[$key]);
  275. }
  276. }
  277. $url = 'index.php?'.JURI::buildQuery($vars);
  278. }
  279. // Decompose link into url component parts
  280. return new JURI($url);
  281. }
  282. /**
  283. * Encode route segments
  284. *
  285. * @param array An array of route segments
  286. * @return array
  287. */
  288. protected function _encodeSegments($segments)
  289. {
  290. $total = count($segments);
  291. for ($i=0; $i<$total; $i++) {
  292. $segments[$i] = str_replace(':', '-', $segments[$i]);
  293. }
  294. return $segments;
  295. }
  296. /**
  297. * Decode route segments
  298. *
  299. * @param array An array of route segments
  300. * @return array
  301. */
  302. protected function _decodeSegments($segments)
  303. {
  304. $total = count($segments);
  305. for ($i=0; $i<$total; $i++) {
  306. $segments[$i] = preg_replace('/-/', ':', $segments[$i], 1);
  307. }
  308. return $segments;
  309. }
  310. }