PageRenderTime 74ms CodeModel.GetById 16ms RepoModel.GetById 1ms app.codeStats 0ms

/default_www/frontend/init.php

https://github.com/yoniweb/forkcms-Golden-Gate
PHP | 459 lines | 199 code | 88 blank | 172 comment | 34 complexity | c3dc22b72a4deafe3a4a54f02a37b80d MD5 | raw file
  1. <?php
  2. /**
  3. * This class will initiate the frontend-application
  4. *
  5. * @package frontend
  6. * @subpackage core
  7. *
  8. * @author Tijs Verkoyen <tijs@netlash.com>
  9. * @author Davy Hellemans <davy@netlash.com>
  10. * @since 2.0
  11. */
  12. class FrontendInit
  13. {
  14. /**
  15. * Current type
  16. *
  17. * @var string
  18. */
  19. private $type;
  20. /**
  21. * Default constructor
  22. *
  23. * @return void
  24. * @param string $type The type of init to load, possible values are: frontend, frontend_ajax, frontend_js.
  25. */
  26. public function __construct($type)
  27. {
  28. // init vars
  29. $allowedTypes = array('frontend', 'frontend_ajax', 'frontend_js');
  30. $type = (string) $type;
  31. // check if this is a valid type
  32. if(!in_array($type, $allowedTypes)) exit('Invalid init-type');
  33. // set type
  34. $this->type = $type;
  35. // register the autoloader
  36. spl_autoload_register(array('FrontendInit', 'autoLoader'));
  37. // set some ini-options
  38. ini_set('pcre.backtrack_limit', 999999999);
  39. ini_set('pcre.recursion_limit', 999999999);
  40. ini_set('memory_limit', '64M');
  41. // set a default timezone if no one was set by PHP.ini
  42. if(ini_get('date.timezone') == '') date_default_timezone_set('Europe/Brussels');
  43. /**
  44. * At first we enable the error reporting. Later on it will be disabled based on the
  45. * value of SPOON_DEBUG, but for now it's required to see possible errors while trying
  46. * to include the globals file(s).
  47. */
  48. error_reporting(E_ALL | E_STRICT);
  49. ini_set('display_errors', 'On');
  50. // require globals
  51. $this->requireGlobals();
  52. // get last modified time for globals
  53. $lastModifiedTime = @filemtime(PATH_LIBRARY . '/globals.php');
  54. // reset lastmodified time if needed (SPOON_DEBUG is enabled or we don't get a decent timestamp)
  55. if($lastModifiedTime === false || SPOON_DEBUG) $lastModifiedTime = time();
  56. // define as a constant
  57. define('LAST_MODIFIED_TIME', $lastModifiedTime);
  58. // define constants
  59. $this->definePaths();
  60. $this->defineURLs();
  61. // set include path
  62. $this->setIncludePath();
  63. // set debugging
  64. $this->setDebugging();
  65. // require spoon
  66. require_once 'spoon/spoon.php';
  67. // require frontend-classes
  68. $this->requireFrontendClasses();
  69. // disable magic quotes
  70. SpoonFilter::disableMagicQuotes();
  71. // start session
  72. $this->initSession();
  73. }
  74. /**
  75. * Autoloader for the frontend
  76. *
  77. * @return void
  78. * @param string $className The name of the class to require.
  79. */
  80. public static function autoLoader($className)
  81. {
  82. // redefine
  83. $className = strtolower((string) $className);
  84. // init var
  85. $pathToLoad = '';
  86. // exceptions
  87. $exceptions = array();
  88. $exceptions['frontend'] = FRONTEND_CORE_PATH . '/engine/frontend.php';
  89. $exceptions['frontendbaseajaxaction'] = FRONTEND_CORE_PATH . '/engine/base.php';
  90. $exceptions['frontendbaseconfig'] = FRONTEND_CORE_PATH . '/engine/base.php';
  91. $exceptions['frontendbaseobject'] = FRONTEND_CORE_PATH . '/engine/base.php';
  92. $exceptions['frontendblockextra'] = FRONTEND_CORE_PATH . '/engine/block.php';
  93. $exceptions['frontendblockwidget'] = FRONTEND_CORE_PATH . '/engine/block.php';
  94. $exceptions['frontendtemplatecompiler'] = FRONTEND_CORE_PATH . '/engine/template_compiler.php';
  95. // is it an exception
  96. if(isset($exceptions[$className])) $pathToLoad = $exceptions[$className];
  97. // frontend
  98. elseif(substr($className, 0, 8) == 'frontend') $pathToLoad = FRONTEND_CORE_PATH . '/engine/' . str_replace('frontend', '', $className) . '.php';
  99. // file check in core
  100. if($pathToLoad != '' && SpoonFile::exists($pathToLoad)) require_once $pathToLoad;
  101. // check if module file exists
  102. else
  103. {
  104. // we'll need the original class name again, with the uppercases
  105. $className = func_get_arg(0);
  106. // split in parts
  107. if(preg_match_all('/[A-Z][a-z0-9]*/', $className, $parts))
  108. {
  109. // the real matches
  110. $parts = $parts[0];
  111. // doublecheck that we are looking for a frontend class
  112. $root = array_shift($parts);
  113. if(strtolower($root) == 'frontend')
  114. {
  115. foreach($parts as $i => $part)
  116. {
  117. // skip the first
  118. if($i == 0) continue;
  119. // action
  120. $action = strtolower(implode('_', $parts));
  121. // module
  122. $module = '';
  123. for($j = 0; $j < $i; $j++) $module .= strtolower($parts[$j]) . '_';
  124. // fix action & module
  125. $action = str_replace($module, '', $action);
  126. $module = substr($module, 0, -1);
  127. // file to be loaded
  128. $pathToLoad = FRONTEND_PATH . '/modules/' . $module . '/engine/' . $action . '.php';
  129. // if it exists, load it!
  130. if($pathToLoad != '' && SpoonFile::exists($pathToLoad))
  131. {
  132. require_once $pathToLoad;
  133. break;
  134. }
  135. }
  136. }
  137. }
  138. }
  139. }
  140. /**
  141. * Define paths
  142. *
  143. * @return void
  144. */
  145. private function definePaths()
  146. {
  147. // fix the Application setting
  148. if($this->type == 'frontend_js') define('APPLICATION', 'frontend');
  149. elseif($this->type == 'frontend_ajax') define('APPLICATION', 'frontend');
  150. // general paths
  151. define('FRONTEND_PATH', PATH_WWW . '/' . APPLICATION);
  152. define('FRONTEND_CACHE_PATH', FRONTEND_PATH . '/cache');
  153. define('FRONTEND_CORE_PATH', FRONTEND_PATH . '/core');
  154. define('FRONTEND_MODULES_PATH', FRONTEND_PATH . '/modules');
  155. define('FRONTEND_FILES_PATH', FRONTEND_PATH . '/files');
  156. }
  157. /**
  158. * Define URLs
  159. *
  160. * @return void
  161. */
  162. private function defineURLs()
  163. {
  164. define('FRONTEND_CORE_URL', '/' . APPLICATION . '/core');
  165. define('FRONTEND_CACHE_URL', '/' . APPLICATION . '/cache');
  166. define('FRONTEND_FILES_URL', '/frontend/files');
  167. }
  168. /**
  169. * A custom error-handler so we can handle warnings about undefined labels
  170. *
  171. * @return bool
  172. * @param int $errorNumber The level of the error raised, as an integer.
  173. * @param string $errorString The error message, as a string.
  174. */
  175. public static function errorHandler($errorNumber, $errorString)
  176. {
  177. // redefine
  178. $errorNumber = (int) $errorNumber;
  179. $errorString = (string) $errorString;
  180. // is this an undefined index?
  181. if(mb_substr_count($errorString, 'Undefined index:') > 0)
  182. {
  183. // cleanup
  184. $index = trim(str_replace('Undefined index:', '', $errorString));
  185. // get the type
  186. $type = mb_substr($index, 0, 3);
  187. // is the index locale?
  188. if(in_array($type, array('act', 'err', 'lbl', 'msg'))) echo '{$' . $index . '}';
  189. // return false, so the standard error handler isn't bypassed
  190. else return false;
  191. }
  192. // return false, so the standard error handler isn't bypassed
  193. else return false;
  194. }
  195. /**
  196. * This method will be called by the Spoon Exceptionhandler and is specific for exceptions thrown in AJAX-actions
  197. *
  198. * @return void
  199. * @param object $exception The exception that was thrown.
  200. * @param string $output The output that should be mailed.
  201. */
  202. public static function exceptionAJAXHandler($exception, $output)
  203. {
  204. // redefine
  205. $output = (string) $output;
  206. // set headers
  207. SpoonHTTP::setHeaders('content-type: application/json');
  208. // create response array
  209. $response = array('code' => ($exception->getCode() != 0) ? $exception->getCode() : 500, 'message' => $exception->getMessage());
  210. // output to the browser
  211. echo json_encode($response);
  212. // stop script execution
  213. exit;
  214. }
  215. /**
  216. * This method will be called by the Spoon Exceptionhandler
  217. *
  218. * @return void
  219. * @param object $exception The exception that was thrown.
  220. * @param string $output The output that should be mailed.
  221. */
  222. public static function exceptionHandler($exception, $output)
  223. {
  224. // redefine
  225. $exception = $exception;
  226. $output = (string) $output;
  227. // mail it?
  228. if(SPOON_DEBUG_EMAIL != '')
  229. {
  230. // e-mail headers
  231. $headers = "MIME-Version: 1.0\n";
  232. $headers .= "Content-type: text/html; charset=iso-8859-15\n";
  233. $headers .= "X-Priority: 3\n";
  234. $headers .= "X-MSMail-Priority: Normal\n";
  235. $headers .= "X-Mailer: SpoonLibrary Webmail\n";
  236. $headers .= "From: Spoon Library <no-reply@spoon-library.com>\n";
  237. // send email
  238. @mail(SPOON_DEBUG_EMAIL, 'Exception Occured (' . SITE_DOMAIN . ')', $output, $headers);
  239. }
  240. // build HTML for nice error
  241. $html = '<html><body>Something went wrong.</body></html>';
  242. // output
  243. echo $html;
  244. // stop script execution
  245. exit;
  246. }
  247. /**
  248. * This method will be called by the Spoon Exceptionhandler and is specific for exceptions thrown in JS-files parsed through PHP
  249. *
  250. * @return void
  251. * @param object $exception The exception that was thrown.
  252. * @param string $output The output that should be mailed.
  253. */
  254. public static function exceptionJSHandler($exception, $output)
  255. {
  256. // redefine
  257. $output = (string) $output;
  258. // set correct headers
  259. SpoonHTTP::setHeaders('content-type: application/javascript');
  260. // output
  261. echo '// ' . $exception->getMessage();
  262. // stop script execution
  263. exit;
  264. }
  265. /**
  266. * Start session
  267. *
  268. * @return void
  269. */
  270. private function initSession()
  271. {
  272. SpoonSession::start();
  273. }
  274. /**
  275. * Require all needed classes
  276. *
  277. * @return void
  278. */
  279. private function requireFrontendClasses()
  280. {
  281. // based on the type
  282. switch($this->type)
  283. {
  284. case 'frontend':
  285. case 'frontend_ajax':
  286. require_once FRONTEND_CORE_PATH . '/engine/template_custom.php';
  287. require_once FRONTEND_PATH . '/modules/tags/engine/model.php';
  288. break;
  289. }
  290. }
  291. /**
  292. * Require globals-file
  293. *
  294. * @return void
  295. */
  296. private function requireGlobals()
  297. {
  298. // fetch config
  299. $installed[] = @include_once dirname(__FILE__) . '/cache/config/config.php';
  300. // load the globals
  301. $installed[] = @include_once INIT_PATH_LIBRARY . '/globals.php';
  302. $installed[] = @include_once INIT_PATH_LIBRARY . '/globals_backend.php';
  303. $installed[] = @include_once INIT_PATH_LIBRARY . '/globals_frontend.php';
  304. // something could not be loaded
  305. if(in_array(false, $installed))
  306. {
  307. // installation folder
  308. $installer = dirname(__FILE__) . '/../install/cache';
  309. // Fork has not yet been installed
  310. if(file_exists($installer) && is_dir($installer) && !file_exists($installer . '/installed.txt'))
  311. {
  312. // redirect to installer
  313. header('Location: /install');
  314. }
  315. // we can nog load configuration file, however we can not run installer
  316. echo 'Required configuration files are missing. Try deleting current files, clearing your database, re-uploading <a href="http://www.fork-cms.be">Fork CMS</a> and <a href="/install">rerun the installer</a>.';
  317. // stop script execution
  318. exit;
  319. }
  320. }
  321. /**
  322. * Set debugging
  323. *
  324. * @return void
  325. */
  326. private function setDebugging()
  327. {
  328. // debugging enabled
  329. if(SPOON_DEBUG)
  330. {
  331. // set error reporting as high as possible
  332. error_reporting(E_ALL | E_STRICT);
  333. // show errors on the screen
  334. ini_set('display_errors', 'On');
  335. // in debug mode notices are triggered when using non existing locale, so we use a custom errorhandler to cleanup the message
  336. set_error_handler(array('FrontendInit', 'errorHandler'));
  337. }
  338. // debugging disabled
  339. else
  340. {
  341. // set error reporting as low as possible
  342. error_reporting(0);
  343. // don't show error on the screen
  344. ini_set('display_errors', 'Off');
  345. // add callback for the spoon exceptionhandler
  346. switch($this->type)
  347. {
  348. case 'backend_ajax':
  349. define('SPOON_EXCEPTION_CALLBACK', __CLASS__ . '::exceptionAJAXHandler');
  350. break;
  351. case 'backend_js':
  352. define('SPOON_EXCEPTION_CALLBACK', __CLASS__ . '::exceptionJSHandler');
  353. break;
  354. default:
  355. define('SPOON_EXCEPTION_CALLBACK', __CLASS__ . '::exceptionHandler');
  356. break;
  357. }
  358. }
  359. }
  360. /**
  361. * Set include path
  362. *
  363. * @return void
  364. */
  365. private function setIncludePath()
  366. {
  367. // prepend the libary and document_root to the existing include path
  368. set_include_path(PATH_LIBRARY . PATH_SEPARATOR . PATH_WWW . PATH_SEPARATOR . get_include_path());
  369. }
  370. }
  371. ?>