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

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 Pimcore\Model\DataObject;
  16. use Pimcore\Model\Document;
  17. use Symfony\Component\Dotenv\Dotenv;
  18. use Symfony\Component\ErrorHandler\Debug;
  19. use Symfony\Component\HttpFoundation\Request;
  20. use Symfony\Component\HttpKernel\KernelInterface;
  21. class Bootstrap
  22. {
  23. public static function startup()
  24. {
  25. self::setProjectRoot();
  26. self::bootstrap();
  27. $kernel = self::kernel();
  28. return $kernel;
  29. }
  30. /**
  31. * @return KernelInterface
  32. */
  33. public static function startupCli()
  34. {
  35. // ensure the cli arguments are set
  36. if (!isset($_SERVER['argv'])) {
  37. $_SERVER['argv'] = [];
  38. }
  39. self::setProjectRoot();
  40. self::bootstrap();
  41. $workingDirectory = getcwd();
  42. chdir(__DIR__);
  43. // init shell verbosity as 0 - this would normally be handled by the console application,
  44. // but as we boot the kernel early the kernel initializes this to 3 (verbose) by default
  45. putenv('SHELL_VERBOSITY=0');
  46. $_ENV['SHELL_VERBOSITY'] = 0;
  47. $_SERVER['SHELL_VERBOSITY'] = 0;
  48. /** @var \Pimcore\Kernel $kernel */
  49. $kernel = self::kernel();
  50. if (is_readable($workingDirectory)) {
  51. chdir($workingDirectory);
  52. }
  53. // activate inheritance for cli-scripts
  54. \Pimcore::unsetAdminMode();
  55. Document::setHideUnpublished(true);
  56. DataObject::setHideUnpublished(true);
  57. DataObject::setGetInheritedValues(true);
  58. DataObject\Localizedfield::setGetFallbackValues(true);
  59. // CLI has no memory/time limits
  60. @ini_set('memory_limit', '-1');
  61. @ini_set('max_execution_time', '-1');
  62. @ini_set('max_input_time', '-1');
  63. // Error reporting is enabled in CLI
  64. @ini_set('display_errors', 'On');
  65. @ini_set('display_startup_errors', 'On');
  66. // Pimcore\Console handles maintenance mode through the AbstractCommand
  67. $pimcoreConsole = (defined('PIMCORE_CONSOLE') && true === PIMCORE_CONSOLE);
  68. if (!$pimcoreConsole) {
  69. // skip if maintenance mode is on and the flag is not set
  70. if (\Pimcore\Tool\Admin::isInMaintenanceMode() && !in_array('--ignore-maintenance-mode', $_SERVER['argv'])) {
  71. die("in maintenance mode -> skip\nset the flag --ignore-maintenance-mode to force execution\n");
  72. }
  73. }
  74. return $kernel;
  75. }
  76. public static function setProjectRoot()
  77. {
  78. // this should already be defined at this point, but we include a fallback for backwards compatibility here
  79. if (!defined('PIMCORE_PROJECT_ROOT')) {
  80. define(
  81. 'PIMCORE_PROJECT_ROOT',
  82. $_SERVER['PIMCORE_PROJECT_ROOT'] ?? $_ENV['PIMCORE_PROJECT_ROOT'] ??
  83. $_SERVER['REDIRECT_PIMCORE_PROJECT_ROOT'] ?? $_ENV['REDIRECT_PIMCORE_PROJECT_ROOT'] ??
  84. realpath(__DIR__ . '/../../../..')
  85. );
  86. }
  87. }
  88. public static function bootstrap()
  89. {
  90. if (defined('PIMCORE_PROJECT_ROOT') && file_exists(PIMCORE_PROJECT_ROOT . '/vendor/autoload.php')) {
  91. // PIMCORE_PROJECT_ROOT is usually always set at this point (self::setProjectRoot()), so it makes sense to check this first
  92. $loader = include PIMCORE_PROJECT_ROOT . '/vendor/autoload.php';
  93. } elseif (file_exists(__DIR__ . '/../vendor/autoload.php')) {
  94. $loader = include __DIR__ . '/../vendor/autoload.php';
  95. } elseif (file_exists(__DIR__ . '/../../../../vendor/autoload.php')) {
  96. $loader = include __DIR__ . '/../../../../vendor/autoload.php';
  97. } else {
  98. throw new \Exception('Unable to locate autoloader! Pimcore project root not found or invalid, please set/check env variable PIMCORE_PROJECT_ROOT.');
  99. }
  100. self::defineConstants();
  101. /** @var \Composer\Autoload\ClassLoader $loader */
  102. \Pimcore::setAutoloader($loader);
  103. self::autoload();
  104. ini_set('error_log', PIMCORE_PHP_ERROR_LOG);
  105. ini_set('log_errors', '1');
  106. // load a startup file if it exists - this is a good place to preconfigure the system
  107. // before the kernel is loaded - e.g. to set trusted proxies on the request object
  108. $startupFile = PIMCORE_PROJECT_ROOT . '/config/pimcore/startup.php';
  109. if (file_exists($startupFile)) {
  110. include_once $startupFile;
  111. }
  112. if (false === in_array(\PHP_SAPI, ['cli', 'phpdbg', 'embed'], true)) {
  113. // see https://github.com/symfony/recipes/blob/master/symfony/framework-bundle/4.2/public/index.php#L15
  114. if ($trustedProxies = $_SERVER['TRUSTED_PROXIES'] ?? false) {
  115. Request::setTrustedProxies(explode(',', $trustedProxies), Request::HEADER_X_FORWARDED_FOR | Request::HEADER_X_FORWARDED_PORT | Request::HEADER_X_FORWARDED_PROTO);
  116. }
  117. if ($trustedHosts = $_SERVER['TRUSTED_HOSTS'] ?? false) {
  118. Request::setTrustedHosts([$trustedHosts]);
  119. }
  120. }
  121. }
  122. private static function prepareEnvVariables()
  123. {
  124. if (!($_SERVER['PIMCORE_SKIP_DOTENV_FILE'] ?? false)) {
  125. if (class_exists('Symfony\Component\Dotenv\Dotenv')) {
  126. (new Dotenv())->bootEnv(PIMCORE_PROJECT_ROOT . '/.env');
  127. } else {
  128. $_SERVER += $_ENV;
  129. }
  130. }
  131. }
  132. public static function defineConstants()
  133. {
  134. self::prepareEnvVariables();
  135. // load custom constants
  136. $customConstantsFile = PIMCORE_PROJECT_ROOT . '/config/pimcore/constants.php';
  137. if (file_exists($customConstantsFile)) {
  138. include_once $customConstantsFile;
  139. }
  140. $resolveConstant = function (string $name, $default, bool $define = true) {
  141. // return constant if defined
  142. if (defined($name)) {
  143. return constant($name);
  144. }
  145. $value = $_SERVER[$name] ?? $default;
  146. if ($define) {
  147. define($name, $value);
  148. }
  149. return $value;
  150. };
  151. // basic paths
  152. $resolveConstant('PIMCORE_COMPOSER_PATH', PIMCORE_PROJECT_ROOT . '/vendor');
  153. $resolveConstant('PIMCORE_COMPOSER_FILE_PATH', PIMCORE_PROJECT_ROOT);
  154. $resolveConstant('PIMCORE_PATH', realpath(__DIR__ . '/..'));
  155. $resolveConstant('PIMCORE_WEB_ROOT', PIMCORE_PROJECT_ROOT . '/public');
  156. $resolveConstant('PIMCORE_PRIVATE_VAR', PIMCORE_PROJECT_ROOT . '/var');
  157. // special directories for tests
  158. // test mode can bei either controlled by a constant or an env variable
  159. $testMode = (bool)$resolveConstant('PIMCORE_TEST', false, false);
  160. if ($testMode) {
  161. // override and initialize directories
  162. $resolveConstant('PIMCORE_CLASS_DIRECTORY', PIMCORE_PATH . '/tests/_output/var/classes');
  163. if (!defined('PIMCORE_TEST')) {
  164. define('PIMCORE_TEST', true);
  165. }
  166. }
  167. // paths relying on basic paths above
  168. $resolveConstant('PIMCORE_CUSTOM_CONFIGURATION_DIRECTORY', PIMCORE_PROJECT_ROOT . '/config/pimcore');
  169. $resolveConstant('PIMCORE_CUSTOM_CONFIGURATION_CLASS_DEFINITION_DIRECTORY', PIMCORE_CUSTOM_CONFIGURATION_DIRECTORY . '/classes');
  170. $resolveConstant('PIMCORE_CONFIGURATION_DIRECTORY', PIMCORE_PRIVATE_VAR . '/config');
  171. $resolveConstant('PIMCORE_LOG_DIRECTORY', PIMCORE_PRIVATE_VAR . '/log');
  172. $resolveConstant('PIMCORE_CACHE_DIRECTORY', PIMCORE_PRIVATE_VAR . '/cache/pimcore');
  173. $resolveConstant('PIMCORE_LOG_FILEOBJECT_DIRECTORY', PIMCORE_PRIVATE_VAR . '/application-logger');
  174. $resolveConstant('PIMCORE_SYMFONY_CACHE_DIRECTORY', PIMCORE_PRIVATE_VAR . '/cache');
  175. $resolveConstant('PIMCORE_CLASS_DIRECTORY', PIMCORE_PRIVATE_VAR . '/classes');
  176. $resolveConstant('PIMCORE_CLASS_DEFINITION_DIRECTORY', PIMCORE_CLASS_DIRECTORY);
  177. $resolveConstant('PIMCORE_CUSTOMLAYOUT_DIRECTORY', PIMCORE_CLASS_DEFINITION_DIRECTORY . '/customlayouts');
  178. $resolveConstant('PIMCORE_SYSTEM_TEMP_DIRECTORY', PIMCORE_PRIVATE_VAR . '/tmp');
  179. // configure PHP's error logging
  180. $resolveConstant('PIMCORE_PHP_ERROR_LOG', PIMCORE_LOG_DIRECTORY . '/php.log');
  181. $resolveConstant('PIMCORE_KERNEL_CLASS', '\App\Kernel');
  182. }
  183. private static function autoload()
  184. {
  185. $loader = \Pimcore::getAutoloader();
  186. // tell the autoloader where to find Pimcore's generated class stubs
  187. // this is primarily necessary for tests and custom class directories, which are not covered in composer.json
  188. $loader->addPsr4('Pimcore\\Model\\DataObject\\', PIMCORE_CLASS_DIRECTORY . '/DataObject');
  189. if (defined('PIMCORE_APP_BUNDLE_CLASS_FILE')) {
  190. require_once PIMCORE_APP_BUNDLE_CLASS_FILE;
  191. }
  192. }
  193. /**
  194. * @return KernelInterface
  195. */
  196. public static function kernel()
  197. {
  198. $environment = Config::getEnvironment();
  199. $debug = (bool) ($_SERVER['APP_DEBUG'] ?? false);
  200. if ($debug) {
  201. umask(0000);
  202. Debug::enable();
  203. @ini_set('display_errors', 'On');
  204. }
  205. if (defined('PIMCORE_KERNEL_CLASS')) {
  206. $kernelClass = PIMCORE_KERNEL_CLASS;
  207. } else {
  208. $kernelClass = '\App\Kernel';
  209. }
  210. if (!class_exists($kernelClass)) {
  211. throw new \InvalidArgumentException(sprintf('Defined Kernel Class %s not found', $kernelClass));
  212. }
  213. if (!is_subclass_of($kernelClass, Kernel::class)) {
  214. throw new \InvalidArgumentException(sprintf('Defined Kernel Class %s needs to extend the \Pimcore\Kernel Class', $kernelClass));
  215. }
  216. $kernel = new $kernelClass($environment, $debug);
  217. \Pimcore::setKernel($kernel);
  218. $kernel->boot();
  219. $conf = \Pimcore::getContainer()->getParameter('pimcore.config');
  220. if ($conf['general']['timezone']) {
  221. date_default_timezone_set($conf['general']['timezone']);
  222. }
  223. return $kernel;
  224. }
  225. }