Mercurial > hg > isophonics-drupal-site
comparison vendor/symfony/console/Helper/Table.php @ 17:129ea1e6d783
Update, including to Drupal core 8.6.10
author | Chris Cannam |
---|---|
date | Thu, 28 Feb 2019 13:21:36 +0000 |
parents | 1fec387a4317 |
children |
comparison
equal
deleted
inserted
replaced
16:c2387f117808 | 17:129ea1e6d783 |
---|---|
9 * file that was distributed with this source code. | 9 * file that was distributed with this source code. |
10 */ | 10 */ |
11 | 11 |
12 namespace Symfony\Component\Console\Helper; | 12 namespace Symfony\Component\Console\Helper; |
13 | 13 |
14 use Symfony\Component\Console\Exception\InvalidArgumentException; | |
14 use Symfony\Component\Console\Output\OutputInterface; | 15 use Symfony\Component\Console\Output\OutputInterface; |
15 use Symfony\Component\Console\Exception\InvalidArgumentException; | |
16 | 16 |
17 /** | 17 /** |
18 * Provides helpers to display a table. | 18 * Provides helpers to display a table. |
19 * | 19 * |
20 * @author Fabien Potencier <fabien@symfony.com> | 20 * @author Fabien Potencier <fabien@symfony.com> |
25 class Table | 25 class Table |
26 { | 26 { |
27 /** | 27 /** |
28 * Table headers. | 28 * Table headers. |
29 */ | 29 */ |
30 private $headers = array(); | 30 private $headers = []; |
31 | 31 |
32 /** | 32 /** |
33 * Table rows. | 33 * Table rows. |
34 */ | 34 */ |
35 private $rows = array(); | 35 private $rows = []; |
36 | 36 |
37 /** | 37 /** |
38 * Column widths cache. | 38 * Column widths cache. |
39 */ | 39 */ |
40 private $effectiveColumnWidths = array(); | 40 private $effectiveColumnWidths = []; |
41 | 41 |
42 /** | 42 /** |
43 * Number of columns cache. | 43 * Number of columns cache. |
44 * | 44 * |
45 * @var int | 45 * @var int |
57 private $style; | 57 private $style; |
58 | 58 |
59 /** | 59 /** |
60 * @var array | 60 * @var array |
61 */ | 61 */ |
62 private $columnStyles = array(); | 62 private $columnStyles = []; |
63 | 63 |
64 /** | 64 /** |
65 * User set column widths. | 65 * User set column widths. |
66 * | 66 * |
67 * @var array | 67 * @var array |
68 */ | 68 */ |
69 private $columnWidths = array(); | 69 private $columnWidths = []; |
70 | 70 |
71 private static $styles; | 71 private static $styles; |
72 | 72 |
73 public function __construct(OutputInterface $output) | 73 public function __construct(OutputInterface $output) |
74 { | 74 { |
197 * | 197 * |
198 * @return $this | 198 * @return $this |
199 */ | 199 */ |
200 public function setColumnWidths(array $widths) | 200 public function setColumnWidths(array $widths) |
201 { | 201 { |
202 $this->columnWidths = array(); | 202 $this->columnWidths = []; |
203 foreach ($widths as $index => $width) { | 203 foreach ($widths as $index => $width) { |
204 $this->setColumnWidth($index, $width); | 204 $this->setColumnWidth($index, $width); |
205 } | 205 } |
206 | 206 |
207 return $this; | 207 return $this; |
208 } | 208 } |
209 | 209 |
210 public function setHeaders(array $headers) | 210 public function setHeaders(array $headers) |
211 { | 211 { |
212 $headers = array_values($headers); | 212 $headers = array_values($headers); |
213 if (!empty($headers) && !is_array($headers[0])) { | 213 if (!empty($headers) && !\is_array($headers[0])) { |
214 $headers = array($headers); | 214 $headers = [$headers]; |
215 } | 215 } |
216 | 216 |
217 $this->headers = $headers; | 217 $this->headers = $headers; |
218 | 218 |
219 return $this; | 219 return $this; |
220 } | 220 } |
221 | 221 |
222 public function setRows(array $rows) | 222 public function setRows(array $rows) |
223 { | 223 { |
224 $this->rows = array(); | 224 $this->rows = []; |
225 | 225 |
226 return $this->addRows($rows); | 226 return $this->addRows($rows); |
227 } | 227 } |
228 | 228 |
229 public function addRows(array $rows) | 229 public function addRows(array $rows) |
241 $this->rows[] = $row; | 241 $this->rows[] = $row; |
242 | 242 |
243 return $this; | 243 return $this; |
244 } | 244 } |
245 | 245 |
246 if (!is_array($row)) { | 246 if (!\is_array($row)) { |
247 throw new InvalidArgumentException('A row must be an array or a TableSeparator instance.'); | 247 throw new InvalidArgumentException('A row must be an array or a TableSeparator instance.'); |
248 } | 248 } |
249 | 249 |
250 $this->rows[] = array_values($row); | 250 $this->rows[] = array_values($row); |
251 | 251 |
261 | 261 |
262 /** | 262 /** |
263 * Renders table to output. | 263 * Renders table to output. |
264 * | 264 * |
265 * Example: | 265 * Example: |
266 * <code> | 266 * |
267 * +---------------+-----------------------+------------------+ | 267 * +---------------+-----------------------+------------------+ |
268 * | ISBN | Title | Author | | 268 * | ISBN | Title | Author | |
269 * +---------------+-----------------------+------------------+ | 269 * +---------------+-----------------------+------------------+ |
270 * | 99921-58-10-7 | Divine Comedy | Dante Alighieri | | 270 * | 99921-58-10-7 | Divine Comedy | Dante Alighieri | |
271 * | 9971-5-0210-0 | A Tale of Two Cities | Charles Dickens | | 271 * | 9971-5-0210-0 | A Tale of Two Cities | Charles Dickens | |
272 * | 960-425-059-0 | The Lord of the Rings | J. R. R. Tolkien | | 272 * | 960-425-059-0 | The Lord of the Rings | J. R. R. Tolkien | |
273 * +---------------+-----------------------+------------------+ | 273 * +---------------+-----------------------+------------------+ |
274 * </code> | |
275 */ | 274 */ |
276 public function render() | 275 public function render() |
277 { | 276 { |
278 $this->calculateNumberOfColumns(); | 277 $this->calculateNumberOfColumns(); |
279 $rows = $this->buildTableRows($this->rows); | 278 $rows = $this->buildTableRows($this->rows); |
303 } | 302 } |
304 | 303 |
305 /** | 304 /** |
306 * Renders horizontal header separator. | 305 * Renders horizontal header separator. |
307 * | 306 * |
308 * Example: <code>+-----+-----------+-------+</code> | 307 * Example: |
308 * | |
309 * +-----+-----------+-------+ | |
309 */ | 310 */ |
310 private function renderRowSeparator() | 311 private function renderRowSeparator() |
311 { | 312 { |
312 if (0 === $count = $this->numberOfColumns) { | 313 if (0 === $count = $this->numberOfColumns) { |
313 return; | 314 return; |
334 } | 335 } |
335 | 336 |
336 /** | 337 /** |
337 * Renders table row. | 338 * Renders table row. |
338 * | 339 * |
339 * Example: <code>| 9971-5-0210-0 | A Tale of Two Cities | Charles Dickens |</code> | 340 * Example: |
341 * | |
342 * | 9971-5-0210-0 | A Tale of Two Cities | Charles Dickens | | |
340 * | 343 * |
341 * @param array $row | 344 * @param array $row |
342 * @param string $cellFormat | 345 * @param string $cellFormat |
343 */ | 346 */ |
344 private function renderRow(array $row, $cellFormat) | 347 private function renderRow(array $row, $cellFormat) |
373 } | 376 } |
374 } | 377 } |
375 | 378 |
376 // str_pad won't work properly with multi-byte strings, we need to fix the padding | 379 // str_pad won't work properly with multi-byte strings, we need to fix the padding |
377 if (false !== $encoding = mb_detect_encoding($cell, null, true)) { | 380 if (false !== $encoding = mb_detect_encoding($cell, null, true)) { |
378 $width += strlen($cell) - mb_strwidth($cell, $encoding); | 381 $width += \strlen($cell) - mb_strwidth($cell, $encoding); |
379 } | 382 } |
380 | 383 |
381 $style = $this->getColumnStyle($column); | 384 $style = $this->getColumnStyle($column); |
382 | 385 |
383 if ($cell instanceof TableSeparator) { | 386 if ($cell instanceof TableSeparator) { |
397 { | 400 { |
398 if (null !== $this->numberOfColumns) { | 401 if (null !== $this->numberOfColumns) { |
399 return; | 402 return; |
400 } | 403 } |
401 | 404 |
402 $columns = array(0); | 405 $columns = [0]; |
403 foreach (array_merge($this->headers, $this->rows) as $row) { | 406 foreach (array_merge($this->headers, $this->rows) as $row) { |
404 if ($row instanceof TableSeparator) { | 407 if ($row instanceof TableSeparator) { |
405 continue; | 408 continue; |
406 } | 409 } |
407 | 410 |
411 $this->numberOfColumns = max($columns); | 414 $this->numberOfColumns = max($columns); |
412 } | 415 } |
413 | 416 |
414 private function buildTableRows($rows) | 417 private function buildTableRows($rows) |
415 { | 418 { |
416 $unmergedRows = array(); | 419 $unmergedRows = []; |
417 for ($rowKey = 0; $rowKey < count($rows); ++$rowKey) { | 420 for ($rowKey = 0; $rowKey < \count($rows); ++$rowKey) { |
418 $rows = $this->fillNextRows($rows, $rowKey); | 421 $rows = $this->fillNextRows($rows, $rowKey); |
419 | 422 |
420 // Remove any new line breaks and replace it with a new line | 423 // Remove any new line breaks and replace it with a new line |
421 foreach ($rows[$rowKey] as $column => $cell) { | 424 foreach ($rows[$rowKey] as $column => $cell) { |
422 if (!strstr($cell, "\n")) { | 425 if (!strstr($cell, "\n")) { |
423 continue; | 426 continue; |
424 } | 427 } |
425 $lines = explode("\n", str_replace("\n", "<fg=default;bg=default>\n</>", $cell)); | 428 $lines = explode("\n", str_replace("\n", "<fg=default;bg=default>\n</>", $cell)); |
426 foreach ($lines as $lineKey => $line) { | 429 foreach ($lines as $lineKey => $line) { |
427 if ($cell instanceof TableCell) { | 430 if ($cell instanceof TableCell) { |
428 $line = new TableCell($line, array('colspan' => $cell->getColspan())); | 431 $line = new TableCell($line, ['colspan' => $cell->getColspan()]); |
429 } | 432 } |
430 if (0 === $lineKey) { | 433 if (0 === $lineKey) { |
431 $rows[$rowKey][$column] = $line; | 434 $rows[$rowKey][$column] = $line; |
432 } else { | 435 } else { |
433 $unmergedRows[$rowKey][$lineKey][$column] = $line; | 436 $unmergedRows[$rowKey][$lineKey][$column] = $line; |
434 } | 437 } |
435 } | 438 } |
436 } | 439 } |
437 } | 440 } |
438 | 441 |
439 $tableRows = array(); | 442 $tableRows = []; |
440 foreach ($rows as $rowKey => $row) { | 443 foreach ($rows as $rowKey => $row) { |
441 $tableRows[] = $this->fillCells($row); | 444 $tableRows[] = $this->fillCells($row); |
442 if (isset($unmergedRows[$rowKey])) { | 445 if (isset($unmergedRows[$rowKey])) { |
443 $tableRows = array_merge($tableRows, $unmergedRows[$rowKey]); | 446 $tableRows = array_merge($tableRows, $unmergedRows[$rowKey]); |
444 } | 447 } |
457 * | 460 * |
458 * @throws InvalidArgumentException | 461 * @throws InvalidArgumentException |
459 */ | 462 */ |
460 private function fillNextRows(array $rows, $line) | 463 private function fillNextRows(array $rows, $line) |
461 { | 464 { |
462 $unmergedRows = array(); | 465 $unmergedRows = []; |
463 foreach ($rows[$line] as $column => $cell) { | 466 foreach ($rows[$line] as $column => $cell) { |
464 if (null !== $cell && !$cell instanceof TableCell && !is_scalar($cell) && !(is_object($cell) && method_exists($cell, '__toString'))) { | 467 if (null !== $cell && !$cell instanceof TableCell && !is_scalar($cell) && !(\is_object($cell) && method_exists($cell, '__toString'))) { |
465 throw new InvalidArgumentException(sprintf('A cell must be a TableCell, a scalar or an object implementing __toString, %s given.', gettype($cell))); | 468 throw new InvalidArgumentException(sprintf('A cell must be a TableCell, a scalar or an object implementing __toString, %s given.', \gettype($cell))); |
466 } | 469 } |
467 if ($cell instanceof TableCell && $cell->getRowspan() > 1) { | 470 if ($cell instanceof TableCell && $cell->getRowspan() > 1) { |
468 $nbLines = $cell->getRowspan() - 1; | 471 $nbLines = $cell->getRowspan() - 1; |
469 $lines = array($cell); | 472 $lines = [$cell]; |
470 if (strstr($cell, "\n")) { | 473 if (strstr($cell, "\n")) { |
471 $lines = explode("\n", str_replace("\n", "<fg=default;bg=default>\n</>", $cell)); | 474 $lines = explode("\n", str_replace("\n", "<fg=default;bg=default>\n</>", $cell)); |
472 $nbLines = count($lines) > $nbLines ? substr_count($cell, "\n") : $nbLines; | 475 $nbLines = \count($lines) > $nbLines ? substr_count($cell, "\n") : $nbLines; |
473 | 476 |
474 $rows[$line][$column] = new TableCell($lines[0], array('colspan' => $cell->getColspan())); | 477 $rows[$line][$column] = new TableCell($lines[0], ['colspan' => $cell->getColspan()]); |
475 unset($lines[0]); | 478 unset($lines[0]); |
476 } | 479 } |
477 | 480 |
478 // create a two dimensional array (rowspan x colspan) | 481 // create a two dimensional array (rowspan x colspan) |
479 $unmergedRows = array_replace_recursive(array_fill($line + 1, $nbLines, array()), $unmergedRows); | 482 $unmergedRows = array_replace_recursive(array_fill($line + 1, $nbLines, []), $unmergedRows); |
480 foreach ($unmergedRows as $unmergedRowKey => $unmergedRow) { | 483 foreach ($unmergedRows as $unmergedRowKey => $unmergedRow) { |
481 $value = isset($lines[$unmergedRowKey - $line]) ? $lines[$unmergedRowKey - $line] : ''; | 484 $value = isset($lines[$unmergedRowKey - $line]) ? $lines[$unmergedRowKey - $line] : ''; |
482 $unmergedRows[$unmergedRowKey][$column] = new TableCell($value, array('colspan' => $cell->getColspan())); | 485 $unmergedRows[$unmergedRowKey][$column] = new TableCell($value, ['colspan' => $cell->getColspan()]); |
483 if ($nbLines === $unmergedRowKey - $line) { | 486 if ($nbLines === $unmergedRowKey - $line) { |
484 break; | 487 break; |
485 } | 488 } |
486 } | 489 } |
487 } | 490 } |
488 } | 491 } |
489 | 492 |
490 foreach ($unmergedRows as $unmergedRowKey => $unmergedRow) { | 493 foreach ($unmergedRows as $unmergedRowKey => $unmergedRow) { |
491 // we need to know if $unmergedRow will be merged or inserted into $rows | 494 // we need to know if $unmergedRow will be merged or inserted into $rows |
492 if (isset($rows[$unmergedRowKey]) && is_array($rows[$unmergedRowKey]) && ($this->getNumberOfColumns($rows[$unmergedRowKey]) + $this->getNumberOfColumns($unmergedRows[$unmergedRowKey]) <= $this->numberOfColumns)) { | 495 if (isset($rows[$unmergedRowKey]) && \is_array($rows[$unmergedRowKey]) && ($this->getNumberOfColumns($rows[$unmergedRowKey]) + $this->getNumberOfColumns($unmergedRows[$unmergedRowKey]) <= $this->numberOfColumns)) { |
493 foreach ($unmergedRow as $cellKey => $cell) { | 496 foreach ($unmergedRow as $cellKey => $cell) { |
494 // insert cell into row at cellKey position | 497 // insert cell into row at cellKey position |
495 array_splice($rows[$unmergedRowKey], $cellKey, 0, array($cell)); | 498 array_splice($rows[$unmergedRowKey], $cellKey, 0, [$cell]); |
496 } | 499 } |
497 } else { | 500 } else { |
498 $row = $this->copyRow($rows, $unmergedRowKey - 1); | 501 $row = $this->copyRow($rows, $unmergedRowKey - 1); |
499 foreach ($unmergedRow as $column => $cell) { | 502 foreach ($unmergedRow as $column => $cell) { |
500 if (!empty($cell)) { | 503 if (!empty($cell)) { |
501 $row[$column] = $unmergedRow[$column]; | 504 $row[$column] = $unmergedRow[$column]; |
502 } | 505 } |
503 } | 506 } |
504 array_splice($rows, $unmergedRowKey, 0, array($row)); | 507 array_splice($rows, $unmergedRowKey, 0, [$row]); |
505 } | 508 } |
506 } | 509 } |
507 | 510 |
508 return $rows; | 511 return $rows; |
509 } | 512 } |
513 * | 516 * |
514 * @return array | 517 * @return array |
515 */ | 518 */ |
516 private function fillCells($row) | 519 private function fillCells($row) |
517 { | 520 { |
518 $newRow = array(); | 521 $newRow = []; |
519 foreach ($row as $column => $cell) { | 522 foreach ($row as $column => $cell) { |
520 $newRow[] = $cell; | 523 $newRow[] = $cell; |
521 if ($cell instanceof TableCell && $cell->getColspan() > 1) { | 524 if ($cell instanceof TableCell && $cell->getColspan() > 1) { |
522 foreach (range($column + 1, $column + $cell->getColspan() - 1) as $position) { | 525 foreach (range($column + 1, $column + $cell->getColspan() - 1) as $position) { |
523 // insert empty value at column position | 526 // insert empty value at column position |
539 { | 542 { |
540 $row = $rows[$line]; | 543 $row = $rows[$line]; |
541 foreach ($row as $cellKey => $cellValue) { | 544 foreach ($row as $cellKey => $cellValue) { |
542 $row[$cellKey] = ''; | 545 $row[$cellKey] = ''; |
543 if ($cellValue instanceof TableCell) { | 546 if ($cellValue instanceof TableCell) { |
544 $row[$cellKey] = new TableCell('', array('colspan' => $cellValue->getColspan())); | 547 $row[$cellKey] = new TableCell('', ['colspan' => $cellValue->getColspan()]); |
545 } | 548 } |
546 } | 549 } |
547 | 550 |
548 return $row; | 551 return $row; |
549 } | 552 } |
553 * | 556 * |
554 * @return int | 557 * @return int |
555 */ | 558 */ |
556 private function getNumberOfColumns(array $row) | 559 private function getNumberOfColumns(array $row) |
557 { | 560 { |
558 $columns = count($row); | 561 $columns = \count($row); |
559 foreach ($row as $column) { | 562 foreach ($row as $column) { |
560 $columns += $column instanceof TableCell ? ($column->getColspan() - 1) : 0; | 563 $columns += $column instanceof TableCell ? ($column->getColspan() - 1) : 0; |
561 } | 564 } |
562 | 565 |
563 return $columns; | 566 return $columns; |
585 * Calculates columns widths. | 588 * Calculates columns widths. |
586 */ | 589 */ |
587 private function calculateColumnsWidth(array $rows) | 590 private function calculateColumnsWidth(array $rows) |
588 { | 591 { |
589 for ($column = 0; $column < $this->numberOfColumns; ++$column) { | 592 for ($column = 0; $column < $this->numberOfColumns; ++$column) { |
590 $lengths = array(); | 593 $lengths = []; |
591 foreach ($rows as $row) { | 594 foreach ($rows as $row) { |
592 if ($row instanceof TableSeparator) { | 595 if ($row instanceof TableSeparator) { |
593 continue; | 596 continue; |
594 } | 597 } |
595 | 598 |
607 } | 610 } |
608 | 611 |
609 $lengths[] = $this->getCellWidth($row, $column); | 612 $lengths[] = $this->getCellWidth($row, $column); |
610 } | 613 } |
611 | 614 |
612 $this->effectiveColumnWidths[$column] = max($lengths) + strlen($this->style->getCellRowContentFormat()) - 2; | 615 $this->effectiveColumnWidths[$column] = max($lengths) + Helper::strlen($this->style->getCellRowContentFormat()) - 2; |
613 } | 616 } |
614 } | 617 } |
615 | 618 |
616 /** | 619 /** |
617 * Gets column width. | 620 * Gets column width. |
618 * | 621 * |
619 * @return int | 622 * @return int |
620 */ | 623 */ |
621 private function getColumnSeparatorWidth() | 624 private function getColumnSeparatorWidth() |
622 { | 625 { |
623 return strlen(sprintf($this->style->getBorderFormat(), $this->style->getVerticalBorderChar())); | 626 return Helper::strlen(sprintf($this->style->getBorderFormat(), $this->style->getVerticalBorderChar())); |
624 } | 627 } |
625 | 628 |
626 /** | 629 /** |
627 * Gets cell width. | 630 * Gets cell width. |
628 * | 631 * |
648 /** | 651 /** |
649 * Called after rendering to cleanup cache data. | 652 * Called after rendering to cleanup cache data. |
650 */ | 653 */ |
651 private function cleanup() | 654 private function cleanup() |
652 { | 655 { |
653 $this->effectiveColumnWidths = array(); | 656 $this->effectiveColumnWidths = []; |
654 $this->numberOfColumns = null; | 657 $this->numberOfColumns = null; |
655 } | 658 } |
656 | 659 |
657 private static function initStyles() | 660 private static function initStyles() |
658 { | 661 { |
677 ->setVerticalBorderChar(' ') | 680 ->setVerticalBorderChar(' ') |
678 ->setCrossingChar(' ') | 681 ->setCrossingChar(' ') |
679 ->setCellHeaderFormat('%s') | 682 ->setCellHeaderFormat('%s') |
680 ; | 683 ; |
681 | 684 |
682 return array( | 685 return [ |
683 'default' => new TableStyle(), | 686 'default' => new TableStyle(), |
684 'borderless' => $borderless, | 687 'borderless' => $borderless, |
685 'compact' => $compact, | 688 'compact' => $compact, |
686 'symfony-style-guide' => $styleGuide, | 689 'symfony-style-guide' => $styleGuide, |
687 ); | 690 ]; |
688 } | 691 } |
689 | 692 |
690 private function resolveStyle($name) | 693 private function resolveStyle($name) |
691 { | 694 { |
692 if ($name instanceof TableStyle) { | 695 if ($name instanceof TableStyle) { |