1 | <?php |
||||
2 | |||||
3 | namespace coExp\WunderBar; |
||||
4 | |||||
5 | use coExp\WunderBar\Exception\MultipleBarConfigurationException; |
||||
6 | use Symfony\Component\Console\Output\OutputInterface; |
||||
7 | use \Symfony\Component\Console\Helper\ProgressBar as ProgressBar; |
||||
0 ignored issues
–
show
|
|||||
8 | use Symfony\Component\Console\Output\StreamOutput; |
||||
9 | |||||
10 | class MultipleBar |
||||
11 | { |
||||
12 | const CLEAR_LINE = "\e[2K\r"; |
||||
13 | const MOVE_CURSOR_UP = "\e[1A"; |
||||
14 | |||||
15 | protected $title; |
||||
16 | |||||
17 | /** @var ProgressBar[] */ |
||||
18 | protected $progressBars = []; |
||||
19 | |||||
20 | /** @var OutputInterface */ |
||||
21 | protected $originalOutput; |
||||
22 | |||||
23 | /** @var StreamOutput */ |
||||
24 | protected $stdOutput; |
||||
25 | |||||
26 | /** @var bool */ |
||||
27 | protected $isStdError = false; |
||||
28 | |||||
29 | private $length = 0; |
||||
30 | |||||
31 | /** |
||||
32 | * Time of begin of command |
||||
33 | * @var int|null |
||||
34 | */ |
||||
35 | protected $time = null; |
||||
36 | |||||
37 | /** |
||||
38 | * ProgressBar constructor. |
||||
39 | * @param OutputInterface $output |
||||
40 | */ |
||||
41 | public function __construct(OutputInterface $output) |
||||
42 | { |
||||
43 | // Force writing on StdOut |
||||
44 | $this->stdOutput = new StreamOutput($output->getStream()); |
||||
0 ignored issues
–
show
The method
getStream() does not exist on Symfony\Component\Console\Output\OutputInterface . It seems like you code against a sub-type of Symfony\Component\Console\Output\OutputInterface such as Symfony\Component\Console\Output\StreamOutput or Symfony\Component\Console\Output\ConsoleOutput .
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
![]() |
|||||
45 | |||||
46 | // By default, Symfony/Helper write on stdError |
||||
47 | $this->originalOutput = $output; |
||||
48 | $this->time = time(); |
||||
49 | } |
||||
50 | |||||
51 | /** |
||||
52 | * @return bool |
||||
53 | */ |
||||
54 | public function isStdError(): bool |
||||
55 | { |
||||
56 | return $this->isStdError; |
||||
57 | } |
||||
58 | |||||
59 | /** |
||||
60 | * @param bool $stdError |
||||
61 | * @return MultipleBar |
||||
62 | */ |
||||
63 | public function setStdError(bool $stdError): self |
||||
64 | { |
||||
65 | $this->isStdError = $stdError; |
||||
66 | |||||
67 | return $this; |
||||
68 | } |
||||
69 | |||||
70 | /** |
||||
71 | * @param string|null $title |
||||
72 | * @return $this |
||||
73 | */ |
||||
74 | public function setTitle(?string $title) |
||||
75 | { |
||||
76 | $this->title = $title; |
||||
77 | |||||
78 | return $this; |
||||
79 | } |
||||
80 | |||||
81 | /** |
||||
82 | * @return $this |
||||
83 | */ |
||||
84 | public function erase() |
||||
85 | { |
||||
86 | for ($i = 0 ; $i < $this->length; $i++) { |
||||
87 | $this->originalOutput->write(self::CLEAR_LINE.self::MOVE_CURSOR_UP); |
||||
88 | } |
||||
89 | |||||
90 | $this->length = 0; |
||||
91 | |||||
92 | return $this; |
||||
93 | } |
||||
94 | |||||
95 | /** |
||||
96 | * @return $this |
||||
97 | */ |
||||
98 | public function show() |
||||
99 | { |
||||
100 | $this->erase(); |
||||
101 | |||||
102 | if (false === empty($this->title)) { |
||||
103 | $this->originalOutput->writeln(self::CLEAR_LINE.$this->title); |
||||
104 | $this->length++; |
||||
105 | } |
||||
106 | |||||
107 | foreach ($this->progressBars as $progressBar) { |
||||
108 | $progressBar->display(); |
||||
109 | $this->originalOutput->write("\n"); |
||||
110 | $this->length++; |
||||
111 | } |
||||
112 | |||||
113 | return $this; |
||||
114 | } |
||||
115 | |||||
116 | /** |
||||
117 | * @param int $index |
||||
118 | * @return $this |
||||
119 | */ |
||||
120 | public function removeProgressBarByIndex(int $index) |
||||
121 | { |
||||
122 | unset($this->progressBars[$index]); |
||||
123 | |||||
124 | return $this; |
||||
125 | } |
||||
126 | |||||
127 | /** |
||||
128 | * @param string $name |
||||
129 | * @return $this |
||||
130 | */ |
||||
131 | public function removeProgressBarByName(string $name) |
||||
132 | { |
||||
133 | unset($this->progressBars[$name]); |
||||
134 | |||||
135 | return $this; |
||||
136 | } |
||||
137 | |||||
138 | /** |
||||
139 | * @return OutputInterface|StreamOutput |
||||
140 | */ |
||||
141 | protected function getOutput() |
||||
142 | { |
||||
143 | if ($this->isStdError()) { |
||||
144 | return $this->originalOutput; |
||||
145 | } |
||||
146 | |||||
147 | return $this->stdOutput; |
||||
148 | } |
||||
149 | |||||
150 | /** |
||||
151 | * @param int $number |
||||
152 | * @return MultipleBar |
||||
153 | * @throws MultipleBarConfigurationException |
||||
154 | */ |
||||
155 | public function addProgressBar(int $number = 1) |
||||
156 | { |
||||
157 | if ($number < 1) { |
||||
158 | throw new MultipleBarConfigurationException('Illegal number of ProgressBar'); |
||||
159 | } |
||||
160 | |||||
161 | for ($i = 0 ; $i < $number ; $i++) { |
||||
162 | $this->progressBars[] = new ProgressBar($this->getOutput()); |
||||
163 | } |
||||
164 | |||||
165 | return $this; |
||||
166 | } |
||||
167 | |||||
168 | /** |
||||
169 | * @param string[] $names |
||||
170 | * @return MultipleBar |
||||
171 | */ |
||||
172 | public function addProgressBarByName(array $names) |
||||
173 | { |
||||
174 | foreach ($names as $name) { |
||||
175 | $this->progressBars[$name] = new ProgressBar($this->getOutput()); |
||||
176 | } |
||||
177 | |||||
178 | return $this; |
||||
179 | } |
||||
180 | |||||
181 | /** |
||||
182 | * @param int $index |
||||
183 | * @return ProgressBar|null |
||||
184 | */ |
||||
185 | public function getProgressBarByIndex(int $index) |
||||
186 | { |
||||
187 | return $this->progressBars[$index] ?? null; |
||||
188 | } |
||||
189 | |||||
190 | /** |
||||
191 | * @param string $name |
||||
192 | * @return ProgressBar|null |
||||
193 | */ |
||||
194 | public function getProgressBarByName(string $name) |
||||
195 | { |
||||
196 | return $this->progressBars[$name] ?? null; |
||||
197 | } |
||||
198 | } |
||||
199 |
Let?s assume that you have a directory layout like this:
and let?s assume the following content of
Bar.php
:If both files
OtherDir/Foo.php
andSomeDir/Foo.php
are loaded in the same runtime, you will see a PHP error such as the following:PHP Fatal error: Cannot use SomeDir\Foo as Foo because the name is already in use in OtherDir/Foo.php
However, as
OtherDir/Foo.php
does not necessarily have to be loaded and the error is only triggered if it is loaded beforeOtherDir/Bar.php
, this problem might go unnoticed for a while. In order to prevent this error from surfacing, you must import the namespace with a different alias: