Completed
Push — master ( b28d44...6f2c13 )
by Marko
40:03 queued 25:04
created

src/Command/CKEditorInstallerCommand.php (1 issue)

1
<?php
2
3
/*
4
 * This file is part of the FOSCKEditor Bundle.
5
 *
6
 * (c) 2018 - present  Friends of Symfony
7
 * (c) 2009 - 2017     Eric GELOEN <[email protected]>
8
 *
9
 * For the full copyright and license information, please read the LICENSE
10
 * file that was distributed with this source code.
11
 */
12
13
namespace FOS\CKEditorBundle\Command;
14
15
use FOS\CKEditorBundle\Installer\CKEditorInstaller;
16
use Symfony\Component\Console\Command\Command;
17
use Symfony\Component\Console\Helper\ProgressBar;
18
use Symfony\Component\Console\Helper\QuestionHelper;
19
use Symfony\Component\Console\Input\InputArgument;
20
use Symfony\Component\Console\Input\InputInterface;
21
use Symfony\Component\Console\Input\InputOption;
22
use Symfony\Component\Console\Output\OutputInterface;
23
use Symfony\Component\Console\Question\ChoiceQuestion;
24
25
/**
26
 * @author GeLo <[email protected]>
27
 */
28
final class CKEditorInstallerCommand extends Command
29
{
30
    /**
31
     * @var CKEditorInstaller
32
     */
33
    private $installer;
34
35
    /**
36
     * @param CKEditorInstaller|null $installer
37
     */
38
    public function __construct(CKEditorInstaller $installer = null)
39
    {
40
        parent::__construct();
41
42
        $this->installer = $installer ?: new CKEditorInstaller();
43
    }
44
45
    /**
46
     * {@inheritdoc}
47
     */
48
    protected function configure()
49
    {
50
        $this
51
            ->setName('ckeditor:install')
52
            ->setDescription('Install CKEditor')
53
            ->addArgument('path', InputArgument::OPTIONAL, 'Where to install CKEditor')
54
            ->addOption(
55
                'release',
56
                null,
57
                InputOption::VALUE_OPTIONAL,
58
                'CKEditor release (basic, standard or full)'
59
            )
60
            ->addOption('tag', null, InputOption::VALUE_OPTIONAL, 'CKEditor tag (x.y.z or latest)')
61
            ->addOption(
62
                'clear',
63
                null,
64
                InputOption::VALUE_OPTIONAL,
65
                'How to clear previous CKEditor installation (drop, keep or skip)'
66
            )
67
            ->addOption(
68
                'exclude',
69
                null,
70
                InputOption::VALUE_IS_ARRAY | InputOption::VALUE_OPTIONAL,
71
                'Path to exclude when extracting CKEditor'
72
            )
73
            ->setHelp(
74
                <<<'EOF'
75
The <info>%command.name%</info> command install CKEditor in your application:
76
77
  <info>php %command.full_name%</info>
78
  
79
You can install it at a specific path (absolute):
80
81
  <info>php %command.full_name% path</info>
82
  
83
You can install a specific release (basic, standard or full):
84
85
  <info>php %command.full_name% --release=full</info>
86
  
87
You can install a specific version:
88
89
  <info>php %command.full_name% --tag=4.7.0</info>
90
91
If there is a previous CKEditor installation detected, 
92
you can control how it should be handled in non-interactive mode:
93
94
  <info>php %command.full_name% --clear=drop</info>
95
  <info>php %command.full_name% --clear=keep</info>
96
  <info>php %command.full_name% --clear=skip</info>
97
  
98
You can exclude path(s) when extracting CKEditor:
99
100
  <info>php %command.full_name% --exclude=samples --exclude=adapters</info>
101
EOF
102
            );
103
    }
104
105
    /**
106
     * {@inheritdoc}
107
     */
108
    protected function execute(InputInterface $input, OutputInterface $output)
109
    {
110
        $this->title($output);
111
112
        $success = $this->installer->install($this->createOptions($input, $output));
113
114
        if ($success) {
0 ignored issues
show
The condition $success is always true.
Loading history...
115
            $this->success('CKEditor has been successfully installed...', $output);
116
        } else {
117
            $this->info('CKEditor installation has been skipped...', $output);
118
        }
119
    }
120
121
    /**
122
     * @param InputInterface  $input
123
     * @param OutputInterface $output
124
     *
125
     * @return mixed[]
126
     */
127
    private function createOptions(InputInterface $input, OutputInterface $output)
128
    {
129
        $options = ['notifier' => $this->createNotifier($input, $output)];
130
131
        if ($input->hasArgument('path')) {
132
            $options['path'] = $input->getArgument('path');
133
        }
134
135
        if ($input->hasOption('release')) {
136
            $options['release'] = $input->getOption('release');
137
        }
138
139
        if ($input->hasOption('tag')) {
140
            $options['version'] = $input->getOption('tag');
141
        }
142
143
        if ($input->hasOption('exclude')) {
144
            $options['excludes'] = $input->getOption('exclude');
145
        }
146
147
        if ($input->hasOption('clear')) {
148
            $options['clear'] = $input->getOption('clear');
149
        }
150
151
        return array_filter($options);
152
    }
153
154
    /**
155
     * @param InputInterface  $input
156
     * @param OutputInterface $output
157
     *
158
     * @return \Closure
159
     */
160
    private function createNotifier(InputInterface $input, OutputInterface $output)
161
    {
162
        $clear = new ProgressBar($output);
163
        $download = new ProgressBar($output);
164
        $extract = new ProgressBar($output);
165
166
        return function ($type, $data) use ($input, $output, $clear, $download, $extract) {
167
            switch ($type) {
168
                case CKEditorInstaller::NOTIFY_CLEAR:
169
                    $result = $this->choice(
170
                        [
171
                            sprintf('CKEditor is already installed in "%s"...', $data),
172
                            '',
173
                            'What do you want to do?',
174
                        ],
175
                        $choices = [
176
                            CKEditorInstaller::CLEAR_DROP => 'Drop the directory & reinstall CKEditor',
177
                            CKEditorInstaller::CLEAR_KEEP => 'Keep the directory & reinstall CKEditor by overriding files',
178
                            CKEditorInstaller::CLEAR_SKIP => 'Skip installation',
179
                        ],
180
                        CKEditorInstaller::CLEAR_DROP,
181
                        $input,
182
                        $output
183
                    );
184
185
                    if (false !== ($key = array_search($result, $choices, true))) {
186
                        $result = $key;
187
                    }
188
189
                    if (CKEditorInstaller::CLEAR_DROP === $result) {
190
                        $this->comment(sprintf('Dropping CKEditor from "%s"', $data), $output);
191
                    }
192
193
                    return $result;
194
195
                case CKEditorInstaller::NOTIFY_CLEAR_ARCHIVE:
196
                    $this->comment(sprintf('Dropping CKEditor ZIP archive "%s"', $data), $output);
197
198
                    break;
199
200
                case CKEditorInstaller::NOTIFY_CLEAR_COMPLETE:
201
                    $this->finishProgressBar($clear, $output);
202
203
                    break;
204
205
                case CKEditorInstaller::NOTIFY_CLEAR_PROGRESS:
206
                    $clear->advance();
207
208
                    break;
209
210
                case CKEditorInstaller::NOTIFY_CLEAR_SIZE:
211
                    $clear->start($data);
212
213
                    break;
214
215
                case CKEditorInstaller::NOTIFY_DOWNLOAD:
216
                    $this->comment(sprintf('Downloading CKEditor ZIP archive from "%s"', $data), $output);
217
218
                    break;
219
220
                case CKEditorInstaller::NOTIFY_DOWNLOAD_COMPLETE:
221
                    $this->finishProgressBar($download, $output);
222
223
                    break;
224
225
                case CKEditorInstaller::NOTIFY_DOWNLOAD_PROGRESS:
226
                    $download->setProgress($data);
227
228
                    break;
229
230
                case CKEditorInstaller::NOTIFY_DOWNLOAD_SIZE:
231
                    $download->start($data);
232
233
                    break;
234
235
                case CKEditorInstaller::NOTIFY_EXTRACT:
236
                    $this->comment(sprintf('Extracting CKEditor ZIP archive to "%s"', $data), $output);
237
238
                    break;
239
240
                case CKEditorInstaller::NOTIFY_EXTRACT_COMPLETE:
241
                    $this->finishProgressBar($extract, $output);
242
243
                    break;
244
245
                case CKEditorInstaller::NOTIFY_EXTRACT_PROGRESS:
246
                    $extract->advance();
247
248
                    break;
249
250
                case CKEditorInstaller::NOTIFY_EXTRACT_SIZE:
251
                    $extract->start($data);
252
253
                    break;
254
            }
255
        };
256
    }
257
258
    /**
259
     * @param OutputInterface $output
260
     */
261
    private function title(OutputInterface $output)
262
    {
263
        $output->writeln(
264
            [
265
                '----------------------',
266
                '| CKEditor Installer |',
267
                '----------------------',
268
                '',
269
            ]
270
        );
271
    }
272
273
    /**
274
     * @param string|string[] $message
275
     * @param OutputInterface $output
276
     */
277
    private function comment($message, OutputInterface $output)
278
    {
279
        $output->writeln(' // '.$message);
280
        $output->writeln('');
281
    }
282
283
    /**
284
     * @param string          $message
285
     * @param OutputInterface $output
286
     */
287
    private function success($message, OutputInterface $output)
288
    {
289
        $this->block('[OK] - '.$message, $output, 'green', 'black');
290
    }
291
292
    /**
293
     * @param string          $message
294
     * @param OutputInterface $output
295
     */
296
    private function info($message, OutputInterface $output)
297
    {
298
        $this->block('[INFO] - '.$message, $output, 'yellow', 'black');
299
    }
300
301
    /**
302
     * @param string          $message
303
     * @param OutputInterface $output
304
     * @param string          $background
305
     * @param string          $font
306
     */
307
    private function block($message, OutputInterface $output, $background = null, $font = null)
308
    {
309
        $options = [];
310
311
        if (null !== $background) {
312
            $options[] = 'bg='.$background;
313
        }
314
315
        if (null !== $font) {
316
            $options[] = 'fg='.$font;
317
        }
318
319
        $pattern = ' %s ';
320
321
        if (!empty($options)) {
322
            $pattern = '<'.implode(';', $options).'>'.$pattern.'</>';
323
        }
324
325
        $output->writeln($block = sprintf($pattern, str_repeat(' ', strlen($message))));
326
        $output->writeln(sprintf($pattern, $message));
327
        $output->writeln($block);
328
    }
329
330
    /**
331
     * @param string|string[] $question
332
     * @param string[]        $choices
333
     * @param string          $default
334
     * @param InputInterface  $input
335
     * @param OutputInterface $output
336
     *
337
     * @return string|null
338
     */
339
    private function choice($question, array $choices, $default, InputInterface $input, OutputInterface $output)
340
    {
341
        $helper = new QuestionHelper();
342
343
        if (is_array($question)) {
344
            $question = implode("\n", $question);
345
        }
346
347
        $result = $helper->ask(
348
            $input,
349
            $output,
350
            new ChoiceQuestion($question, $choices, $default)
351
        );
352
353
        $output->writeln('');
354
355
        return $result;
356
    }
357
358
    /**
359
     * @param ProgressBar     $progress
360
     * @param OutputInterface $output
361
     */
362
    private function finishProgressBar($progress, OutputInterface $output)
363
    {
364
        $progress->finish();
365
        $output->writeln(['', '']);
366
    }
367
}
368