--- /dev/null
+<?php
+namespace Robo\Common;
+
+use Symfony\Component\Console\Helper\QuestionHelper;
+use Symfony\Component\Console\Question\ConfirmationQuestion;
+use Symfony\Component\Console\Question\Question;
+use Symfony\Component\Console\Style\SymfonyStyle;
+
+trait IO
+{
+ use InputAwareTrait;
+ use OutputAwareTrait;
+
+ /**
+ * @var \Symfony\Component\Console\Style\SymfonyStyle
+ */
+ protected $io;
+
+ /**
+ * Provide access to SymfonyStyle object.
+ *
+ * @return SymfonyStyle
+ *
+ * @see http://symfony.com/blog/new-in-symfony-2-8-console-style-guide
+ */
+ protected function io()
+ {
+ if (!$this->io) {
+ $this->io = new SymfonyStyle($this->input(), $this->output());
+ }
+ return $this->io;
+ }
+
+ /**
+ * @param string $nonDecorated
+ * @param string $decorated
+ *
+ * @return string
+ */
+ protected function decorationCharacter($nonDecorated, $decorated)
+ {
+ if (!$this->output()->isDecorated() || (strncasecmp(PHP_OS, 'WIN', 3) == 0)) {
+ return $nonDecorated;
+ }
+ return $decorated;
+ }
+
+ /**
+ * @param string $text
+ */
+ protected function say($text)
+ {
+ $char = $this->decorationCharacter('>', '➜');
+ $this->writeln("$char $text");
+ }
+
+ /**
+ * @param string $text
+ * @param int $length
+ * @param string $color
+ */
+ protected function yell($text, $length = 40, $color = 'green')
+ {
+ $char = $this->decorationCharacter(' ', '➜');
+ $format = "$char <fg=white;bg=$color;options=bold>%s</fg=white;bg=$color;options=bold>";
+ $this->formattedOutput($text, $length, $format);
+ }
+
+ /**
+ * @param string $text
+ * @param int $length
+ * @param string $format
+ */
+ protected function formattedOutput($text, $length, $format)
+ {
+ $lines = explode("\n", trim($text, "\n"));
+ $maxLineLength = array_reduce(array_map('strlen', $lines), 'max');
+ $length = max($length, $maxLineLength);
+ $len = $length + 2;
+ $space = str_repeat(' ', $len);
+ $this->writeln(sprintf($format, $space));
+ foreach ($lines as $line) {
+ $line = str_pad($line, $length, ' ', STR_PAD_BOTH);
+ $this->writeln(sprintf($format, " $line "));
+ }
+ $this->writeln(sprintf($format, $space));
+ }
+
+ /**
+ * @param string $question
+ * @param bool $hideAnswer
+ *
+ * @return string
+ */
+ protected function ask($question, $hideAnswer = false)
+ {
+ if ($hideAnswer) {
+ return $this->askHidden($question);
+ }
+ return $this->doAsk(new Question($this->formatQuestion($question)));
+ }
+
+ /**
+ * @param string $question
+ *
+ * @return string
+ */
+ protected function askHidden($question)
+ {
+ $question = new Question($this->formatQuestion($question));
+ $question->setHidden(true);
+ return $this->doAsk($question);
+ }
+
+ /**
+ * @param string $question
+ * @param string $default
+ *
+ * @return string
+ */
+ protected function askDefault($question, $default)
+ {
+ return $this->doAsk(new Question($this->formatQuestion("$question [$default]"), $default));
+ }
+
+ /**
+ * @param string $question
+ *
+ * @return string
+ */
+ protected function confirm($question)
+ {
+ return $this->doAsk(new ConfirmationQuestion($this->formatQuestion($question . ' (y/n)'), false));
+ }
+
+ /**
+ * @param \Symfony\Component\Console\Question\Question $question
+ *
+ * @return string
+ */
+ protected function doAsk(Question $question)
+ {
+ return $this->getDialog()->ask($this->input(), $this->output(), $question);
+ }
+
+ /**
+ * @param string $message
+ *
+ * @return string
+ */
+ protected function formatQuestion($message)
+ {
+ return "<question>? $message</question> ";
+ }
+
+ /**
+ * @return \Symfony\Component\Console\Helper\QuestionHelper
+ */
+ protected function getDialog()
+ {
+ return new QuestionHelper();
+ }
+
+ /**
+ * @param $text
+ */
+ protected function writeln($text)
+ {
+ $this->output()->writeln($text);
+ }
+}