Completed
Push — master ( d3a073...5737c8 )
by Greg
02:21
created

src/Common/IO.php (5 issues)

Upgrade to new PHP Analysis Engine

These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more

1
<?php
2
namespace Robo\Common;
3
4
use Robo\Symfony\IOStorage;
5
use Symfony\Component\Console\Helper\QuestionHelper;
6
use Symfony\Component\Console\Question\ConfirmationQuestion;
7
use Symfony\Component\Console\Question\Question;
8
use Symfony\Component\Console\Style\SymfonyStyle;
9
use Symfony\Component\Console\Input\InputInterface;
10
use Symfony\Component\Console\Output\OutputInterface;
11
12
trait IO
13
{
14
    use InputAwareTrait {
15
        input as parentInput;
16
    }
17
    use OutputAwareTrait {
18
        output as parentOutput;
19
    }
20
21
    /**
22
     * @var Robo\Symfony\IOStorage
23
     */
24
    protected $ioStorage;
25
26
    public function setIOStorage(IOStorage $ioStorage)
27
    {
28
        $this->ioStorage = $ioStorage;
0 ignored issues
show
Documentation Bug introduced by
It seems like $ioStorage of type object<Robo\Symfony\IOStorage> is incompatible with the declared type object<Robo\Common\Robo\Symfony\IOStorage> of property $ioStorage.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
29
    }
30
31
    public function resetIO(InputInterface $input, OutputInterface $output)
32
    {
33
        if (!$this->ioStorage) {
34
            $this->ioStorage = new IOStorage();
0 ignored issues
show
Documentation Bug introduced by
It seems like new \Robo\Symfony\IOStorage() of type object<Robo\Symfony\IOStorage> is incompatible with the declared type object<Robo\Common\Robo\Symfony\IOStorage> of property $ioStorage.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
35
        }
36
        $this->ioStorage->create($input, $output);
37
    }
38
39
    protected function output()
40
    {
41
        $result = null;
42
        if ($this->ioStorage) {
43
            $result = $this->ioStorage->output();
44
        }
45
        return $result ?: $this->parentOutput();
0 ignored issues
show
The method parentOutput() does not exist on Robo\Common\IO. Did you maybe mean output()?

This check marks calls to methods that do not seem to exist on an object.

This is most likely the result of a method being renamed without all references to it being renamed likewise.

Loading history...
46
    }
47
48
    protected function input()
49
    {
50
        $result = null;
51
        if ($this->ioStorage) {
52
            $result = $this->ioStorage->input();
53
        }
54
        return $result ?: $this->parentInput();
0 ignored issues
show
It seems like parentInput() must be provided by classes using this trait. How about adding it as abstract method to this trait?

This check looks for methods that are used by a trait but not required by it.

To illustrate, let’s look at the following code example

trait Idable {
    public function equalIds(Idable $other) {
        return $this->getId() === $other->getId();
    }
}

The trait Idable provides a method equalsId that in turn relies on the method getId(). If this method does not exist on a class mixing in this trait, the method will fail.

Adding the getId() as an abstract method to the trait will make sure it is available.

Loading history...
55
    }
56
57
    /**
58
     * Provide access to SymfonyStyle object.
59
     *
60
     * @return SymfonyStyle
61
     *
62
     * @see http://symfony.com/blog/new-in-symfony-2-8-console-style-guide
63
     */
64
    protected function io()
65
    {
66
        if (!$this->ioStorage) {
67
            $this->ioStorage = new IOStorage();
0 ignored issues
show
Documentation Bug introduced by
It seems like new \Robo\Symfony\IOStorage() of type object<Robo\Symfony\IOStorage> is incompatible with the declared type object<Robo\Common\Robo\Symfony\IOStorage> of property $ioStorage.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
68
        }
69
        return $this->ioStorage->get($this->input, $this->output);
70
    }
71
72
    /**
73
     * @param string $nonDecorated
74
     * @param string $decorated
75
     *
76
     * @return string
77
     */
78
    protected function decorationCharacter($nonDecorated, $decorated)
79
    {
80
        if (!$this->output()->isDecorated() || (strncasecmp(PHP_OS, 'WIN', 3) == 0)) {
81
            return $nonDecorated;
82
        }
83
        return $decorated;
84
    }
85
86
    /**
87
     * @param string $text
88
     */
89
    protected function say($text)
90
    {
91
        $char = $this->decorationCharacter('>', '➜');
92
        $this->writeln("$char  $text");
93
    }
94
95
    /**
96
     * @param string $text
97
     * @param int $length
98
     * @param string $color
99
     */
100
    protected function yell($text, $length = 40, $color = 'green')
101
    {
102
        $char = $this->decorationCharacter(' ', '➜');
103
        $format = "$char  <fg=white;bg=$color;options=bold>%s</fg=white;bg=$color;options=bold>";
104
        $this->formattedOutput($text, $length, $format);
105
    }
106
107
    /**
108
     * @param string $text
109
     * @param int $length
110
     * @param string $format
111
     */
112
    protected function formattedOutput($text, $length, $format)
113
    {
114
        $lines = explode("\n", trim($text, "\n"));
115
        $maxLineLength = array_reduce(array_map('strlen', $lines), 'max');
116
        $length = max($length, $maxLineLength);
117
        $len = $length + 2;
118
        $space = str_repeat(' ', $len);
119
        $this->writeln(sprintf($format, $space));
120
        foreach ($lines as $line) {
121
            $line = str_pad($line, $length, ' ', STR_PAD_BOTH);
122
            $this->writeln(sprintf($format, " $line "));
123
        }
124
        $this->writeln(sprintf($format, $space));
125
    }
126
127
    /**
128
     * @param string $question
129
     * @param bool $hideAnswer
130
     *
131
     * @return string
132
     */
133
    protected function ask($question, $hideAnswer = false)
134
    {
135
        if ($hideAnswer) {
136
            return $this->askHidden($question);
137
        }
138
        return $this->doAsk(new Question($this->formatQuestion($question)));
139
    }
140
141
    /**
142
     * @param string $question
143
     *
144
     * @return string
145
     */
146
    protected function askHidden($question)
147
    {
148
        $question = new Question($this->formatQuestion($question));
149
        $question->setHidden(true);
150
        return $this->doAsk($question);
151
    }
152
153
    /**
154
     * @param string $question
155
     * @param string $default
156
     *
157
     * @return string
158
     */
159
    protected function askDefault($question, $default)
160
    {
161
        return $this->doAsk(new Question($this->formatQuestion("$question [$default]"), $default));
162
    }
163
164
    /**
165
     * @param string $question
166
     *
167
     * @return string
168
     */
169
    protected function confirm($question)
170
    {
171
        return $this->doAsk(new ConfirmationQuestion($this->formatQuestion($question . ' (y/n)'), false));
172
    }
173
174
    /**
175
     * @param \Symfony\Component\Console\Question\Question $question
176
     *
177
     * @return string
178
     */
179
    protected function doAsk(Question $question)
180
    {
181
        return $this->getDialog()->ask($this->input(), $this->output(), $question);
182
    }
183
184
    /**
185
     * @param string $message
186
     *
187
     * @return string
188
     */
189
    protected function formatQuestion($message)
190
    {
191
        return  "<question>?  $message</question> ";
192
    }
193
194
    /**
195
     * @return \Symfony\Component\Console\Helper\QuestionHelper
196
     */
197
    protected function getDialog()
198
    {
199
        return new QuestionHelper();
200
    }
201
202
    /**
203
     * @param $text
204
     */
205
    protected function writeln($text)
206
    {
207
        $this->output()->writeln($text);
208
    }
209
}
210