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

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 Commercial License (PCL)
  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 PCL
  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::setHideUnpublished(true);
  69.         DataObject::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.         // Pimcore\Console handles maintenance mode through the AbstractCommand
  79.         if (!$pimcoreConsole) {
  80.             // skip if maintenance mode is on and the flag is not set
  81.             if (\Pimcore\Tool\Admin::isInMaintenanceMode() && !in_array('--ignore-maintenance-mode'$_SERVER['argv'])) {
  82.                 die("in maintenance mode -> skip\nset the flag --ignore-maintenance-mode to force execution \n");
  83.             }
  84.         }
  85.         return $kernel;
  86.     }
  87.     public static function setProjectRoot()
  88.     {
  89.         // this should already be defined at this point, but we include a fallback for backwards compatibility here
  90.         if (!defined('PIMCORE_PROJECT_ROOT')) {
  91.             define(
  92.                 'PIMCORE_PROJECT_ROOT',
  93.                 $_SERVER['PIMCORE_PROJECT_ROOT'] ?? $_ENV['PIMCORE_PROJECT_ROOT'] ??
  94.                 $_SERVER['REDIRECT_PIMCORE_PROJECT_ROOT'] ?? $_ENV['REDIRECT_PIMCORE_PROJECT_ROOT'] ??
  95.                 realpath(__DIR__ '/../../../..')
  96.             );
  97.         }
  98.     }
  99.     public static function bootstrap()
  100.     {
  101.         if (defined('PIMCORE_PROJECT_ROOT') && file_exists(PIMCORE_PROJECT_ROOT '/vendor/autoload.php')) {
  102.             // PIMCORE_PROJECT_ROOT is usually always set at this point (self::setProjectRoot()), so it makes sense to check this first
  103.             $loader = include PIMCORE_PROJECT_ROOT '/vendor/autoload.php';
  104.         } elseif (file_exists(__DIR__ '/../vendor/autoload.php')) {
  105.             $loader = include __DIR__ '/../vendor/autoload.php';
  106.         } elseif (file_exists(__DIR__ '/../../../../vendor/autoload.php')) {
  107.             $loader = include __DIR__ '/../../../../vendor/autoload.php';
  108.         } else {
  109.             throw new \Exception('Unable to locate autoloader! Pimcore project root not found or invalid, please set/check env variable PIMCORE_PROJECT_ROOT.');
  110.         }
  111.         Config::initDebugDevMode();
  112.         self::defineConstants();
  113.         error_reporting(PIMCORE_PHP_ERROR_REPORTING);
  114.         /** @var \Composer\Autoload\ClassLoader $loader */
  115.         \Pimcore::setAutoloader($loader);
  116.         self::autoload();
  117.         ini_set('error_log'PIMCORE_PHP_ERROR_LOG);
  118.         ini_set('log_errors''1');
  119.         // load a startup file if it exists - this is a good place to preconfigure the system
  120.         // before the kernel is loaded - e.g. to set trusted proxies on the request object
  121.         $startupFile PIMCORE_PROJECT_ROOT '/app/startup.php';
  122.         if (file_exists($startupFile)) {
  123.             include_once $startupFile;
  124.         }
  125.         if (false === in_array(\PHP_SAPI, ['cli''phpdbg''embed'], true)) {
  126.             // see https://github.com/symfony/recipes/blob/master/symfony/framework-bundle/4.2/public/index.php#L15
  127.             if ($trustedProxies $_SERVER['TRUSTED_PROXIES'] ?? false) {
  128.                 Request::setTrustedProxies(explode(','$trustedProxies),
  129.                     Request::HEADER_X_FORWARDED_ALL Request::HEADER_X_FORWARDED_HOST);
  130.             }
  131.             if ($trustedHosts $_SERVER['TRUSTED_HOSTS'] ?? false) {
  132.                 Request::setTrustedHosts([$trustedHosts]);
  133.             }
  134.         }
  135.     }
  136.     /**
  137.      * @deprecated Pimcore 10 Typo in name; use Bootstrap::bootstrap() instead
  138.      * @see Bootstrap::bootstrap()
  139.      */
  140.     public static function boostrap()
  141.     {
  142.         self::bootstrap();
  143.     }
  144.     protected static function prepareEnvVariables()
  145.     {
  146.         // load .env file if available
  147.         $dotEnvFile PIMCORE_PROJECT_ROOT '/.env';
  148.         $dotEnvLocalPhpFile PIMCORE_PROJECT_ROOT .'/.env.local.php';
  149.         if (file_exists($dotEnvLocalPhpFile) && is_array($env = include $dotEnvLocalPhpFile)) {
  150.             foreach ($env as $k => $v) {
  151.                 $_ENV[$k] = $_ENV[$k] ?? (isset($_SERVER[$k]) && !== strpos($k'HTTP_') ? $_SERVER[$k] : $v);
  152.             }
  153.         } elseif (file_exists($dotEnvFile)) {
  154.             // load all the .env files
  155.             $dotEnv = new Dotenv();
  156.             if (method_exists($dotEnv'loadEnv')) {
  157.                 // Symfony => 4.2 style
  158.                 $envVarName 'APP_ENV';
  159.                 foreach (['PIMCORE_ENVIRONMENT''SYMFONY_ENV''APP_ENV'] as $varName) {
  160.                     if (isset($_SERVER[$varName]) || isset($_ENV[$varName])) {
  161.                         $envVarName $varName;
  162.                         break;
  163.                     }
  164.                     if (isset($_SERVER['REDIRECT_' $varName]) || isset($_ENV['REDIRECT_' $varName])) {
  165.                         $envVarName 'REDIRECT_' $varName;
  166.                         break;
  167.                     }
  168.                 }
  169.                 $defaultEnvironment Config::getEnvironmentConfig()->getDefaultEnvironment();
  170.                 $dotEnv->loadEnv($dotEnvFile$envVarName$defaultEnvironment);
  171.             } else {
  172.                 $dotEnv->load($dotEnvFile);
  173.             }
  174.         }
  175.         $_ENV['PIMCORE_ENVIRONMENT'] = $_ENV['SYMFONY_ENV'] = $_ENV['APP_ENV'] = Config::getEnvironment();
  176.         $_SERVER += $_ENV;
  177.     }
  178.     public static function defineConstants()
  179.     {
  180.         self::prepareEnvVariables();
  181.         // load custom constants
  182.         $customConstantsFile PIMCORE_PROJECT_ROOT '/app/constants.php';
  183.         if (file_exists($customConstantsFile)) {
  184.             include_once $customConstantsFile;
  185.         }
  186.         $resolveConstant = function (string $name$defaultbool $define true) {
  187.             // return constant if defined
  188.             if (defined($name)) {
  189.                 return constant($name);
  190.             }
  191.             // load env var with fallback to REDIRECT_ prefixed env var
  192.             $value $_SERVER[$name] ?? $_SERVER['REDIRECT_' $name] ?? $default;
  193.             if ($define) {
  194.                 define($name$value);
  195.             }
  196.             return $value;
  197.         };
  198.         // basic paths
  199.         $resolveConstant('PIMCORE_COMPOSER_PATH'PIMCORE_PROJECT_ROOT '/vendor');
  200.         $resolveConstant('PIMCORE_COMPOSER_FILE_PATH'PIMCORE_PROJECT_ROOT);
  201.         $resolveConstant('PIMCORE_PATH'realpath(__DIR__ '/..'));
  202.         $resolveConstant('PIMCORE_APP_ROOT'PIMCORE_PROJECT_ROOT '/app');
  203.         $resolveConstant('PIMCORE_WEB_ROOT'PIMCORE_PROJECT_ROOT '/web');
  204.         $resolveConstant('PIMCORE_PRIVATE_VAR'PIMCORE_PROJECT_ROOT '/var');
  205.         $resolveConstant('PIMCORE_PUBLIC_VAR'PIMCORE_WEB_ROOT '/var');
  206.         // special directories for tests
  207.         // test mode can bei either controlled by a constant or an env variable
  208.         $testMode = (bool)$resolveConstant('PIMCORE_TEST'falsefalse);
  209.         if ($testMode) {
  210.             // override and initialize directories
  211.             $resolveConstant('PIMCORE_CLASS_DIRECTORY'PIMCORE_PATH '/tests/_output/var/classes');
  212.             $resolveConstant('PIMCORE_ASSET_DIRECTORY'PIMCORE_WEB_ROOT '/var/tests/assets');
  213.             if (!defined('PIMCORE_TEST')) {
  214.                 define('PIMCORE_TEST'true);
  215.             }
  216.         }
  217.         // paths relying on basic paths above
  218.         $resolveConstant('PIMCORE_CUSTOM_CONFIGURATION_DIRECTORY'PIMCORE_APP_ROOT '/config/pimcore');
  219.         $resolveConstant('PIMCORE_CONFIGURATION_DIRECTORY'PIMCORE_PRIVATE_VAR '/config');
  220.         $resolveConstant('PIMCORE_ASSET_DIRECTORY'PIMCORE_PUBLIC_VAR '/assets');
  221.         $resolveConstant('PIMCORE_VERSION_DIRECTORY'PIMCORE_PRIVATE_VAR '/versions');
  222.         $resolveConstant('PIMCORE_LOG_DIRECTORY'PIMCORE_PRIVATE_VAR '/logs');
  223.         $resolveConstant('PIMCORE_LOG_FILEOBJECT_DIRECTORY'PIMCORE_PRIVATE_VAR '/application-logger');
  224.         $resolveConstant('PIMCORE_TEMPORARY_DIRECTORY'PIMCORE_PUBLIC_VAR '/tmp');
  225.         $resolveConstant('PIMCORE_CACHE_DIRECTORY'PIMCORE_PRIVATE_VAR '/cache/pimcore');
  226.         $resolveConstant('PIMCORE_SYMFONY_CACHE_DIRECTORY'PIMCORE_PRIVATE_VAR '/cache');
  227.         $resolveConstant('PIMCORE_CLASS_DIRECTORY'PIMCORE_PRIVATE_VAR '/classes');
  228.         $resolveConstant('PIMCORE_CUSTOMLAYOUT_DIRECTORY'PIMCORE_CLASS_DIRECTORY '/customlayouts');
  229.         $resolveConstant('PIMCORE_RECYCLEBIN_DIRECTORY'PIMCORE_PRIVATE_VAR '/recyclebin');
  230.         $resolveConstant('PIMCORE_SYSTEM_TEMP_DIRECTORY'PIMCORE_PRIVATE_VAR '/tmp');
  231.         $resolveConstant('PIMCORE_LOG_MAIL_PERMANENT'PIMCORE_PRIVATE_VAR '/email');
  232.         $resolveConstant('PIMCORE_USERIMAGE_DIRECTORY'PIMCORE_PRIVATE_VAR '/user-image');
  233.         // configure PHP's error logging
  234.         $resolveConstant('PIMCORE_PHP_ERROR_REPORTING'E_ALL & ~E_NOTICE & ~E_STRICT);
  235.         $resolveConstant('PIMCORE_PHP_ERROR_LOG'PIMCORE_LOG_DIRECTORY '/php.log');
  236.         $resolveConstant('PIMCORE_KERNEL_CLASS''\AppKernel');
  237.         $kernelDebug $resolveConstant('PIMCORE_KERNEL_DEBUG'nullfalse);
  238.         if ($kernelDebug === 'true') {
  239.             $kernelDebug true;
  240.         } elseif ($kernelDebug === 'false') {
  241.             $kernelDebug false;
  242.         } else {
  243.             $kernelDebug null;
  244.         }
  245.         /**
  246.          * @deprecated Will be removed in Pimcore 10
  247.          */
  248.         define('PIMCORE_KERNEL_DEBUG'$kernelDebug);
  249.     }
  250.     public static function autoload()
  251.     {
  252.         $loader = \Pimcore::getAutoloader();
  253.         // tell the autoloader where to find Pimcore's generated class stubs
  254.         // this is primarily necessary for tests and custom class directories, which are not covered in composer.json
  255.         $loader->addPsr4('Pimcore\\Model\\DataObject\\'PIMCORE_CLASS_DIRECTORY '/DataObject');
  256.         // ignore apiDoc params (see http://apidocjs.com/) as we use apiDoc in webservice
  257.         $apiDocAnnotations = [
  258.             'api''apiDefine',
  259.             'apiDeprecated''apiDescription''apiError',  'apiErrorExample''apiExample''apiGroup''apiHeader',
  260.             'apiHeaderExample''apiIgnore''apiName''apiParam''apiParamExample''apiPermission''apiSampleRequest',
  261.             'apiSuccess''apiSuccessExample''apiUse''apiVersion',
  262.         ];
  263.         foreach ($apiDocAnnotations as $apiDocAnnotation) {
  264.             AnnotationReader::addGlobalIgnoredName($apiDocAnnotation);
  265.         }
  266.         if (defined('PIMCORE_APP_BUNDLE_CLASS_FILE')) {
  267.             require_once PIMCORE_APP_BUNDLE_CLASS_FILE;
  268.         }
  269.     }
  270.     /**
  271.      * @return KernelInterface
  272.      */
  273.     public static function kernel()
  274.     {
  275.         $environment Config::getEnvironment();
  276.         $debug Config::getEnvironmentConfig()->activatesKernelDebugMode($environment);
  277.         if (isset($_SERVER['APP_DEBUG'])) {
  278.             $_SERVER['APP_DEBUG'] = $_ENV['APP_DEBUG'] = (int)$_SERVER['APP_DEBUG'] || filter_var($_SERVER['APP_DEBUG'],
  279.                 FILTER_VALIDATE_BOOLEAN) ? '1' '0';
  280.         }
  281.         $envDebug PIMCORE_KERNEL_DEBUG ?? $_SERVER['APP_DEBUG'] ?? null;
  282.         if (null !== $envDebug) {
  283.             $debug $envDebug;
  284.         }
  285.         if ($debug) {
  286.             Debug::enable(PIMCORE_PHP_ERROR_REPORTING);
  287.             @ini_set('display_errors''On');
  288.         }
  289.         if (defined('PIMCORE_KERNEL_CLASS')) {
  290.             $kernelClass PIMCORE_KERNEL_CLASS;
  291.         } else {
  292.             $kernelClass '\AppKernel';
  293.         }
  294.         if (!class_exists($kernelClass)) {
  295.             throw new \InvalidArgumentException(sprintf('Defined Kernel Class %s not found'$kernelClass));
  296.         }
  297.         if (!is_subclass_of($kernelClassKernel::class)) {
  298.             throw new \InvalidArgumentException(sprintf('Defined Kernel Class %s needs to extend the \Pimcore\Kernel Class'$kernelClass));
  299.         }
  300.         $kernel = new $kernelClass($environment$debug);
  301.         \Pimcore::setKernel($kernel);
  302.         $kernel->boot();
  303.         $conf = \Pimcore::getContainer()->getParameter('pimcore.config');
  304.         if (isset($conf['general']['timezone']) && !empty($conf['general']['timezone'])) {
  305.             date_default_timezone_set($conf['general']['timezone']);
  306.         }
  307.         return $kernel;
  308.     }
  309. }