PageRenderTime 62ms CodeModel.GetById 26ms RepoModel.GetById 0ms app.codeStats 0ms

/pimcore/lib/Pimcore.php

https://github.com/benawv/bogor-city-guide
PHP | 966 lines | 743 code | 113 blank | 110 comment | 98 complexity | 923da4f01aa81edda922e397b230f750 MD5 | raw file
Possible License(s): BSD-3-Clause, GPL-3.0, LGPL-2.1, MPL-2.0-no-copyleft-exception
  1. <?php
  2. /**
  3. * Pimcore
  4. *
  5. * LICENSE
  6. *
  7. * This source file is subject to the new BSD license that is bundled
  8. * with this package in the file LICENSE.txt.
  9. * It is also available through the world-wide-web at this URL:
  10. * http://www.pimcore.org/license
  11. *
  12. * @copyright Copyright (c) 2009-2013 pimcore GmbH (http://www.pimcore.org)
  13. * @license http://www.pimcore.org/license New BSD License
  14. */
  15. class Pimcore {
  16. /**
  17. * @var bool
  18. */
  19. public static $adminMode;
  20. /**
  21. * @var bool
  22. */
  23. private static $inShutdown = false;
  24. /**
  25. * @var Zend_EventManager_EventManager
  26. */
  27. private static $eventManager;
  28. /**
  29. * @static
  30. * @throws Exception|Zend_Controller_Router_Exception
  31. */
  32. public static function run() {
  33. self::setSystemRequirements();
  34. // detect frontend (website)
  35. $frontend = Pimcore_Tool::isFrontend();
  36. // enable the output-buffer, why? see in self::outputBufferStart()
  37. //if($frontend) {
  38. self::outputBufferStart();
  39. //}
  40. self::initAutoloader();
  41. self::initConfiguration();
  42. self::setupFramework();
  43. // config is loaded now init the real logger
  44. self::initLogger();
  45. // initialize cache
  46. Pimcore_Model_Cache::init();
  47. // load plugins and modules (=core plugins)
  48. self::initModules();
  49. self::initPlugins();
  50. // init front controller
  51. $front = Zend_Controller_Front::getInstance();
  52. $conf = Pimcore_Config::getSystemConfig();
  53. if(!$conf) {
  54. // redirect to installer if configuration isn't present
  55. if (!preg_match("/^\/install.*/", $_SERVER["REQUEST_URI"])) {
  56. header("Location: /install/");
  57. exit;
  58. }
  59. }
  60. if(self::inDebugMode() && $frontend && !defined("HHVM_VERSION")) {
  61. $whoops = new \Whoops\Run;
  62. $whoops->pushHandler(new \Whoops\Handler\PrettyPageHandler);
  63. $jsonErrorHandler = new \Whoops\Handler\JsonResponseHandler;
  64. $jsonErrorHandler->onlyForAjaxRequests(true);
  65. $whoops->pushHandler($jsonErrorHandler);
  66. $whoops->register();
  67. // add event handler before Pimcore::shutdown() to ensure fatal errors are handled by Whoops
  68. self::getEventManager()->attach("system.shutdown", array($whoops, "handleShutdown"), 10000);
  69. }
  70. $front->registerPlugin(new Pimcore_Controller_Plugin_ErrorHandler(), 1);
  71. $front->registerPlugin(new Pimcore_Controller_Plugin_Maintenance(), 2);
  72. // register general pimcore plugins for frontend
  73. if ($frontend) {
  74. $front->registerPlugin(new Pimcore_Controller_Plugin_Thumbnail(), 795);
  75. $front->registerPlugin(new Pimcore_Controller_Plugin_Less(), 799);
  76. $front->registerPlugin(new Pimcore_Controller_Plugin_AdminButton(), 806);
  77. }
  78. if (Pimcore_Tool::useFrontendOutputFilters(new Zend_Controller_Request_Http())) {
  79. $front->registerPlugin(new Pimcore_Controller_Plugin_HybridAuth(), 792);
  80. $front->registerPlugin(new Pimcore_Controller_Plugin_QrCode(), 793);
  81. $front->registerPlugin(new Pimcore_Controller_Plugin_CommonFilesFilter(), 794);
  82. $front->registerPlugin(new Pimcore_Controller_Plugin_WysiwygAttributes(), 796);
  83. $front->registerPlugin(new Pimcore_Controller_Plugin_Webmastertools(), 797);
  84. $front->registerPlugin(new Pimcore_Controller_Plugin_Analytics(), 798);
  85. $front->registerPlugin(new Pimcore_Controller_Plugin_TagManagement(), 804);
  86. $front->registerPlugin(new Pimcore_Controller_Plugin_Targeting(), 805);
  87. $front->registerPlugin(new Pimcore_Controller_Plugin_HttpErrorLog(), 850);
  88. $front->registerPlugin(new Pimcore_Controller_Plugin_ContentLog(), 851);
  89. $front->registerPlugin(new Pimcore_Controller_Plugin_Cache(), 901); // for caching
  90. }
  91. self::initControllerFront($front);
  92. // set router
  93. $router = $front->getRouter();
  94. $routeAdmin = new Zend_Controller_Router_Route(
  95. 'admin/:controller/:action/*',
  96. array(
  97. 'module' => 'admin',
  98. "controller" => "index",
  99. "action" => "index"
  100. )
  101. );
  102. $routeInstall = new Zend_Controller_Router_Route(
  103. 'install/:controller/:action/*',
  104. array(
  105. 'module' => 'install',
  106. "controller" => "index",
  107. "action" => "index"
  108. )
  109. );
  110. $routeUpdate = new Zend_Controller_Router_Route(
  111. 'admin/update/:controller/:action/*',
  112. array(
  113. 'module' => 'update',
  114. "controller" => "index",
  115. "action" => "index"
  116. )
  117. );
  118. $routePlugins = new Zend_Controller_Router_Route(
  119. 'admin/plugin/:controller/:action/*',
  120. array(
  121. 'module' => 'pluginadmin',
  122. "controller" => "index",
  123. "action" => "index"
  124. )
  125. );
  126. $routeExtensions = new Zend_Controller_Router_Route(
  127. 'admin/extensionmanager/:controller/:action/*',
  128. array(
  129. 'module' => 'extensionmanager',
  130. "controller" => "index",
  131. "action" => "index"
  132. )
  133. );
  134. $routeReports = new Zend_Controller_Router_Route(
  135. 'admin/reports/:controller/:action/*',
  136. array(
  137. 'module' => 'reports',
  138. "controller" => "index",
  139. "action" => "index"
  140. )
  141. );
  142. $routePlugin = new Zend_Controller_Router_Route(
  143. 'plugin/:module/:controller/:action/*',
  144. array(
  145. "controller" => "index",
  146. "action" => "index"
  147. )
  148. );
  149. $routeWebservice = new Zend_Controller_Router_Route(
  150. 'webservice/:controller/:action/*',
  151. array(
  152. "module" => "webservice",
  153. "controller" => "index",
  154. "action" => "index"
  155. )
  156. );
  157. $routeSearchAdmin = new Zend_Controller_Router_Route(
  158. 'admin/search/:controller/:action/*',
  159. array(
  160. "module" => "searchadmin",
  161. "controller" => "index",
  162. "action" => "index",
  163. )
  164. );
  165. // website route => custom router which check for a suitable document
  166. $routeFrontend = new Pimcore_Controller_Router_Route_Frontend();
  167. $router->addRoute('default', $routeFrontend);
  168. // only do this if not frontend => performance issue
  169. if (!$frontend) {
  170. $router->addRoute("install", $routeInstall);
  171. $router->addRoute('plugin', $routePlugin);
  172. $router->addRoute('admin', $routeAdmin);
  173. $router->addRoute('update', $routeUpdate);
  174. $router->addRoute('plugins', $routePlugins);
  175. $router->addRoute('extensionmanager', $routeExtensions);
  176. $router->addRoute('reports', $routeReports);
  177. $router->addRoute('searchadmin', $routeSearchAdmin);
  178. if ($conf instanceof Zend_Config and $conf->webservice and $conf->webservice->enabled) {
  179. $router->addRoute('webservice', $routeWebservice);
  180. }
  181. // force the main (default) domain for "admin" requests
  182. if($conf->general->domain && $conf->general->domain != Pimcore_Tool::getHostname()) {
  183. $url = (($_SERVER['HTTPS'] == "on") ? "https" : "http") . "://" . $conf->general->domain . $_SERVER["REQUEST_URI"];
  184. header("HTTP/1.1 301 Moved Permanently");
  185. header("Location: " . $url, true, 301);
  186. exit;
  187. }
  188. }
  189. // check if webdav is configured and add router
  190. if ($conf instanceof Zend_Config) {
  191. if ($conf->assets->webdav->hostname) {
  192. $routeWebdav = new Zend_Controller_Router_Route_Hostname(
  193. $conf->assets->webdav->hostname,
  194. array(
  195. "module" => "admin",
  196. 'controller' => 'asset',
  197. 'action' => 'webdav'
  198. )
  199. );
  200. $router->addRoute('webdav', $routeWebdav);
  201. }
  202. }
  203. $front->setRouter($router);
  204. self::getEventManager()->trigger("system.startup", $front);
  205. // throw exceptions also when in preview or in editmode (documents) to see it immediately when there's a problem with this page
  206. $throwExceptions = false;
  207. if(Pimcore_Tool::isFrontentRequestByAdmin()) {
  208. $user = Pimcore_Tool_Authentication::authenticateSession();
  209. if($user instanceof User) {
  210. $throwExceptions = true;
  211. }
  212. }
  213. // run dispatcher
  214. if (!PIMCORE_DEBUG && !$throwExceptions && !PIMCORE_DEVMODE) {
  215. @ini_set("display_errors", "Off");
  216. @ini_set("display_startup_errors", "Off");
  217. $front->dispatch();
  218. }
  219. else {
  220. @ini_set("display_errors", "On");
  221. @ini_set("display_startup_errors", "On");
  222. $front->throwExceptions(true);
  223. try {
  224. $front->dispatch();
  225. }
  226. catch (Zend_Controller_Router_Exception $e) {
  227. if(!headers_sent()) {
  228. header("HTTP/1.0 404 Not Found");
  229. }
  230. throw new Zend_Controller_Router_Exception("No route, document, custom route or redirect is matching the request: " . $_SERVER["REQUEST_URI"] . " | \n" . "Specific ERROR: " . $e->getMessage());
  231. }
  232. catch (Exception $e) {
  233. if(!headers_sent()) {
  234. header("HTTP/1.0 500 Internal Server Error");
  235. }
  236. throw $e;
  237. }
  238. }
  239. }
  240. /**
  241. * @static
  242. * @param Zend_Controller_Front $front
  243. */
  244. public static function initControllerFront (Zend_Controller_Front $front) {
  245. // disable build-in error handler
  246. $front->setParam('noErrorHandler', true);
  247. // for admin an other modules directly in the core
  248. $front->addModuleDirectory(PIMCORE_PATH . "/modules");
  249. // for plugins
  250. if (is_dir(PIMCORE_PLUGINS_PATH) && is_readable(PIMCORE_PLUGINS_PATH)) {
  251. $front->addModuleDirectory(PIMCORE_PLUGINS_PATH);
  252. }
  253. // for frontend (default: website)
  254. $front->addControllerDirectory(PIMCORE_WEBSITE_PATH . "/controllers", PIMCORE_FRONTEND_MODULE);
  255. $front->setDefaultModule(PIMCORE_FRONTEND_MODULE);
  256. }
  257. /**
  258. * @static
  259. *
  260. */
  261. public static function initLogger() {
  262. // for forks, etc ...
  263. Logger::resetLoggers();
  264. // try to load configuration
  265. $conf = Pimcore_Config::getSystemConfig();
  266. if($conf) {
  267. // redirect php error_log to /website/var/log/php.log
  268. if($conf->general->custom_php_logfile) {
  269. $phpLog = PIMCORE_LOG_DIRECTORY . "/php.log";
  270. if(is_writable($phpLog)) {
  271. ini_set("error_log", $phpLog);
  272. ini_set("log_errors", "1");
  273. }
  274. }
  275. }
  276. if(!is_file(PIMCORE_LOG_DEBUG)) {
  277. if(is_writable(dirname(PIMCORE_LOG_DEBUG))) {
  278. Pimcore_File::put(PIMCORE_LOG_DEBUG, "AUTOCREATE\n");
  279. }
  280. }
  281. $prioMapping = array(
  282. "debug" => Zend_Log::DEBUG,
  283. "info" => Zend_Log::INFO,
  284. "notice" => Zend_Log::NOTICE,
  285. "warning" => Zend_Log::WARN,
  286. "error" => Zend_Log::ERR,
  287. "critical" => Zend_Log::CRIT,
  288. "alert" => Zend_Log::ALERT,
  289. "emergency" => Zend_Log::EMERG
  290. );
  291. $prios = array();
  292. if($conf && $conf->general->debugloglevel) {
  293. $prioMapping = array_reverse($prioMapping);
  294. foreach ($prioMapping as $level => $state) {
  295. $prios[] = $prioMapping[$level];
  296. if($level == $conf->general->debugloglevel) {
  297. break;
  298. }
  299. }
  300. }
  301. else {
  302. // log everything if config isn't loaded (eg. at the installer)
  303. foreach ($prioMapping as $p) {
  304. $prios[] = $p;
  305. }
  306. }
  307. Logger::setPriorities($prios);
  308. if (is_writable(PIMCORE_LOG_DEBUG)) {
  309. // check for big logfile, empty it if it's bigger than about 200M
  310. if (filesize(PIMCORE_LOG_DEBUG) > 200000000) {
  311. rename(PIMCORE_LOG_DEBUG, PIMCORE_LOG_DEBUG . "-archive-" . date("m-d-Y-H-i")); // archive log (will be cleaned up by maintenance)
  312. Pimcore_File::put(PIMCORE_LOG_DEBUG, "");
  313. }
  314. if(!empty($prios)) {
  315. $writerFile = new Zend_Log_Writer_Stream(PIMCORE_LOG_DEBUG);
  316. $loggerFile = new Zend_Log($writerFile);
  317. Logger::addLogger($loggerFile);
  318. }
  319. $conf = Pimcore_Config::getSystemConfig();
  320. if($conf) {
  321. //email logger
  322. if(!empty($conf->general->logrecipient)) {
  323. $user = User::getById($conf->general->logrecipient);
  324. if($user instanceof User && $user->isAdmin()) {
  325. $email = $user->getEmail();
  326. if(!empty($email)){
  327. $mail = Pimcore_Tool::getMail(array($email),"pimcore log notification");
  328. $mail->setIgnoreDebugMode(true);
  329. if(!is_dir(PIMCORE_LOG_MAIL_TEMP)){
  330. Pimcore_File::mkdir(PIMCORE_LOG_MAIL_TEMP);
  331. }
  332. $tempfile = PIMCORE_LOG_MAIL_TEMP."/log-".uniqid().".log";
  333. $writerEmail = new Pimcore_Log_Writer_Mail($tempfile,$mail);
  334. $loggerEmail = new Zend_Log($writerEmail);
  335. Logger::addLogger($loggerEmail);
  336. }
  337. }
  338. }
  339. }
  340. } else {
  341. // try to use syslog instead
  342. try {
  343. $writerSyslog = new Zend_Log_Writer_Syslog(array('application' => 'pimcore'));
  344. $loggerSyslog = new Zend_Log($writerSyslog);
  345. Logger::addLogger($loggerSyslog);
  346. } catch (\Exception $e) {
  347. }
  348. }
  349. if(array_key_exists("pimcore_log", $_REQUEST) && self::inDebugMode()) {
  350. if(empty($_REQUEST["pimcore_log"])) {
  351. $requestLogName = date("Y-m-d_H-i-s");
  352. } else {
  353. $requestLogName = $_REQUEST["pimcore_log"];
  354. }
  355. $requestLogFile = dirname(PIMCORE_LOG_DEBUG) . "/request-" . $requestLogName . ".log";
  356. if(!file_exists($requestLogFile)) {
  357. Pimcore_File::put($requestLogFile,"");
  358. }
  359. $writerRequestLog = new Zend_Log_Writer_Stream($requestLogFile);
  360. $loggerRequest = new Zend_Log($writerRequestLog);
  361. Logger::addLogger($loggerRequest);
  362. Logger::setVerbosePriorities();
  363. }
  364. }
  365. /**
  366. * @static
  367. *
  368. */
  369. public static function setSystemRequirements() {
  370. // try to set system-internal variables
  371. $maxExecutionTime = 240;
  372. if(php_sapi_name() == "cli") {
  373. $maxExecutionTime = 0;
  374. }
  375. error_reporting(E_ALL & ~E_NOTICE & ~E_STRICT);
  376. //@ini_set("memory_limit", "1024M");
  377. @ini_set("max_execution_time", $maxExecutionTime);
  378. set_time_limit($maxExecutionTime);
  379. mb_internal_encoding("UTF-8");
  380. // this is for simple_dom_html
  381. ini_set('pcre.recursion-limit', 100000);
  382. // set dummy timezone if no tz is specified / required for example by the logger, ...
  383. $defaultTimezone = @date_default_timezone_get();
  384. if(!$defaultTimezone) {
  385. date_default_timezone_set("UTC"); // UTC -> default timezone
  386. }
  387. // check some system variables
  388. if (version_compare(PHP_VERSION, '5.4', "<")) {
  389. $m = "pimcore requires at least PHP version 5.4.0 your PHP version is: " . PHP_VERSION;
  390. Pimcore_Tool::exitWithError($m);
  391. }
  392. }
  393. /**
  394. * initialisze system modules and register them with the broker
  395. *
  396. * @static
  397. * @return void
  398. */
  399. public static function initModules() {
  400. $broker = Pimcore_API_Plugin_Broker::getInstance();
  401. $broker->registerModule("Search_Backend_Module");
  402. $conf = Pimcore_Config::getSystemConfig();
  403. if($conf->general->instanceIdentifier) {
  404. $broker->registerModule("Tool_UUID_Module");
  405. }
  406. }
  407. public static function initPlugins() {
  408. // add plugin include paths
  409. $autoloader = Zend_Loader_Autoloader::getInstance();
  410. try {
  411. $pluginConfigs = Pimcore_ExtensionManager::getPluginConfigs();
  412. if (!empty($pluginConfigs)) {
  413. $includePaths = array(
  414. get_include_path()
  415. );
  416. //adding plugin include paths and namespaces
  417. if (count($pluginConfigs) > 0) {
  418. foreach ($pluginConfigs as $p) {
  419. if(!Pimcore_ExtensionManager::isEnabled("plugin", $p["plugin"]["pluginName"])){
  420. continue;
  421. }
  422. if (is_array($p['plugin']['pluginIncludePaths']['path'])) {
  423. foreach ($p['plugin']['pluginIncludePaths']['path'] as $path) {
  424. $includePaths[] = PIMCORE_PLUGINS_PATH . $path;
  425. }
  426. }
  427. else if ($p['plugin']['pluginIncludePaths']['path'] != null) {
  428. $includePaths[] = PIMCORE_PLUGINS_PATH . $p['plugin']['pluginIncludePaths']['path'];
  429. }
  430. if (is_array($p['plugin']['pluginNamespaces']['namespace'])) {
  431. foreach ($p['plugin']['pluginNamespaces']['namespace'] as $namespace) {
  432. $autoloader->registerNamespace($namespace);
  433. }
  434. }
  435. else if ($p['plugin']['pluginNamespaces']['namespace'] != null) {
  436. $autoloader->registerNamespace($p['plugin']['pluginNamespaces']['namespace']);
  437. }
  438. }
  439. }
  440. set_include_path(implode(PATH_SEPARATOR, $includePaths));
  441. $broker = Pimcore_API_Plugin_Broker::getInstance();
  442. //registering plugins
  443. foreach ($pluginConfigs as $p) {
  444. if(!Pimcore_ExtensionManager::isEnabled("plugin", $p["plugin"]["pluginName"])){
  445. continue;
  446. }
  447. $jsPaths = array();
  448. if (is_array($p['plugin']['pluginJsPaths'])
  449. && isset($p['plugin']['pluginJsPaths']['path'])
  450. && is_array($p['plugin']['pluginJsPaths']['path'])) {
  451. $jsPaths = $p['plugin']['pluginJsPaths']['path'];
  452. }
  453. else if (is_array($p['plugin']['pluginJsPaths'])
  454. && $p['plugin']['pluginJsPaths']['path'] != null) {
  455. $jsPaths[0] = $p['plugin']['pluginJsPaths']['path'];
  456. }
  457. //manipulate path for frontend
  458. if (is_array($jsPaths) and count($jsPaths) > 0) {
  459. for ($i = 0; $i < count($jsPaths); $i++) {
  460. if (is_file(PIMCORE_PLUGINS_PATH . $jsPaths[$i])) {
  461. $jsPaths[$i] = "/plugins" . $jsPaths[$i];
  462. }
  463. }
  464. }
  465. $cssPaths = array();
  466. if (is_array($p['plugin']['pluginCssPaths'])
  467. && isset($p['plugin']['pluginCssPaths']['path'])
  468. && is_array($p['plugin']['pluginCssPaths']['path'])) {
  469. $cssPaths = $p['plugin']['pluginCssPaths']['path'];
  470. }
  471. else if (is_array($p['plugin']['pluginCssPaths'])
  472. && $p['plugin']['pluginCssPaths']['path'] != null) {
  473. $cssPaths[0] = $p['plugin']['pluginCssPaths']['path'];
  474. }
  475. //manipulate path for frontend
  476. if (is_array($cssPaths) and count($cssPaths) > 0) {
  477. for ($i = 0; $i < count($cssPaths); $i++) {
  478. if (is_file(PIMCORE_PLUGINS_PATH . $cssPaths[$i])) {
  479. $cssPaths[$i] = "/plugins" . $cssPaths[$i];
  480. }
  481. }
  482. }
  483. try {
  484. $className = $p['plugin']['pluginClassName'];
  485. if (!empty($className) && Pimcore_Tool::classExists($className)) {
  486. $plugin = new $className($jsPaths, $cssPaths);
  487. if ($plugin instanceof Pimcore_API_Plugin_Abstract) {
  488. $broker->registerPlugin($plugin);
  489. }
  490. }
  491. } catch (Exception $e) {
  492. Logger::err("Could not instantiate and register plugin [" . $p['plugin']['pluginClassName'] . "]");
  493. }
  494. }
  495. Zend_Registry::set("Pimcore_API_Plugin_Broker", $broker);
  496. }
  497. }
  498. catch (Exception $e) {
  499. Logger::alert("there is a problem with the plugin configuration");
  500. Logger::alert($e);
  501. }
  502. }
  503. /**
  504. * @static
  505. *
  506. */
  507. public static function initAutoloader() {
  508. $autoloader = Zend_Loader_Autoloader::getInstance();
  509. $autoloader->registerNamespace('Logger');
  510. $autoloader->registerNamespace('Pimcore');
  511. $autoloader->registerNamespace('Document');
  512. $autoloader->registerNamespace('Object');
  513. $autoloader->registerNamespace('Asset');
  514. $autoloader->registerNamespace('User');
  515. $autoloader->registerNamespace('Property');
  516. $autoloader->registerNamespace('Version');
  517. $autoloader->registerNamespace('Sabre');
  518. $autoloader->registerNamespace('Site');
  519. $autoloader->registerNamespace('Services_');
  520. $autoloader->registerNamespace('HTTP_');
  521. $autoloader->registerNamespace('Net_');
  522. $autoloader->registerNamespace('File_');
  523. $autoloader->registerNamespace('System_');
  524. $autoloader->registerNamespace('PEAR_');
  525. $autoloader->registerNamespace('Thumbnail');
  526. $autoloader->registerNamespace('Staticroute');
  527. $autoloader->registerNamespace('Redirect');
  528. $autoloader->registerNamespace('Dependency');
  529. $autoloader->registerNamespace('Schedule');
  530. $autoloader->registerNamespace('Translation');
  531. $autoloader->registerNamespace('Glossary');
  532. $autoloader->registerNamespace('Website');
  533. $autoloader->registerNamespace('Element');
  534. $autoloader->registerNamespace('API');
  535. $autoloader->registerNamespace('Archive');
  536. $autoloader->registerNamespace('Csv');
  537. $autoloader->registerNamespace('Webservice');
  538. $autoloader->registerNamespace('Search');
  539. $autoloader->registerNamespace('Tool');
  540. $autoloader->registerNamespace('Whoops');
  541. Pimcore_Tool::registerClassModelMappingNamespaces();
  542. }
  543. /**
  544. * @static
  545. * @return bool
  546. */
  547. public static function initConfiguration() {
  548. // init configuration
  549. try {
  550. $conf = Pimcore_Config::getSystemConfig();
  551. // set timezone
  552. if ($conf instanceof Zend_Config) {
  553. if ($conf->general->timezone) {
  554. date_default_timezone_set($conf->general->timezone);
  555. }
  556. }
  557. $debug = self::inDebugMode();
  558. if (!defined("PIMCORE_DEBUG")) define("PIMCORE_DEBUG", $debug);
  559. if (!defined("PIMCORE_DEVMODE")) define("PIMCORE_DEVMODE", (bool) $conf->general->devmode);
  560. // check for output-cache settings
  561. // if a lifetime for the output cache is specified then the cache tag "output" will be ignored on clear
  562. $cacheLifetime = (int) $conf->cache->lifetime;
  563. if (!empty($cacheLifetime) && $conf->cache->enabled) {
  564. Pimcore_Model_Cache::addIgnoredTagOnClear("output");
  565. }
  566. return true;
  567. }
  568. catch (Exception $e) {
  569. $m = "Couldn't load system configuration";
  570. Logger::err($m);
  571. //@TODO check here for /install otherwise exit here
  572. }
  573. if (!defined("PIMCORE_DEBUG")) define("PIMCORE_DEBUG", true);
  574. if (!defined("PIMCORE_DEVMODE")) define("PIMCORE_DEVMODE", false);
  575. // custom error logging in DEVMODE
  576. if(PIMCORE_DEVMODE) {
  577. error_reporting( (E_ALL ^ E_NOTICE) | E_STRICT);
  578. ini_set('error_log', PIMCORE_LOG_DIRECTORY . '/php.log');
  579. }
  580. }
  581. /**
  582. * @static
  583. * @return bool
  584. */
  585. public static function inDebugMode () {
  586. if(defined("PIMCORE_DEBUG")) {
  587. return PIMCORE_DEBUG;
  588. }
  589. $conf = Pimcore_Config::getSystemConfig();
  590. $debug = (bool) $conf->general->debug;
  591. // enable debug mode only for one IP
  592. if($conf->general->debug_ip && $conf->general->debug) {
  593. $debug = false;
  594. $debugIpAddresses = explode_and_trim(',',$conf->general->debug_ip);
  595. if(in_array(Pimcore_Tool::getClientIp(),$debugIpAddresses)) {
  596. $debug = true;
  597. }
  598. }
  599. return $debug;
  600. }
  601. /**
  602. * @static
  603. *
  604. */
  605. public static function setupFramework () {
  606. // try to set tmp directoy into superglobals, ZF and other frameworks (PEAR) sometimes relies on that
  607. foreach (array('TMPDIR', 'TEMP', 'TMP', 'windir', 'SystemRoot') as $key) {
  608. $_ENV[$key] = PIMCORE_CACHE_DIRECTORY;
  609. $_SERVER[$key] = PIMCORE_CACHE_DIRECTORY;
  610. }
  611. // set custom view renderer
  612. $pimcoreViewHelper = new Pimcore_Controller_Action_Helper_ViewRenderer();
  613. Zend_Controller_Action_HelperBroker::addHelper($pimcoreViewHelper);
  614. }
  615. /**
  616. * switches pimcore into the admin mode - there you can access also unpublished elements, ....
  617. * @static
  618. * @return void
  619. */
  620. public static function setAdminMode () {
  621. self::$adminMode = true;
  622. }
  623. /**
  624. * switches back to the non admin mode, where unpublished elements are invisible
  625. * @static
  626. * @return void
  627. */
  628. public static function unsetAdminMode() {
  629. self::$adminMode = false;
  630. }
  631. /**
  632. * check if the process is currently in admin mode or not
  633. * @static
  634. * @return bool
  635. */
  636. public static function inAdmin () {
  637. if(self::$adminMode !== null) {
  638. return self::$adminMode;
  639. }
  640. return false;
  641. }
  642. /**
  643. * @return Zend_EventManager_EventManager
  644. */
  645. public static function getEventManager() {
  646. if(!self::$eventManager) {
  647. self::$eventManager = new Zend_EventManager_EventManager();
  648. }
  649. return self::$eventManager;
  650. }
  651. /**
  652. * Forces a garbage collection.
  653. * @static
  654. * @return void
  655. */
  656. public static function collectGarbage ($keepItems = array()) {
  657. // close mysql-connection
  658. Pimcore_Resource::close();
  659. $protectedItems = array(
  660. "Zend_Locale",
  661. "Zend_View_Helper_Placeholder_Registry",
  662. "Zend_View_Helper_Doctype",
  663. "Zend_Translate",
  664. "Zend_Navigation",
  665. "Pimcore_API_Plugin_Broker",
  666. "pimcore_tag_block_current",
  667. "pimcore_tag_block_numeration",
  668. "pimcore_config_system",
  669. "pimcore_admin_user",
  670. "pimcore_config_website",
  671. "pimcore_editmode",
  672. "pimcore_error_document",
  673. "pimcore_site",
  674. "Pimcore_Resource_Mysql"
  675. );
  676. if(is_array($keepItems) && count($keepItems) > 0) {
  677. $protectedItems = array_merge($protectedItems, $keepItems);
  678. }
  679. $registryBackup = array();
  680. foreach ($protectedItems as $item) {
  681. if(Zend_Registry::isRegistered($item)) {
  682. $registryBackup[$item] = Zend_Registry::get($item);
  683. }
  684. }
  685. Zend_Registry::_unsetInstance();
  686. foreach ($registryBackup as $key => $value) {
  687. Zend_Registry::set($key, $value);
  688. }
  689. Pimcore_Resource::reset();
  690. // force PHP garbage collector
  691. gc_enable();
  692. $collectedCycles = gc_collect_cycles();
  693. Logger::debug("garbage collection finished, collected cycles: " . $collectedCycles);
  694. }
  695. /**
  696. * this initiates the pimcore output-buffer, which is used to allow the registered shutdown-function
  697. * (created with register_shutdown_function) to run in the background without blocking the browser (loading indicator).
  698. * This is useful because the cache is written in the shutdown function and it takes sometimes a while to write the
  699. * max. 50 items into the cache (~ 1-10 secs depending on the backend and the data). Although all the content is
  700. * already arrived at the browser, he blocks the javascript execution (eg. jQuery's $(document).ready() ), because
  701. * the request is not finished or wasn't closed (sure the script is still running), what is really not necessary
  702. * This method is only called in Pimcore_Controller_Action_Frontend::init() to enable it only for frontend/website HTTP requests
  703. * - more infos see also self::outputBufferEnd()
  704. * @static
  705. * @return void
  706. */
  707. public static function outputBufferStart () {
  708. // only for HTTP(S)
  709. if(php_sapi_name() != "cli") {
  710. ob_start("Pimcore::outputBufferEnd");
  711. }
  712. }
  713. /**
  714. * if this method is called in self::shutdown() it forces the browser to close the connection an allows the
  715. * shutdown-function to run in the background
  716. * @static
  717. * @return string
  718. */
  719. public static function outputBufferEnd ($data) {
  720. $output = null;
  721. $contentEncoding = null;
  722. if(headers_sent()) {
  723. return $data;
  724. }
  725. header("Connection: close\r\n");
  726. // check for supported content-encodings
  727. if(strpos($_SERVER["HTTP_ACCEPT_ENCODING"], "gzip") !== false) {
  728. $contentEncoding = "gzip";
  729. }
  730. // only send this headers in the shutdown-function, so that it is also possible to get the contents of this buffer earlier without sending headers
  731. if(self::$inShutdown && !headers_sent() && !empty($data) && $contentEncoding) {
  732. ignore_user_abort(true);
  733. // find the content-type of the response
  734. $front = Zend_Controller_Front::getInstance();
  735. $a = $front->getResponse()->getHeaders();
  736. $b = array_merge(headers_list(), $front->getResponse()->getRawHeaders());
  737. $contentType = null;
  738. // first check headers in headers_list() because they overwrite all other headers => see SOAP controller
  739. foreach ($b as $header) {
  740. if(stripos($header, "content-type") !== false) {
  741. $parts = explode(":", $header);
  742. if(strtolower(trim($parts[0])) == "content-type") {
  743. $contentType = trim($parts[1]);
  744. break;
  745. }
  746. }
  747. }
  748. if(!$contentType) {
  749. foreach ($a as $header) {
  750. if(strtolower(trim($header["name"])) == "content-type") {
  751. $contentType = $header["value"];
  752. break;
  753. }
  754. }
  755. }
  756. // prepare the response to be sent (gzip or not)
  757. // do not add text/xml or a wildcard for text/* here because this causes problems with the SOAP server
  758. $gzipContentTypes = array("@text/html@i","@application/json@");
  759. $gzipIt = false;
  760. foreach ($gzipContentTypes as $type) {
  761. if(@preg_match($type, $contentType)) {
  762. $gzipIt = true;
  763. break;
  764. }
  765. }
  766. // gzip the contents and send connection close tthat the process can run in the background to finish
  767. // some tasks like writing the cache ...
  768. // using mb_strlen() because of PIMCORE-1509
  769. if($gzipIt) {
  770. $output = "\x1f\x8b\x08\x00\x00\x00\x00\x00".
  771. substr(gzcompress($data, 2), 0, -4).
  772. pack('V', crc32($data)). // packing the CRC and the strlen is still required
  773. pack('V', mb_strlen($data, "latin1")); // (although all modern browsers don't need it anymore) to work properly with google adwords check & co.
  774. header("Content-Encoding: $contentEncoding\r\n");
  775. }
  776. }
  777. // no gzip/deflate encoding
  778. if(!$output) {
  779. $output = $data;
  780. }
  781. if(strlen($output) > 0) {
  782. // check here if there is actually content, otherwise readfile() and similar functions are not working anymore
  783. header("Content-Length: " . mb_strlen($output, "latin1"));
  784. }
  785. header("X-Powered-By: pimcore");
  786. // return the data unchanged
  787. return $output;
  788. }
  789. /**
  790. * this method is called with register_shutdown_function() and writes all data queued into the cache
  791. * @static
  792. * @return void
  793. */
  794. public static function shutdown () {
  795. // set inShutdown to true so that the output-buffer knows that he is allowed to send the headers
  796. self::$inShutdown = true;
  797. // flush all custom output buffers
  798. while(@ob_end_flush());
  799. // flush everything
  800. flush();
  801. // clear tags scheduled for the shutdown
  802. Pimcore_Model_Cache::clearTagsOnShutdown();
  803. // write collected items to cache backend and remove the write lock
  804. Pimcore_Model_Cache::write();
  805. Pimcore_Model_Cache::removeWriteLock();
  806. // release all open locks from this process
  807. Tool_Lock::releaseAll();
  808. // disable logging - otherwise this will cause problems in the ongoing shutdown process (session write, __destruct(), ...)
  809. Logger::resetLoggers();
  810. }
  811. }