Verzeichnisstruktur phpBB-3.1.0
- Veröffentlicht
- 27.10.2014
So funktioniert es
|
Auf das letzte Element klicken. Dies geht jeweils ein Schritt zurück |
Auf das Icon klicken, dies öffnet das Verzeichnis. Nochmal klicken schließt das Verzeichnis. |
|
(Beispiel Datei-Icons)
|
Auf das Icon klicken um den Quellcode anzuzeigen |
TableHelper.php
001 <?php
002
003 /*
004 * This file is part of the Symfony package.
005 *
006 * (c) Fabien Potencier <fabien@symfony.com>
007 *
008 * For the full copyright and license information, please view the LICENSE
009 * file that was distributed with this source code.
010 */
011
012 namespace Symfony\Component\Console\Helper;
013
014 use Symfony\Component\Console\Output\OutputInterface;
015 use InvalidArgumentException;
016
017 /**
018 * Provides helpers to display table output.
019 *
020 * @author Саша Стаменковић <umpirsky@gmail.com>
021 */
022 class TableHelper extends Helper
023 {
024 const LAYOUT_DEFAULT = 0;
025 const LAYOUT_BORDERLESS = 1;
026
027 /**
028 * Table headers.
029 *
030 * @var array
031 */
032 private $headers = array();
033
034 /**
035 * Table rows.
036 *
037 * @var array
038 */
039 private $rows = array();
040
041 // Rendering options
042 private $paddingChar;
043 private $horizontalBorderChar;
044 private $verticalBorderChar;
045 private $crossingChar;
046 private $cellHeaderFormat;
047 private $cellRowFormat;
048 private $borderFormat;
049 private $padType;
050
051 /**
052 * Column widths cache.
053 *
054 * @var array
055 */
056 private $columnWidths = array();
057
058 /**
059 * Number of columns cache.
060 *
061 * @var array
062 */
063 private $numberOfColumns;
064
065 /**
066 * @var OutputInterface
067 */
068 private $output;
069
070 public function __construct()
071 {
072 $this->setLayout(self::LAYOUT_DEFAULT);
073 }
074
075 /**
076 * Sets table layout type.
077 *
078 * @param int $layout self::LAYOUT_*
079 *
080 * @return TableHelper
081 *
082 * @throws InvalidArgumentException when the table layout is not known
083 */
084 public function setLayout($layout)
085 {
086 switch ($layout) {
087 case self::LAYOUT_BORDERLESS:
088 $this
089 ->setPaddingChar(' ')
090 ->setHorizontalBorderChar('=')
091 ->setVerticalBorderChar(' ')
092 ->setCrossingChar(' ')
093 ->setCellHeaderFormat('<info>%s</info>')
094 ->setCellRowFormat('<comment>%s</comment>')
095 ->setBorderFormat('%s')
096 ->setPadType(STR_PAD_RIGHT)
097 ;
098 break;
099
100 case self::LAYOUT_DEFAULT:
101 $this
102 ->setPaddingChar(' ')
103 ->setHorizontalBorderChar('-')
104 ->setVerticalBorderChar('|')
105 ->setCrossingChar('+')
106 ->setCellHeaderFormat('<info>%s</info>')
107 ->setCellRowFormat('<comment>%s</comment>')
108 ->setBorderFormat('%s')
109 ->setPadType(STR_PAD_RIGHT)
110 ;
111 break;
112
113 default:
114 throw new InvalidArgumentException(sprintf('Invalid table layout "%s".', $layout));
115 break;
116 };
117
118 return $this;
119 }
120
121 public function setHeaders(array $headers)
122 {
123 $this->headers = array_values($headers);
124
125 return $this;
126 }
127
128 public function setRows(array $rows)
129 {
130 $this->rows = array();
131
132 return $this->addRows($rows);
133 }
134
135 public function addRows(array $rows)
136 {
137 foreach ($rows as $row) {
138 $this->addRow($row);
139 }
140
141 return $this;
142 }
143
144 public function addRow(array $row)
145 {
146 $this->rows[] = array_values($row);
147
148 $keys = array_keys($this->rows);
149 $rowKey = array_pop($keys);
150
151 foreach ($row as $key => $cellValue) {
152 if (!strstr($cellValue, "\n")) {
153 continue;
154 }
155
156 $lines = explode("\n", $cellValue);
157 $this->rows[$rowKey][$key] = $lines[0];
158 unset($lines[0]);
159
160 foreach ($lines as $lineKey => $line) {
161 $nextRowKey = $rowKey + $lineKey + 1;
162
163 if (isset($this->rows[$nextRowKey])) {
164 $this->rows[$nextRowKey][$key] = $line;
165 } else {
166 $this->rows[$nextRowKey] = array($key => $line);
167 }
168 }
169 }
170
171 return $this;
172 }
173
174 public function setRow($column, array $row)
175 {
176 $this->rows[$column] = $row;
177
178 return $this;
179 }
180
181 /**
182 * Sets padding character, used for cell padding.
183 *
184 * @param string $paddingChar
185 *
186 * @return TableHelper
187 */
188 public function setPaddingChar($paddingChar)
189 {
190 $this->paddingChar = $paddingChar;
191
192 return $this;
193 }
194
195 /**
196 * Sets horizontal border character.
197 *
198 * @param string $horizontalBorderChar
199 *
200 * @return TableHelper
201 */
202 public function setHorizontalBorderChar($horizontalBorderChar)
203 {
204 $this->horizontalBorderChar = $horizontalBorderChar;
205
206 return $this;
207 }
208
209 /**
210 * Sets vertical border character.
211 *
212 * @param string $verticalBorderChar
213 *
214 * @return TableHelper
215 */
216 public function setVerticalBorderChar($verticalBorderChar)
217 {
218 $this->verticalBorderChar = $verticalBorderChar;
219
220 return $this;
221 }
222
223 /**
224 * Sets crossing character.
225 *
226 * @param string $crossingChar
227 *
228 * @return TableHelper
229 */
230 public function setCrossingChar($crossingChar)
231 {
232 $this->crossingChar = $crossingChar;
233
234 return $this;
235 }
236
237 /**
238 * Sets header cell format.
239 *
240 * @param string $cellHeaderFormat
241 *
242 * @return TableHelper
243 */
244 public function setCellHeaderFormat($cellHeaderFormat)
245 {
246 $this->cellHeaderFormat = $cellHeaderFormat;
247
248 return $this;
249 }
250
251 /**
252 * Sets row cell format.
253 *
254 * @param string $cellRowFormat
255 *
256 * @return TableHelper
257 */
258 public function setCellRowFormat($cellRowFormat)
259 {
260 $this->cellRowFormat = $cellRowFormat;
261
262 return $this;
263 }
264
265 /**
266 * Sets table border format.
267 *
268 * @param string $borderFormat
269 *
270 * @return TableHelper
271 */
272 public function setBorderFormat($borderFormat)
273 {
274 $this->borderFormat = $borderFormat;
275
276 return $this;
277 }
278
279 /**
280 * Sets cell padding type.
281 *
282 * @param int $padType STR_PAD_*
283 *
284 * @return TableHelper
285 */
286 public function setPadType($padType)
287 {
288 $this->padType = $padType;
289
290 return $this;
291 }
292
293 /**
294 * Renders table to output.
295 *
296 * Example:
297 * +---------------+-----------------------+------------------+
298 * | ISBN | Title | Author |
299 * +---------------+-----------------------+------------------+
300 * | 99921-58-10-7 | Divine Comedy | Dante Alighieri |
301 * | 9971-5-0210-0 | A Tale of Two Cities | Charles Dickens |
302 * | 960-425-059-0 | The Lord of the Rings | J. R. R. Tolkien |
303 * +---------------+-----------------------+------------------+
304 *
305 * @param OutputInterface $output
306 */
307 public function render(OutputInterface $output)
308 {
309 $this->output = $output;
310
311 $this->renderRowSeparator();
312 $this->renderRow($this->headers, $this->cellHeaderFormat);
313 if (!empty($this->headers)) {
314 $this->renderRowSeparator();
315 }
316 foreach ($this->rows as $row) {
317 $this->renderRow($row, $this->cellRowFormat);
318 }
319 if (!empty($this->rows)) {
320 $this->renderRowSeparator();
321 }
322
323 $this->cleanup();
324 }
325
326 /**
327 * Renders horizontal header separator.
328 *
329 * Example: +-----+-----------+-------+
330 */
331 private function renderRowSeparator()
332 {
333 if (0 === $count = $this->getNumberOfColumns()) {
334 return;
335 }
336
337 $markup = $this->crossingChar;
338 for ($column = 0; $column < $count; $column++) {
339 $markup .= str_repeat($this->horizontalBorderChar, $this->getColumnWidth($column))
340 .$this->crossingChar
341 ;
342 }
343
344 $this->output->writeln(sprintf($this->borderFormat, $markup));
345 }
346
347 /**
348 * Renders vertical column separator.
349 */
350 private function renderColumnSeparator()
351 {
352 $this->output->write(sprintf($this->borderFormat, $this->verticalBorderChar));
353 }
354
355 /**
356 * Renders table row.
357 *
358 * Example: | 9971-5-0210-0 | A Tale of Two Cities | Charles Dickens |
359 *
360 * @param array $row
361 * @param string $cellFormat
362 */
363 private function renderRow(array $row, $cellFormat)
364 {
365 if (empty($row)) {
366 return;
367 }
368
369 $this->renderColumnSeparator();
370 for ($column = 0, $count = $this->getNumberOfColumns(); $column < $count; $column++) {
371 $this->renderCell($row, $column, $cellFormat);
372 $this->renderColumnSeparator();
373 }
374 $this->output->writeln('');
375 }
376
377 /**
378 * Renders table cell with padding.
379 *
380 * @param array $row
381 * @param int $column
382 * @param string $cellFormat
383 */
384 private function renderCell(array $row, $column, $cellFormat)
385 {
386 $cell = isset($row[$column]) ? $row[$column] : '';
387 $width = $this->getColumnWidth($column);
388
389 // str_pad won't work properly with multi-byte strings, we need to fix the padding
390 if (function_exists('mb_strlen') && false !== $encoding = mb_detect_encoding($cell)) {
391 $width += strlen($cell) - mb_strlen($cell, $encoding);
392 }
393
394 $width += $this->strlen($cell) - $this->computeLengthWithoutDecoration($cell);
395
396 $this->output->write(sprintf(
397 $cellFormat,
398 str_pad(
399 $this->paddingChar.$cell.$this->paddingChar,
400 $width,
401 $this->paddingChar,
402 $this->padType
403 )
404 ));
405 }
406
407 /**
408 * Gets number of columns for this table.
409 *
410 * @return int
411 */
412 private function getNumberOfColumns()
413 {
414 if (null !== $this->numberOfColumns) {
415 return $this->numberOfColumns;
416 }
417
418 $columns = array(0);
419 $columns[] = count($this->headers);
420 foreach ($this->rows as $row) {
421 $columns[] = count($row);
422 }
423
424 return $this->numberOfColumns = max($columns);
425 }
426
427 /**
428 * Gets column width.
429 *
430 * @param int $column
431 *
432 * @return int
433 */
434 private function getColumnWidth($column)
435 {
436 if (isset($this->columnWidths[$column])) {
437 return $this->columnWidths[$column];
438 }
439
440 $lengths = array(0);
441 $lengths[] = $this->getCellWidth($this->headers, $column);
442 foreach ($this->rows as $row) {
443 $lengths[] = $this->getCellWidth($row, $column);
444 }
445
446 return $this->columnWidths[$column] = max($lengths) + 2;
447 }
448
449 /**
450 * Gets cell width.
451 *
452 * @param array $row
453 * @param int $column
454 *
455 * @return int
456 */
457 private function getCellWidth(array $row, $column)
458 {
459 return isset($row[$column]) ? $this->computeLengthWithoutDecoration($row[$column]) : 0;
460 }
461
462 /**
463 * Called after rendering to cleanup cache data.
464 */
465 private function cleanup()
466 {
467 $this->columnWidths = array();
468 $this->numberOfColumns = null;
469 }
470
471 private function computeLengthWithoutDecoration($string)
472 {
473 $formatter = $this->output->getFormatter();
474 $isDecorated = $formatter->isDecorated();
475 $formatter->setDecorated(false);
476
477 $string = $formatter->format($string);
478 $formatter->setDecorated($isDecorated);
479
480 return $this->strlen($string);
481 }
482
483 /**
484 * {@inheritdoc}
485 */
486 public function getName()
487 {
488 return 'table';
489 }
490 }
491