PageRenderTime 57ms CodeModel.GetById 30ms RepoModel.GetById 0ms app.codeStats 0ms

/Engine.php

https://github.com/poitch/dokin
PHP | 249 lines | 145 code | 37 blank | 67 comment | 25 complexity | c1357eead257fffe0ec7733864288a6a MD5 | raw file
  1. <?php
  2. /**
  3. *****************************************************************************
  4. ** Copyright (c) 2007-2010 Jerome Poichet <jerome@frencaze.com>
  5. **
  6. ** This software is supplied to you by Jerome Poichet in consideration of
  7. ** your agreement to the following terms, and your use, installation,
  8. ** modification or redistribution of this software constitutes acceptance of
  9. ** these terms. If you do not agree with these terms, please do not use,
  10. ** install, modify or redistribute this software.
  11. **
  12. ** In consideration of your agreement to abide by the following terms, and
  13. ** subject to these terms, Jerome Poichet grants you a personal, non-exclusive
  14. ** license, to use, reproduce, modify and redistribute the software, with or
  15. ** without modifications, in source and/or binary forms; provided that if you
  16. ** redistribute the software in its entirety and without modifications, you
  17. ** must retain this notice and the following text and disclaimers in all such
  18. ** redistributions of the software, and that in all cases attribution of
  19. ** Jerome Poichet as the original author of the source code shall be included
  20. ** in all such resulting software products or distributions.
  21. **
  22. ** Neither the name, trademarks, service marks or logos of Jerome Poichet may
  23. ** be used to endorse or promote products derived from the software without
  24. ** specific prior written permission from Jerome Poichet. Except as expressly
  25. ** stated in this notice, no other rights or licenses, express or implied, are
  26. ** granted by Jerome Poichet herein, including but not limited to any patent
  27. ** rights that may be infringed by your derivative works or by other works in
  28. ** which the software may be incorporated.
  29. **
  30. ** The software is provided by Jerome Poichet on an "AS IS" basis.
  31. ** JEROME POICHET MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT
  32. ** LIMITATION THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND
  33. ** FITNESS FOR A PARTICULAR PURPOSE, REGARDING THE SOFTWARE OR ITS USE AND
  34. ** OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS.
  35. **
  36. ** IN NO EVENT SHALL JEROME POICHET BE LIABLE FOR ANY SPECIAL, INDIRECT,
  37. ** INCIDENTAL OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
  38. ** PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
  39. ** OR BUSINESS INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION,
  40. ** MODIFICATION AND/OR DISTRIBUTION OF THE SOFTWARE, HOWEVER CAUSED AND
  41. ** WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), STRICT
  42. ** LIABILITY OR OTHERWISE, EVEN IF JEROME POICHET HAS BEEN ADVISED OF THE
  43. ** POSSIBILITY OF SUCH DAMAGE.
  44. *****************************************************************************
  45. **/
  46. require_once DOKIN_DIR.'Log.php';
  47. class Engine
  48. {
  49. public static $aWatches = array();
  50. static private $instance = null;
  51. private function __construct()
  52. {
  53. }
  54. public static function get_instance()
  55. {
  56. if (!self::$instance) {
  57. self::$instance = new Engine();
  58. }
  59. return self::$instance;
  60. }
  61. public function run()
  62. {
  63. global $aAppConfig;
  64. $iStartTime = microtime(true);
  65. if (file_exists('app/lib/Helpers.php')) {
  66. include_once('app/lib/Helpers.php');
  67. }
  68. // Retrieve the URL, remove the leading /
  69. if (isset($_SERVER['GATEWAY_INTERFACE']) && isset($_GET['path'])) {
  70. // FCGI MODE
  71. $sURL = isset($_GET['path']) ? $_GET['path'] : '/';
  72. $sURL = $sURL[0] == '/' ? substr($sURL, 1) : $sURL;
  73. } else {
  74. // MOD_PHP MODE
  75. $sURL = $_SERVER['REDIRECT_URL'];
  76. $sURL = substr($sURL, 1);
  77. if ($sURL == 'dispatch.php') {
  78. $sURL = $_SERVER['REQUEST_URI'];
  79. $sURL = substr($sURL, 1);
  80. // Remove query string
  81. if (strstr($sURL,'?')) {
  82. $sURL = substr($sURL, 0, strpos($sURL, '?'));
  83. }
  84. if (strstr($sURL, '&')) {
  85. $sURL = substr($sURL, 0, strpos($sURL, '&'));
  86. }
  87. }
  88. }
  89. // Clean up the URL from the path where the application actually is
  90. $sRoot = $_SERVER['DOCUMENT_ROOT'];
  91. $sScript = $_SERVER['SCRIPT_FILENAME'];
  92. $sIgnore = substr(str_replace($sRoot, '', $sScript), 1);
  93. $sIgnore = dirname($sIgnore).'/';
  94. $sURL = str_replace($sIgnore, '', $sURL);
  95. // Ignore the extension
  96. if (strpos($sURL,'.')) {
  97. $sExt = substr($sURL, strrpos($sURL, '.') + 1);
  98. $sURL = substr($sURL, 0, strrpos($sURL, '.'));
  99. }
  100. $sExt = isset($sExt) ? $sExt : 'html';
  101. $sExt = strtolower($sExt);
  102. // Explode the URL to figure out the controller and method being called
  103. $aURLComponents = explode('/', $sURL);
  104. // Underscores and dashes are replaced by spaces, then camel case
  105. $sController = $aURLComponents[0] ? $aURLComponents[0] : 'Default';
  106. $sController = str_replace(array('_', '-'), ' ', $sController);
  107. $sController = ucwords($sController);
  108. $sController = str_replace(' ', '', $sController);
  109. // Underscores and dashes are replaced by spaces, periods are ignored
  110. // numbers will be preceded with n
  111. $sMethod = isset($aURLComponents[1]) ? $aURLComponents[1] : 'index';
  112. $sMethod = str_replace(array('_', '-'), ' ', $sMethod);
  113. $sMethod = ucwords($sMethod);
  114. $sMethod = str_replace(' ', '', $sMethod);
  115. $sMethod = str_replace('.', '', $sMethod);
  116. $sMethod = strtolower(substr($sMethod, 0, 1)).substr($sMethod,1);
  117. $sMethod = is_numeric($sMethod) ? 'n'.$sMethod : $sMethod;
  118. // Determine controller class and path
  119. $sControllerClass = $sController.'Controller';
  120. $sControllerPath = 'app/controllers/'.$sControllerClass.'.php';
  121. if (!file_exists($sControllerPath)) {
  122. // Analyze routes
  123. // TODO improve routing
  124. if (isset($aAppConfig['MAPPING']) && is_array($aAppConfig['MAPPING'])) {
  125. foreach ($aAppConfig['MAPPING'] as $sPattern => $sController) {
  126. if (preg_match($sPattern, $sURL)) {
  127. $bFound = true;
  128. break;
  129. }
  130. }
  131. }
  132. $sController = ucwords($sController);
  133. $sMethod = 'index';
  134. $sControllerClass = $sController.'Controller';
  135. $sControllerPath = 'app/controllers/'.$sControllerClass.'.php';
  136. if (!file_exists($sControllerPath)) {
  137. $this->notFound('controller '.$sController.' not found');
  138. }
  139. }
  140. $GLOBALS['controller'] = $sController;
  141. $GLOBALS['method'] = $sMethod;
  142. include_once($sControllerPath);
  143. if ($aAppConfig['TARGET'] == 'dev') {
  144. _DEBUG('---> '.$sControllerClass.' '.$sMethod);
  145. }
  146. ob_start();
  147. $oController = new $sControllerClass();
  148. $__debug = ob_get_contents();
  149. ob_end_clean();
  150. if (!$oController->__early_exit) {
  151. if (!method_exists($oController, $sMethod)) {
  152. $this->notFound('method '.$sMethod.' not found');
  153. }
  154. $oController->set('controller', $sController);
  155. $oController->set('method', $sMethod);
  156. $oController->set('extension', $sExt);
  157. if (method_exists($oController, 'preExec')) {
  158. $oController->preExec();
  159. }
  160. $aArgs = array_slice($aURLComponents,2);
  161. $oController->$sMethod($args);
  162. }
  163. if (method_exists($oController, 'postExec')) {
  164. $oController->postExec();
  165. }
  166. // TEMPLATE
  167. $sTemplate = $oController->getTemplate();
  168. $sTemplate = $sTemplate ? $sTemplate : strtolower($sController).'.php';
  169. $sTemplatePath = 'app/templates/'.$sTemplate;
  170. if (!file_exists($sTemplatePath)) {
  171. $this->notFound('template '.$sTemplate.' not found');
  172. }
  173. $GLOBALS['_content_template'] = $sTemplate;
  174. $iEndTime = microtime(true);
  175. $iTotalTime = $iEndTime - $iStartTime;
  176. /*
  177. $oController->set('time_elapsed', $iTotalTime);
  178. $oController->set('__data', $oController->get());
  179. $oController->set('queries', DB::get_query_count());
  180. $oController->set('aQueries', DB::get_queries());
  181. $oController->set('__debug', $__debug);
  182. */
  183. // Rendering
  184. if (method_exists($oController, 'preRender')) {
  185. $oController->preRender();
  186. }
  187. ob_start();
  188. $oController->_render($sTemplatePath);
  189. $sContent = ob_get_contents();
  190. ob_end_clean();
  191. if (method_exists($oController, 'postRender')) {
  192. $sContent = $oController->postRender($sContent);
  193. }
  194. print $sContent;
  195. }
  196. public function notFound($msg)
  197. {
  198. // XXX configure 404 page
  199. header('HTTP/1.1 404 Not Found', true, 404);
  200. header('Location: /404.html');
  201. _ERROR($msg);
  202. exit();
  203. }
  204. public static function watch_start($k)
  205. {
  206. self::$aWatches[$k] = microtime(true);
  207. }
  208. public static function watch_stop($k)
  209. {
  210. self::$aWatches[$k] = microtime(true) - self::$aWatches[$k];
  211. }
  212. }