Version 1
[yaffs-website] / vendor / consolidation / output-formatters / src / Formatters / TableFormatter.php
1 <?php
2 namespace Consolidation\OutputFormatters\Formatters;
3
4 use Symfony\Component\Console\Output\OutputInterface;
5 use Symfony\Component\Console\Helper\Table;
6 use Symfony\Component\Console\Helper\TableStyle;
7
8 use Consolidation\OutputFormatters\Validate\ValidDataTypesInterface;
9 use Consolidation\OutputFormatters\Options\FormatterOptions;
10 use Consolidation\OutputFormatters\Validate\ValidDataTypesTrait;
11 use Consolidation\OutputFormatters\StructuredData\TableDataInterface;
12 use Consolidation\OutputFormatters\Transformations\ReorderFields;
13 use Consolidation\OutputFormatters\Exception\IncompatibleDataException;
14 use Consolidation\OutputFormatters\Transformations\WordWrapper;
15
16 /**
17  * Display a table of data with the Symfony Table class.
18  *
19  * This formatter takes data of either the RowsOfFields or
20  * PropertyList data type.  Tables can be rendered with the
21  * rows running either vertically (the normal orientation) or
22  * horizontally.  By default, associative lists will be displayed
23  * as two columns, with the key in the first column and the
24  * value in the second column.
25  */
26 class TableFormatter implements FormatterInterface, ValidDataTypesInterface, RenderDataInterface
27 {
28     use ValidDataTypesTrait;
29     use RenderTableDataTrait;
30
31     protected $fieldLabels;
32     protected $defaultFields;
33
34     public function __construct()
35     {
36     }
37
38     public function validDataTypes()
39     {
40         return
41             [
42                 new \ReflectionClass('\Consolidation\OutputFormatters\StructuredData\RowsOfFields'),
43                 new \ReflectionClass('\Consolidation\OutputFormatters\StructuredData\PropertyList')
44             ];
45     }
46
47     /**
48      * @inheritdoc
49      */
50     public function validate($structuredData)
51     {
52         // If the provided data was of class RowsOfFields
53         // or PropertyList, it will be converted into
54         // a TableTransformation object by the restructure call.
55         if (!$structuredData instanceof TableDataInterface) {
56             throw new IncompatibleDataException(
57                 $this,
58                 $structuredData,
59                 $this->validDataTypes()
60             );
61         }
62         return $structuredData;
63     }
64
65     /**
66      * @inheritdoc
67      */
68     public function write(OutputInterface $output, $tableTransformer, FormatterOptions $options)
69     {
70         $headers = [];
71         $defaults = [
72             FormatterOptions::TABLE_STYLE => 'consolidation',
73             FormatterOptions::INCLUDE_FIELD_LABELS => true,
74         ];
75
76         $table = new Table($output);
77
78         static::addCustomTableStyles($table);
79
80         $table->setStyle($options->get(FormatterOptions::TABLE_STYLE, $defaults));
81         $isList = $tableTransformer->isList();
82         $includeHeaders = $options->get(FormatterOptions::INCLUDE_FIELD_LABELS, $defaults);
83         $listDelimiter = $options->get(FormatterOptions::LIST_DELIMITER, $defaults);
84
85         $headers = $tableTransformer->getHeaders();
86         $data = $tableTransformer->getTableData($includeHeaders && $isList);
87
88         if ($listDelimiter) {
89             if (!empty($headers)) {
90                 array_splice($headers, 1, 0, ':');
91             }
92             $data = array_map(function ($item) {
93                 array_splice($item, 1, 0, ':');
94                 return $item;
95             }, $data);
96         }
97
98         if ($includeHeaders && !$isList) {
99             $table->setHeaders($headers);
100         }
101
102         // todo: $output->getFormatter();
103         $data = $this->wrap($headers, $data, $table->getStyle(), $options);
104         $table->setRows($data);
105         $table->render();
106     }
107
108     /**
109      * Wrap the table data
110      * @param array $data
111      * @param TableStyle $tableStyle
112      * @param FormatterOptions $options
113      * @return array
114      */
115     protected function wrap($headers, $data, TableStyle $tableStyle, FormatterOptions $options)
116     {
117         $wrapper = new WordWrapper($options->get(FormatterOptions::TERMINAL_WIDTH));
118         $wrapper->setPaddingFromStyle($tableStyle);
119         if (!empty($headers)) {
120             $headerLengths = array_map(function ($item) {
121                 return strlen($item);
122             }, $headers);
123             $wrapper->setMinimumWidths($headerLengths);
124         }
125         return $wrapper->wrap($data);
126     }
127
128     /**
129      * Add our custom table style(s) to the table.
130      */
131     protected static function addCustomTableStyles($table)
132     {
133         // The 'consolidation' style is the same as the 'symfony-style-guide'
134         // style, except it maintains the colored headers used in 'default'.
135         $consolidationStyle = new TableStyle();
136         $consolidationStyle
137             ->setHorizontalBorderChar('-')
138             ->setVerticalBorderChar(' ')
139             ->setCrossingChar(' ')
140         ;
141         $table->setStyleDefinition('consolidation', $consolidationStyle);
142     }
143 }