vendor/pimcore/pimcore/lib/Bootstrap.php line 352

Open in your IDE?
  1. <?php
  2. /**
  3.  * Pimcore
  4.  *
  5.  * This source file is available under two different licenses:
  6.  * - GNU General Public License version 3 (GPLv3)
  7.  * - Pimcore Enterprise License (PEL)
  8.  * Full copyright and license information is available in
  9.  * LICENSE.md which is distributed with this source code.
  10.  *
  11.  * @copyright  Copyright (c) Pimcore GmbH (http://www.pimcore.org)
  12.  * @license    http://www.pimcore.org/license     GPLv3 and PEL
  13.  */
  14. namespace Pimcore;
  15. use Doctrine\Common\Annotations\AnnotationReader;
  16. use Pimcore\Model\DataObject;
  17. use Pimcore\Model\Document;
  18. use Symfony\Component\Console\Input\ArgvInput;
  19. use Symfony\Component\Debug\Debug;
  20. use Symfony\Component\Dotenv\Dotenv;
  21. use Symfony\Component\HttpFoundation\Request;
  22. use Symfony\Component\HttpKernel\KernelInterface;
  23. class Bootstrap
  24. {
  25.     public static function startup()
  26.     {
  27.         self::setProjectRoot();
  28.         self::bootstrap();
  29.         $kernel self::kernel();
  30.         return $kernel;
  31.     }
  32.     /**
  33.      * @return KernelInterface
  34.      */
  35.     public static function startupCli()
  36.     {
  37.         // ensure the cli arguments are set
  38.         if (!isset($_SERVER['argv'])) {
  39.             $_SERVER['argv'] = [];
  40.         }
  41.         self::setProjectRoot();
  42.         // determines if we're in Pimcore\Console mode
  43.         $pimcoreConsole = (defined('PIMCORE_CONSOLE') && true === PIMCORE_CONSOLE);
  44.         if ($pimcoreConsole) {
  45.             $input = new ArgvInput();
  46.             if (!defined('PIMCORE_DEBUG') && $input->hasParameterOption(['--no-debug'''])) {
  47.                 /**
  48.                  * @deprecated
  49.                  */
  50.                 define('PIMCORE_DEBUG'false);
  51.                 \Pimcore::setDebugMode(false);
  52.             }
  53.         }
  54.         self::bootstrap();
  55.         $workingDirectory getcwd();
  56.         chdir(__DIR__);
  57.         // init shell verbosity as 0 - this would normally be handled by the console application,
  58.         // but as we boot the kernel early the kernel initializes this to 3 (verbose) by default
  59.         putenv('SHELL_VERBOSITY=0');
  60.         $_ENV['SHELL_VERBOSITY'] = 0;
  61.         $_SERVER['SHELL_VERBOSITY'] = 0;
  62.         /** @var \Pimcore\Kernel $kernel */
  63.         $kernel self::kernel();
  64.         chdir($workingDirectory);
  65.         // activate inheritance for cli-scripts
  66.         \Pimcore::unsetAdminMode();
  67.         Document::setHideUnpublished(true);
  68.         DataObject\AbstractObject::setHideUnpublished(true);
  69.         DataObject\AbstractObject::setGetInheritedValues(true);
  70.         DataObject\Localizedfield::setGetFallbackValues(true);
  71.         // CLI has no memory/time limits
  72.         @ini_set('memory_limit', -1);
  73.         @ini_set('max_execution_time', -1);
  74.         @ini_set('max_input_time', -1);
  75.         // Error reporting is enabled in CLI
  76.         @ini_set('display_errors''On');
  77.         @ini_set('display_startup_errors''On');
  78.         error_reporting(E_ALL & ~E_NOTICE & ~E_STRICT);
  79.         // Pimcore\Console handles maintenance mode through the AbstractCommand
  80.         if (!$pimcoreConsole) {
  81.             // skip if maintenance mode is on and the flag is not set
  82.             if (\Pimcore\Tool\Admin::isInMaintenanceMode() && !in_array('--ignore-maintenance-mode'$_SERVER['argv'])) {
  83.                 die("in maintenance mode -> skip\nset the flag --ignore-maintenance-mode to force execution \n");
  84.             }
  85.         }
  86.         return $kernel;
  87.     }
  88.     public static function setProjectRoot()
  89.     {
  90.         // this should already be defined at this point, but we include a fallback here
  91.         // fot backwards compatibility
  92.         if (!defined('PIMCORE_PROJECT_ROOT')) {
  93.             define(
  94.                 'PIMCORE_PROJECT_ROOT',
  95.                 $_SERVER['PIMCORE_PROJECT_ROOT'] ?? $_ENV['PIMCORE_PROJECT_ROOT'] ??
  96.                 $_SERVER['REDIRECT_PIMCORE_PROJECT_ROOT'] ?? $_ENV['REDIRECT_PIMCORE_PROJECT_ROOT'] ??
  97.                 realpath(__DIR__ '/../../../..')
  98.             );
  99.         }
  100.     }
  101.     public static function bootstrap()
  102.     {
  103.         error_reporting(E_ALL & ~E_NOTICE & ~E_STRICT);
  104.         /** @var $loader \Composer\Autoload\ClassLoader */
  105.         if (file_exists(__DIR__ '/../vendor/autoload.php')) {
  106.             $loader = include __DIR__ '/../vendor/autoload.php';
  107.         } else {
  108.             $loader = include __DIR__ '/../../../../vendor/autoload.php';
  109.         }
  110.         Config::initDebugDevMode();
  111.         self::defineConstants();
  112.         error_reporting(PIMCORE_PHP_ERROR_REPORTING);
  113.         \Pimcore::setAutoloader($loader);
  114.         self::autoload();
  115.         ini_set('error_log'PIMCORE_PHP_ERROR_LOG);
  116.         ini_set('log_errors''1');
  117.         // load a startup file if it exists - this is a good place to preconfigure the system
  118.         // before the kernel is loaded - e.g. to set trusted proxies on the request object
  119.         $startupFile PIMCORE_PROJECT_ROOT '/app/startup.php';
  120.         if (file_exists($startupFile)) {
  121.             include_once $startupFile;
  122.         }
  123.         if (false === in_array(\PHP_SAPI, ['cli''phpdbg''embed'], true)) {
  124.             // see https://github.com/symfony/recipes/blob/master/symfony/framework-bundle/4.2/public/index.php#L15
  125.             if ($trustedProxies $_SERVER['TRUSTED_PROXIES'] ?? false) {
  126.                 Request::setTrustedProxies(explode(','$trustedProxies),
  127.                     Request::HEADER_X_FORWARDED_ALL Request::HEADER_X_FORWARDED_HOST);
  128.             }
  129.             if ($trustedHosts $_SERVER['TRUSTED_HOSTS'] ?? false) {
  130.                 Request::setTrustedHosts([$trustedHosts]);
  131.             }
  132.         }
  133.     }
  134.     /**
  135.      * @deprecated 7.0.0 Typo in name; use Bootstrap::bootstrap() instead
  136.      * @see Bootstrap::bootstrap()
  137.      */
  138.     public static function boostrap()
  139.     {
  140.         self::bootstrap();
  141.     }
  142.     protected static function prepareEnvVariables()
  143.     {
  144.         // load .env file if available
  145.         $dotEnvFile PIMCORE_PROJECT_ROOT '/.env';
  146.         if (is_array($env = @include PIMCORE_PROJECT_ROOT .'/.env.local.php')) {
  147.             foreach ($env as $k => $v) {
  148.                 $_ENV[$k] = $_ENV[$k] ?? (isset($_SERVER[$k]) && !== strpos($k'HTTP_') ? $_SERVER[$k] : $v);
  149.             }
  150.         } elseif (file_exists($dotEnvFile)) {
  151.             // load all the .env files
  152.             $dotEnv = new Dotenv();
  153.             if (method_exists($dotEnv'loadEnv')) {
  154.                 // Symfony => 4.2 style
  155.                 $envVarName 'APP_ENV';
  156.                 foreach (['PIMCORE_ENVIRONMENT''SYMFONY_ENV''APP_ENV'] as $varName) {
  157.                     if (isset($_SERVER[$varName]) || isset($_ENV[$varName])) {
  158.                         $envVarName $varName;
  159.                         break;
  160.                     }
  161.                     if (isset($_SERVER['REDIRECT_' $varName]) || isset($_ENV['REDIRECT_' $varName])) {
  162.                         $envVarName 'REDIRECT_' $varName;
  163.                         break;
  164.                     }
  165.                 }
  166.                 $defaultEnvironment Config::getEnvironmentConfig()->getDefaultEnvironment();
  167.                 $dotEnv->loadEnv($dotEnvFile$envVarName$defaultEnvironment);
  168.             } else {
  169.                 $dotEnv->load($dotEnvFile);
  170.             }
  171.         }
  172.         $_ENV['PIMCORE_ENVIRONMENT'] = $_ENV['SYMFONY_ENV'] = $_ENV['APP_ENV'] = Config::getEnvironment();
  173.         $_SERVER += $_ENV;
  174.     }
  175.     public static function defineConstants()
  176.     {
  177.         // load custom constants
  178.         $customConstantsFile PIMCORE_PROJECT_ROOT '/app/constants.php';
  179.         if (file_exists($customConstantsFile)) {
  180.             include_once $customConstantsFile;
  181.         }
  182.         self::prepareEnvVariables();
  183.         $resolveConstant = function (string $name$defaultbool $define true) {
  184.             // return constant if defined
  185.             if (defined($name)) {
  186.                 return constant($name);
  187.             }
  188.             // load env var with fallback to REDIRECT_ prefixed env var
  189.             $value $_SERVER[$name] ?? $_SERVER['REDIRECT_' $name] ?? $default;
  190.             if ($define) {
  191.                 define($name$value);
  192.             }
  193.             return $value;
  194.         };
  195.         // basic paths
  196.         $resolveConstant('PIMCORE_COMPOSER_PATH'PIMCORE_PROJECT_ROOT '/vendor');
  197.         $resolveConstant('PIMCORE_COMPOSER_FILE_PATH'PIMCORE_PROJECT_ROOT);
  198.         $resolveConstant('PIMCORE_PATH'realpath(__DIR__ '/..'));
  199.         $resolveConstant('PIMCORE_APP_ROOT'PIMCORE_PROJECT_ROOT '/app');
  200.         $resolveConstant('PIMCORE_WEB_ROOT'PIMCORE_PROJECT_ROOT '/web');
  201.         $resolveConstant('PIMCORE_PRIVATE_VAR'PIMCORE_PROJECT_ROOT '/var');
  202.         $resolveConstant('PIMCORE_PUBLIC_VAR'PIMCORE_WEB_ROOT '/var');
  203.         // special directories for tests
  204.         // test mode can bei either controlled by a constant or an env variable
  205.         $testMode = (bool)$resolveConstant('PIMCORE_TEST'falsefalse);
  206.         if ($testMode) {
  207.             // override and initialize directories
  208.             $resolveConstant('PIMCORE_CLASS_DIRECTORY'PIMCORE_PATH '/tests/_output/var/classes');
  209.             $resolveConstant('PIMCORE_ASSET_DIRECTORY'PIMCORE_WEB_ROOT '/var/tests/assets');
  210.             if (!defined('PIMCORE_TEST')) {
  211.                 define('PIMCORE_TEST'true);
  212.             }
  213.         }
  214.         // paths relying on basic paths above
  215.         $resolveConstant('PIMCORE_CUSTOM_CONFIGURATION_DIRECTORY'PIMCORE_APP_ROOT '/config/pimcore');
  216.         $resolveConstant('PIMCORE_CONFIGURATION_DIRECTORY'PIMCORE_PRIVATE_VAR '/config');
  217.         $resolveConstant('PIMCORE_ASSET_DIRECTORY'PIMCORE_PUBLIC_VAR '/assets');
  218.         $resolveConstant('PIMCORE_VERSION_DIRECTORY'PIMCORE_PRIVATE_VAR '/versions');
  219.         $resolveConstant('PIMCORE_LOG_DIRECTORY'PIMCORE_PRIVATE_VAR '/logs');
  220.         $resolveConstant('PIMCORE_LOG_FILEOBJECT_DIRECTORY'PIMCORE_PRIVATE_VAR '/application-logger');
  221.         $resolveConstant('PIMCORE_TEMPORARY_DIRECTORY'PIMCORE_PUBLIC_VAR '/tmp');
  222.         $resolveConstant('PIMCORE_CACHE_DIRECTORY'PIMCORE_PRIVATE_VAR '/cache/pimcore');
  223.         $resolveConstant('PIMCORE_SYMFONY_CACHE_DIRECTORY'PIMCORE_PRIVATE_VAR '/cache');
  224.         $resolveConstant('PIMCORE_CLASS_DIRECTORY'PIMCORE_PRIVATE_VAR '/classes');
  225.         $resolveConstant('PIMCORE_CUSTOMLAYOUT_DIRECTORY'PIMCORE_CLASS_DIRECTORY '/customlayouts');
  226.         $resolveConstant('PIMCORE_RECYCLEBIN_DIRECTORY'PIMCORE_PRIVATE_VAR '/recyclebin');
  227.         $resolveConstant('PIMCORE_SYSTEM_TEMP_DIRECTORY'PIMCORE_PRIVATE_VAR '/tmp');
  228.         $resolveConstant('PIMCORE_LOG_MAIL_PERMANENT'PIMCORE_PRIVATE_VAR '/email');
  229.         $resolveConstant('PIMCORE_USERIMAGE_DIRECTORY'PIMCORE_PRIVATE_VAR '/user-image');
  230.         // configure PHP's error logging
  231.         $resolveConstant('PIMCORE_PHP_ERROR_REPORTING'E_ALL & ~E_NOTICE & ~E_STRICT);
  232.         $resolveConstant('PIMCORE_PHP_ERROR_LOG'PIMCORE_LOG_DIRECTORY '/php.log');
  233.         $resolveConstant('PIMCORE_KERNEL_CLASS''\AppKernel');
  234.         $kernelDebug $resolveConstant('PIMCORE_KERNEL_DEBUG'nullfalse);
  235.         if ($kernelDebug === 'true') {
  236.             $kernelDebug true;
  237.         } elseif ($kernelDebug === 'false') {
  238.             $kernelDebug false;
  239.         } else {
  240.             $kernelDebug null;
  241.         }
  242.         define('PIMCORE_KERNEL_DEBUG'$kernelDebug);
  243.     }
  244.     public static function autoload()
  245.     {
  246.         $loader = \Pimcore::getAutoloader();
  247.         // tell the autoloader where to find Pimcore's generated class stubs
  248.         // this is primarily necessary for tests and custom class directories, which are not covered in composer.json
  249.         $loader->addPsr4('Pimcore\\Model\\DataObject\\'PIMCORE_CLASS_DIRECTORY '/DataObject');
  250.         // ignore apiDoc params (see http://apidocjs.com/) as we use apiDoc in webservice
  251.         $apiDocAnnotations = [
  252.             'api''apiDefine',
  253.             'apiDeprecated''apiDescription''apiError',  'apiErrorExample''apiExample''apiGroup''apiHeader',
  254.             'apiHeaderExample''apiIgnore''apiName''apiParam''apiParamExample''apiPermission''apiSampleRequest',
  255.             'apiSuccess''apiSuccessExample''apiUse''apiVersion',
  256.         ];
  257.         foreach ($apiDocAnnotations as $apiDocAnnotation) {
  258.             AnnotationReader::addGlobalIgnoredName($apiDocAnnotation);
  259.         }
  260.         if (defined('PIMCORE_APP_BUNDLE_CLASS_FILE')) {
  261.             require_once PIMCORE_APP_BUNDLE_CLASS_FILE;
  262.         }
  263.     }
  264.     /**
  265.      * @return KernelInterface
  266.      */
  267.     public static function kernel()
  268.     {
  269.         $environment Config::getEnvironment();
  270.         $debug Config::getEnvironmentConfig()->activatesKernelDebugMode($environment);
  271.         if (isset($_SERVER['APP_DEBUG'])) {
  272.             $_SERVER['APP_DEBUG'] = $_ENV['APP_DEBUG'] = (int)$_SERVER['APP_DEBUG'] || filter_var($_SERVER['APP_DEBUG'],
  273.                 FILTER_VALIDATE_BOOLEAN) ? '1' '0';
  274.         }
  275.         $envDebug PIMCORE_KERNEL_DEBUG ?? $_SERVER['APP_DEBUG'] ?? null;
  276.         if (null !== $envDebug) {
  277.             $debug $envDebug;
  278.         }
  279.         if ($debug) {
  280.             Debug::enable();
  281.             @ini_set('display_errors''On');
  282.         }
  283.         if (defined('PIMCORE_KERNEL_CLASS')) {
  284.             $kernelClass PIMCORE_KERNEL_CLASS;
  285.         } else {
  286.             $kernelClass '\AppKernel';
  287.         }
  288.         if (!class_exists($kernelClass)) {
  289.             throw new \InvalidArgumentException(sprintf('Defined Kernel Class %s not found'$kernelClass));
  290.         }
  291.         if (!is_subclass_of($kernelClassKernel::class)) {
  292.             throw new \InvalidArgumentException(sprintf('Defined Kernel Class %s needs to extend the \Pimcore\Kernel Class'$kernelClass));
  293.         }
  294.         $kernel = new $kernelClass($environment$debug);
  295.         \Pimcore::setKernel($kernel);
  296.         $kernel->boot();
  297.         $conf = \Pimcore::getContainer()->getParameter('pimcore.config');
  298.         if (isset($conf['general']['timezone']) && !empty($conf['general']['timezone'])) {
  299.             date_default_timezone_set($conf['general']['timezone']);
  300.         }
  301.         return $kernel;
  302.     }
  303. }