request; } /** * @param \Symfony\Component\HttpFoundation\Request $request */ public function setRequest($request) { $this->request = $request; } /** * @return \Drupal\Core\DrupalKernelInterface */ public function getKernel() { return $this->kernel; } public function validRoot($path) { if (!empty($path) && is_dir($path) && file_exists($path . '/autoload.php')) { // Additional check for the presence of core/composer.json to // grant it is not a Drupal 7 site with a base folder named "core". $candidate = 'core/includes/common.inc'; if (file_exists($path . '/' . $candidate) && file_exists($path . '/core/core.services.yml')) { if (file_exists($path . '/core/misc/drupal.js') || file_exists($path . '/core/assets/js/drupal.js')) { return $candidate; } } } } public function getVersion($drupal_root) { // Are the class constants available? if (!$this->hasAutoloader()) { throw new \Exception('Cannot access Drupal 8 class constants - Drupal autoloader not loaded yet.'); } // Drush depends on bootstrap being loaded at this point. require_once $drupal_root .'/core/includes/bootstrap.inc'; if (defined('\Drupal::VERSION')) { return \Drupal::VERSION; } } public function confPath($require_settings = true, $reset = false) { if (\Drupal::hasService('kernel')) { $site_path = \Drupal::service('kernel')->getSitePath(); } if (!isset($site_path) || empty($site_path)) { $site_path = DrupalKernel::findSitePath($this->getRequest(), $require_settings); } return $site_path; } public function addLogger() { // Provide a logger which sends // output to drush_log(). This should catch every message logged through every // channel. $container = \Drupal::getContainer(); $parser = $container->get('logger.log_message_parser'); $drushLogger = Drush::logger(); $logger = new DrushLog($parser, $drushLogger); $container->get('logger.factory')->addLogger($logger); } public function bootstrapDrupalCore($drupal_root) { $core = DRUPAL_ROOT . '/core'; return $core; } public function bootstrapDrupalSiteValidate() { parent::bootstrapDrupalSiteValidate(); // Account for users who omit the http:// prefix. if (!parse_url($this->uri, PHP_URL_SCHEME)) { $this->uri = 'http://' . $this->uri; } $request = Request::create($this->uri, 'GET', [], [], [], ['SCRIPT_NAME' => '/index.php']); $this->setRequest($request); $confPath = drush_bootstrap_value('confPath', $this->confPath(true, true)); drush_bootstrap_value('site', $request->getHttpHost()); return true; } public function bootstrapDrupalConfigurationValidate() { $conf_file = $this->confPath() . '/settings.php'; if (!file_exists($conf_file)) { $msg = dt("Could not find a Drupal settings.php file at !file.", ['!file' => $conf_file]); $this->logger->debug($msg); // Cant do this because site:install deliberately bootstraps to configure without a settings.php file. // return drush_set_error($msg); } return true; } public function bootstrapDrupalDatabaseValidate() { return parent::bootstrapDrupalDatabaseValidate() && $this->bootstrapDrupalDatabaseHasTable('key_value'); } public function bootstrapDrupalDatabase() { // D8 omits this bootstrap level as nothing special needs to be done. parent::bootstrapDrupalDatabase(); } public function bootstrapDrupalConfiguration(AnnotationData $annotationData = null) { // Default to the standard kernel. $kernel = Kernels::DRUPAL; if (!empty($annotationData)) { $kernel = $annotationData->get('kernel', Kernels::DRUPAL); } $classloader = $this->autoloader(); $request = $this->getRequest(); $kernel_factory = Kernels::getKernelFactory($kernel); /** @var \Drupal\Core\DrupalKernelInterface kernel */ $this->kernel = $kernel_factory($request, $classloader, 'prod'); // Include Drush services in the container. // @see Drush\Drupal\DrupalKernel::addServiceModifier() $this->kernel->addServiceModifier(new DrushServiceModifier()); // Unset drupal error handler and restore Drush's one. restore_error_handler(); // Disable automated cron if the module is enabled. $GLOBALS['config']['automated_cron.settings']['interval'] = 0; parent::bootstrapDrupalConfiguration(); } public function bootstrapDrupalFull() { $this->logger->debug(dt('Start bootstrap of the Drupal Kernel.')); $this->kernel->boot(); $this->kernel->prepareLegacyRequest($this->getRequest()); $this->logger->debug(dt('Finished bootstrap of the Drupal Kernel.')); parent::bootstrapDrupalFull(); $this->addLogger(); // Get a list of the modules to ignore $ignored_modules = drush_get_option_list('ignored-modules', []); $application = Drush::getApplication(); $runner = Drush::runner(); // We have to get the service command list from the container, because // it is constructed in an indirect way during the container initialization. // The upshot is that the list of console commands is not available // until after $kernel->boot() is called. $container = \Drupal::getContainer(); // Set the command info alterers. if ($container->has(DrushServiceModifier::DRUSH_COMMAND_INFO_ALTERER_SERVICES)) { $serviceCommandInfoAltererlist = $container->get(DrushServiceModifier::DRUSH_COMMAND_INFO_ALTERER_SERVICES); $commandFactory = Drush::commandFactory(); foreach ($serviceCommandInfoAltererlist->getCommandList() as $altererHandler) { $commandFactory->addCommandInfoAlterer($altererHandler); $this->logger->debug(dt('Commands are potentially altered in !class.', ['!class' => get_class($altererHandler)])); } } $serviceCommandlist = $container->get(DrushServiceModifier::DRUSH_CONSOLE_SERVICES); if ($container->has(DrushServiceModifier::DRUSH_CONSOLE_SERVICES)) { foreach ($serviceCommandlist->getCommandList() as $command) { if (!$this->commandIgnored($command, $ignored_modules)) { $this->inflect($command); $this->logger->log(LogLevel::DEBUG_NOTIFY, dt('Add a command: !name', ['!name' => $command->getName()])); $application->add($command); } } } // Do the same thing with the annotation commands. if ($container->has(DrushServiceModifier::DRUSH_COMMAND_SERVICES)) { $serviceCommandlist = $container->get(DrushServiceModifier::DRUSH_COMMAND_SERVICES); foreach ($serviceCommandlist->getCommandList() as $commandHandler) { if (!$this->commandIgnored($commandHandler, $ignored_modules)) { $this->inflect($commandHandler); $this->logger->log(LogLevel::DEBUG_NOTIFY, dt('Add a commandfile class: !name', ['!name' => get_class($commandHandler)])); $runner->registerCommandClass($application, $commandHandler); } } } } public function commandIgnored($command, $ignored_modules) { if (empty($ignored_modules)) { return false; } $ignored_regex = '#\\\\(' . implode('|', $ignored_modules) . ')\\\\#'; $class = new \ReflectionClass($command); $commandNamespace = $class->getNamespaceName(); return preg_match($ignored_regex, $commandNamespace); } /** * {@inheritdoc} */ public function terminate() { parent::terminate(); if ($this->kernel) { $response = Response::create(''); $this->kernel->terminate($this->getRequest(), $response); } } }