PageRenderTime 43ms CodeModel.GetById 19ms RepoModel.GetById 1ms app.codeStats 0ms

/fuel/core/classes/request.php

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