CFBundleIdentifier drupalconsole CFBundleName Drupal Console DocSetPlatformFamily drupalconsole isDashDocset dashIndexFilePath index.html PLIST; private $single_commands = [ 'about', 'chain', 'drush', 'help', 'init', 'list', 'self-update' ]; /** * @var SQLite3 Controller for the sqlite db required by the docset format. */ private $sqlite; /** * @var ConfigurationManager $configurationManager */ protected $configurationManager; /** * GenerateDocDashCommand constructor. * * @param $renderer * @param $consoleRoot */ public function __construct(TwigRenderer $renderer, $consoleRoot) { $this->renderer = $renderer; $this->consoleRoot = $consoleRoot; parent::__construct(); } /** * {@inheritdoc} */ protected function configure() { $this ->setName('generate:doc:dash') ->setDescription($this->trans('commands.generate.doc.dash.description')) ->addOption( 'path', null, InputOption::VALUE_OPTIONAL, $this->trans('commands.generate.doc.dash.options.path') ); ; } /** * {@inheritdoc} */ protected function execute(InputInterface $input, OutputInterface $output) { $io = new DrupalStyle($input, $output); $path = null; if ($input->hasOption('path')) { $path = $input->getOption('path'); } if (!$path) { $io->error( $this->trans('commands.generate.doc.dash.messages.missing_path') ); return 1; } // Setup the docset structure $this->initDocset($path); $application = $this->getApplication(); $command_list = []; foreach ($this->single_commands as $single_command) { $command = $application->find($single_command); $command_list['none'][] = [ 'name' => $command->getName(), 'description' => $command->getDescription(), ]; $this->renderCommand($command, $path, $this->renderer); $this->registerCommand($command, $path); } $namespaces = $application->getNamespaces(); sort($namespaces); $namespaces = array_filter( $namespaces, function ($item) { return (strpos($item, ':') <= 0); } ); foreach ($namespaces as $namespace) { $commands = $application->all($namespace); usort( $commands, function ($cmd1, $cmd2) { return strcmp($cmd1->getName(), $cmd2->getName()); } ); foreach ($commands as $command) { if ($command->getModule() == 'Console') { $command_list[$namespace][] = [ 'name' => $command->getName(), 'description' => $command->getDescription(), ]; $this->renderCommand($command, $path, $this->renderer); $this->registerCommand($command, $path); } } } $input = $application->getDefinition(); $options = $input->getOptions(); $arguments = $input->getArguments(); $parameters = [ 'command_list' => $command_list, 'options' => $options, 'arguments' => $arguments, 'css_path' => 'style.css' ]; // Set the index page $this->renderFile( 'dash/index.html.twig', $path . '/DrupalConsole.docset/Contents/Resources/Documents/index.html', $parameters, null, $this->renderer ); } private function renderCommand($command, $path, $renderer) { $input = $command->getDefinition(); $options = $input->getOptions(); $arguments = $input->getArguments(); $parameters = [ 'options' => $options, 'arguments' => $arguments, 'command' => $command->getName(), 'description' => $command->getDescription(), 'aliases' => $command->getAliases(), 'css_path' => '../style.css' ]; $this->renderFile( 'dash/generate-doc.html.twig', $path . '/DrupalConsole.docset/Contents/Resources/Documents/commands/' . str_replace(':', '-', $command->getName()) . '.html', $parameters, null, $renderer ); } private function registerCommand($command) { try { $statement = $this->sqlite->prepare('INSERT OR IGNORE INTO searchIndex(name, type, path) VALUES (:name, :type, :path)'); $statement->bindValue(':name', $command->getName(), SQLITE3_TEXT); $statement->bindValue(':type', 'Command', SQLITE3_TEXT); $statement->bindValue( ':path', 'commands/' . str_replace(':', '-', $command->getName()) . '.html', SQLITE3_TEXT ); $statement->execute(); } catch (\Exception $e) { throw $e; } } private function renderFile( $template, $target, $parameters, $renderer ) { $filesystem = new Filesystem(); try { $filesystem->dumpFile( $target, $renderer->render($template, $parameters) ); } catch (IOException $e) { throw $e; } } private function initDocset($path) { try { $filesystem = new Filesystem(); $filesystem->mkdir( $path . '/DrupalConsole.docset/Contents/Resources/Documents/', 0777 ); $filesystem->dumpFile( $path . '/DrupalConsole.docset/Contents/Info.plist', self::PLIST ); $filesystem->copy( $this->consoleRoot . '/resources/drupal-console.png', $path . '/DrupalConsole.docset/icon.png' ); $filesystem->copy( $this->consoleRoot . '/resources/dash.css', $path . '/DrupalConsole.docset/Contents/Resources/Documents/style.css' ); // create the required sqlite db $this->sqlite = new \SQLite3($path . '/DrupalConsole.docset/Contents/Resources/docSet.dsidx'); $this->sqlite->query("CREATE TABLE searchIndex(id INTEGER PRIMARY KEY, name TEXT, type TEXT, path TEXT)"); $this->sqlite->query("CREATE UNIQUE INDEX anchor ON searchIndex (name, type, path)"); } catch (\Exception $e) { throw $e; } } }