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

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