Updated to Drupal 8.5. Core Media not yet in use.
[yaffs-website] / vendor / drush / drush / src / Drupal / Commands / core / CliCommands.php
diff --git a/vendor/drush/drush/src/Drupal/Commands/core/CliCommands.php b/vendor/drush/drush/src/Drupal/Commands/core/CliCommands.php
new file mode 100644 (file)
index 0000000..538893b
--- /dev/null
@@ -0,0 +1,274 @@
+<?php
+
+namespace Drush\Drupal\Commands\core;
+
+use Drush\Commands\DrushCommands;
+use Drush\Drush;
+use Drush\Log\LogLevel;
+use Drush\Psysh\DrushCommand;
+use Drush\Psysh\DrushHelpCommand;
+use Drupal\Component\Assertion\Handle;
+use Drush\Psysh\Shell;
+use Psy\Configuration;
+use Psy\VersionUpdater\Checker;
+use Webmozart\PathUtil\Path;
+
+class CliCommands extends DrushCommands
+{
+    /**
+     * Drush's PHP Shell.
+     *
+     * @command docs:repl
+     * @aliases docs-repl
+     * @hidden
+     * @topic
+     */
+    public function docs()
+    {
+        self::printFile(DRUSH_BASE_PATH. '/docs/repl.md');
+    }
+
+    /**
+     * @command php:cli
+     * @description Open an interactive shell on a Drupal site.
+     * @aliases php,core:cli,core-cli
+     * @option $version-history Use command history based on Drupal version
+     *   (Default is per site).
+     * @topics docs:repl
+     * @remote-tty
+     */
+    public function cli(array $options = ['version-history' => false])
+    {
+        $configuration = new Configuration();
+
+        // Set the Drush specific history file path.
+        $configuration->setHistoryFile($this->historyPath($options));
+
+        // Disable checking for updates. Our dependencies are managed with Composer.
+        $configuration->setUpdateCheck(Checker::NEVER);
+
+        $shell = new Shell($configuration);
+
+
+        // Register the assertion handler so exceptions are thrown instead of errors
+        // being triggered. This plays nicer with PsySH.
+        Handle::register();
+        $shell->setScopeVariables(['container' => \Drupal::getContainer()]);
+
+        // Add Drupal 8 specific casters to the shell configuration.
+        $configuration->addCasters($this->getCasters());
+
+        // Add Drush commands to the shell.
+        $shell->addCommands([new DrushHelpCommand()]);
+        $shell->addCommands($this->getDrushCommands());
+
+        // PsySH will never return control to us, but our shutdown handler will still
+        // run after the user presses ^D.  Mark this command as completed to avoid a
+        // spurious error message.
+        drush_set_context('DRUSH_EXECUTION_COMPLETED', true);
+
+        // Run the terminate event before the shell is run. Otherwise, if the shell
+        // is forking processes (the default), any child processes will close the
+        // database connection when they are killed. So when we return back to the
+        // parent process after, there is no connection. This will be called after the
+        // command in preflight still, but the subscriber instances are already
+        // created from before. Call terminate() regardless, this is a no-op for all
+        // DrupalBoot classes except DrupalBoot8.
+        if ($bootstrap = Drush::bootstrap()) {
+            $bootstrap->terminate();
+        }
+
+        $shell->run();
+    }
+
+    /**
+     * Returns a filtered list of Drush commands used for CLI commands.
+     *
+     * @return array
+     */
+    protected function getDrushCommands()
+    {
+        $application = Drush::getApplication();
+        $commands = $application->all();
+
+        $ignored_commands = [
+            'help',
+            'php:cli',
+                'core:cli',
+                'core-cli',
+                'php',
+            'php:eval',
+                'eval',
+                'ev',
+            'php:script',
+                'scr',
+        ];
+        $php_keywords = $this->getPhpKeywords();
+
+        /** @var \Consolidation\AnnotatedCommand\AnnotatedCommand $command */
+        foreach ($commands as $name => $command) {
+            $definition = $command->getDefinition();
+
+            // Ignore some commands that don't make sense inside PsySH, are PHP keywords
+            // are hidden, or are aliases.
+            if (in_array($name, $ignored_commands) || in_array($name, $php_keywords) || ($name !== $command->getName())) {
+                unset($commands[$name]);
+            } else {
+                $aliases = $command->getAliases();
+                // Make sure the command aliases don't contain any PHP keywords.
+                if (!empty($aliases)) {
+                    $command->setAliases(array_diff($aliases, $php_keywords));
+                }
+            }
+        }
+
+        return array_map(function ($command) {
+            return new DrushCommand($command);
+        }, $commands);
+    }
+
+    /**
+     * Returns a mapped array of casters for use in the shell.
+     *
+     * These are Symfony VarDumper casters.
+     * See http://symfony.com/doc/current/components/var_dumper/advanced.html#casters
+     * for more information.
+     *
+     * @return array.
+     *   An array of caster callbacks keyed by class or interface.
+     */
+    protected function getCasters()
+    {
+        return [
+        'Drupal\Core\Entity\ContentEntityInterface' => 'Drush\Psysh\Caster::castContentEntity',
+        'Drupal\Core\Field\FieldItemListInterface' => 'Drush\Psysh\Caster::castFieldItemList',
+        'Drupal\Core\Field\FieldItemInterface' => 'Drush\Psysh\Caster::castFieldItem',
+        'Drupal\Core\Config\Entity\ConfigEntityInterface' => 'Drush\Psysh\Caster::castConfigEntity',
+        'Drupal\Core\Config\ConfigBase' => 'Drush\Psysh\Caster::castConfig',
+        'Drupal\Component\DependencyInjection\Container' => 'Drush\Psysh\Caster::castContainer',
+        'Drupal\Component\Render\MarkupInterface' => 'Drush\Psysh\Caster::castMarkup',
+        ];
+    }
+
+    /**
+     * Returns the file path for the CLI history.
+     *
+     * This can either be site specific (default) or Drupal version specific.
+     *
+     * @param array $options
+     *
+     * @return string.
+     */
+    protected function historyPath(array $options)
+    {
+        $cli_directory = Path::join($this->getConfig()->cache(), 'cli');
+        $drupal_major_version = Drush::getMajorVersion();
+
+        // If there is no drupal version (and thus no root). Just use the current
+        // path.
+        // @todo Could use a global file within drush?
+        if (!$drupal_major_version) {
+            $file_name = 'global-' . md5($this->getConfig()->cwd());
+        } // If only the Drupal version is being used for the history.
+        else if ($options['version-history']) {
+            $file_name = "drupal-$drupal_major_version";
+        } // If there is an alias, use that in the site specific name. Otherwise,
+        // use a hash of the root path.
+        else {
+             $aliasRecord = Drush::aliasManager()->getSelf();
+
+            if ($aliasRecord->name()) {
+                $site_suffix = ltrim($aliasRecord->name(), '@');
+            } else {
+                $drupal_root = Drush::bootstrapManager()->getRoot();
+                $site_suffix = md5($drupal_root);
+            }
+
+            $file_name = "drupal-site-$site_suffix";
+        }
+
+        $full_path = "$cli_directory/$file_name";
+
+        $this->logger()->info(dt('History: @full_path', ['@full_path' => $full_path]));
+
+        return $full_path;
+    }
+
+    /**
+     * Returns a list of PHP keywords.
+     *
+     * This will act as a blacklist for command and alias names.
+     *
+     * @return array
+     */
+    protected function getPhpKeywords()
+    {
+        return [
+        '__halt_compiler',
+        'abstract',
+        'and',
+        'array',
+        'as',
+        'break',
+        'callable',
+        'case',
+        'catch',
+        'class',
+        'clone',
+        'const',
+        'continue',
+        'declare',
+        'default',
+        'die',
+        'do',
+        'echo',
+        'else',
+        'elseif',
+        'empty',
+        'enddeclare',
+        'endfor',
+        'endforeach',
+        'endif',
+        'endswitch',
+        'endwhile',
+        'eval',
+        'exit',
+        'extends',
+        'final',
+        'for',
+        'foreach',
+        'function',
+        'global',
+        'goto',
+        'if',
+        'implements',
+        'include',
+        'include_once',
+        'instanceof',
+        'insteadof',
+        'interface',
+        'isset',
+        'list',
+        'namespace',
+        'new',
+        'or',
+        'print',
+        'private',
+        'protected',
+        'public',
+        'require',
+        'require_once',
+        'return',
+        'static',
+        'switch',
+        'throw',
+        'trait',
+        'try',
+        'unset',
+        'use',
+        'var',
+        'while',
+        'xor',
+        ];
+    }
+}