PageRenderTime 42ms CodeModel.GetById 13ms RepoModel.GetById 0ms app.codeStats 0ms

/lib/Cake/Routing/Dispatcher.php

https://gitlab.com/fouzia23chowdhury/cakephpCRUD
PHP | 273 lines | 145 code | 23 blank | 105 comment | 27 complexity | b19f5524df0cf159c6b655f5c8a3d31a MD5 | raw file
  1. <?php
  2. /**
  3. * Dispatcher takes the URL information, parses it for parameters and
  4. * tells the involved controllers what to do.
  5. *
  6. * This is the heart of CakePHP's operation.
  7. *
  8. * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
  9. * Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
  10. *
  11. * Licensed under The MIT License
  12. * For full copyright and license information, please see the LICENSE.txt
  13. * Redistributions of files must retain the above copyright notice.
  14. *
  15. * @copyright Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
  16. * @link http://cakephp.org CakePHP(tm) Project
  17. * @package Cake.Routing
  18. * @since CakePHP(tm) v 0.2.9
  19. * @license http://www.opensource.org/licenses/mit-license.php MIT License
  20. */
  21. App::uses('Router', 'Routing');
  22. App::uses('CakeRequest', 'Network');
  23. App::uses('CakeResponse', 'Network');
  24. App::uses('Controller', 'Controller');
  25. App::uses('Scaffold', 'Controller');
  26. App::uses('View', 'View');
  27. App::uses('Debugger', 'Utility');
  28. App::uses('CakeEvent', 'Event');
  29. App::uses('CakeEventManager', 'Event');
  30. App::uses('CakeEventListener', 'Event');
  31. /**
  32. * Dispatcher converts Requests into controller actions. It uses the dispatched Request
  33. * to locate and load the correct controller. If found, the requested action is called on
  34. * the controller.
  35. *
  36. * @package Cake.Routing
  37. */
  38. class Dispatcher implements CakeEventListener {
  39. /**
  40. * Event manager, used to handle dispatcher filters
  41. *
  42. * @var CakeEventManager
  43. */
  44. protected $_eventManager;
  45. /**
  46. * Constructor.
  47. *
  48. * @param string $base The base directory for the application. Writes `App.base` to Configure.
  49. */
  50. public function __construct($base = false) {
  51. if ($base !== false) {
  52. Configure::write('App.base', $base);
  53. }
  54. }
  55. /**
  56. * Returns the CakeEventManager instance or creates one if none was
  57. * created. Attaches the default listeners and filters
  58. *
  59. * @return CakeEventManager
  60. */
  61. public function getEventManager() {
  62. if (!$this->_eventManager) {
  63. $this->_eventManager = new CakeEventManager();
  64. $this->_eventManager->attach($this);
  65. $this->_attachFilters($this->_eventManager);
  66. }
  67. return $this->_eventManager;
  68. }
  69. /**
  70. * Returns the list of events this object listens to.
  71. *
  72. * @return array
  73. */
  74. public function implementedEvents() {
  75. return array('Dispatcher.beforeDispatch' => 'parseParams');
  76. }
  77. /**
  78. * Attaches all event listeners for this dispatcher instance. Loads the
  79. * dispatcher filters from the configured locations.
  80. *
  81. * @param CakeEventManager $manager Event manager instance.
  82. * @return void
  83. * @throws MissingDispatcherFilterException
  84. */
  85. protected function _attachFilters($manager) {
  86. $filters = Configure::read('Dispatcher.filters');
  87. if (empty($filters)) {
  88. return;
  89. }
  90. foreach ($filters as $index => $filter) {
  91. $settings = array();
  92. if (is_array($filter) && !is_int($index) && class_exists($index)) {
  93. $settings = $filter;
  94. $filter = $index;
  95. }
  96. if (is_string($filter)) {
  97. $filter = array('callable' => $filter);
  98. }
  99. if (is_string($filter['callable'])) {
  100. list($plugin, $callable) = pluginSplit($filter['callable'], true);
  101. App::uses($callable, $plugin . 'Routing/Filter');
  102. if (!class_exists($callable)) {
  103. throw new MissingDispatcherFilterException($callable);
  104. }
  105. $manager->attach(new $callable($settings));
  106. } else {
  107. $on = strtolower($filter['on']);
  108. $options = array();
  109. if (isset($filter['priority'])) {
  110. $options = array('priority' => $filter['priority']);
  111. }
  112. $manager->attach($filter['callable'], 'Dispatcher.' . $on . 'Dispatch', $options);
  113. }
  114. }
  115. }
  116. /**
  117. * Dispatches and invokes given Request, handing over control to the involved controller. If the controller is set
  118. * to autoRender, via Controller::$autoRender, then Dispatcher will render the view.
  119. *
  120. * Actions in CakePHP can be any public method on a controller, that is not declared in Controller. If you
  121. * want controller methods to be public and in-accessible by URL, then prefix them with a `_`.
  122. * For example `public function _loadPosts() { }` would not be accessible via URL. Private and protected methods
  123. * are also not accessible via URL.
  124. *
  125. * If no controller of given name can be found, invoke() will throw an exception.
  126. * If the controller is found, and the action is not found an exception will be thrown.
  127. *
  128. * @param CakeRequest $request Request object to dispatch.
  129. * @param CakeResponse $response Response object to put the results of the dispatch into.
  130. * @param array $additionalParams Settings array ("bare", "return") which is melded with the GET and POST params
  131. * @return string|void if `$request['return']` is set then it returns response body, null otherwise
  132. * @triggers Dispatcher.beforeDispatch $this, compact('request', 'response', 'additionalParams')
  133. * @triggers Dispatcher.afterDispatch $this, compact('request', 'response')
  134. * @throws MissingControllerException When the controller is missing.
  135. */
  136. public function dispatch(CakeRequest $request, CakeResponse $response, $additionalParams = array()) {
  137. $beforeEvent = new CakeEvent('Dispatcher.beforeDispatch', $this, compact('request', 'response', 'additionalParams'));
  138. $this->getEventManager()->dispatch($beforeEvent);
  139. $request = $beforeEvent->data['request'];
  140. if ($beforeEvent->result instanceof CakeResponse) {
  141. if (isset($request->params['return'])) {
  142. return $beforeEvent->result->body();
  143. }
  144. $beforeEvent->result->send();
  145. return;
  146. }
  147. $controller = $this->_getController($request, $response);
  148. if (!($controller instanceof Controller)) {
  149. throw new MissingControllerException(array(
  150. 'class' => Inflector::camelize($request->params['controller']) . 'Controller',
  151. 'plugin' => empty($request->params['plugin']) ? null : Inflector::camelize($request->params['plugin'])
  152. ));
  153. }
  154. $response = $this->_invoke($controller, $request);
  155. if (isset($request->params['return'])) {
  156. return $response->body();
  157. }
  158. $afterEvent = new CakeEvent('Dispatcher.afterDispatch', $this, compact('request', 'response'));
  159. $this->getEventManager()->dispatch($afterEvent);
  160. $afterEvent->data['response']->send();
  161. }
  162. /**
  163. * Initializes the components and models a controller will be using.
  164. * Triggers the controller action, and invokes the rendering if Controller::$autoRender
  165. * is true and echo's the output. Otherwise the return value of the controller
  166. * action are returned.
  167. *
  168. * @param Controller $controller Controller to invoke
  169. * @param CakeRequest $request The request object to invoke the controller for.
  170. * @return CakeResponse the resulting response object
  171. */
  172. protected function _invoke(Controller $controller, CakeRequest $request) {
  173. $controller->constructClasses();
  174. $controller->startupProcess();
  175. $response = $controller->response;
  176. $render = true;
  177. $result = $controller->invokeAction($request);
  178. if ($result instanceof CakeResponse) {
  179. $render = false;
  180. $response = $result;
  181. }
  182. if ($render && $controller->autoRender) {
  183. $response = $controller->render();
  184. } elseif (!($result instanceof CakeResponse) && $response->body() === null) {
  185. $response->body($result);
  186. }
  187. $controller->shutdownProcess();
  188. return $response;
  189. }
  190. /**
  191. * Applies Routing and additionalParameters to the request to be dispatched.
  192. * If Routes have not been loaded they will be loaded, and app/Config/routes.php will be run.
  193. *
  194. * @param CakeEvent $event containing the request, response and additional params
  195. * @return void
  196. */
  197. public function parseParams($event) {
  198. $request = $event->data['request'];
  199. Router::setRequestInfo($request);
  200. $params = Router::parse($request->url);
  201. $request->addParams($params);
  202. if (!empty($event->data['additionalParams'])) {
  203. $request->addParams($event->data['additionalParams']);
  204. }
  205. }
  206. /**
  207. * Get controller to use, either plugin controller or application controller
  208. *
  209. * @param CakeRequest $request Request object
  210. * @param CakeResponse $response Response for the controller.
  211. * @return mixed name of controller if not loaded, or object if loaded
  212. */
  213. protected function _getController($request, $response) {
  214. $ctrlClass = $this->_loadController($request);
  215. if (!$ctrlClass) {
  216. return false;
  217. }
  218. $reflection = new ReflectionClass($ctrlClass);
  219. if ($reflection->isAbstract() || $reflection->isInterface()) {
  220. return false;
  221. }
  222. return $reflection->newInstance($request, $response);
  223. }
  224. /**
  225. * Load controller and return controller class name
  226. *
  227. * @param CakeRequest $request Request instance.
  228. * @return string|bool Name of controller class name
  229. */
  230. protected function _loadController($request) {
  231. $pluginName = $pluginPath = $controller = null;
  232. if (!empty($request->params['plugin'])) {
  233. $pluginName = $controller = Inflector::camelize($request->params['plugin']);
  234. $pluginPath = $pluginName . '.';
  235. }
  236. if (!empty($request->params['controller'])) {
  237. $controller = Inflector::camelize($request->params['controller']);
  238. }
  239. if ($pluginPath . $controller) {
  240. $class = $controller . 'Controller';
  241. App::uses('AppController', 'Controller');
  242. App::uses($pluginName . 'AppController', $pluginPath . 'Controller');
  243. App::uses($class, $pluginPath . 'Controller');
  244. if (class_exists($class)) {
  245. return $class;
  246. }
  247. }
  248. return false;
  249. }
  250. }