PageRenderTime 24ms CodeModel.GetById 27ms RepoModel.GetById 1ms app.codeStats 0ms

/fuel/core/classes/request.php

https://github.com/mzkrelx/milm-search-ui-php
PHP | 575 lines | 242 code | 73 blank | 260 comment | 23 complexity | d6bcdc237dceb938cc81bbf75727cca5 MD5 | raw file
  1. <?php
  2. /**
  3. * Part of the Fuel framework.
  4. *
  5. * @package Fuel
  6. * @version 1.0
  7. * @author Fuel Development Team
  8. * @license MIT License
  9. * @copyright 2010 - 2012 Fuel Development Team
  10. * @link http://fuelphp.com
  11. */
  12. namespace Fuel\Core;
  13. /**
  14. * The Request class is used to create and manage new and existing requests. There
  15. * is a main request which comes in from the browser or command line, then new
  16. * requests can be created for HMVC requests.
  17. *
  18. * Example Usage:
  19. *
  20. * $request = Request::forge('foo/bar')->execute();
  21. * echo $request->response();
  22. *
  23. * @package Fuel
  24. * @subpackage Core
  25. */
  26. class Request
  27. {
  28. /**
  29. * Holds the main request instance
  30. *
  31. * @var Request
  32. */
  33. protected static $main = false;
  34. /**
  35. * Holds the global active request instance
  36. *
  37. * @var Request
  38. */
  39. protected static $active = false;
  40. /**
  41. * Generates a new request. The request is then set to be the active
  42. * request. If this is the first request, then save that as the main
  43. * request for the app.
  44. *
  45. * Usage:
  46. *
  47. * Request::forge('hello/world');
  48. *
  49. * @param string The URI of the request
  50. * @param mixed Internal: whether to use the routes; external: driver type or array with settings (driver key must be set)
  51. * @param string request method
  52. * @return Request The new request object
  53. */
  54. public static function forge($uri = null, $options = true, $method = null)
  55. {
  56. is_bool($options) and $options = array('route' => $options);
  57. is_string($options) and $options = array('driver' => $options);
  58. if ( ! empty($options['driver']))
  59. {
  60. $class = \Inflector::words_to_upper('Request_'.$options['driver']);
  61. return $class::forge($uri, $options, $method);
  62. }
  63. $request = new static($uri, isset($options['route']) ? $options['route'] : true, $method);
  64. if (static::$active)
  65. {
  66. $request->parent = static::$active;
  67. static::$active->children[] = $request;
  68. }
  69. return $request;
  70. }
  71. /**
  72. * Returns the main request instance (the one from the browser or CLI).
  73. * This is the first executed Request, not necessarily the root parent of the current request.
  74. *
  75. * Usage:
  76. *
  77. * Request::main();
  78. *
  79. * @return Request
  80. */
  81. public static function main()
  82. {
  83. return static::$main;
  84. }
  85. /**
  86. * Returns the active request currently being used.
  87. *
  88. * Usage:
  89. *
  90. * Request::active();
  91. *
  92. * @param Request|null|false overwrite current request before returning, false prevents overwrite
  93. * @return Request
  94. */
  95. public static function active($request = false)
  96. {
  97. if ($request !== false)
  98. {
  99. static::$active = $request;
  100. }
  101. return static::$active;
  102. }
  103. /**
  104. * Returns the current request is an HMVC request
  105. *
  106. * Usage:
  107. *
  108. * if (Request::is_hmvc())
  109. * {
  110. * // Do something special...
  111. * return;
  112. * }
  113. *
  114. * @return bool
  115. */
  116. public static function is_hmvc()
  117. {
  118. return static::active() !== static::main();
  119. }
  120. /**
  121. * Reset's the active request with the previous one. This is needed after
  122. * the active request is finished.
  123. *
  124. * Usage:
  125. *
  126. * Request::reset_request();
  127. *
  128. * @return void
  129. */
  130. public static function reset_request()
  131. {
  132. // Let's make the previous Request active since we are done executing this one.
  133. static::$active = static::$active->parent();
  134. }
  135. /**
  136. * Holds the response object of the request.
  137. *
  138. * @var Response
  139. */
  140. public $response = null;
  141. /**
  142. * The Request's URI object.
  143. *
  144. * @var Uri
  145. */
  146. public $uri = null;
  147. /**
  148. * The request's route object
  149. *
  150. * @var Route
  151. */
  152. public $route = null;
  153. /**
  154. * @var string $method request method
  155. */
  156. protected $method = null;
  157. /**
  158. * The current module
  159. *
  160. * @var string
  161. */
  162. public $module = '';
  163. /**
  164. * The current controller directory
  165. *
  166. * @var string
  167. */
  168. public $directory = '';
  169. /**
  170. * The request's controller
  171. *
  172. * @var string
  173. */
  174. public $controller = '';
  175. /**
  176. * The request's controller action
  177. *
  178. * @var string
  179. */
  180. public $action = '';
  181. /**
  182. * The request's method params
  183. *
  184. * @var array
  185. */
  186. public $method_params = array();
  187. /**
  188. * The request's named params
  189. *
  190. * @var array
  191. */
  192. public $named_params = array();
  193. /**
  194. * Controller instance once instantiated
  195. *
  196. * @var Controller
  197. */
  198. public $controller_instance;
  199. /**
  200. * Search paths for the current active request
  201. *
  202. * @var array
  203. */
  204. public $paths = array();
  205. /**
  206. * Request that created this one
  207. *
  208. * @var Request
  209. */
  210. protected $parent = null;
  211. /**
  212. * Requests created by this request
  213. *
  214. * @var array
  215. */
  216. protected $children = array();
  217. /**
  218. * Creates the new Request object by getting a new URI object, then parsing
  219. * the uri with the Route class.
  220. *
  221. * Usage:
  222. *
  223. * $request = new Request('foo/bar');
  224. *
  225. * @param string the uri string
  226. * @param bool whether or not to route the URI
  227. * @param string request method
  228. * @return void
  229. */
  230. public function __construct($uri, $route = true, $method = null)
  231. {
  232. $this->uri = new \Uri($uri);
  233. $this->method = $method;
  234. logger(\Fuel::L_INFO, 'Creating a new Request with URI = "'.$this->uri->get().'"', __METHOD__);
  235. // check if a module was requested
  236. if (count($this->uri->get_segments()) and $module_path = \Module::exists($this->uri->get_segment(1)))
  237. {
  238. // check if the module has routes
  239. if (is_file($module_path .= 'config/routes.php'))
  240. {
  241. $module = $this->uri->get_segment(1);
  242. // load and add the module routes
  243. $module_routes = \Fuel::load($module_path);
  244. $prepped_routes = array();
  245. foreach($module_routes as $name => $_route)
  246. {
  247. if ($name === '_root_')
  248. {
  249. $name = $module;
  250. }
  251. elseif (strpos($name, $module.'/') !== 0 and $name != $module and $name !== '_404_')
  252. {
  253. $name = $module.'/'.$name;
  254. }
  255. $prepped_routes[$name] = $_route;
  256. };
  257. // update the loaded list of routes
  258. \Router::add($prepped_routes, null, true);
  259. }
  260. }
  261. $this->route = \Router::process($this, $route);
  262. if ( ! $this->route)
  263. {
  264. return;
  265. }
  266. $this->module = $this->route->module;
  267. $this->controller = $this->route->controller;
  268. $this->action = $this->route->action;
  269. $this->method_params = $this->route->method_params;
  270. $this->named_params = $this->route->named_params;
  271. if ($this->route->module !== null)
  272. {
  273. $this->add_path(\Module::exists($this->module));
  274. }
  275. }
  276. /**
  277. * This executes the request and sets the output to be used later.
  278. *
  279. * Usage:
  280. *
  281. * $request = Request::forge('hello/world')->execute();
  282. *
  283. * @param array|null $method_params An array of parameters to pass to the method being executed
  284. * @return Request This request object
  285. */
  286. public function execute($method_params = null)
  287. {
  288. if (\Fuel::$profiling)
  289. {
  290. \Profiler::mark(__METHOD__.' Start');
  291. }
  292. logger(\Fuel::L_INFO, 'Called', __METHOD__);
  293. // Make the current request active
  294. static::$active = $this;
  295. // First request called is also the main request
  296. if ( ! static::$main)
  297. {
  298. logger(\Fuel::L_INFO, 'Setting main Request', __METHOD__);
  299. static::$main = $this;
  300. }
  301. if ( ! $this->route)
  302. {
  303. static::reset_request();
  304. throw new \HttpNotFoundException();
  305. }
  306. try
  307. {
  308. if ($this->route->callable !== null)
  309. {
  310. $response = call_user_func_array($this->route->callable, array($this));
  311. }
  312. else
  313. {
  314. $method_prefix = 'action_';
  315. $class = $this->controller;
  316. // Allow override of method params from execute
  317. if (is_array($method_params))
  318. {
  319. $this->method_params = array_merge($this->method_params, $method_params);
  320. }
  321. // If the class doesn't exist then 404
  322. if ( ! class_exists($class))
  323. {
  324. throw new \HttpNotFoundException();
  325. }
  326. // Load the controller using reflection
  327. $class = new \ReflectionClass($class);
  328. if ($class->isAbstract())
  329. {
  330. throw new \HttpNotFoundException();
  331. }
  332. // Create a new instance of the controller
  333. $this->controller_instance = $class->newInstance($this, new \Response);
  334. $this->action = $this->action ?: ($class->hasProperty('default_action') ? $class->getProperty('default_action')->getValue($this->controller_instance) : 'index');
  335. $method = $method_prefix.$this->action;
  336. // Allow to do in controller routing if method router(action, params) exists
  337. if ($class->hasMethod('router'))
  338. {
  339. $method = 'router';
  340. $this->method_params = array($this->action, $this->method_params);
  341. }
  342. if ($class->hasMethod($method))
  343. {
  344. $action = $class->getMethod($method);
  345. if ( ! $action->isPublic())
  346. {
  347. throw new \HttpNotFoundException();
  348. }
  349. $class->hasMethod('before') and $class->getMethod('before')->invoke($this->controller_instance);
  350. $response = $action->invokeArgs($this->controller_instance, $this->method_params);
  351. $class->hasMethod('after') and $response = $class->getMethod('after')->invoke($this->controller_instance, $response);
  352. }
  353. else
  354. {
  355. throw new \HttpNotFoundException();
  356. }
  357. }
  358. }
  359. catch (\Exception $e)
  360. {
  361. static::reset_request();
  362. throw $e;
  363. }
  364. // Get the controller's output
  365. if (is_null($response))
  366. {
  367. throw new \FuelException(get_class($this->controller_instance).'::'.$method.'() or the controller after() method must return a Response object.');
  368. }
  369. elseif ($response instanceof \Response)
  370. {
  371. $this->response = $response;
  372. }
  373. else
  374. {
  375. $this->response = \Response::forge($response, 200);
  376. }
  377. static::reset_request();
  378. if (\Fuel::$profiling)
  379. {
  380. \Profiler::mark(__METHOD__.' End');
  381. }
  382. return $this;
  383. }
  384. /**
  385. * Sets the request method.
  386. *
  387. * @param string $method request method
  388. * @return object current instance
  389. */
  390. public function set_method($method)
  391. {
  392. $this->method = strtoupper($method);
  393. return $this;
  394. }
  395. /**
  396. * Returns the request method. Defaults to \Input::method().
  397. *
  398. * @return string request method
  399. */
  400. public function get_method()
  401. {
  402. return $this->method ?: \Input::method();
  403. }
  404. /**
  405. * Gets this Request's Response object;
  406. *
  407. * Usage:
  408. *
  409. * $response = Request::forge('foo/bar')->execute()->response();
  410. *
  411. * @return Response This Request's Response object
  412. */
  413. public function response()
  414. {
  415. return $this->response;
  416. }
  417. /**
  418. * Returns the Request that created this one
  419. *
  420. * @return Request|null
  421. */
  422. public function parent()
  423. {
  424. return $this->parent;
  425. }
  426. /**
  427. * Returns an array of Requests created by this one
  428. *
  429. * @return array
  430. */
  431. public function children()
  432. {
  433. return $this->children;
  434. }
  435. /**
  436. * Add to paths which are used by Finder::search()
  437. *
  438. * @param string the new path
  439. * @param bool whether to add to the front or the back of the array
  440. * @return void
  441. */
  442. public function add_path($path, $prefix = false)
  443. {
  444. if ($prefix)
  445. {
  446. // prefix the path to the paths array
  447. array_unshift($this->paths, $path);
  448. }
  449. else
  450. {
  451. // add the new path
  452. $this->paths[] = $path;
  453. }
  454. }
  455. /**
  456. * Returns the array of currently loaded search paths.
  457. *
  458. * @return array the array of paths
  459. */
  460. public function get_paths()
  461. {
  462. return $this->paths;
  463. }
  464. /**
  465. * Gets a specific named parameter
  466. *
  467. * @param string $param Name of the parameter
  468. * @param mixed $default Default value
  469. * @return mixed
  470. */
  471. public function param($param, $default = null)
  472. {
  473. if ( ! isset($this->named_params[$param]))
  474. {
  475. return \Fuel::value($default);
  476. }
  477. return $this->named_params[$param];
  478. }
  479. /**
  480. * Gets all of the named parameters
  481. *
  482. * @return array
  483. */
  484. public function params()
  485. {
  486. return $this->named_params;
  487. }
  488. /**
  489. * PHP magic function returns the Output of the request.
  490. *
  491. * Usage:
  492. *
  493. * $request = Request::forge('hello/world')->execute();
  494. * echo $request;
  495. *
  496. * @return string the response
  497. */
  498. public function __toString()
  499. {
  500. return (string) $this->response;
  501. }
  502. }