Version 1
[yaffs-website] / vendor / drupal / console / src / Command / Develop / GenerateDocDashCommand.php
1 <?php
2
3 /**
4  * @file
5  * Contains \Drupal\Console\Command\Develop\GenerateDocDashCommand.
6  */
7
8 namespace Drupal\Console\Command\Develop;
9
10 use Symfony\Component\Console\Input\InputInterface;
11 use Symfony\Component\Console\Output\OutputInterface;
12 use Symfony\Component\Console\Input\InputOption;
13 use Symfony\Component\Filesystem\Exception\IOException;
14 use Symfony\Component\Filesystem\Filesystem;
15 use Symfony\Component\Console\Command\Command;
16 use Drupal\Console\Core\Style\DrupalStyle;
17 use Drupal\Console\Core\Command\Shared\CommandTrait;
18 use Drupal\Console\Core\Utils\TwigRenderer;
19 use Drupal\Console\Core\Utils\ConfigurationManager;
20
21 class GenerateDocDashCommand extends Command
22 {
23     use CommandTrait;
24
25     /**
26      * @var TwigRenderer $renderer
27      */
28     protected $renderer;
29     protected $consoleRoot;
30     /**
31      * @constant Contents of the plist file required by the docset format.
32      */
33     const PLIST = <<<PLIST
34 <?xml version="1.0" encoding="UTF-8"?>
35 <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
36 <plist version="1.0">
37 <dict>
38         <key>CFBundleIdentifier</key>
39         <string>drupalconsole</string>
40         <key>CFBundleName</key>
41         <string>Drupal Console</string>
42         <key>DocSetPlatformFamily</key>
43         <string>drupalconsole</string>
44         <key>isDashDocset</key>
45         <true/>
46         <key>dashIndexFilePath</key>
47     <string>index.html</string>
48 </dict>
49 </plist>
50 PLIST;
51
52     private $single_commands = [
53       'about',
54       'chain',
55       'drush',
56       'help',
57       'init',
58       'list',
59       'self-update'
60     ];
61
62     /**
63      * @var SQLite3 Controller for the sqlite db required by the docset format.
64      */
65     private $sqlite;
66
67     /**
68      * @var ConfigurationManager $configurationManager
69      */
70     protected $configurationManager;
71
72     /**
73      * GenerateDocDashCommand constructor.
74      *
75      * @param $renderer
76      * @param $consoleRoot
77      */
78     public function __construct(TwigRenderer $renderer, $consoleRoot)
79     {
80         $this->renderer = $renderer;
81         $this->consoleRoot = $consoleRoot;
82         parent::__construct();
83     }
84
85
86
87     /**
88      * {@inheritdoc}
89      */
90     protected function configure()
91     {
92         $this
93             ->setName('generate:doc:dash')
94             ->setDescription($this->trans('commands.generate.doc.dash.description'))
95             ->addOption(
96                 'path',
97                 null,
98                 InputOption::VALUE_OPTIONAL,
99                 $this->trans('commands.generate.doc.dash.options.path')
100             );
101         ;
102     }
103
104     /**
105      * {@inheritdoc}
106      */
107     protected function execute(InputInterface $input, OutputInterface $output)
108     {
109         $io = new DrupalStyle($input, $output);
110
111         $path = null;
112         if ($input->hasOption('path')) {
113             $path = $input->getOption('path');
114         }
115
116         if (!$path) {
117             $io->error(
118                 $this->trans('commands.generate.doc.dash.messages.missing_path')
119             );
120
121             return 1;
122         }
123
124         // Setup the docset structure
125         $this->initDocset($path);
126
127         $application = $this->getApplication();
128         $command_list = [];
129
130         foreach ($this->single_commands as $single_command) {
131             $command = $application->find($single_command);
132             $command_list['none'][] = [
133               'name' => $command->getName(),
134               'description' => $command->getDescription(),
135             ];
136             $this->renderCommand($command, $path, $this->renderer);
137             $this->registerCommand($command, $path);
138         }
139
140         $namespaces = $application->getNamespaces();
141         sort($namespaces);
142
143         $namespaces = array_filter(
144             $namespaces, function ($item) {
145                 return (strpos($item, ':') <= 0);
146             }
147         );
148
149         foreach ($namespaces as $namespace) {
150             $commands = $application->all($namespace);
151
152             usort(
153                 $commands, function ($cmd1, $cmd2) {
154                     return strcmp($cmd1->getName(), $cmd2->getName());
155                 }
156             );
157
158             foreach ($commands as $command) {
159                 if ($command->getModule() == 'Console') {
160                     $command_list[$namespace][] = [
161                       'name' => $command->getName(),
162                       'description' => $command->getDescription(),
163                     ];
164                     $this->renderCommand($command, $path, $this->renderer);
165                     $this->registerCommand($command, $path);
166                 }
167             }
168         }
169
170         $input = $application->getDefinition();
171         $options = $input->getOptions();
172         $arguments = $input->getArguments();
173         $parameters = [
174           'command_list' => $command_list,
175           'options' => $options,
176           'arguments' => $arguments,
177           'css_path' => 'style.css'
178         ];
179
180         // Set the index page
181         $this->renderFile(
182             'dash/index.html.twig',
183             $path . '/DrupalConsole.docset/Contents/Resources/Documents/index.html',
184             $parameters,
185             null,
186             $this->renderer
187         );
188     }
189
190     private function renderCommand($command, $path, $renderer)
191     {
192         $input = $command->getDefinition();
193         $options = $input->getOptions();
194         $arguments = $input->getArguments();
195
196         $parameters = [
197           'options' => $options,
198           'arguments' => $arguments,
199           'command' => $command->getName(),
200           'description' => $command->getDescription(),
201           'aliases' => $command->getAliases(),
202           'css_path' => '../style.css'
203         ];
204
205         $this->renderFile(
206             'dash/generate-doc.html.twig',
207             $path . '/DrupalConsole.docset/Contents/Resources/Documents/commands/'
208             . str_replace(':', '-', $command->getName()) . '.html',
209             $parameters,
210             null,
211             $renderer
212         );
213     }
214
215     private function registerCommand($command)
216     {
217         try {
218             $statement = $this->sqlite->prepare('INSERT OR IGNORE INTO searchIndex(name, type, path) VALUES (:name, :type, :path)');
219             $statement->bindValue(':name', $command->getName(), SQLITE3_TEXT);
220             $statement->bindValue(':type', 'Command', SQLITE3_TEXT);
221             $statement->bindValue(
222                 ':path',
223                 'commands/'
224                 . str_replace(':', '-', $command->getName()) . '.html',
225                 SQLITE3_TEXT
226             );
227             $statement->execute();
228         } catch (\Exception $e) {
229             throw $e;
230         }
231     }
232
233     private function renderFile(
234         $template,
235         $target,
236         $parameters,
237         $renderer
238     ) {
239         $filesystem = new Filesystem();
240         try {
241             $filesystem->dumpFile(
242                 $target,
243                 $renderer->render($template, $parameters)
244             );
245         } catch (IOException $e) {
246             throw $e;
247         }
248     }
249
250     private function initDocset($path)
251     {
252         try {
253             $filesystem = new Filesystem();
254             $filesystem->mkdir(
255                 $path . '/DrupalConsole.docset/Contents/Resources/Documents/',
256                 0777
257             );
258             $filesystem->dumpFile(
259                 $path . '/DrupalConsole.docset/Contents/Info.plist',
260                 self::PLIST
261             );
262
263             $filesystem->copy(
264                 $this->consoleRoot . '/resources/drupal-console.png',
265                 $path . '/DrupalConsole.docset/icon.png'
266             );
267             $filesystem->copy(
268                 $this->consoleRoot . '/resources/dash.css',
269                 $path . '/DrupalConsole.docset/Contents/Resources/Documents/style.css'
270             );
271             // create the required sqlite db
272             $this->sqlite = new \SQLite3($path . '/DrupalConsole.docset/Contents/Resources/docSet.dsidx');
273             $this->sqlite->query("CREATE TABLE searchIndex(id INTEGER PRIMARY KEY, name TEXT, type TEXT, path TEXT)");
274             $this->sqlite->query("CREATE UNIQUE INDEX anchor ON searchIndex (name, type, path)");
275         } catch (\Exception $e) {
276             throw $e;
277         }
278     }
279 }