Issues (2)

src/MultipleBar.php (2 issues)

Labels
Severity
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
This use statement conflicts with another class in this namespace, coExp\WunderBar\ProgressBar. Consider defining an alias.

Let?s assume that you have a directory layout like this:

.
|-- OtherDir
|   |-- Bar.php
|   `-- Foo.php
`-- SomeDir
    `-- Foo.php

and let?s assume the following content of Bar.php:

// Bar.php
namespace OtherDir;

use SomeDir\Foo; // This now conflicts the class OtherDir\Foo

If both files OtherDir/Foo.php and SomeDir/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 before OtherDir/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:

// Bar.php
namespace OtherDir;

use SomeDir\Foo as SomeDirFoo; // There is no conflict anymore.
Loading history...
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 ignore-call  annotation

44
        $this->stdOutput = new StreamOutput($output->/** @scrutinizer ignore-call */ getStream());
Loading history...
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