28
28
class Table
29
29
{
30
30
private const SEPARATOR_TOP = 0 ;
31
- private const SEPARATOR_MID = 1 ;
32
- private const SEPARATOR_BOTTOM = 2 ;
31
+ private const SEPARATOR_TOP_BOTTOM = 1 ;
32
+ private const SEPARATOR_MID = 2 ;
33
+ private const SEPARATOR_BOTTOM = 3 ;
34
+ private const BORDER_OUTSIDE = 0 ;
35
+ private const BORDER_INSIDE = 1 ;
33
36
34
37
/**
35
38
* Table headers.
@@ -328,7 +331,7 @@ public function render()
328
331
}
329
332
330
333
if ($ isHeader || $ isFirstRow ) {
331
- $ this ->renderRowSeparator ($ isFirstRow ? self ::SEPARATOR_MID : self ::SEPARATOR_TOP );
334
+ $ this ->renderRowSeparator ($ isFirstRow ? self ::SEPARATOR_TOP_BOTTOM : self ::SEPARATOR_TOP );
332
335
if ($ isFirstRow ) {
333
336
$ isFirstRow = false ;
334
337
}
@@ -353,22 +356,25 @@ private function renderRowSeparator(int $type = self::SEPARATOR_MID)
353
356
return ;
354
357
}
355
358
356
- if (!$ this ->style ->getHorizontalBorderChar () && !$ this ->style ->getCrossingChar ()) {
359
+ $ borders = $ this ->style ->getBorderChars ();
360
+ if (!$ borders [0 ] && !$ borders [2 ] && !$ this ->style ->getCrossingChar ()) {
357
361
return ;
358
362
}
359
363
360
- $ chars = $ this ->style ->getCrossingChars ();
364
+ $ crossings = $ this ->style ->getCrossingChars ();
361
365
if (self ::SEPARATOR_MID === $ type ) {
362
- list ($ leftChar , $ midChar , $ rightChar ) = array ($ chars [ 8 ], $ chars [0 ], $ chars [4 ]);
366
+ list ($ horizontal , $ leftChar , $ midChar , $ rightChar ) = array ($ borders [ 2 ], $ crossings [ 8 ], $ crossings [0 ], $ crossings [4 ]);
363
367
} elseif (self ::SEPARATOR_TOP === $ type ) {
364
- list ($ leftChar , $ midChar , $ rightChar ) = array ($ chars [1 ], $ chars [2 ], $ chars [3 ]);
368
+ list ($ horizontal , $ leftChar , $ midChar , $ rightChar ) = array ($ borders [0 ], $ crossings [1 ], $ crossings [2 ], $ crossings [3 ]);
369
+ } elseif (self ::SEPARATOR_TOP_BOTTOM === $ type ) {
370
+ list ($ horizontal , $ leftChar , $ midChar , $ rightChar ) = array ($ borders [0 ], $ crossings [9 ], $ crossings [10 ], $ crossings [11 ]);
365
371
} else {
366
- list ($ leftChar , $ midChar , $ rightChar ) = array ($ chars [ 7 ], $ chars [6 ], $ chars [5 ]);
372
+ list ($ horizontal , $ leftChar , $ midChar , $ rightChar ) = array ($ borders [ 0 ], $ crossings [ 7 ], $ crossings [6 ], $ crossings [5 ]);
367
373
}
368
374
369
375
$ markup = $ leftChar ;
370
376
for ($ column = 0 ; $ column < $ count ; ++$ column ) {
371
- $ markup .= str_repeat ($ this -> style -> getHorizontalBorderChar () , $ this ->effectiveColumnWidths [$ column ]);
377
+ $ markup .= str_repeat ($ horizontal , $ this ->effectiveColumnWidths [$ column ]);
372
378
$ markup .= $ column === $ count - 1 ? $ rightChar : $ midChar ;
373
379
}
374
380
@@ -378,9 +384,11 @@ private function renderRowSeparator(int $type = self::SEPARATOR_MID)
378
384
/**
379
385
* Renders vertical column separator.
380
386
*/
381
- private function renderColumnSeparator ()
387
+ private function renderColumnSeparator ($ type = self :: BORDER_OUTSIDE )
382
388
{
383
- return sprintf ($ this ->style ->getBorderFormat (), $ this ->style ->getVerticalBorderChar ());
389
+ $ borders = $ this ->style ->getBorderChars ();
390
+
391
+ return sprintf ($ this ->style ->getBorderFormat (), self ::BORDER_OUTSIDE === $ type ? $ borders [1 ] : $ borders [3 ]);
384
392
}
385
393
386
394
/**
@@ -390,10 +398,12 @@ private function renderColumnSeparator()
390
398
*/
391
399
private function renderRow (array $ row , string $ cellFormat )
392
400
{
393
- $ rowContent = $ this ->renderColumnSeparator ();
394
- foreach ($ this ->getRowColumns ($ row ) as $ column ) {
401
+ $ rowContent = $ this ->renderColumnSeparator (self ::BORDER_OUTSIDE );
402
+ $ columns = $ this ->getRowColumns ($ row );
403
+ $ last = count ($ columns ) - 1 ;
404
+ foreach ($ columns as $ i => $ column ) {
395
405
$ rowContent .= $ this ->renderCell ($ row , $ column , $ cellFormat );
396
- $ rowContent .= $ this ->renderColumnSeparator ();
406
+ $ rowContent .= $ this ->renderColumnSeparator ($ last === $ i ? self :: BORDER_OUTSIDE : self :: BORDER_INSIDE );
397
407
}
398
408
$ this ->output ->writeln ($ rowContent );
399
409
}
@@ -420,7 +430,7 @@ private function renderCell(array $row, int $column, string $cellFormat)
420
430
$ style = $ this ->getColumnStyle ($ column );
421
431
422
432
if ($ cell instanceof TableSeparator) {
423
- return sprintf ($ style ->getBorderFormat (), str_repeat ($ style ->getHorizontalBorderChar () , $ width ));
433
+ return sprintf ($ style ->getBorderFormat (), str_repeat ($ style ->getBorderChars ()[ 2 ] , $ width ));
424
434
}
425
435
426
436
$ width += Helper::strlen ($ cell ) - Helper::strlenWithoutDecoration ($ this ->output ->getFormatter (), $ cell );
@@ -648,7 +658,7 @@ private function calculateColumnsWidth(iterable $rows)
648
658
649
659
private function getColumnSeparatorWidth (): int
650
660
{
651
- return strlen (sprintf ($ this ->style ->getBorderFormat (), $ this ->style ->getVerticalBorderChar () ));
661
+ return strlen (sprintf ($ this ->style ->getBorderFormat (), $ this ->style ->getBorderChars ()[ 3 ] ));
652
662
}
653
663
654
664
private function getCellWidth (array $ row , int $ column ): int
@@ -678,39 +688,46 @@ private static function initStyles()
678
688
{
679
689
$ borderless = new TableStyle ();
680
690
$ borderless
681
- ->setHorizontalBorderChar ('= ' )
682
- ->setVerticalBorderChar (' ' )
691
+ ->setHorizontalBorderChars ('= ' )
692
+ ->setVerticalBorderChars (' ' )
683
693
->setDefaultCrossingChar (' ' )
684
694
;
685
695
686
696
$ compact = new TableStyle ();
687
697
$ compact
688
- ->setHorizontalBorderChar ('' )
689
- ->setVerticalBorderChar (' ' )
698
+ ->setHorizontalBorderChars ('' )
699
+ ->setVerticalBorderChars (' ' )
690
700
->setDefaultCrossingChar ('' )
691
701
->setCellRowContentFormat ('%s ' )
692
702
;
693
703
694
704
$ styleGuide = new TableStyle ();
695
705
$ styleGuide
696
- ->setHorizontalBorderChar ('- ' )
697
- ->setVerticalBorderChar (' ' )
706
+ ->setHorizontalBorderChars ('- ' )
707
+ ->setVerticalBorderChars (' ' )
698
708
->setDefaultCrossingChar (' ' )
699
709
->setCellHeaderFormat ('%s ' )
700
710
;
701
711
702
712
$ box = (new TableStyle ())
703
- ->setHorizontalBorderChar ('─ ' )
704
- ->setVerticalBorderChar ('│ ' )
713
+ ->setHorizontalBorderChars ('─ ' )
714
+ ->setVerticalBorderChars ('│ ' )
705
715
->setCrossingChars ('┼ ' , '┌ ' , '┬ ' , '┐ ' , '┤ ' , '┘ ' , '┴ ' , '└ ' , '├ ' )
706
716
;
707
717
718
+ $ boxDouble = (new TableStyle ())
719
+ ->setHorizontalBorderChars ('═ ' , '─ ' )
720
+ ->setVerticalBorderChars ('║ ' , '│ ' )
721
+ ->setCrossingChars ('┼ ' , '╔ ' , '╤ ' , '╗ ' , '╢ ' , '╝ ' , '╧ ' , '╚ ' , '╟ ' , '╠ ' , '╪ ' , '╣ ' )
722
+ ;
723
+
708
724
return array (
709
725
'default ' => new TableStyle (),
710
726
'borderless ' => $ borderless ,
711
727
'compact ' => $ compact ,
712
728
'symfony-style-guide ' => $ styleGuide ,
713
729
'box ' => $ box ,
730
+ 'box-double ' => $ boxDouble ,
714
731
);
715
732
}
716
733
0 commit comments