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