/library/Zend/Mvc/Controller/ActionController.php

https://github.com/MontmereLimited/zf2 · PHP · 325 lines · 174 code · 31 blank · 120 comment · 13 complexity · 9c318861a9f99ab59cf4d577f657ab3a MD5 · raw file

  1. <?php
  2. namespace Zend\Mvc\Controller;
  3. use Zend\Di\Locator,
  4. Zend\EventManager\EventCollection,
  5. Zend\EventManager\EventDescription as Event,
  6. Zend\EventManager\EventManager,
  7. Zend\Http\PhpEnvironment\Response as HttpResponse,
  8. Zend\Loader\Broker,
  9. Zend\Loader\Pluggable,
  10. Zend\Mvc\Exception,
  11. Zend\Mvc\InjectApplicationEvent,
  12. Zend\Mvc\LocatorAware,
  13. Zend\Mvc\MvcEvent,
  14. Zend\Stdlib\Dispatchable,
  15. Zend\Stdlib\RequestDescription as Request,
  16. Zend\Stdlib\ResponseDescription as Response,
  17. Zend\View\Model\ViewModel;
  18. /**
  19. * Basic action controller
  20. */
  21. abstract class ActionController implements Dispatchable, InjectApplicationEvent, LocatorAware, Pluggable
  22. {
  23. //use \Zend\EventManager\ProvidesEvents;
  24. protected $broker;
  25. protected $event;
  26. protected $events;
  27. protected $locator;
  28. protected $request;
  29. protected $response;
  30. /**
  31. * Default action if none provided
  32. *
  33. * @return array
  34. */
  35. public function indexAction()
  36. {
  37. return new ViewModel(array(
  38. 'content' => 'Placeholder page'
  39. ));
  40. }
  41. /**
  42. * Action called if matched action does not exist
  43. *
  44. * @return array
  45. */
  46. public function notFoundAction()
  47. {
  48. $response = $this->response;
  49. $event = $this->getEvent();
  50. $routeMatch = $event->getRouteMatch();
  51. $response->setStatusCode(404);
  52. $routeMatch->setParam('action', 'not-found');
  53. return new ViewModel(array(
  54. 'content' => 'Page not found'
  55. ));
  56. }
  57. /**
  58. * Dispatch a request
  59. *
  60. * @events dispatch.pre, dispatch.post
  61. * @param Request $request
  62. * @param null|Response $response
  63. * @return Response|mixed
  64. */
  65. public function dispatch(Request $request, Response $response = null)
  66. {
  67. $this->request = $request;
  68. if (!$response) {
  69. $response = new HttpResponse();
  70. }
  71. $this->response = $response;
  72. $e = $this->getEvent();
  73. $e->setRequest($request)
  74. ->setResponse($response)
  75. ->setTarget($this);
  76. $result = $this->events()->trigger('dispatch', $e, function($test) {
  77. return ($test instanceof Response);
  78. });
  79. if ($result->stopped()) {
  80. return $result->last();
  81. }
  82. return $e->getResult();
  83. }
  84. /**
  85. * Execute the request
  86. *
  87. * @param MvcEvent $e
  88. * @return mixed
  89. */
  90. public function execute(MvcEvent $e)
  91. {
  92. $routeMatch = $e->getRouteMatch();
  93. if (!$routeMatch) {
  94. /**
  95. * @todo Determine requirements for when route match is missing.
  96. * Potentially allow pulling directly from request metadata?
  97. */
  98. throw new \DomainException('Missing route matches; unsure how to retrieve action');
  99. }
  100. $action = $routeMatch->getParam('action', 'not-found');
  101. $method = static::getMethodFromAction($action);
  102. if (!method_exists($this, $method)) {
  103. $method = 'notFoundAction';
  104. }
  105. $actionResponse = $this->$method();
  106. $e->setResult($actionResponse);
  107. return $actionResponse;
  108. }
  109. /**
  110. * Get the request object
  111. *
  112. * @return Request
  113. */
  114. public function getRequest()
  115. {
  116. return $this->request;
  117. }
  118. /**
  119. * Get the response object
  120. *
  121. * @return Response
  122. */
  123. public function getResponse()
  124. {
  125. if (null === $this->response) {
  126. $this->response = new HttpResponse();
  127. }
  128. return $this->response;
  129. }
  130. /**
  131. * Set the event manager instance used by this context
  132. *
  133. * @param EventCollection $events
  134. * @return AppContext
  135. */
  136. public function setEventManager(EventCollection $events)
  137. {
  138. $this->events = $events;
  139. return $this;
  140. }
  141. /**
  142. * Retrieve the event manager
  143. *
  144. * Lazy-loads an EventManager instance if none registered.
  145. *
  146. * @return EventCollection
  147. */
  148. public function events()
  149. {
  150. if (!$this->events instanceof EventCollection) {
  151. $this->setEventManager(new EventManager(array(
  152. 'Zend\Stdlib\Dispatchable',
  153. __CLASS__,
  154. get_called_class()
  155. )));
  156. $this->attachDefaultListeners();
  157. }
  158. return $this->events;
  159. }
  160. /**
  161. * Set an event to use during dispatch
  162. *
  163. * By default, will re-cast to MvcEvent if another event type is provided.
  164. *
  165. * @param Event $e
  166. * @return void
  167. */
  168. public function setEvent(Event $e)
  169. {
  170. if ($e instanceof Event && !$e instanceof MvcEvent) {
  171. $eventParams = $e->getParams();
  172. $e = new MvcEvent();
  173. $e->setParams($eventParams);
  174. unset($eventParams);
  175. }
  176. $this->event = $e;
  177. }
  178. /**
  179. * Get the attached event
  180. *
  181. * Will create a new MvcEvent if none provided.
  182. *
  183. * @return Event
  184. */
  185. public function getEvent()
  186. {
  187. if (!$this->event) {
  188. $this->setEvent(new MvcEvent());
  189. }
  190. return $this->event;
  191. }
  192. /**
  193. * Set locator instance
  194. *
  195. * @param Locator $locator
  196. * @return void
  197. */
  198. public function setLocator(Locator $locator)
  199. {
  200. $this->locator = $locator;
  201. }
  202. /**
  203. * Retrieve locator instance
  204. *
  205. * @return Locator
  206. */
  207. public function getLocator()
  208. {
  209. return $this->locator;
  210. }
  211. /**
  212. * Get plugin broker instance
  213. *
  214. * @return Zend\Loader\Broker
  215. */
  216. public function getBroker()
  217. {
  218. if (!$this->broker) {
  219. $this->setBroker(new PluginBroker());
  220. }
  221. return $this->broker;
  222. }
  223. /**
  224. * Set plugin broker instance
  225. *
  226. * @param string|Broker $broker Plugin broker to load plugins
  227. * @return Zend\Loader\Pluggable
  228. */
  229. public function setBroker($broker)
  230. {
  231. if (!$broker instanceof Broker) {
  232. throw new Exception\InvalidArgumentException('Broker must implement Zend\Loader\Broker');
  233. }
  234. $this->broker = $broker;
  235. if (method_exists($broker, 'setController')) {
  236. $this->broker->setController($this);
  237. }
  238. return $this;
  239. }
  240. /**
  241. * Get plugin instance
  242. *
  243. * @param string $plugin Name of plugin to return
  244. * @param null|array $options Options to pass to plugin constructor (if not already instantiated)
  245. * @return mixed
  246. */
  247. public function plugin($name, array $options = null)
  248. {
  249. return $this->getBroker()->load($name, $options);
  250. }
  251. /**
  252. * Method overloading: return/call plugins
  253. *
  254. * If the plugin is a functor, call it, passing the parameters provided.
  255. * Otherwise, return the plugin instance.
  256. *
  257. * @param string $method
  258. * @param array $params
  259. * @return mixed
  260. */
  261. public function __call($method, array $params)
  262. {
  263. $plugin = $this->plugin($method);
  264. if (is_callable($plugin)) {
  265. return call_user_func_array($plugin, $params);
  266. }
  267. return $plugin;
  268. }
  269. /**
  270. * Register the default events for this controller
  271. *
  272. * @return void
  273. */
  274. protected function attachDefaultListeners()
  275. {
  276. $events = $this->events();
  277. $events->attach('dispatch', array($this, 'execute'));
  278. }
  279. /**
  280. * Transform an action name into a method name
  281. *
  282. * @param string $action
  283. * @return string
  284. */
  285. public static function getMethodFromAction($action)
  286. {
  287. $method = str_replace(array('.', '-', '_'), ' ', $action);
  288. $method = ucwords($method);
  289. $method = str_replace(' ', '', $method);
  290. $method = lcfirst($method);
  291. $method .= 'Action';
  292. return $method;
  293. }
  294. }