factory = $factory; $this->rootDir = $rootDir; $this->server = $initParams; } /** * Gets the current parameters * * @return array */ public function getParams() { return $this->server; } /** * Factory method for creating application instances * * @param string $type * @param array $arguments * @return \Magento\Framework\AppInterface * @throws \InvalidArgumentException */ public function createApplication($type, $arguments = []) { try { $this->initObjectManager(); $application = $this->objectManager->create($type, $arguments); if (!($application instanceof AppInterface)) { throw new \InvalidArgumentException("The provided class doesn't implement AppInterface: {$type}"); } return $application; } catch (\Exception $e) { $this->terminate($e); } } /** * Runs an application * * @param \Magento\Framework\AppInterface $application * @return void */ public function run(AppInterface $application) { try { try { \Magento\Framework\Profiler::start('magento'); $this->initErrorHandler(); $this->initObjectManager(); $this->assertMaintenance(); $this->assertInstalled(); $response = $application->launch(); $response->sendResponse(); \Magento\Framework\Profiler::stop('magento'); } catch (\Exception $e) { \Magento\Framework\Profiler::stop('magento'); if (!$application->catchException($this, $e)) { throw $e; } } } catch (\Exception $e) { $this->terminate($e); } } /** * Asserts maintenance mode * * @return void * @throws \Exception */ protected function assertMaintenance() { $isExpected = $this->getIsExpected(self::PARAM_REQUIRE_MAINTENANCE, self::DEFAULT_REQUIRE_MAINTENANCE); if (null === $isExpected) { return; } $this->initObjectManager(); /** @var \Magento\Framework\App\MaintenanceMode $maintenance */ $this->maintenance = $this->objectManager->get('Magento\Framework\App\MaintenanceMode'); $isOn = $this->maintenance->isOn(isset($this->server['REMOTE_ADDR']) ? $this->server['REMOTE_ADDR'] : ''); if ($isOn && !$isExpected) { $this->errorCode = self::ERR_MAINTENANCE; throw new \Exception('Unable to proceed: the maintenance mode is enabled. '); } if (!$isOn && $isExpected) { $this->errorCode = self::ERR_MAINTENANCE; throw new \Exception('Unable to proceed: the maintenance mode must be enabled first. '); } } /** * Asserts whether application is installed * * @return void * @throws \Exception */ protected function assertInstalled() { $isExpected = $this->getIsExpected(self::PARAM_REQUIRE_IS_INSTALLED, self::DEFAULT_REQUIRE_IS_INSTALLED); if (null === $isExpected) { return; } $this->initObjectManager(); $isInstalled = $this->isInstalled(); if (!$isInstalled && $isExpected) { $this->errorCode = self::ERR_IS_INSTALLED; throw new \Exception('Error: Application is not installed yet. '); } if ($isInstalled && !$isExpected) { $this->errorCode = self::ERR_IS_INSTALLED; throw new \Exception('Error: Application is already installed. '); } } /** * Analyze a key in the initialization parameters as "is expected" parameter * * If there is no such key, returns default value. Otherwise casts it to boolean, unless it is null * * @param string $key * @param bool $default * @return bool|null */ private function getIsExpected($key, $default) { if (array_key_exists($key, $this->server)) { if (isset($this->server[$key])) { return (bool)(int)$this->server[$key]; } return null; } return $default; } /** * Determines whether application is installed * * @return bool */ private function isInstalled() { $this->initObjectManager(); /** @var \Magento\Framework\App\DeploymentConfig $deploymentConfig */ $deploymentConfig = $this->objectManager->get('Magento\Framework\App\DeploymentConfig'); return $deploymentConfig->isAvailable(); } /** * Gets the object manager instance * * @return \Magento\Framework\ObjectManagerInterface */ public function getObjectManager() { $this->initObjectManager(); return $this->objectManager; } /** * Sets a custom error handler * * @return void */ private function initErrorHandler() { $handler = new ErrorHandler(); set_error_handler([$handler, 'handler']); } /** * Initializes object manager * * @return void */ private function initObjectManager() { if (!$this->objectManager) { $this->objectManager = $this->factory->create($this->server); $this->maintenance = $this->objectManager->get('Magento\Framework\App\MaintenanceMode'); } } /** * Getter for error code * * @return int */ public function getErrorCode() { return $this->errorCode; } /** * Checks whether developer mode is set in the initialization parameters * * @return bool */ public function isDeveloperMode() { $mode = 'default'; if (isset($this->server[State::PARAM_MODE])) { $mode = $this->server[State::PARAM_MODE]; } else { $deploymentConfig = $this->getObjectManager()->get(DeploymentConfig::class); $configMode = $deploymentConfig->get(State::PARAM_MODE); if ($configMode) { $mode = $configMode; } } return $mode == State::MODE_DEVELOPER; } /** * Display an exception and terminate program execution * * @param \Exception $e * @return void * @SuppressWarnings(PHPMD.ExitExpression) */ protected function terminate(\Exception $e) { if ($this->isDeveloperMode()) { echo $e; } else { $message = "An error has happened during application run. See exception log for details.\n"; try { if (!$this->objectManager) { throw new \DomainException(); } $this->objectManager->get('Psr\Log\LoggerInterface')->critical($e); } catch (\Exception $e) { $message .= "Could not write error message to log. Please use developer mode to see the message.\n"; } echo $message; } exit(1); } }