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

/fuel/core/classes/request.php

https://github.com/ifaour/fuel
PHP | 372 lines | 175 code | 59 blank | 138 comment | 20 complexity | 545261d48c213acf71ca317d0b27afc5 MD5 | raw file
Possible License(s): MIT, BSD-3-Clause
  1. <?php
  2. /**
  3. * Fuel
  4. *
  5. * Fuel is a fast, lightweight, community driven PHP5 framework.
  6. *
  7. * @package Fuel
  8. * @version 1.0
  9. * @author Fuel Development Team
  10. * @license MIT License
  11. * @copyright 2010 - 2011 Fuel Development Team
  12. * @link http://fuelphp.com
  13. */
  14. namespace Fuel\Core;
  15. class Request {
  16. /**
  17. * @var object Holds the main request instance
  18. */
  19. protected static $main = false;
  20. /**
  21. * @var object Holds the global request instance
  22. */
  23. protected static $active = false;
  24. /**
  25. * @var array search paths for the current active request
  26. */
  27. public $paths = array();
  28. /**
  29. * Generates a new request. The request is then set to be the active
  30. * request. If this is the first request, then save that as the main
  31. * request for the app.
  32. *
  33. * Usage:
  34. *
  35. * <code>Request::factory('hello/world');</code>
  36. *
  37. * @access public
  38. * @param string The URI of the request
  39. * @param bool if true use routes to process the URI
  40. * @return object The new request
  41. */
  42. public static function factory($uri = null, $route = true)
  43. {
  44. logger(Fuel::L_INFO, 'Creating a new Request with URI = "'.$uri.'"', __METHOD__);
  45. static::$active = new static($uri, $route);
  46. if ( ! static::$main)
  47. {
  48. logger(Fuel::L_INFO, 'Setting main Request', __METHOD__);
  49. static::$main = static::$active;
  50. }
  51. return static::$active;
  52. }
  53. /**
  54. * Returns the main request instance.
  55. *
  56. * Usage:
  57. *
  58. * <code>Request::main();</code>
  59. *
  60. * @access public
  61. * @return object
  62. */
  63. public static function main()
  64. {
  65. logger(Fuel::L_INFO, 'Called', __METHOD__);
  66. return static::$main;
  67. }
  68. /**
  69. * Returns the active request currently being used.
  70. *
  71. * Usage:
  72. *
  73. * <code>Request::active();</code>
  74. *
  75. * @access public
  76. * @return object
  77. */
  78. public static function active()
  79. {
  80. logger(Fuel::L_INFO, 'Called', __METHOD__);
  81. return static::$active;
  82. }
  83. /**
  84. * Shows a 404. Checks to see if a 404_override route is set, if not show
  85. * a default 404.
  86. *
  87. * Usage:
  88. *
  89. * <code>Request::show_404();</code>
  90. *
  91. * @access public
  92. * @return void
  93. */
  94. public static function show_404($return = false)
  95. {
  96. logger(Fuel::L_INFO, 'Called', __METHOD__);
  97. \Output::$status = 404;
  98. if (\Config::get('routes.404') === null)
  99. {
  100. static::active()->output = \View::factory('404');
  101. }
  102. else
  103. {
  104. list($controller, $action) = array_pad(explode('/', \Config::get('routes.404')), 2, false);
  105. $action or $action = 'index';
  106. $class = '\\Controller_'.ucfirst($controller);
  107. $method = 'action_'.$action;
  108. if (class_exists($class))
  109. {
  110. $controller = new $class(static::active());
  111. if (method_exists($controller, $method))
  112. {
  113. // Call the before method if it exists
  114. if (method_exists($controller, 'before'))
  115. {
  116. $controller->before();
  117. }
  118. $controller->{$method}();
  119. // Call the after method if it exists
  120. if (method_exists($controller, 'after'))
  121. {
  122. $controller->after();
  123. }
  124. // Get the controller's output
  125. if ($return)
  126. {
  127. return $controller->output;
  128. }
  129. exit($controller->output);
  130. }
  131. else
  132. {
  133. throw new \Exception('404 Action not found.');
  134. }
  135. }
  136. else
  137. {
  138. throw new \Exception('404 Controller not found.');
  139. }
  140. }
  141. }
  142. /**
  143. * @var string Holds the response of the request.
  144. */
  145. public $output = NULL;
  146. /**
  147. * @var object The request's URI object
  148. */
  149. public $uri = '';
  150. /**
  151. * @var string Controller module
  152. */
  153. public $module = '';
  154. /**
  155. * @var string Controller directory
  156. */
  157. public $directory = '';
  158. /**
  159. * @var string The request's controller
  160. */
  161. public $controller = '';
  162. /**
  163. * @var string The request's action
  164. */
  165. public $action = '';
  166. /**
  167. * @var string The request's method params
  168. */
  169. public $method_params = array();
  170. /**
  171. * @var string The request's named params
  172. */
  173. public $named_params = array();
  174. /**
  175. * Creates the new Request object by getting a new URI object, then parsing
  176. * the uri with the Route class.
  177. *
  178. * @access public
  179. * @param string the uri string
  180. * @param bool whether or not to route the URI
  181. * @return void
  182. */
  183. public function __construct($uri, $route)
  184. {
  185. $this->uri = new \URI($uri);
  186. $route = $route === true ? \Route::parse($this->uri) : \Route::parse_match($uri);
  187. // Attempts to register the first segment as a module
  188. $mod_path = \Fuel::add_module($route['segments'][0]);
  189. if ($mod_path !== false)
  190. {
  191. $this->module = array_shift($route['segments']);
  192. $this->paths = array($mod_path, $mod_path.'classes'.DS);
  193. }
  194. // Check for directory
  195. $path = ( ! empty($this->module) ? $mod_path : APPPATH).'controller'.DS;
  196. if ( ! empty($route['segments']) && is_dir($dirpath = $path.strtolower($route['segments'][0])))
  197. {
  198. $this->directory = array_shift($route['segments']);
  199. }
  200. // When emptied the controller defaults to directory or module
  201. $controller = empty($this->directory) ? $this->module : $this->directory;
  202. if (count($route['segments']) == 0)
  203. {
  204. $route['segments'] = array($controller);
  205. }
  206. $this->controller = $route['segments'][0];
  207. $this->action = isset($route['segments'][1]) ? $route['segments'][1] : '';
  208. $this->method_params = array_slice($route['segments'], 2);
  209. $this->named_params = $route['named_params'];
  210. unset($route);
  211. }
  212. /**
  213. * This executes the request and sets the output to be used later.
  214. *
  215. * Usage:
  216. *
  217. * <code>$request = Request::factory('hello/world')->execute();</code>
  218. *
  219. * @access public
  220. * @return void
  221. */
  222. public function execute()
  223. {
  224. logger(Fuel::L_INFO, 'Called', __METHOD__);
  225. $controller_prefix = '\\'.($this->module ? ucfirst($this->module).'\\' : '').'Controller_';
  226. $method_prefix = 'action_';
  227. $class = $controller_prefix.($this->directory ? ucfirst($this->directory).'_' : '').ucfirst($this->controller);
  228. $method = $this->action;
  229. // Allow omitting the controller name when in an equally named directory or module
  230. if ( ! class_exists($class))
  231. {
  232. // set the new controller to directory or module when applicable
  233. $controller = $this->directory ?: $this->module;
  234. // ... or to the default controller if it was in neither
  235. $controller = $controller ?: preg_replace('#/([a-z0-9/_]*)$#uiD', '', \Route::$routes['#']);
  236. // try again with new controller if it differs from the previous attempt
  237. if ($controller != $this->controller)
  238. {
  239. $class = $controller_prefix.($this->directory ? $this->directory.'_' : '').ucfirst($controller);
  240. array_unshift($this->method_params, $this->action);
  241. $this->action = $this->controller;
  242. $method = $this->action ?: '';
  243. $this->controller = $controller;
  244. }
  245. // 404 if it's still not found
  246. if ( ! class_exists($class))
  247. {
  248. $this->output =& static::show_404(true);
  249. return $this;
  250. }
  251. }
  252. logger(Fuel::L_INFO, 'Loading controller '.$class, __METHOD__);
  253. $controller = new $class($this);
  254. $method = $method_prefix.($method ?: (property_exists($controller, 'default_action') ? $controller->default_action : 'index'));
  255. // Allow to do in controller routing if method router(action, params) exists
  256. if (method_exists($controller, 'router'))
  257. {
  258. $method = 'router';
  259. $this->method_params = array($this->action, $this->method_params);
  260. }
  261. if (method_exists($controller, $method))
  262. {
  263. // Call the before method if it exists
  264. if (method_exists($controller, 'before'))
  265. {
  266. logger(Fuel::L_INFO, 'Calling '.$class.'::before', __METHOD__);
  267. $controller->before();
  268. }
  269. logger(Fuel::L_INFO, 'Calling '.$class.'::'.$method, __METHOD__);
  270. call_user_func_array(array($controller, $method), $this->method_params);
  271. // Call the after method if it exists
  272. if (method_exists($controller, 'after'))
  273. {
  274. logger(Fuel::L_INFO, 'Calling '.$class.'::after', __METHOD__);
  275. $controller->after();
  276. }
  277. // Get the controller's output
  278. $this->output =& $controller->output;
  279. }
  280. else
  281. {
  282. $this->output =& static::show_404(true);
  283. }
  284. return $this;
  285. }
  286. public function send_headers()
  287. {
  288. \Output::send_headers();
  289. return $this;
  290. }
  291. public function output()
  292. {
  293. echo $this->output;
  294. }
  295. /**
  296. * PHP magic function returns the Output of the request.
  297. *
  298. * Usage:
  299. *
  300. * <code>
  301. * $request = Request::factory('hello/world')->execute();
  302. * echo $request;
  303. * </code>
  304. *
  305. * @access public
  306. * @return string
  307. */
  308. public function __toString()
  309. {
  310. return (string) $this->output;
  311. }
  312. }
  313. /* End of file request.php */