3 namespace Drush\Commands\core;
5 use Consolidation\OutputFormatters\StructuredData\PropertyList;
6 use Drupal\Core\StreamWrapper\PrivateStream;
7 use Drupal\Core\StreamWrapper\PublicStream;
8 use Drush\Boot\BootstrapManager;
9 use Drush\Boot\DrupalBoot;
10 use Drush\Commands\DrushCommands;
12 use Drush\Sql\SqlBase;
13 use Consolidation\SiteAlias\SiteAliasManagerAwareInterface;
14 use Consolidation\SiteAlias\SiteAliasManagerAwareTrait;
15 use Consolidation\OutputFormatters\Options\FormatterOptions;
16 use Consolidation\AnnotatedCommand\CommandData;
18 class StatusCommands extends DrushCommands implements SiteAliasManagerAwareInterface
20 use SiteAliasManagerAwareTrait;
23 * An overview of the environment - Drush and Drupal.
25 * @command core:status
26 * @param $filter A field to filter on. @deprecated - use --field option instead.
27 * @option project A comma delimited list of projects. Their paths will be added to path-aliases section.
28 * @usage drush core-status --field=files
29 * Emit just one field, not all the default fields.
30 * @usage drush core-status --fields=*
31 * Emit all fields, not just the default ones.
32 * @aliases status,st,core-status
33 * @table-style compact
36 * drupal-version: Drupal version
38 * db-driver: DB driver
39 * db-hostname: DB hostname
41 * db-username: DB username
42 * db-password: DB password
45 * bootstrap: Drupal bootstrap
46 * theme: Default theme
47 * admin-theme: Admin theme
49 * php-conf: PHP config
51 * drush-script: Drush script
52 * drush-version: Drush version
53 * drush-temp: Drush temp
54 * drush-cache-directory: Drush cache folder
55 * drush-conf: Drush configs
56 * drush-alias-files: Drush aliases
57 * alias-searchpaths: Alias search paths
58 * install-profile: Install profile
60 * drupal-settings-file: Drupal Settings
61 * site-path: Site path
64 * modules: Modules path
65 * files: Files, Public
66 * private: Files, Private
68 * config-sync: Drupal config
69 * files-path: Files, Public
70 * temp-path: Files, Temp
72 * @default-fields drupal-version,uri,db-driver,db-hostname,db-port,db-username,db-name,db-status,bootstrap,theme,admin-theme,php-bin,php-conf,php-os,drush-script,drush-version,drush-temp,drush-conf,install-profile,root,site,files,private,temp
74 * @hidden-options project
78 * @return \Consolidation\OutputFormatters\StructuredData\PropertyList
80 public function status($filter = '', $options = ['project' => self::REQ, 'format' => 'table'])
82 $data = $this->getPropertyList($options);
84 $result = new PropertyList($data);
85 $result->addRendererFunction([$this, 'renderStatusCell']);
90 public function getPropertyList($options)
92 $boot_manager = Drush::bootstrapManager();
93 $boot_object = Drush::bootstrap();
94 if (($drupal_root = $boot_manager->getRoot()) && ($boot_object instanceof DrupalBoot)) {
95 $status_table['drupal-version'] = $boot_object->getVersion($drupal_root);
96 $conf_dir = $boot_object->confPath();
97 $settings_file = "$conf_dir/settings.php";
98 $status_table['drupal-settings-file'] = file_exists($settings_file) ? $settings_file : '';
99 if ($boot_manager->hasBootstrapped(DRUSH_BOOTSTRAP_DRUPAL_SITE)) {
100 $status_table['uri'] = $boot_manager->getUri();
102 $sql = SqlBase::create($options);
103 $db_spec = $sql->getDbSpec();
104 $status_table['db-driver'] = $db_spec['driver'];
105 if (!empty($db_spec['unix_socket'])) {
106 $status_table['db-socket'] = $db_spec['unix_socket'];
107 } elseif (isset($db_spec['host'])) {
108 $status_table['db-hostname'] = $db_spec['host'];
110 $status_table['db-username'] = isset($db_spec['username']) ? $db_spec['username'] : null;
111 $status_table['db-password'] = isset($db_spec['password']) ? $db_spec['password'] : null;
112 $status_table['db-name'] = isset($db_spec['database']) ? $db_spec['database'] : null;
113 $status_table['db-port'] = isset($db_spec['port']) ? $db_spec['port'] : null;
114 if ($boot_manager->hasBootstrapped(DRUSH_BOOTSTRAP_DRUPAL_CONFIGURATION)) {
115 if (method_exists('Drupal', 'installProfile')) {
116 $status_table['install-profile'] = \Drupal::installProfile();
118 if ($boot_manager->hasBootstrapped(DRUSH_BOOTSTRAP_DRUPAL_DATABASE)) {
119 $status_table['db-status'] = dt('Connected');
120 if ($boot_manager->hasBootstrapped(DRUSH_BOOTSTRAP_DRUPAL_FULL)) {
121 $status_table['bootstrap'] = dt('Successful');
125 } catch (\Exception $e) {
126 // Don't worry be happy.
129 if ($boot_manager->hasBootstrapped(DRUSH_BOOTSTRAP_DRUPAL_FULL)) {
130 $status_table['theme'] = \Drupal::config('system.theme')->get('default');
131 $status_table['admin-theme'] = $theme = \Drupal::config('system.theme')->get('admin') ?: 'seven';
134 $status_table['php-bin'] = PHP_BINARY;
135 $status_table['php-os'] = PHP_OS;
136 if ($phpIniFiles = EditCommands::phpIniFiles()) {
137 $status_table['php-conf'] = $phpIniFiles;
139 $status_table['drush-script'] = DRUSH_COMMAND;
140 $status_table['drush-version'] = Drush::getVersion();
141 $status_table['drush-temp'] = $this->getConfig()->tmp();
142 $status_table['drush-cache-directory'] = $this->getConfig()->cache();
143 $status_table['drush-conf'] = Drush::config()->get('runtime.config.paths');
144 // List available alias files
145 $alias_files = $this->siteAliasManager()->listAllFilePaths();
147 $status_table['drush-alias-files'] = $alias_files;
148 $alias_searchpaths = $this->siteAliasManager()->searchLocations();
149 $status_table['alias-searchpaths'] = $alias_searchpaths;
151 $paths = self::pathAliases($options, $boot_manager, $boot_object);
152 if (!empty($paths)) {
153 foreach ($paths as $target => $one_path) {
155 if (substr($name, 0, 1) == '%') {
156 $name = substr($name, 1);
158 $status_table[$name] = $one_path;
162 // Store the paths into the '%paths' index; this will be
163 // used by other code, but will not be included in the output
164 // of the drush status command.
165 $status_table['%paths'] = $paths;
167 return $status_table;
170 public function renderStatusCell($key, $cellData, FormatterOptions $options)
172 if (is_array($cellData)) {
173 return implode("\n", $cellData);
179 * @hook pre-command core-status
181 public function adjustStatusOptions(CommandData $commandData)
183 $input = $commandData->input();
184 $args = $input->getArguments();
185 if (!empty($args['filter'])) {
186 $input->setOption('fields', '*' . $args['filter'] . '*');
191 * @param array $options
192 * @param BootstrapManager $boot_manager
195 public static function pathAliases(array $options, BootstrapManager $boot_manager, $boot)
198 $site_wide = 'sites/all';
199 if ($drupal_root = $boot_manager->getRoot()) {
200 $paths['%root'] = $drupal_root;
201 if (($boot instanceof DrupalBoot) && ($site_root = $boot->confPath())) {
202 $paths['%site'] = $site_root;
203 if (is_dir($modules_path = $site_root . '/modules')) {
204 $paths['%modules'] = $modules_path;
206 $paths['%modules'] = ltrim($site_wide . '/modules', '/');
208 if (is_dir($themes_path = $site_root . '/themes')) {
209 $paths['%themes'] = $themes_path;
211 $paths['%themes'] = ltrim($site_wide . '/themes', '/');
213 if ($boot_manager->hasBootstrapped(DRUSH_BOOTSTRAP_DRUPAL_CONFIGURATION)) {
215 if (isset($GLOBALS['config_directories'])) {
216 foreach ($GLOBALS['config_directories'] as $label => $unused) {
217 $paths["%config-$label"] = config_get_config_directory($label);
220 } catch (\Exception $e) {
225 if ($boot_manager->hasBootstrapped(DRUSH_BOOTSTRAP_DRUPAL_FULL)) {
226 $paths['%files'] = PublicStream::basePath();
227 $paths['%temp'] = file_directory_temp();
228 if ($private_path = PrivateStream::basePath()) {
229 $paths['%private'] = $private_path;
232 $modules = \Drupal::moduleHandler()->getModuleList();
233 $themes = \Drupal::service('theme_handler')->listInfo();
234 $projects = array_merge($modules, $themes);
235 foreach (explode(',', $options['project']) as $target) {
236 if (array_key_exists($target, $projects)) {
237 $paths['%' . $target] = $drupal_root . '/' . $projects[$target]->getPath();
244 // Add in all of the global paths from $options['path-aliases']
245 // @todo is this used?
246 if (isset($options['path-aliases'])) {
247 $paths = array_merge($paths, $options['path-aliases']);