5 use Symfony\Component\HttpFoundation\Request;
6 use Symfony\Component\HttpFoundation\Response;
7 use Psr\Log\LoggerInterface;
8 use Drupal\Core\DrupalKernel;
9 use Drush\Drupal\DrupalKernel as DrushDrupalKernel;
10 use Drush\Drupal\DrushServiceModfier;
11 use Symfony\Component\DependencyInjection\Reference;
13 use Drush\Log\LogLevel;
15 class DrupalBoot8 extends DrupalBoot {
18 * @var \Drupal\Core\DrupalKernelInterface
23 * @var \Symfony\Component\HttpFoundation\Request
27 function valid_root($path) {
28 if (!empty($path) && is_dir($path) && file_exists($path . '/autoload.php')) {
29 // Additional check for the presence of core/composer.json to
30 // grant it is not a Drupal 7 site with a base folder named "core".
31 $candidate = 'core/includes/common.inc';
32 if (file_exists($path . '/' . $candidate) && file_exists($path . '/core/core.services.yml')) {
33 if (file_exists($path . '/core/misc/drupal.js') || file_exists($path . '/core/assets/js/drupal.js')) {
40 function get_version($drupal_root) {
41 // Load the autoloader so we can access the class constants.
42 drush_drupal_load_autoloader($drupal_root);
43 // Drush depends on bootstrap being loaded at this point.
44 require_once $drupal_root .'/core/includes/bootstrap.inc';
45 if (defined('\Drupal::VERSION')) {
46 return \Drupal::VERSION;
50 function get_profile() {
51 return drupal_get_profile();
54 function conf_path($require_settings = TRUE, $reset = FALSE, Request $request = NULL) {
55 if (!isset($request)) {
56 if (\Drupal::hasRequest()) {
57 $request = \Drupal::request();
59 // @todo Remove once external CLI scripts (Drush) are updated.
61 $request = Request::createFromGlobals();
64 if (\Drupal::hasService('kernel')) {
65 $site_path = \Drupal::service('kernel')->getSitePath();
67 if (!isset($site_path) || empty($site_path)) {
68 $site_path = DrupalKernel::findSitePath($request, $require_settings);
73 function add_logger() {
74 // If we're running on Drupal 8 or later, we provide a logger which will send
75 // output to drush_log(). This should catch every message logged through every
77 $container = \Drupal::getContainer();
78 $parser = $container->get('logger.log_message_parser');
79 $drushLogger = drush_get_context('DRUSH_LOG_CALLBACK');
80 $logger = new \Drush\Log\DrushLog($parser, $drushLogger);
81 $container->get('logger.factory')->addLogger($logger);
84 function contrib_modules_paths() {
86 $this->conf_path() . '/modules',
93 * @return array of strings - paths to directories where contrib
96 function contrib_themes_paths() {
98 $this->conf_path() . '/themes',
104 function bootstrap_drupal_core($drupal_root) {
105 $core = DRUPAL_ROOT . '/core';
110 function bootstrap_drupal_database_validate() {
111 return parent::bootstrap_drupal_database_validate() && $this->bootstrap_drupal_database_has_table('key_value');
114 function bootstrap_drupal_database() {
115 // D8 omits this bootstrap level as nothing special needs to be done.
116 parent::bootstrap_drupal_database();
119 function bootstrap_drupal_configuration() {
120 $this->request = Request::createFromGlobals();
121 $classloader = drush_drupal_load_autoloader(DRUPAL_ROOT);
122 // @todo - use Request::create() and then no need to set PHP superglobals
123 $kernelClass = new \ReflectionClass('\Drupal\Core\DrupalKernel');
124 if ($kernelClass->hasMethod('addServiceModifier')) {
125 $this->kernel = DrupalKernel::createFromRequest($this->request, $classloader, 'prod');
128 $this->kernel = DrushDrupalKernel::createFromRequest($this->request, $classloader, 'prod');
130 // @see Drush\Drupal\DrupalKernel::addServiceModifier()
131 $this->kernel->addServiceModifier(new DrushServiceModfier());
133 // Unset drupal error handler and restore Drush's one.
134 restore_error_handler();
136 // Disable automated cron if the module is enabled.
137 $GLOBALS['config']['automated_cron.settings']['interval'] = 0;
139 parent::bootstrap_drupal_configuration();
142 function bootstrap_drupal_full() {
143 drush_log(dt('About to bootstrap the Drupal 8 Kernel.'), LogLevel::DEBUG);
144 // TODO: do we need to do ob_start any longer?
145 if (!drush_get_context('DRUSH_QUIET', FALSE)) {
148 $this->kernel->invalidateContainer();
149 $this->kernel->boot();
150 $this->kernel->prepareLegacyRequest($this->request);
151 if (!drush_get_context('DRUSH_QUIET', FALSE)) {
154 drush_log(dt('Finished bootstraping the Drupal 8 Kernel.'), LogLevel::DEBUG);
156 parent::bootstrap_drupal_full();
158 // Get a list of the modules to ignore
159 $ignored_modules = drush_get_option_list('ignored-modules', array());
161 // We have to get the service command list from the container, because
162 // it is constructed in an indirect way during the container initialization.
163 // The upshot is that the list of console commands is not available
164 // until after $kernel->boot() is called.
165 $container = \Drupal::getContainer();
166 $serviceCommandlist = $container->get('drush.service.consolecommands');
167 foreach ($serviceCommandlist->getCommandList() as $command) {
168 if (!$this->commandIgnored($command, $ignored_modules)) {
169 drush_log(dt('Add a command: !name', ['!name' => $command->getName()]), LogLevel::DEBUG);
170 annotationcommand_adapter_cache_module_console_commands($command);
173 // Do the same thing with the annotation commands.
174 $serviceCommandlist = $container->get('drush.service.consolidationcommands');
175 foreach ($serviceCommandlist->getCommandList() as $commandhandler) {
176 if (!$this->commandIgnored($commandhandler, $ignored_modules)) {
177 drush_log(dt('Add a commandhandler: !name', ['!name' => get_class($commandhandler)]), LogLevel::DEBUG);
178 annotationcommand_adapter_cache_module_service_commands($commandhandler);
183 public function commandIgnored($command, $ignored_modules) {
184 if (empty($ignored_modules)) {
187 $ignored_regex = '#\\\\(' . implode('|', $ignored_modules) . ')\\\\#';
188 $class = new \ReflectionClass($command);
189 $commandNamespace = $class->getNamespaceName();
190 return preg_match($ignored_regex, $commandNamespace);
196 public function terminate() {
200 $response = Response::create('');
201 $this->kernel->terminate($this->request, $response);