Yaffs site version 1.1
[yaffs-website] / vendor / drush / drush / commands / core / cli.drush.inc
1 <?php
2
3 use Drush\Log\LogLevel;
4 use Drupal\Component\Assertion\Handle;
5 use Drush\Psysh\DrushHelpCommand;
6 use Drush\Psysh\DrushCommand;
7 use Drush\Psysh\Shell;
8
9 /**
10  * Implements hook_drush_command().
11  */
12 function cli_drush_command() {
13   $items['core-cli'] = array(
14     'description' => 'Open an interactive shell on a Drupal site.',
15     'remote-tty' => TRUE,
16     'aliases' => array('php'),
17     'bootstrap' => DRUSH_BOOTSTRAP_MAX,
18     'topics' => array('docs-repl'),
19     'options' => array(
20       'version-history' => 'Use command history based on Drupal version (Default is per site).',
21     ),
22   );
23   $items['docs-repl'] = array(
24     'description' => 'repl.md',
25     'hidden' => TRUE,
26     'topic' => TRUE,
27     'bootstrap' => DRUSH_BOOTSTRAP_NONE,
28     'callback' => 'drush_print_file',
29     'callback arguments' => array(drush_get_context('DOC_PREFIX', DRUSH_BASE_PATH) . '/docs/repl.md'),
30   );
31   return $items;
32 }
33
34 /**
35  * Command callback.
36  */
37 function drush_cli_core_cli() {
38   $drupal_major_version = drush_drupal_major_version();
39   $configuration = new \Psy\Configuration();
40
41   // Set the Drush specific history file path.
42   $configuration->setHistoryFile(drush_history_path_cli());
43
44   $shell = new Shell($configuration);
45
46   if ($drupal_major_version >= 8) {
47     // Register the assertion handler so exceptions are thrown instead of errors
48     // being triggered. This plays nicer with PsySH.
49     Handle::register();
50     $shell->setScopeVariables(['container' => \Drupal::getContainer()]);
51
52     // Add Drupal 8 specific casters to the shell configuration.
53     $configuration->addCasters(_drush_core_cli_get_casters());
54   }
55
56   // Add Drush commands to the shell.
57   $commands = [new DrushHelpCommand()];
58
59   foreach (drush_commands_categorize(_drush_core_cli_get_commands()) as $category_data) {
60     $category_title = (string) $category_data['title'];
61     foreach ($category_data['commands'] as $command_config) {
62       $command = new DrushCommand($command_config);
63       // Set the category label on each.
64       $command->setCategory($category_title);
65       $commands[] = $command;
66     }
67   }
68
69   $shell->addCommands($commands);
70
71   // PsySH will never return control to us, but our shutdown handler will still
72   // run after the user presses ^D.  Mark this command as completed to avoid a
73   // spurious error message.
74   drush_set_context('DRUSH_EXECUTION_COMPLETED', TRUE);
75
76   // Run the terminate event before the shell is run. Otherwise, if the shell
77   // is forking processes (the default), any child processes will close the
78   // database connection when they are killed. So when we return back to the
79   // parent process after, there is no connection. This will be called after the
80   // command in preflight still, but the subscriber instances are already
81   // created from before. Call terminate() regardless, this is a no-op for all
82   // DrupalBoot classes except DrupalBoot8.
83   if ($bootstrap = drush_get_bootstrap_object()) {
84     $bootstrap->terminate();
85   }
86
87   // To fix the above problem in Drupal 7, the connection can be closed manually.
88   // This will make sure a new connection is created again in child loops. So
89   // any shutdown functions will still run ok after the shell has exited.
90   if ($drupal_major_version == 7) {
91     Database::closeConnection();
92   }
93
94   $shell->run();
95 }
96
97 /**
98  * Returns a filtered list of Drush commands used for CLI commands.
99  *
100  * @return array
101  */
102 function _drush_core_cli_get_commands() {
103   $commands = drush_get_commands();
104   $ignored_commands = ['help', 'drush-psysh', 'php-eval', 'core-cli', 'php'];
105   $php_keywords = _drush_core_cli_get_php_keywords();
106
107   foreach ($commands as $name => $config) {
108     // Ignore some commands that don't make sense inside PsySH, are PHP keywords
109     // are hidden, or are aliases.
110     if (in_array($name, $ignored_commands) || in_array($name, $php_keywords) || !empty($config['hidden']) || ($name !== $config['command'])) {
111       unset($commands[$name]);
112     }
113     else {
114       // Make sure the command aliases don't contain any PHP keywords.
115       if (!empty($config['aliases'])) {
116         $commands[$name]['aliases'] = array_diff($commands[$name]['aliases'], $php_keywords);
117       }
118     }
119   }
120
121   return $commands;
122 }
123
124 /**
125  * Returns a mapped array of casters for use in the shell.
126  *
127  * These are Symfony VarDumper casters.
128  * See http://symfony.com/doc/current/components/var_dumper/advanced.html#casters
129  * for more information.
130  *
131  * @return array.
132  *   An array of caster callbacks keyed by class or interface.
133  */
134 function _drush_core_cli_get_casters() {
135   return [
136     'Drupal\Core\Entity\ContentEntityInterface' => 'Drush\Psysh\Caster::castContentEntity',
137     'Drupal\Core\Field\FieldItemListInterface' => 'Drush\Psysh\Caster::castFieldItemList',
138     'Drupal\Core\Field\FieldItemInterface' => 'Drush\Psysh\Caster::castFieldItem',
139     'Drupal\Core\Config\Entity\ConfigEntityInterface' => 'Drush\Psysh\Caster::castConfigEntity',
140     'Drupal\Core\Config\ConfigBase' => 'Drush\Psysh\Caster::castConfig',
141     'Drupal\Component\DependencyInjection\Container' => 'Drush\Psysh\Caster::castContainer',
142   ];
143 }
144
145 /**
146  * Returns the file path for the CLI history.
147  *
148  * This can either be site specific (default) or Drupal version specific.
149  *
150  * @return string.
151  */
152 function drush_history_path_cli() {
153   $cli_directory = drush_directory_cache('cli');
154
155   // If only the Drupal version is being used for the history.
156   if (drush_get_option('version-history', FALSE)) {
157     $drupal_major_version = drush_drupal_major_version();
158     $file_name = "drupal-$drupal_major_version";
159   }
160   // If there is an alias, use that in the site specific name. Otherwise,
161   // use a hash of the root path.
162   else {
163     if ($alias = drush_get_context('DRUSH_TARGET_SITE_ALIAS')) {
164       $site = drush_sitealias_get_record($alias);
165       $site_suffix = $site['#name'];
166     }
167     else {
168       $site_suffix = md5(DRUPAL_ROOT);
169     }
170
171     $file_name = "drupal-site-$site_suffix";
172   }
173
174   $full_path = "$cli_directory/$file_name";
175
176   // Output the history path if verbose is enabled.
177   if (drush_get_context('DRUSH_VERBOSE')) {
178     drush_log(dt('History: @full_path', ['@full_path' => $full_path]), LogLevel::INFO);
179   }
180
181   return $full_path;
182 }
183
184 /**
185  * Returns a list of PHP keywords.
186  *
187  * This will act as a blacklist for command and alias names.
188  *
189  * @return array
190  */
191 function _drush_core_cli_get_php_keywords() {
192   return [
193     '__halt_compiler',
194     'abstract',
195     'and',
196     'array',
197     'as',
198     'break',
199     'callable',
200     'case',
201     'catch',
202     'class',
203     'clone',
204     'const',
205     'continue',
206     'declare',
207     'default',
208     'die',
209     'do',
210     'echo',
211     'else',
212     'elseif',
213     'empty',
214     'enddeclare',
215     'endfor',
216     'endforeach',
217     'endif',
218     'endswitch',
219     'endwhile',
220     'eval',
221     'exit',
222     'extends',
223     'final',
224     'for',
225     'foreach',
226     'function',
227     'global',
228     'goto',
229     'if',
230     'implements',
231     'include',
232     'include_once',
233     'instanceof',
234     'insteadof',
235     'interface',
236     'isset',
237     'list',
238     'namespace',
239     'new',
240     'or',
241     'print',
242     'private',
243     'protected',
244     'public',
245     'require',
246     'require_once',
247     'return',
248     'static',
249     'switch',
250     'throw',
251     'trait',
252     'try',
253     'unset',
254     'use',
255     'var',
256     'while',
257     'xor',
258   ];
259 }