PageRenderTime 36ms CodeModel.GetById 11ms RepoModel.GetById 0ms app.codeStats 0ms

/panada/Gear.php

http://github.com/panada/Panada
PHP | 288 lines | 225 code | 26 blank | 37 comment | 8 complexity | 780c240d27009e347c17982f7f39894f MD5 | raw file
Possible License(s): BSD-3-Clause
  1. <?php
  2. /**
  3. * This is the heart of the whole Panada system.
  4. *
  5. * @author Iskandar Soesman <k4ndar@yahoo.com>
  6. *
  7. * @link http://panadaframework.com/
  8. *
  9. * @license http://www.opensource.org/licenses/bsd-license.php
  10. *
  11. * @since version 1.0.0
  12. */
  13. final class Gear
  14. {
  15. private $uriObj;
  16. private $config;
  17. private $firstUriPath;
  18. public static $uri;
  19. /**
  20. * Preparation step before anything else.
  21. */
  22. public function __construct($errorReporting)
  23. {
  24. error_reporting($errorReporting);
  25. spl_autoload_register([$this, 'loader']);
  26. set_exception_handler('Resources\RunException::main');
  27. set_error_handler('Resources\RunException::errorHandlerCallback', error_reporting());
  28. $this->config['main'] = Resources\Config::main();
  29. $this->uriObj = new Resources\Uri();
  30. $this->uriObj->setDefaultController($this->config['main']['defaultController']);
  31. self::$uri = $this->uriObj;
  32. $this->firstUriPath = ucwords($this->uriObj->getClass());
  33. $this->controllerHandler();
  34. }
  35. /**
  36. * Magic loader to load instantiated class.
  37. *
  38. * @param string $file Class namespace.
  39. */
  40. private function loader($file)
  41. {
  42. $prefix = explode('\\', $file);
  43. switch ($prefix[0]) {
  44. case 'Models':
  45. $folder = APP;
  46. break;
  47. case 'Libraries':
  48. $folder = APP;
  49. break;
  50. case 'Controllers':
  51. $folder = APP;
  52. break;
  53. case 'Resources':
  54. $folder = GEAR;
  55. break;
  56. case 'Drivers':
  57. $folder = GEAR;
  58. break;
  59. case 'Modules':
  60. $folder = $this->config['main']['module']['path'];
  61. break;
  62. default:
  63. if (!isset($this->config['main']['namespace'])) {
  64. throw new Resources\RunException('Resource '.$file.' not available!');
  65. }
  66. if (!isset($this->config['main']['namespace'][$prefix[0]])) {
  67. throw new Resources\RunException('Resource '.$file.' not available!');
  68. }
  69. $folder = $this->config['main']['namespace'][$prefix[0]];
  70. break;
  71. }
  72. if (!file_exists($file = $folder.str_ireplace('\\', '/', $file).'.php')) {
  73. throw new Resources\RunException('Resource '.$file.' not available!');
  74. }
  75. include $file;
  76. }
  77. /**
  78. * Hendle the controller calling process.
  79. *
  80. * The steps is:
  81. * - Does alias controller are defined in main config?
  82. * - If not, is sub-controller exists?
  83. * - If not, module with this name exists?
  84. * - If all fault, then throw 404.
  85. */
  86. private function controllerHandler()
  87. {
  88. $controllerNamespace = 'Controllers\\'.$this->firstUriPath;
  89. if (!file_exists($classFile = APP.'Controllers/'.$this->firstUriPath.'.php')) {
  90. $this->subControllerHandler();
  91. return;
  92. }
  93. $method = $this->uriObj->getMethod();
  94. if (!$request = $this->uriObj->getRequests()) {
  95. $request = array();
  96. }
  97. if (!class_exists($controllerNamespace)) {
  98. throw new Resources\RunException('Class '.$controllerNamespace.' not found in '.$classFile);
  99. }
  100. $instance = new $controllerNamespace();
  101. if (!method_exists($instance, $method)) {
  102. $request = array_slice($this->uriObj->path(), 1);
  103. $method = $this->config['main']['alias']['method'];
  104. if (!method_exists($instance, $method)) {
  105. throw new Resources\HttpException('Method '.$this->uriObj->getMethod().' does not exists in controller '.$this->firstUriPath);
  106. }
  107. }
  108. $this->run($instance, $method, $request);
  109. }
  110. /**
  111. * Hendle the sub-controller calling process.
  112. */
  113. private function subControllerHandler()
  114. {
  115. if (!is_dir($subControllerFolder = APP.'Controllers/'.$this->firstUriPath.'/')) {
  116. $this->moduleHandler();
  117. return;
  118. }
  119. $controllerClass = $this->uriObj->getMethod(null);
  120. // No argument? set to default controller.
  121. if (is_null($controllerClass)) {
  122. $controllerClass = $this->config['main']['defaultController'];
  123. }
  124. $controllerClass = ucwords($controllerClass);
  125. if (!file_exists($classFile = $subControllerFolder.$controllerClass.'.php')) {
  126. throw new Resources\HttpException('Controller '.$controllerClass.' does not exists in sub-controller '.$this->firstUriPath.'.');
  127. }
  128. $controllerNamespace = 'Controllers\\'.$this->firstUriPath.'\\'.$controllerClass;
  129. if (!class_exists($controllerNamespace)) {
  130. throw new Resources\RunException('Class '.$controllerNamespace.' not found in '.$classFile);
  131. }
  132. $instance = new $controllerNamespace();
  133. $request = array_slice($this->uriObj->path(), 3);
  134. if (!$method = $this->uriObj->path(2)) {
  135. $method = 'index';
  136. }
  137. if (!method_exists($instance, $method)) {
  138. $request = array_slice($this->uriObj->path(), 2);
  139. $method = $this->config['main']['alias']['method'];
  140. if (!method_exists($instance, $method)) {
  141. throw new Resources\HttpException('Method '.$this->uriObj->path(2).' does not exists in controller /'.$this->firstUriPath.'/'.$controllerClass.'.');
  142. }
  143. }
  144. $this->run($instance, $method, $request);
  145. }
  146. /**
  147. * Hendle the module calling process.
  148. */
  149. private function moduleHandler()
  150. {
  151. if (!is_dir($moduleFolder = $this->config['main']['module']['path'].'Modules/'.$this->firstUriPath.'/')) {
  152. if (isset($this->config['main']['alias']['controller']['class'])) {
  153. $controllerClass = $this->config['main']['alias']['controller']['class'];
  154. if (!file_exists(APP.'Controllers/'.$controllerClass.'.php')) {
  155. throw new Resources\HttpException('Controller, sub-controller or module '.$this->firstUriPath.' does not exists');
  156. }
  157. $controllerNamespace = 'Controllers\\'.$controllerClass;
  158. $method = $this->config['main']['alias']['controller']['method'];
  159. $instance = new $controllerNamespace();
  160. $request = $this->uriObj->path();
  161. $this->run($instance, $method, $request);
  162. return;
  163. }
  164. }
  165. if (!$controllerClass = $this->uriObj->path(1)) {
  166. $controllerClass = $this->config['main']['defaultController'];
  167. }
  168. $controllerClass = ucwords($controllerClass);
  169. // Does this class's file exists?
  170. if (!file_exists($classFile = $moduleFolder.'Controllers/'.$controllerClass.'.php')) {
  171. if (!isset($this->config['main']['alias']['controller']['class'])) {
  172. throw new Resources\HttpException('Controller '.$controllerClass.' does not exists in module '.$this->firstUriPath);
  173. }
  174. $controllerClass = $this->config['main']['alias']['controller']['class'];
  175. $method = $this->config['main']['alias']['controller']['method'];
  176. $request = array_slice($this->uriObj->path(), 1);
  177. // Does class for alias file exists?
  178. if (!file_exists($classFile = $moduleFolder.'Controllers/'.$controllerClass.'.php')) {
  179. throw new Resources\HttpException('Controller '.$controllerClass.' does not exists in module '.$this->firstUriPath);
  180. }
  181. goto createNamespace;
  182. }
  183. $request = array_slice($this->uriObj->path(), 3);
  184. if (!$method = $this->uriObj->path(2)) {
  185. $method = 'index';
  186. }
  187. createNamespace:
  188. $controllerNamespace = 'Modules\\'.$this->firstUriPath.'\Controllers\\'.$controllerClass;
  189. if (!class_exists($controllerNamespace)) {
  190. throw new Resources\RunException('Class '.$controllerNamespace.' not found in '.$classFile);
  191. }
  192. $instance = new $controllerNamespace();
  193. if (!method_exists($instance, $method)) {
  194. $request = array_slice($this->uriObj->path(), 2);
  195. $method = $this->config['main']['alias']['method'];
  196. if (!method_exists($instance, $method)) {
  197. throw new Resources\HttpException('Method '.$method.' does not exists in controller '.$moduleFolder.$controllerClass);
  198. }
  199. }
  200. $this->run($instance, $method, $request);
  201. }
  202. public function __toString()
  203. {
  204. return (new Resources\Response)->send();
  205. }
  206. /**
  207. * Call the controller's method.
  208. *
  209. * @param object $instance
  210. * @param string $method
  211. * @param array $request
  212. */
  213. private function run($instance, $method, $request)
  214. {
  215. Resources\Response::$body = call_user_func_array([$instance, $method], $request);
  216. }
  217. public static function send($errorReporting = E_ALL)
  218. {
  219. try{
  220. echo new self($errorReporting);
  221. }
  222. catch(Resources\HttpException $e){
  223. echo Resources\HttpException::outputError($e)->send();
  224. }
  225. catch(Resources\RunException $e){
  226. echo Resources\RunException::main($e)->send();
  227. }
  228. catch(Exception $e){
  229. echo Resources\RunException::main($e)->send();
  230. }
  231. }
  232. }