Verzeichnisstruktur phpBB-3.3.15
- Veröffentlicht
- 28.08.2024
So funktioniert es
|
Auf das letzte Element klicken. Dies geht jeweils ein Schritt zurück |
Auf das Icon klicken, dies öffnet das Verzeichnis. Nochmal klicken schließt das Verzeichnis. |
|
(Beispiel Datei-Icons)
|
Auf das Icon klicken um den Quellcode anzuzeigen |
SymfonyStyle.php
001 <?php
002
003 /*
004 * This file is part of the Symfony package.
005 *
006 * (c) Fabien Potencier <fabien@symfony.com>
007 *
008 * For the full copyright and license information, please view the LICENSE
009 * file that was distributed with this source code.
010 */
011
012 namespace Symfony\Component\Console\Style;
013
014 use Symfony\Component\Console\Exception\RuntimeException;
015 use Symfony\Component\Console\Formatter\OutputFormatter;
016 use Symfony\Component\Console\Helper\Helper;
017 use Symfony\Component\Console\Helper\ProgressBar;
018 use Symfony\Component\Console\Helper\SymfonyQuestionHelper;
019 use Symfony\Component\Console\Helper\Table;
020 use Symfony\Component\Console\Input\InputInterface;
021 use Symfony\Component\Console\Output\BufferedOutput;
022 use Symfony\Component\Console\Output\OutputInterface;
023 use Symfony\Component\Console\Question\ChoiceQuestion;
024 use Symfony\Component\Console\Question\ConfirmationQuestion;
025 use Symfony\Component\Console\Question\Question;
026 use Symfony\Component\Console\Terminal;
027
028 /**
029 * Output decorator helpers for the Symfony Style Guide.
030 *
031 * @author Kevin Bond <kevinbond@gmail.com>
032 */
033 class SymfonyStyle extends OutputStyle
034 {
035 const MAX_LINE_LENGTH = 120;
036
037 private $input;
038 private $questionHelper;
039 private $progressBar;
040 private $lineLength;
041 private $bufferedOutput;
042
043 public function __construct(InputInterface $input, OutputInterface $output)
044 {
045 $this->input = $input;
046 $this->bufferedOutput = new BufferedOutput($output->getVerbosity(), false, clone $output->getFormatter());
047 // Windows cmd wraps lines as soon as the terminal width is reached, whether there are following chars or not.
048 $width = (new Terminal())->getWidth() ?: self::MAX_LINE_LENGTH;
049 $this->lineLength = min($width - (int) (\DIRECTORY_SEPARATOR === '\\'), self::MAX_LINE_LENGTH);
050
051 parent::__construct($output);
052 }
053
054 /**
055 * Formats a message as a block of text.
056 *
057 * @param string|array $messages The message to write in the block
058 * @param string|null $type The block type (added in [] on first line)
059 * @param string|null $style The style to apply to the whole block
060 * @param string $prefix The prefix for the block
061 * @param bool $padding Whether to add vertical padding
062 * @param bool $escape Whether to escape the message
063 */
064 public function block($messages, $type = null, $style = null, $prefix = ' ', $padding = false, $escape = true)
065 {
066 $messages = \is_array($messages) ? array_values($messages) : [$messages];
067
068 $this->autoPrependBlock();
069 $this->writeln($this->createBlock($messages, $type, $style, $prefix, $padding, $escape));
070 $this->newLine();
071 }
072
073 /**
074 * {@inheritdoc}
075 */
076 public function title($message)
077 {
078 $this->autoPrependBlock();
079 $this->writeln([
080 sprintf('<comment>%s</>', OutputFormatter::escapeTrailingBackslash($message)),
081 sprintf('<comment>%s</>', str_repeat('=', Helper::strlenWithoutDecoration($this->getFormatter(), $message))),
082 ]);
083 $this->newLine();
084 }
085
086 /**
087 * {@inheritdoc}
088 */
089 public function section($message)
090 {
091 $this->autoPrependBlock();
092 $this->writeln([
093 sprintf('<comment>%s</>', OutputFormatter::escapeTrailingBackslash($message)),
094 sprintf('<comment>%s</>', str_repeat('-', Helper::strlenWithoutDecoration($this->getFormatter(), $message))),
095 ]);
096 $this->newLine();
097 }
098
099 /**
100 * {@inheritdoc}
101 */
102 public function listing(array $elements)
103 {
104 $this->autoPrependText();
105 $elements = array_map(function ($element) {
106 return sprintf(' * %s', $element);
107 }, $elements);
108
109 $this->writeln($elements);
110 $this->newLine();
111 }
112
113 /**
114 * {@inheritdoc}
115 */
116 public function text($message)
117 {
118 $this->autoPrependText();
119
120 $messages = \is_array($message) ? array_values($message) : [$message];
121 foreach ($messages as $message) {
122 $this->writeln(sprintf(' %s', $message));
123 }
124 }
125
126 /**
127 * Formats a command comment.
128 *
129 * @param string|array $message
130 */
131 public function comment($message)
132 {
133 $this->block($message, null, null, '<fg=default;bg=default> // </>', false, false);
134 }
135
136 /**
137 * {@inheritdoc}
138 */
139 public function success($message)
140 {
141 $this->block($message, 'OK', 'fg=black;bg=green', ' ', true);
142 }
143
144 /**
145 * {@inheritdoc}
146 */
147 public function error($message)
148 {
149 $this->block($message, 'ERROR', 'fg=white;bg=red', ' ', true);
150 }
151
152 /**
153 * {@inheritdoc}
154 */
155 public function warning($message)
156 {
157 $this->block($message, 'WARNING', 'fg=white;bg=red', ' ', true);
158 }
159
160 /**
161 * {@inheritdoc}
162 */
163 public function note($message)
164 {
165 $this->block($message, 'NOTE', 'fg=yellow', ' ! ');
166 }
167
168 /**
169 * {@inheritdoc}
170 */
171 public function caution($message)
172 {
173 $this->block($message, 'CAUTION', 'fg=white;bg=red', ' ! ', true);
174 }
175
176 /**
177 * {@inheritdoc}
178 */
179 public function table(array $headers, array $rows)
180 {
181 $style = clone Table::getStyleDefinition('symfony-style-guide');
182 $style->setCellHeaderFormat('<info>%s</info>');
183
184 $table = new Table($this);
185 $table->setHeaders($headers);
186 $table->setRows($rows);
187 $table->setStyle($style);
188
189 $table->render();
190 $this->newLine();
191 }
192
193 /**
194 * {@inheritdoc}
195 */
196 public function ask($question, $default = null, $validator = null)
197 {
198 $question = new Question($question, $default);
199 $question->setValidator($validator);
200
201 return $this->askQuestion($question);
202 }
203
204 /**
205 * {@inheritdoc}
206 */
207 public function askHidden($question, $validator = null)
208 {
209 $question = new Question($question);
210
211 $question->setHidden(true);
212 $question->setValidator($validator);
213
214 return $this->askQuestion($question);
215 }
216
217 /**
218 * {@inheritdoc}
219 */
220 public function confirm($question, $default = true)
221 {
222 return $this->askQuestion(new ConfirmationQuestion($question, $default));
223 }
224
225 /**
226 * {@inheritdoc}
227 */
228 public function choice($question, array $choices, $default = null)
229 {
230 if (null !== $default) {
231 $values = array_flip($choices);
232 $default = isset($values[$default]) ? $values[$default] : $default;
233 }
234
235 return $this->askQuestion(new ChoiceQuestion($question, $choices, $default));
236 }
237
238 /**
239 * {@inheritdoc}
240 */
241 public function progressStart($max = 0)
242 {
243 $this->progressBar = $this->createProgressBar($max);
244 $this->progressBar->start();
245 }
246
247 /**
248 * {@inheritdoc}
249 */
250 public function progressAdvance($step = 1)
251 {
252 $this->getProgressBar()->advance($step);
253 }
254
255 /**
256 * {@inheritdoc}
257 */
258 public function progressFinish()
259 {
260 $this->getProgressBar()->finish();
261 $this->newLine(2);
262 $this->progressBar = null;
263 }
264
265 /**
266 * {@inheritdoc}
267 */
268 public function createProgressBar($max = 0)
269 {
270 $progressBar = parent::createProgressBar($max);
271
272 if ('\\' !== \DIRECTORY_SEPARATOR || 'Hyper' === getenv('TERM_PROGRAM')) {
273 $progressBar->setEmptyBarCharacter('░'); // light shade character \u2591
274 $progressBar->setProgressCharacter('');
275 $progressBar->setBarCharacter('▓'); // dark shade character \u2593
276 }
277
278 return $progressBar;
279 }
280
281 /**
282 * @return mixed
283 */
284 public function askQuestion(Question $question)
285 {
286 if ($this->input->isInteractive()) {
287 $this->autoPrependBlock();
288 }
289
290 if (!$this->questionHelper) {
291 $this->questionHelper = new SymfonyQuestionHelper();
292 }
293
294 $answer = $this->questionHelper->ask($this->input, $this, $question);
295
296 if ($this->input->isInteractive()) {
297 $this->newLine();
298 $this->bufferedOutput->write("\n");
299 }
300
301 return $answer;
302 }
303
304 /**
305 * {@inheritdoc}
306 */
307 public function writeln($messages, $type = self::OUTPUT_NORMAL)
308 {
309 parent::writeln($messages, $type);
310 $this->bufferedOutput->writeln($this->reduceBuffer($messages), $type);
311 }
312
313 /**
314 * {@inheritdoc}
315 */
316 public function write($messages, $newline = false, $type = self::OUTPUT_NORMAL)
317 {
318 parent::write($messages, $newline, $type);
319 $this->bufferedOutput->write($this->reduceBuffer($messages), $newline, $type);
320 }
321
322 /**
323 * {@inheritdoc}
324 */
325 public function newLine($count = 1)
326 {
327 parent::newLine($count);
328 $this->bufferedOutput->write(str_repeat("\n", $count));
329 }
330
331 /**
332 * Returns a new instance which makes use of stderr if available.
333 *
334 * @return self
335 */
336 public function getErrorStyle()
337 {
338 return new self($this->input, $this->getErrorOutput());
339 }
340
341 /**
342 * @return ProgressBar
343 */
344 private function getProgressBar()
345 {
346 if (!$this->progressBar) {
347 throw new RuntimeException('The ProgressBar is not started.');
348 }
349
350 return $this->progressBar;
351 }
352
353 private function autoPrependBlock()
354 {
355 $chars = substr(str_replace(\PHP_EOL, "\n", $this->bufferedOutput->fetch()), -2);
356
357 if (!isset($chars[0])) {
358 $this->newLine(); //empty history, so we should start with a new line.
359
360 return;
361 }
362 //Prepend new line for each non LF chars (This means no blank line was output before)
363 $this->newLine(2 - substr_count($chars, "\n"));
364 }
365
366 private function autoPrependText()
367 {
368 $fetched = $this->bufferedOutput->fetch();
369 //Prepend new line if last char isn't EOL:
370 if ("\n" !== substr($fetched, -1)) {
371 $this->newLine();
372 }
373 }
374
375 private function reduceBuffer($messages)
376 {
377 // We need to know if the two last chars are PHP_EOL
378 // Preserve the last 4 chars inserted (PHP_EOL on windows is two chars) in the history buffer
379 return array_map(function ($value) {
380 return substr($value, -4);
381 }, array_merge([$this->bufferedOutput->fetch()], (array) $messages));
382 }
383
384 private function createBlock($messages, $type = null, $style = null, $prefix = ' ', $padding = false, $escape = false)
385 {
386 $indentLength = 0;
387 $prefixLength = Helper::strlenWithoutDecoration($this->getFormatter(), $prefix);
388 $lines = [];
389
390 if (null !== $type) {
391 $type = sprintf('[%s] ', $type);
392 $indentLength = \strlen($type);
393 $lineIndentation = str_repeat(' ', $indentLength);
394 }
395
396 // wrap and add newlines for each element
397 foreach ($messages as $key => $message) {
398 if ($escape) {
399 $message = OutputFormatter::escape($message);
400 }
401
402 $lines = array_merge($lines, explode(\PHP_EOL, wordwrap($message, $this->lineLength - $prefixLength - $indentLength, \PHP_EOL, true)));
403
404 if (\count($messages) > 1 && $key < \count($messages) - 1) {
405 $lines[] = '';
406 }
407 }
408
409 $firstLineIndex = 0;
410 if ($padding && $this->isDecorated()) {
411 $firstLineIndex = 1;
412 array_unshift($lines, '');
413 $lines[] = '';
414 }
415
416 foreach ($lines as $i => &$line) {
417 if (null !== $type) {
418 $line = $firstLineIndex === $i ? $type.$line : $lineIndentation.$line;
419 }
420
421 $line = $prefix.$line;
422 $line .= str_repeat(' ', $this->lineLength - Helper::strlenWithoutDecoration($this->getFormatter(), $line));
423
424 if ($style) {
425 $line = sprintf('<%s>%s</>', $style, $line);
426 }
427 }
428
429 return $lines;
430 }
431 }
432