Dispatcher.php 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189
  1. <?php
  2. /**
  3. *
  4. * Cube Framework $Id$ zznEwS8sxzhx2PxPdsSqmI4X5Xjp/A8j9rC4HaQ8ZeU=
  5. *
  6. * @link http://codecu.be/framework
  7. * @copyright Copyright (c) 2015 CodeCube SRL
  8. * @license http://codecu.be/framework/license Commercial License
  9. *
  10. * @version 1.4
  11. */
  12. /**
  13. * dispatcher class
  14. */
  15. namespace Cube\Controller;
  16. use Cube\Controller\Request\AbstractRequest,
  17. Cube\Controller\Response\ResponseInterface,
  18. Cube\Exception\Dispatcher as DispatcherException,
  19. Cube\View;
  20. class Dispatcher implements Dispatcher\DispatcherInterface
  21. {
  22. const DIR_SEPARATOR = '/';
  23. const DIR_CONTROLLERS = 'Controller';
  24. /**
  25. * extended suffix
  26. */
  27. const EXTENDED_SUFFIX = 'Extended';
  28. /**
  29. *
  30. * response object
  31. *
  32. * @var \Cube\Controller\Response\ResponseInterface
  33. */
  34. protected $_response;
  35. /**
  36. *
  37. * view object
  38. *
  39. * @var \Cube\View
  40. */
  41. protected $_view;
  42. /**
  43. *
  44. * get the view object
  45. *
  46. * @return \Cube\View
  47. */
  48. public function getView()
  49. {
  50. if ($this->_view === null) {
  51. $this->setView();
  52. }
  53. return $this->_view;
  54. }
  55. /**
  56. * set the view object
  57. *
  58. * @param \Cube\View $view
  59. *
  60. * @return \Cube\Controller\Dispatcher
  61. */
  62. public function setView(View $view = null)
  63. {
  64. if (!$view instanceof View) {
  65. $bootstrap = Front::getInstance()->getBootstrap();
  66. if ($bootstrap->hasResource('view')) {
  67. $view = $bootstrap->getResource('view');
  68. }
  69. else {
  70. $view = new View();
  71. }
  72. }
  73. $this->_view = $view;
  74. return $this;
  75. }
  76. /**
  77. *
  78. * dispatch method
  79. *
  80. * the method will try to run the action method called from the request, and based on the data returned, output the necessary data
  81. * - if the output is an instance of the View class, then the view application resource is ignored even if instantiated
  82. * - if the output is an array, we will inject the array in the view resource if it was created or we create a new view object and inject the data
  83. *
  84. * @param \Cube\Controller\Request\AbstractRequest $request
  85. * @param \Cube\Controller\Response\ResponseInterface $response
  86. * @param bool $partial set to true if a we have an action helper.
  87. *
  88. * @throws \Cube\Exception\Dispatcher
  89. * @return \Cube\Controller\Response\ResponseInterface $response
  90. */
  91. public function dispatch(AbstractRequest $request, ResponseInterface $response, $partial = false)
  92. {
  93. $output = null;
  94. $moduleName = $request->getModule();
  95. $controllerName = $request->getController();
  96. $actionName = $request->getAction();
  97. $className = $moduleName . '\\' . self::DIR_CONTROLLERS . '\\' . $controllerName;
  98. // try loading an extended controller first
  99. if (class_exists($className . self::EXTENDED_SUFFIX)) {
  100. $className .= self::EXTENDED_SUFFIX;
  101. }
  102. if (class_exists($className)) {
  103. $controller = new $className($request, $response);
  104. if (method_exists($controller, $actionName)) {
  105. // we catch any output given directly from the action method
  106. // and display it after outputting the view file
  107. ob_start();
  108. $result = $controller->$actionName();
  109. $actionOutput = ob_get_clean();
  110. if ($result instanceof View) {
  111. $output = $result->render();
  112. }
  113. else if (is_array($result)) {
  114. $view = $this->getView();
  115. if ($view instanceof View) {
  116. // for the action view helper, this will overwrite any action variables with the newer ones
  117. $view->setVariables($result);
  118. }
  119. $viewFileName = $view->getViewFileName();
  120. $viewPath = self::DIR_SEPARATOR
  121. . $request->normalize($moduleName, true) . self::DIR_SEPARATOR
  122. . $request->normalize($controllerName, true) . self::DIR_SEPARATOR
  123. . ((!empty($viewFileName)) ?
  124. $viewFileName : $request->normalize($actionName, true) . View::FILES_EXTENSION);
  125. $view->setViewFileName(null);
  126. if ($partial === true) {
  127. $output = $view->process($viewPath, true);
  128. }
  129. else {
  130. $view->process($viewPath);
  131. $view->setContent($actionOutput);
  132. $output = $view->render();
  133. }
  134. }
  135. $response->appendBody($output);
  136. }
  137. else {
  138. $response->setHeader(' ')
  139. ->setResponseCode(404);
  140. throw new DispatcherException(sprintf("Module: '%s' - action '%s' for the '%s' controller does not exist",
  141. $moduleName, $actionName, $className));
  142. }
  143. }
  144. else {
  145. $response->setHeader(' ')
  146. ->setResponseCode(404);
  147. throw new DispatcherException(sprintf("Module: '%s' - controller '%s' does not exist.", $moduleName,
  148. $className));
  149. }
  150. $this->_response = $response;
  151. return $response;
  152. }
  153. }