PageRenderTime 44ms CodeModel.GetById 17ms RepoModel.GetById 1ms app.codeStats 0ms

/default_www/backend/init.php

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