This project does not seem to handle request data directly as such no vulnerable execution paths were found.
include
, or for example
via PHP's auto-loading mechanism.
These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more
1 | <?php |
||
2 | |||
3 | /* |
||
4 | * This file is part of the webmozart/console package. |
||
5 | * |
||
6 | * (c) Bernhard Schussek <[email protected]> |
||
7 | * |
||
8 | * For the full copyright and license information, please view the LICENSE |
||
9 | * file that was distributed with this source code. |
||
10 | */ |
||
11 | |||
12 | namespace Webmozart\Console\UI\Component; |
||
13 | |||
14 | use LogicException; |
||
15 | use Webmozart\Console\Api\Formatter\Formatter; |
||
16 | use Webmozart\Console\Api\IO\IO; |
||
17 | use Webmozart\Console\UI\Component; |
||
18 | use Webmozart\Console\UI\Style\TableStyle; |
||
19 | use Webmozart\Console\Util\StringUtil; |
||
20 | |||
21 | /** |
||
22 | * A table of rows and columns. |
||
23 | * |
||
24 | * You can add rows to the table with {@link addRow()}. You may optionally set |
||
25 | * a header row with {@link setHeaderRow()}. |
||
26 | * |
||
27 | * If you want to style the table, pass a {@link TableStyle} instance to the |
||
28 | * constructor. |
||
29 | * |
||
30 | * @since 1.0 |
||
31 | * |
||
32 | * @author Bernhard Schussek <[email protected]> |
||
33 | */ |
||
34 | class Table implements Component |
||
35 | { |
||
36 | /** |
||
37 | * @var TableStyle |
||
38 | */ |
||
39 | private $style; |
||
40 | |||
41 | /** |
||
42 | * @var string[] |
||
43 | */ |
||
44 | private $headerRow = array(); |
||
45 | |||
46 | /** |
||
47 | * @var string[][] |
||
48 | */ |
||
49 | private $rows = array(); |
||
50 | |||
51 | /** |
||
52 | * @var int |
||
53 | */ |
||
54 | private $nbColumns; |
||
55 | |||
56 | /** |
||
57 | * Creates a new table. |
||
58 | * |
||
59 | * @param TableStyle $style The rendering style. By default, the table is |
||
0 ignored issues
–
show
|
|||
60 | * rendered with the style |
||
61 | * {@link TableStyle::asciiBorder()}. |
||
62 | */ |
||
63 | 18 | public function __construct(TableStyle $style = null) |
|
64 | { |
||
65 | 18 | $this->style = $style ?: TableStyle::asciiBorder(); |
|
66 | 18 | } |
|
67 | |||
68 | /** |
||
69 | * Sets the header cells of the table. |
||
70 | * |
||
71 | * @param string[] $row The header cells. |
||
72 | * |
||
73 | * @return static The current instance. |
||
74 | * |
||
75 | * @throws LogicException If the row contains more or less columns than |
||
76 | * rows previously added to the table. |
||
77 | */ |
||
78 | 15 | View Code Duplication | public function setHeaderRow(array $row) |
0 ignored issues
–
show
This method seems to be duplicated in your project.
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation. You can also find more detailed suggestions in the “Code” section of your repository. ![]() |
|||
79 | { |
||
80 | 15 | if (null === $this->nbColumns) { |
|
81 | 13 | $this->nbColumns = count($row); |
|
82 | 2 | } elseif (count($row) !== $this->nbColumns) { |
|
83 | 2 | throw new LogicException(sprintf( |
|
84 | 2 | 'Expected the header row to contain %s cells, but got %s.', |
|
85 | 2 | $this->nbColumns, |
|
86 | count($row) |
||
87 | )); |
||
88 | } |
||
89 | |||
90 | 13 | $this->headerRow = array_values($row); |
|
91 | |||
92 | 13 | return $this; |
|
93 | } |
||
94 | |||
95 | /** |
||
96 | * Adds a row to the table. |
||
97 | * |
||
98 | * @param string[] $row An array of data cells. |
||
99 | * |
||
100 | * @return static The current instance. |
||
101 | * |
||
102 | * @throws LogicException If the row contains more or less columns than |
||
103 | * rows previously added to the table. |
||
104 | */ |
||
105 | 13 | View Code Duplication | public function addRow(array $row) |
0 ignored issues
–
show
This method seems to be duplicated in your project.
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation. You can also find more detailed suggestions in the “Code” section of your repository. ![]() |
|||
106 | { |
||
107 | 13 | if (null === $this->nbColumns) { |
|
108 | 2 | $this->nbColumns = count($row); |
|
109 | 13 | } elseif (count($row) !== $this->nbColumns) { |
|
110 | 2 | throw new LogicException(sprintf( |
|
111 | 2 | 'Expected the row to contain %s cells, but got %s.', |
|
112 | 2 | $this->nbColumns, |
|
113 | count($row) |
||
114 | )); |
||
115 | } |
||
116 | |||
117 | 13 | $this->rows[] = array_values($row); |
|
118 | |||
119 | 13 | return $this; |
|
120 | } |
||
121 | |||
122 | /** |
||
123 | * Adds rows to the table. |
||
124 | * |
||
125 | * @param string[][] $rows The rows to add. |
||
126 | * |
||
127 | * @return static The current instance. |
||
128 | * |
||
129 | * @throws LogicException If a row contains more or less columns than |
||
130 | * rows previously added to the table. |
||
131 | */ |
||
132 | 11 | public function addRows(array $rows) |
|
133 | { |
||
134 | 11 | foreach ($rows as $row) { |
|
135 | 11 | $this->addRow($row); |
|
136 | } |
||
137 | |||
138 | 11 | return $this; |
|
139 | } |
||
140 | |||
141 | /** |
||
142 | * Sets the rows in the table. |
||
143 | * |
||
144 | * @param string[][] $rows The rows to set. |
||
145 | * |
||
146 | * @return static The current instance. |
||
147 | * |
||
148 | * @throws LogicException If a row contains more or less columns than |
||
149 | * rows previously added to the table. |
||
150 | */ |
||
151 | public function setRows(array $rows) |
||
152 | { |
||
153 | $this->rows = array(); |
||
154 | |||
155 | $this->addRows($rows); |
||
156 | |||
157 | return $this; |
||
158 | } |
||
159 | |||
160 | /** |
||
161 | * Sets a specific row in the table. |
||
162 | * |
||
163 | * @param int $index The row index. |
||
164 | * @param string[] $row An array of data cells. |
||
165 | * |
||
166 | * @return static The current instance. |
||
167 | * |
||
168 | * @throws LogicException If the row contains more or less columns than |
||
169 | * rows previously added to the table. |
||
170 | */ |
||
171 | 4 | View Code Duplication | public function setRow($index, array $row) |
0 ignored issues
–
show
This method seems to be duplicated in your project.
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation. You can also find more detailed suggestions in the “Code” section of your repository. ![]() |
|||
172 | { |
||
173 | 4 | if (null === $this->nbColumns) { |
|
174 | 2 | $this->nbColumns = count($row); |
|
175 | 2 | } elseif (count($row) !== $this->nbColumns) { |
|
176 | 2 | throw new LogicException(sprintf( |
|
177 | 2 | 'Expected the row to contain %s cells, but got %s.', |
|
178 | 2 | $this->nbColumns, |
|
179 | count($row) |
||
180 | )); |
||
181 | } |
||
182 | |||
183 | 2 | $this->rows[$index] = array_values($row); |
|
184 | |||
185 | 2 | return $this; |
|
186 | } |
||
187 | |||
188 | /** |
||
189 | * Renders the table. |
||
190 | * |
||
191 | * @param IO $io The I/O. |
||
192 | * @param int $indentation The number of spaces to indent. |
||
193 | */ |
||
194 | 12 | public function render(IO $io, $indentation = 0) |
|
195 | { |
||
196 | // Is the table empty? |
||
197 | 12 | if (!$this->rows) { |
|
0 ignored issues
–
show
The expression
$this->rows of type string[][] is implicitly converted to a boolean; are you sure this is intended? If so, consider using empty($expr) instead to make it clear that you intend to check for an array without elements.
This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent. Consider making the comparison explicit by using ![]() |
|||
198 | 1 | return; |
|
199 | } |
||
200 | |||
201 | 11 | $screenWidth = $io->getTerminalDimensions()->getWidth(); |
|
202 | 11 | $excessColumnWidth = max( |
|
203 | 11 | StringUtil::getLength(sprintf($this->style->getHeaderCellFormat(), ''), $io), |
|
204 | 11 | StringUtil::getLength(sprintf($this->style->getCellFormat(), ''), $io) |
|
205 | ); |
||
206 | |||
207 | 11 | $wrapper = $this->getCellWrapper($io, $screenWidth, $excessColumnWidth, $indentation); |
|
208 | |||
209 | 11 | $this->renderRows($io, $wrapper->getWrappedRows(), $wrapper->getColumnLengths(), $excessColumnWidth, $indentation); |
|
210 | 11 | } |
|
211 | |||
212 | 11 | private function getCellWrapper(Formatter $formatter, $screenWidth, $excessColumnWidth, $indentation) |
|
213 | { |
||
214 | 11 | $borderStyle = $this->style->getBorderStyle(); |
|
215 | 11 | $borderWidth = StringUtil::getLength($borderStyle->getLineVLChar()) |
|
216 | 11 | + ($this->nbColumns - 1) * StringUtil::getLength($borderStyle->getLineVCChar()) |
|
217 | 11 | + StringUtil::getLength($borderStyle->getLineVRChar()); |
|
218 | 11 | $availableWidth = $screenWidth - $indentation - $borderWidth |
|
219 | 11 | - $this->nbColumns * $excessColumnWidth; |
|
220 | |||
221 | 11 | $wrapper = new CellWrapper(); |
|
222 | |||
223 | 11 | foreach ($this->headerRow as $headerCell) { |
|
224 | 11 | $wrapper->addCell($headerCell); |
|
225 | } |
||
226 | |||
227 | 11 | foreach ($this->rows as $row) { |
|
228 | 11 | foreach ($row as $cell) { |
|
229 | 11 | $wrapper->addCell($cell); |
|
230 | } |
||
231 | } |
||
232 | |||
233 | 11 | $wrapper->fit($availableWidth, $this->nbColumns, $formatter); |
|
234 | |||
235 | 11 | return $wrapper; |
|
236 | } |
||
237 | |||
238 | 11 | private function renderRows(IO $io, array $rows, array $columnLengths, $excessColumnLength, $indentation) |
|
239 | { |
||
240 | 11 | $alignments = $this->style->getColumnAlignments(count($columnLengths)); |
|
241 | 11 | $borderStyle = $this->style->getBorderStyle(); |
|
242 | 11 | $borderColumnLengths = array_map(function ($length) use ($excessColumnLength) { |
|
243 | 11 | return $length + $excessColumnLength; |
|
244 | 11 | }, $columnLengths); |
|
245 | |||
246 | 11 | BorderUtil::drawTopBorder($io, $borderStyle, $borderColumnLengths, $indentation); |
|
247 | |||
248 | 11 | if ($this->headerRow) { |
|
0 ignored issues
–
show
The expression
$this->headerRow of type string[] is implicitly converted to a boolean; are you sure this is intended? If so, consider using ! empty($expr) instead to make it clear that you intend to check for an array without elements.
This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent. Consider making the comparison explicit by using ![]() |
|||
249 | 11 | BorderUtil::drawRow( |
|
250 | $io, |
||
251 | $borderStyle, |
||
252 | array_shift($rows), |
||
253 | $columnLengths, |
||
254 | $alignments, |
||
255 | 11 | $this->style->getHeaderCellFormat(), |
|
256 | 11 | $this->style->getHeaderCellStyle(), |
|
257 | 11 | $this->style->getPaddingChar(), |
|
258 | $indentation |
||
259 | ); |
||
260 | |||
261 | 11 | BorderUtil::drawMiddleBorder($io, $borderStyle, $borderColumnLengths, $indentation); |
|
262 | } |
||
263 | |||
264 | 11 | foreach ($rows as $row) { |
|
265 | 11 | BorderUtil::drawRow( |
|
266 | $io, |
||
267 | $borderStyle, |
||
268 | $row, |
||
269 | $columnLengths, |
||
270 | $alignments, |
||
271 | 11 | $this->style->getCellFormat(), |
|
272 | 11 | $this->style->getCellStyle(), |
|
273 | 11 | $this->style->getPaddingChar(), |
|
274 | $indentation |
||
275 | ); |
||
276 | } |
||
277 | |||
278 | 11 | BorderUtil::drawBottomBorder($io, $borderStyle, $borderColumnLengths, $indentation); |
|
279 | 11 | } |
|
280 | } |
||
281 |
This check looks for
@param
annotations where the type inferred by our type inference engine differs from the declared type.It makes a suggestion as to what type it considers more descriptive.
Most often this is a case of a parameter that can be null in addition to its declared types.