b990da16eb72f3b6f6ba423c0cb5689135db8772
[yaffs-website] / vendor / drush / drush / src / Boot / DrupalBoot8.php
1 <?php
2
3 namespace Drush\Boot;
4
5 use Consolidation\AnnotatedCommand\AnnotationData;
6 use Drush\Log\DrushLog;
7 use Symfony\Component\HttpFoundation\Request;
8 use Symfony\Component\HttpFoundation\Response;
9 use Drupal\Core\DrupalKernel;
10 use Drush\Drush;
11 use Drush\Drupal\DrushServiceModifier;
12
13 use Drush\Log\LogLevel;
14
15 class DrupalBoot8 extends DrupalBoot implements AutoloaderAwareInterface
16 {
17     use AutoloaderAwareTrait;
18
19     /**
20      * @var \Drupal\Core\DrupalKernelInterface
21      */
22     protected $kernel;
23
24     /**
25      * @var \Symfony\Component\HttpFoundation\Request
26      */
27     protected $request;
28
29     /**
30      * @return \Symfony\Component\HttpFoundation\Request
31      */
32     public function getRequest()
33     {
34         return $this->request;
35     }
36
37     /**
38      * @param \Symfony\Component\HttpFoundation\Request $request
39      */
40     public function setRequest($request)
41     {
42         $this->request = $request;
43     }
44
45     /**
46      * @return \Drupal\Core\DrupalKernelInterface
47      */
48     public function getKernel()
49     {
50         return $this->kernel;
51     }
52
53     public function validRoot($path)
54     {
55         if (!empty($path) && is_dir($path) && file_exists($path . '/autoload.php')) {
56             // Additional check for the presence of core/composer.json to
57             // grant it is not a Drupal 7 site with a base folder named "core".
58             $candidate = 'core/includes/common.inc';
59             if (file_exists($path . '/' . $candidate) && file_exists($path . '/core/core.services.yml')) {
60                 if (file_exists($path . '/core/misc/drupal.js') || file_exists($path . '/core/assets/js/drupal.js')) {
61                     return $candidate;
62                 }
63             }
64         }
65     }
66
67     public function getVersion($drupal_root)
68     {
69         // Are the class constants available?
70         if (!$this->hasAutoloader()) {
71             throw new \Exception('Cannot access Drupal 8 class constants - Drupal autoloader not loaded yet.');
72         }
73         // Drush depends on bootstrap being loaded at this point.
74         require_once $drupal_root .'/core/includes/bootstrap.inc';
75         if (defined('\Drupal::VERSION')) {
76             return \Drupal::VERSION;
77         }
78     }
79
80     public function confPath($require_settings = true, $reset = false)
81     {
82
83         if (\Drupal::hasService('kernel')) {
84             $site_path = \Drupal::service('kernel')->getSitePath();
85         }
86         if (!isset($site_path) || empty($site_path)) {
87             $site_path = DrupalKernel::findSitePath($this->getRequest(), $require_settings);
88         }
89         return $site_path;
90     }
91
92     public function addLogger()
93     {
94         // Provide a logger which sends
95         // output to drush_log(). This should catch every message logged through every
96         // channel.
97         $container = \Drupal::getContainer();
98         $parser = $container->get('logger.log_message_parser');
99
100         $drushLogger = Drush::logger();
101         $logger = new DrushLog($parser, $drushLogger);
102         $container->get('logger.factory')->addLogger($logger);
103     }
104
105     public function bootstrapDrupalCore($drupal_root)
106     {
107         $core = DRUPAL_ROOT . '/core';
108
109         return $core;
110     }
111
112     public function bootstrapDrupalSiteValidate()
113     {
114         parent::bootstrapDrupalSiteValidate();
115
116         // Normalize URI.
117         $uri = rtrim($this->uri, '/') . '/';
118         $parsed_url = parse_url($uri);
119
120         // Account for users who omit the http:// prefix.
121         if (empty($parsed_url['scheme'])) {
122             $this->uri = 'http://' . $this->uri;
123             $parsed_url = parse_url($this->uri);
124         }
125
126         $server = [
127             'SCRIPT_FILENAME' => getcwd() . '/index.php',
128             'SCRIPT_NAME' => isset($parsed_url['path']) ? $parsed_url['path'] . 'index.php' : '/index.php',
129         ];
130         $request = Request::create($this->uri, 'GET', [], [], [], $server);
131         $this->setRequest($request);
132         $confPath = drush_bootstrap_value('confPath', $this->confPath(true, true));
133         drush_bootstrap_value('site', $request->getHttpHost());
134         return true;
135     }
136
137     public function bootstrapDrupalConfigurationValidate()
138     {
139         $conf_file = $this->confPath() . '/settings.php';
140         if (!file_exists($conf_file)) {
141             $msg = dt("Could not find a Drupal settings.php file at !file.", ['!file' => $conf_file]);
142             $this->logger->debug($msg);
143             // Cant do this because site:install deliberately bootstraps to configure without a settings.php file.
144             // return drush_set_error($msg);
145         }
146         return true;
147     }
148
149     public function bootstrapDrupalDatabaseValidate()
150     {
151         return parent::bootstrapDrupalDatabaseValidate() && $this->bootstrapDrupalDatabaseHasTable('key_value');
152     }
153
154     public function bootstrapDrupalDatabase()
155     {
156         // D8 omits this bootstrap level as nothing special needs to be done.
157         parent::bootstrapDrupalDatabase();
158     }
159
160     public function bootstrapDrupalConfiguration(AnnotationData $annotationData = null)
161     {
162         // Default to the standard kernel.
163         $kernel = Kernels::DRUPAL;
164         if (!empty($annotationData)) {
165             $kernel = $annotationData->get('kernel', Kernels::DRUPAL);
166         }
167         $classloader = $this->autoloader();
168         $request = $this->getRequest();
169         $kernel_factory = Kernels::getKernelFactory($kernel);
170         $allow_dumping = $kernel !== Kernels::UPDATE;
171         /** @var \Drupal\Core\DrupalKernelInterface kernel */
172         $this->kernel = $kernel_factory($request, $classloader, 'prod', $allow_dumping);
173         // Include Drush services in the container.
174         // @see Drush\Drupal\DrupalKernel::addServiceModifier()
175         $this->kernel->addServiceModifier(new DrushServiceModifier());
176
177         // Unset drupal error handler and restore Drush's one.
178         restore_error_handler();
179
180         // Disable automated cron if the module is enabled.
181         $GLOBALS['config']['automated_cron.settings']['interval'] = 0;
182
183         parent::bootstrapDrupalConfiguration();
184     }
185
186     public function bootstrapDrupalFull()
187     {
188         $this->logger->debug(dt('Start bootstrap of the Drupal Kernel.'));
189         $this->kernel->boot();
190         $this->kernel->prepareLegacyRequest($this->getRequest());
191         $this->logger->debug(dt('Finished bootstrap of the Drupal Kernel.'));
192
193         parent::bootstrapDrupalFull();
194         $this->addLogger();
195
196         // Get a list of the modules to ignore
197         $ignored_modules = drush_get_option_list('ignored-modules', []);
198
199         $application = Drush::getApplication();
200         $runner = Drush::runner();
201
202         // We have to get the service command list from the container, because
203         // it is constructed in an indirect way during the container initialization.
204         // The upshot is that the list of console commands is not available
205         // until after $kernel->boot() is called.
206         $container = \Drupal::getContainer();
207
208         // Set the command info alterers.
209         if ($container->has(DrushServiceModifier::DRUSH_COMMAND_INFO_ALTERER_SERVICES)) {
210             $serviceCommandInfoAltererlist = $container->get(DrushServiceModifier::DRUSH_COMMAND_INFO_ALTERER_SERVICES);
211             $commandFactory = Drush::commandFactory();
212             foreach ($serviceCommandInfoAltererlist->getCommandList() as $altererHandler) {
213                 $commandFactory->addCommandInfoAlterer($altererHandler);
214                 $this->logger->debug(dt('Commands are potentially altered in !class.', ['!class' => get_class($altererHandler)]));
215             }
216         }
217
218         $serviceCommandlist = $container->get(DrushServiceModifier::DRUSH_CONSOLE_SERVICES);
219         if ($container->has(DrushServiceModifier::DRUSH_CONSOLE_SERVICES)) {
220             foreach ($serviceCommandlist->getCommandList() as $command) {
221                 if (!$this->commandIgnored($command, $ignored_modules)) {
222                     $this->inflect($command);
223                     $this->logger->log(LogLevel::DEBUG_NOTIFY, dt('Add a command: !name', ['!name' => $command->getName()]));
224                     $application->add($command);
225                 }
226             }
227         }
228         // Do the same thing with the annotation commands.
229         if ($container->has(DrushServiceModifier::DRUSH_COMMAND_SERVICES)) {
230             $serviceCommandlist = $container->get(DrushServiceModifier::DRUSH_COMMAND_SERVICES);
231             foreach ($serviceCommandlist->getCommandList() as $commandHandler) {
232                 if (!$this->commandIgnored($commandHandler, $ignored_modules)) {
233                     $this->inflect($commandHandler);
234                     $this->logger->log(LogLevel::DEBUG_NOTIFY, dt('Add a commandfile class: !name', ['!name' => get_class($commandHandler)]));
235                     $runner->registerCommandClass($application, $commandHandler);
236                 }
237             }
238         }
239     }
240
241     public function commandIgnored($command, $ignored_modules)
242     {
243         if (empty($ignored_modules)) {
244             return false;
245         }
246         $ignored_regex = '#\\\\(' . implode('|', $ignored_modules) . ')\\\\#';
247         $class = new \ReflectionClass($command);
248         $commandNamespace = $class->getNamespaceName();
249         return preg_match($ignored_regex, $commandNamespace);
250     }
251
252     /**
253      * {@inheritdoc}
254      */
255     public function terminate()
256     {
257         parent::terminate();
258
259         if ($this->kernel) {
260             $response = Response::create('');
261             $this->kernel->terminate($this->getRequest(), $response);
262         }
263     }
264 }