4 * Specific functions for a drupal 8+ environment.
5 * drush_include_engine() magically includes either this file
6 * or environment_X.inc depending on which version of drupal Drush
10 use Drupal\Core\Site\Settings;
11 use Drupal\Core\StreamWrapper\PrivateStream;
12 use Drupal\Core\StreamWrapper\PublicStream;
13 use Drush\Log\LogLevel;
14 use Drupal\Core\Logger\RfcLogLevel;
17 * Get complete information for all available modules.
19 * @param $include_hidden
20 * Boolean to indicate whether hidden modules should be excluded or not.
22 * An array containing module info for all available modules.
24 function drush_get_modules($include_hidden = TRUE) {
25 $modules = system_rebuild_module_data();
27 foreach ($modules as $key => $module) {
28 if ((!$include_hidden) && (!empty($module->info['hidden']))) {
29 unset($modules[$key]);
32 $module->schema_version = drupal_get_installed_schema_version($key);
40 * Returns drupal required modules, including modules declared as required dynamically.
42 function _drush_drupal_required_modules($module_info) {
43 $required = drupal_required_modules();
44 foreach ($module_info as $name => $module) {
45 if (isset($module->info['required']) && $module->info['required']) {
49 return array_unique($required);
53 * Return dependencies and its status for modules.
56 * Array of module names
58 * Drupal 'files' array for modules as returned by drush_get_modules().
60 * Array with dependencies and status for $modules
62 function drush_check_module_dependencies($modules, $module_info) {
64 foreach ($modules as $key => $module) {
65 $dependencies = array_reverse($module_info[$module]->requires);
66 $unmet_dependencies = array_diff(array_keys($dependencies), array_keys($module_info));
67 if (!empty($unmet_dependencies)) {
68 $status[$key]['error'] = array(
69 'code' => 'DRUSH_PM_ENABLE_DEPENDENCY_NOT_FOUND',
70 'message' => dt('Module !module cannot be enabled because it depends on the following modules which could not be found: !unmet_dependencies', array('!module' => $module, '!unmet_dependencies' => implode(',', $unmet_dependencies)))
74 // check for version incompatibility
75 foreach ($dependencies as $dependency_name => $v) {
76 $current_version = $module_info[$dependency_name]->info['version'];
77 $current_version = str_replace(drush_get_drupal_core_compatibility() . '-', '', $current_version);
78 $incompatibility = drupal_check_incompatibility($v, $current_version);
79 if (isset($incompatibility)) {
80 $status[$key]['error'] = array(
81 'code' => 'DRUSH_PM_ENABLE_DEPENDENCY_VERSION_MISMATCH',
82 'message' => dt('Module !module cannot be enabled because it depends on !dependency !required_version but !current_version is available', array('!module' => $module, '!dependency' => $dependency_name, '!required_version' => $incompatibility, '!current_version' => $current_version))
87 $status[$key]['unmet-dependencies'] = $unmet_dependencies;
88 $status[$key]['dependencies'] = $dependencies;
95 * Return dependents of modules.
98 * Array of module names
100 * Drupal 'files' array for modules as returned by drush_get_modules().
102 * Array with dependents for each one of $modules
104 function drush_module_dependents($modules, $module_info) {
105 $dependents = array();
106 foreach ($modules as $module) {
107 $keys = array_keys($module_info[$module]->required_by);
108 $dependents = array_merge($dependents, array_combine($keys, $keys));
111 return array_unique($dependents);
115 * Returns a list of enabled modules.
117 * This is a wrapper for module_list().
119 function drush_module_list() {
120 $modules = array_keys(\Drupal::moduleHandler()->getModuleList());
121 return array_combine($modules, $modules);
125 * Installs a given list of modules.
127 * @see \Drupal\Core\Extension\ModuleInstallerInterface::install()
130 function drush_module_install($module_list, $enable_dependencies = TRUE) {
131 return \Drupal::service('module_installer')->install($module_list, $enable_dependencies);
135 * Checks that a given module exists and is enabled.
137 * @see \Drupal\Core\Extension\ModuleHandlerInterface::moduleExists()
140 function drush_module_exists($module) {
141 return \Drupal::moduleHandler()->moduleExists($module);
145 * Determines which modules are implementing a hook.
147 * @param string $hook
150 * Not used in Drupal 8 environment.
152 * TRUE to reset the hook implementation cache.
154 * @see \Drupal\Core\Extension\ModuleHandlerInterface::getImplementations().
155 * @see \Drupal\Core\Extension\ModuleHandlerInterface::resetImplementations().
158 function drush_module_implements($hook, $sort = FALSE, $reset = FALSE) {
159 // $sort is there for consistency, but looks like Drupal 8 has no equilavient for it.
160 // We can sort the list manually later if really needed.
162 \Drupal::moduleHandler()->resetImplementations();
164 return \Drupal::moduleHandler()->getImplementations($hook);
168 * Return a list of modules from a list of named modules.
169 * Both enabled and disabled/uninstalled modules are returned.
171 function drush_get_named_extensions_list($extensions) {
173 $modules = drush_get_modules();
174 foreach($modules as $name => $module) {
175 if (in_array($name, $extensions)) {
176 $result[$name] = $module;
179 $themes = drush_get_themes();
180 foreach($themes as $name => $theme) {
181 if (in_array($name, $extensions)) {
182 $result[$name] = $theme;
189 * Enable a list of modules. It is assumed the list contains all the dependencies not already enabled.
192 * Array of module names
194 function drush_module_enable($modules) {
195 // The list of modules already have all the dependencies, but they might not
196 // be in the correct order. Still pass $enable_dependencies = TRUE so that
197 // Drupal will enable the modules in the correct order.
198 drush_module_install($modules);
200 // Our logger got blown away during the container rebuild above.
201 $boot = drush_select_bootstrap_class();
204 // Flush all caches. No longer needed in D8 per https://github.com/drush-ops/drush/issues/1207
205 // drupal_flush_all_caches();
209 * Disable a list of modules. It is assumed the list contains all dependents not already disabled.
212 * Array of module names
214 function drush_module_disable($modules) {
215 drush_set_error('DRUSH_MODULE_DISABLE', dt('Drupal 8 does not support disabling modules. Use pm-uninstall instead.'));
219 * Uninstall a list of modules.
222 * Array of module names
224 * @see \Drupal\Core\Extension\ModuleInstallerInterface::uninstall()
226 function drush_module_uninstall($modules) {
227 \Drupal::service('module_installer')->uninstall($modules);
228 // Our logger got blown away during the container rebuild above.
229 $boot = drush_select_bootstrap_class();
234 * Invokes a hook in a particular module.
237 function drush_module_invoke($module, $hook) {
238 $args = func_get_args();
239 // Remove $module and $hook from the arguments.
240 unset($args[0], $args[1]);
241 return \Drupal::moduleHandler()->invoke($module, $hook, $args);
245 * Invokes a hook in all enabled modules that implement it.
248 function drush_module_invoke_all($hook) {
249 $args = func_get_args();
250 // Remove $hook from the arguments.
252 return \Drupal::moduleHandler()->invokeAll($hook, $args);
256 * Returns a list of enabled themes. Use drush_get_themes() if you need to rebuild
257 * and include hidden as well.
259 * @return \Drupal\Core\Extension\Extension[]
260 * A list of themes keyed by name.
262 function drush_theme_list() {
263 $theme_handler = \Drupal::service('theme_handler');
264 return $theme_handler->listInfo();
268 * Get complete information for all available themes.
270 * @param $include_hidden
271 * Boolean to indicate whether hidden themes should be excluded or not.
273 * An array containing theme info for all available themes.
275 function drush_get_themes($include_hidden = TRUE) {
276 $themes = \Drupal::service('theme_handler')->rebuildThemeData();
277 foreach ($themes as $key => $theme) {
278 if (!$include_hidden) {
279 if (isset($theme->info['hidden'])) {
280 // Don't exclude default or admin theme.
281 if ($key != _drush_theme_default() && $key != _drush_theme_admin()) {
282 unset($themes[$key]);
292 * Enable a list of themes.
295 * Array of theme names.
297 function drush_theme_enable($themes) {
298 \Drupal::service('theme_handler')->install($themes);
302 * Disable a list of themes.
305 * Array of theme names.
307 function drush_theme_disable($themes) {
308 drush_set_error('DRUSH_THEME_DISABLE', dt('Drupal 8 does not support disabling themes. Use pm-uninstall instead.'));
312 * Uninstall a list of themes.
315 * Array of theme names
317 * @see \Drupal\Core\Extension\ThemeHandlerInterface::uninstall()
319 function drush_theme_uninstall($themes) {
320 \Drupal::service('theme_handler')->uninstall($themes);
321 // Our logger got blown away during the container rebuild above.
322 $boot = drush_select_bootstrap_class();
327 * Helper function to obtain the severity levels based on Drupal version.
330 * Watchdog severity levels keyed by RFC 3164 severities.
332 function drush_watchdog_severity_levels() {
334 RfcLogLevel::EMERGENCY => LogLevel::EMERGENCY,
335 RfcLogLevel::ALERT => LogLevel::ALERT,
336 RfcLogLevel::CRITICAL => LogLevel::CRITICAL,
337 RfcLogLevel::ERROR => LogLevel::ERROR,
338 RfcLogLevel::WARNING => LogLevel::WARNING,
339 RfcLogLevel::NOTICE => LogLevel::NOTICE,
340 RfcLogLevel::INFO => LogLevel::INFO,
341 RfcLogLevel::DEBUG => LogLevel::DEBUG,
346 * Helper function to obtain the message types based on drupal version.
349 * Array of watchdog message types.
351 function drush_watchdog_message_types() {
352 return _dblog_get_message_types();
355 function _drush_theme_default() {
356 return \Drupal::config('system.theme')->get('default');
359 function _drush_theme_admin() {
360 $theme = \Drupal::config('system.theme')->get('admin');
361 return empty($theme) ? 'seven' : $theme;
364 function _drush_file_public_path() {
365 return PublicStream::basePath();
368 function _drush_file_private_path() {
369 return PrivateStream::basePath();
373 * Gets the extension name.
376 * The extension info.
378 * The extension name.
380 function _drush_extension_get_name($info) {
381 return $info->getName();
385 * Gets the extension type.
388 * The extension info.
390 * The extension type.
392 function _drush_extension_get_type($info) {
393 return $info->getType();
397 * Gets the extension path.
400 * The extension info.
402 * The extension path.
404 function _drush_extension_get_path($info) {
405 return $info->getPath();
409 * Wrapper for CSRF token generation.
411 function drush_get_token($value = NULL) {
412 return \Drupal::csrfToken()->get($value);
416 * Wrapper for _url().
418 function drush_url($path = NULL, array $options = array()) {
419 return \Drupal\Core\Url::fromUserInput('/' . $path, $options)->toString();
423 * Output a Drupal render array, object or string as plain text.
425 * @param string $data
429 * The plain-text representation of the input.
431 function drush_render($data) {
432 if (is_array($data)) {
433 $data = \Drupal::service('renderer')->renderRoot($data);
436 $data = \Drupal\Core\Mail\MailFormatHelper::htmlToText($data);