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

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),
  116. Request::HEADER_X_FORWARDED_ALL ^ Request::HEADER_X_FORWARDED_HOST);
  117. }
  118. if ($trustedHosts = $_SERVER['TRUSTED_HOSTS'] ?? false) {
  119. Request::setTrustedHosts([$trustedHosts]);
  120. }
  121. }
  122. }
  123. private static function prepareEnvVariables()
  124. {
  125. (new Dotenv())->bootEnv(PIMCORE_PROJECT_ROOT .'/.env');
  126. }
  127. public static function defineConstants()
  128. {
  129. self::prepareEnvVariables();
  130. // load custom constants
  131. $customConstantsFile = PIMCORE_PROJECT_ROOT . '/config/pimcore/constants.php';
  132. if (file_exists($customConstantsFile)) {
  133. include_once $customConstantsFile;
  134. }
  135. $resolveConstant = function (string $name, $default, bool $define = true) {
  136. // return constant if defined
  137. if (defined($name)) {
  138. return constant($name);
  139. }
  140. $value = $_SERVER[$name] ?? $default;
  141. if ($define) {
  142. define($name, $value);
  143. }
  144. return $value;
  145. };
  146. // basic paths
  147. $resolveConstant('PIMCORE_COMPOSER_PATH', PIMCORE_PROJECT_ROOT . '/vendor');
  148. $resolveConstant('PIMCORE_COMPOSER_FILE_PATH', PIMCORE_PROJECT_ROOT);
  149. $resolveConstant('PIMCORE_PATH', realpath(__DIR__ . '/..'));
  150. $resolveConstant('PIMCORE_WEB_ROOT', PIMCORE_PROJECT_ROOT . '/public');
  151. $resolveConstant('PIMCORE_PRIVATE_VAR', PIMCORE_PROJECT_ROOT . '/var');
  152. // special directories for tests
  153. // test mode can bei either controlled by a constant or an env variable
  154. $testMode = (bool)$resolveConstant('PIMCORE_TEST', false, false);
  155. if ($testMode) {
  156. // override and initialize directories
  157. $resolveConstant('PIMCORE_CLASS_DIRECTORY', PIMCORE_PATH . '/tests/_output/var/classes');
  158. if (!defined('PIMCORE_TEST')) {
  159. define('PIMCORE_TEST', true);
  160. }
  161. }
  162. // paths relying on basic paths above
  163. $resolveConstant('PIMCORE_CUSTOM_CONFIGURATION_DIRECTORY', PIMCORE_PROJECT_ROOT . '/config/pimcore');
  164. $resolveConstant('PIMCORE_CONFIGURATION_DIRECTORY', PIMCORE_PRIVATE_VAR . '/config');
  165. $resolveConstant('PIMCORE_LOG_DIRECTORY', PIMCORE_PRIVATE_VAR . '/log');
  166. $resolveConstant('PIMCORE_LOG_FILEOBJECT_DIRECTORY', PIMCORE_PRIVATE_VAR . '/application-logger');
  167. $resolveConstant('PIMCORE_CACHE_DIRECTORY', PIMCORE_PRIVATE_VAR . '/cache/pimcore');
  168. $resolveConstant('PIMCORE_SYMFONY_CACHE_DIRECTORY', PIMCORE_PRIVATE_VAR . '/cache');
  169. $resolveConstant('PIMCORE_CLASS_DIRECTORY', PIMCORE_PRIVATE_VAR . '/classes');
  170. $resolveConstant('PIMCORE_CUSTOMLAYOUT_DIRECTORY', PIMCORE_CLASS_DIRECTORY . '/customlayouts');
  171. $resolveConstant('PIMCORE_SYSTEM_TEMP_DIRECTORY', PIMCORE_PRIVATE_VAR . '/tmp');
  172. $resolveConstant('PIMCORE_LOG_MAIL_PERMANENT', PIMCORE_PRIVATE_VAR . '/email');
  173. // configure PHP's error logging
  174. $resolveConstant('PIMCORE_PHP_ERROR_LOG', PIMCORE_LOG_DIRECTORY . '/php.log');
  175. $resolveConstant('PIMCORE_KERNEL_CLASS', '\App\Kernel');
  176. }
  177. private static function autoload()
  178. {
  179. $loader = \Pimcore::getAutoloader();
  180. // tell the autoloader where to find Pimcore's generated class stubs
  181. // this is primarily necessary for tests and custom class directories, which are not covered in composer.json
  182. $loader->addPsr4('Pimcore\\Model\\DataObject\\', PIMCORE_CLASS_DIRECTORY . '/DataObject');
  183. if (defined('PIMCORE_APP_BUNDLE_CLASS_FILE')) {
  184. require_once PIMCORE_APP_BUNDLE_CLASS_FILE;
  185. }
  186. }
  187. /**
  188. * @return KernelInterface
  189. */
  190. public static function kernel()
  191. {
  192. $environment = Config::getEnvironment();
  193. $debug = (bool) $_SERVER['APP_DEBUG'];
  194. if ($debug) {
  195. umask(0000);
  196. Debug::enable();
  197. @ini_set('display_errors', 'On');
  198. }
  199. if (defined('PIMCORE_KERNEL_CLASS')) {
  200. $kernelClass = PIMCORE_KERNEL_CLASS;
  201. } else {
  202. $kernelClass = '\App\Kernel';
  203. }
  204. if (!class_exists($kernelClass)) {
  205. throw new \InvalidArgumentException(sprintf('Defined Kernel Class %s not found', $kernelClass));
  206. }
  207. if (!is_subclass_of($kernelClass, Kernel::class)) {
  208. throw new \InvalidArgumentException(sprintf('Defined Kernel Class %s needs to extend the \Pimcore\Kernel Class', $kernelClass));
  209. }
  210. $kernel = new $kernelClass($environment, $debug);
  211. \Pimcore::setKernel($kernel);
  212. $kernel->boot();
  213. $conf = \Pimcore::getContainer()->getParameter('pimcore.config');
  214. if (isset($conf['general']['timezone']) && !empty($conf['general']['timezone'])) {
  215. date_default_timezone_set($conf['general']['timezone']);
  216. }
  217. return $kernel;
  218. }
  219. }