@@ -49,6 +49,7 @@ class Table
49
49
*/
50
50
private $ rows = [];
51
51
private $ horizontal = false ;
52
+ private $ vertical = false ;
52
53
53
54
/**
54
55
* Column widths cache.
@@ -318,6 +319,13 @@ public function setHorizontal(bool $horizontal = true): self
318
319
return $ this ;
319
320
}
320
321
322
+ public function setVertical (bool $ vertical = true ): self
323
+ {
324
+ $ this ->vertical = $ vertical ;
325
+
326
+ return $ this ;
327
+ }
328
+
321
329
/**
322
330
* Renders table to output.
323
331
*
@@ -334,8 +342,12 @@ public function setHorizontal(bool $horizontal = true): self
334
342
public function render ()
335
343
{
336
344
$ divider = new TableSeparator ();
345
+ $ isCellWithColspan = static function ($ cell ): bool {
346
+ return $ cell instanceof TableCell && $ cell ->getColspan () >= 2 ;
347
+ };
348
+
349
+ $ rows = [];
337
350
if ($ this ->horizontal ) {
338
- $ rows = [];
339
351
foreach ($ this ->headers [0 ] ?? [] as $ i => $ header ) {
340
352
$ rows [$ i ] = [$ header ];
341
353
foreach ($ this ->rows as $ row ) {
@@ -344,13 +356,46 @@ public function render()
344
356
}
345
357
if (isset ($ row [$ i ])) {
346
358
$ rows [$ i ][] = $ row [$ i ];
347
- } elseif ($ rows [ $ i ][ 0 ] instanceof TableCell && $ rows [$ i ][0 ]-> getColspan () >= 2 ) {
359
+ } elseif ($ isCellWithColspan ( $ rows [$ i ][0 ]) ) {
348
360
// Noop, there is a "title"
349
361
} else {
350
362
$ rows [$ i ][] = null ;
351
363
}
352
364
}
353
365
}
366
+ } elseif ($ this ->vertical ) {
367
+ $ maxHeaderLength = max (array_map (static function (string $ header ) {
368
+ return mb_strlen ($ header );
369
+ }, $ this ->headers [0 ] ?? ['' ]));
370
+
371
+ foreach ($ this ->rows as $ row ) {
372
+ if ($ row instanceof TableSeparator) {
373
+ continue ;
374
+ }
375
+
376
+ if (0 < \count ($ rows )) {
377
+ $ rows [] = [$ divider ];
378
+ }
379
+
380
+ $ containsColspan = 0 < \count (array_filter ($ row , static function ($ cell ) use ($ isCellWithColspan ): bool {
381
+ return $ isCellWithColspan ($ cell );
382
+ }));
383
+
384
+ $ headers = $ this ->headers [0 ] ?? [];
385
+ $ maxRows = max (\count ($ headers ), \count ($ row ));
386
+ for ($ i = 0 ; $ i < $ maxRows ; ++$ i ) {
387
+ $ cell = (string ) ($ row [$ i ] ?? '' );
388
+ if (!empty ($ headers ) && !$ containsColspan ) {
389
+ $ rows [] = [sprintf (
390
+ '<comment>%s</>: %s ' ,
391
+ str_pad ($ headers [$ i ] ?? '' , $ maxHeaderLength , ' ' , \STR_PAD_LEFT ),
392
+ $ cell
393
+ )];
394
+ } elseif (!empty ($ cell )) {
395
+ $ rows [] = [$ cell ];
396
+ }
397
+ }
398
+ }
354
399
} else {
355
400
$ rows = array_merge ($ this ->headers , [$ divider ], $ this ->rows );
356
401
}
@@ -386,6 +431,11 @@ public function render()
386
431
$ this ->renderRowSeparator (self ::SEPARATOR_TOP , $ this ->headerTitle , $ this ->style ->getHeaderTitleFormat ());
387
432
}
388
433
}
434
+ if ($ this ->vertical ) {
435
+ $ isHeader = false ;
436
+ $ isFirstRow = false ;
437
+ }
438
+
389
439
if ($ this ->horizontal ) {
390
440
$ this ->renderRow ($ row , $ this ->style ->getCellRowFormat (), $ this ->style ->getCellHeaderFormat ());
391
441
} else {
0 commit comments