|
1
|
|
|
<?php |
|
2
|
|
|
namespace Consolidation\OutputFormatters\Transformations\Wrap; |
|
3
|
|
|
|
|
4
|
|
|
use Symfony\Component\Console\Helper\TableStyle; |
|
5
|
|
|
|
|
6
|
|
|
/** |
|
7
|
|
|
* Calculate the width of data in table cells in preparation for word wrapping. |
|
8
|
|
|
*/ |
|
9
|
|
|
class DataCellWidths |
|
10
|
|
|
{ |
|
11
|
|
|
protected $widths; |
|
12
|
|
|
|
|
13
|
|
|
public function __consturct() |
|
14
|
|
|
{ |
|
15
|
|
|
$this->widths = []; |
|
16
|
|
|
} |
|
17
|
|
|
|
|
18
|
|
|
/** |
|
19
|
|
|
* Calculate the longest cell data from any row of each of the cells. |
|
20
|
|
|
*/ |
|
21
|
|
View Code Duplication |
public function calculateLongestCell($rows) |
|
|
|
|
|
|
22
|
|
|
{ |
|
23
|
|
|
$this->widths = []; |
|
24
|
|
|
|
|
25
|
|
|
// Examine each row and find the longest line length and longest |
|
26
|
|
|
// word in each column. |
|
27
|
|
|
foreach ($rows as $rowkey => $row) { |
|
28
|
|
|
foreach ($row as $colkey => $cell) { |
|
29
|
|
|
$lineLength = strlen($cell); |
|
30
|
|
|
if ((!isset($this->widths[$colkey]) || ($this->widths[$colkey] < $lineLength))) { |
|
31
|
|
|
$this->widths[$colkey] = $lineLength; |
|
32
|
|
|
} |
|
33
|
|
|
} |
|
34
|
|
|
} |
|
35
|
|
|
} |
|
36
|
|
|
|
|
37
|
|
|
/** |
|
38
|
|
|
* Calculate the longest word and longest line in the provided data. |
|
39
|
|
|
*/ |
|
40
|
|
View Code Duplication |
public function calculateLongestWord($rows) |
|
|
|
|
|
|
41
|
|
|
{ |
|
42
|
|
|
$this->widths = []; |
|
43
|
|
|
|
|
44
|
|
|
// Examine each row and find the longest line length and longest |
|
45
|
|
|
// word in each column. |
|
46
|
|
|
foreach ($rows as $rowkey => $row) { |
|
47
|
|
|
foreach ($row as $colkey => $cell) { |
|
48
|
|
|
$longestWordLength = static::longestWordLength($cell); |
|
49
|
|
|
if ((!isset($this->widths[$colkey]) || ($this->widths[$colkey] < $longestWordLength))) { |
|
50
|
|
|
$this->widths[$colkey] = $longestWordLength; |
|
51
|
|
|
} |
|
52
|
|
|
} |
|
53
|
|
|
} |
|
54
|
|
|
} |
|
55
|
|
|
|
|
56
|
|
|
public function paddingSpace( |
|
57
|
|
|
$paddingInEachCell, |
|
58
|
|
|
$extraPaddingAtEndOfLine = 0, |
|
59
|
|
|
$extraPaddingAtBeginningOfLine = 0) |
|
60
|
|
|
{ |
|
61
|
|
|
return ($extraPaddingAtBeginningOfLine + $extraPaddingAtEndOfLine + (count($this->widths) * $paddingInEachCell)); |
|
62
|
|
|
} |
|
63
|
|
|
|
|
64
|
|
|
/** |
|
65
|
|
|
* Find all columns that are shorter than the specified threshold width. |
|
66
|
|
|
* These are removed from this object, and returned as the result of |
|
67
|
|
|
* this method. |
|
68
|
|
|
*/ |
|
69
|
|
|
public function removeShortColumns($thresholdWidth) |
|
70
|
|
|
{ |
|
71
|
|
|
$shortColWidths = $this->findShortColumns($thresholdWidth); |
|
72
|
|
|
$this->removeColumns(array_keys($shortColWidths)); |
|
73
|
|
|
return $shortColWidths; |
|
74
|
|
|
} |
|
75
|
|
|
|
|
76
|
|
|
/** |
|
77
|
|
|
* Find all of the columns that are shorter than the specified threshold. |
|
78
|
|
|
*/ |
|
79
|
|
|
public function findShortColumns($thresholdWidth) |
|
80
|
|
|
{ |
|
81
|
|
|
$shortColWidths = []; |
|
82
|
|
|
|
|
83
|
|
|
foreach ($this->widths as $key => $maxLength) { |
|
84
|
|
|
if ($maxLength <= $thresholdWidth) { |
|
85
|
|
|
$shortColWidths[$key] = $maxLength; |
|
86
|
|
|
} |
|
87
|
|
|
} |
|
88
|
|
|
|
|
89
|
|
|
return $shortColWidths; |
|
90
|
|
|
} |
|
91
|
|
|
|
|
92
|
|
|
/** |
|
93
|
|
|
* Remove all of the specified columns from this data structure. |
|
94
|
|
|
*/ |
|
95
|
|
|
public function removeColumns($columnKeys) |
|
96
|
|
|
{ |
|
97
|
|
|
foreach ($columnKeys as $key) { |
|
98
|
|
|
unset($this->widths[$key]); |
|
99
|
|
|
} |
|
100
|
|
|
} |
|
101
|
|
|
|
|
102
|
|
|
/** |
|
103
|
|
|
* Return proportional weights |
|
104
|
|
|
*/ |
|
105
|
|
|
public function distribute($availableWidth) |
|
106
|
|
|
{ |
|
107
|
|
|
$result = []; |
|
108
|
|
|
$totalWidth = $this->totalWidth(); |
|
109
|
|
|
$lastColumn = $this->lastColumn(); |
|
110
|
|
|
$widths = $this->widths(); |
|
111
|
|
|
array_pop($widths); |
|
112
|
|
|
|
|
113
|
|
|
foreach ($widths as $key => $width) { |
|
114
|
|
|
$result[$key] = round(($width / $totalWidth) * $availableWidth); |
|
115
|
|
|
} |
|
116
|
|
|
|
|
117
|
|
|
$usedWidth = $this->sumWidth($result); |
|
118
|
|
|
$result[$lastColumn] = $availableWidth - $usedWidth; |
|
119
|
|
|
|
|
120
|
|
|
return $result; |
|
121
|
|
|
} |
|
122
|
|
|
|
|
123
|
|
|
public function lastColumn() |
|
124
|
|
|
{ |
|
125
|
|
|
$keys = $this->keys(); |
|
126
|
|
|
return array_pop($keys); |
|
127
|
|
|
} |
|
128
|
|
|
|
|
129
|
|
|
/** |
|
130
|
|
|
* Return the available keys (column identifiers) from the calculated |
|
131
|
|
|
* data set. |
|
132
|
|
|
*/ |
|
133
|
|
|
public function keys() |
|
134
|
|
|
{ |
|
135
|
|
|
return array_keys($this->widths); |
|
136
|
|
|
} |
|
137
|
|
|
|
|
138
|
|
|
/** |
|
139
|
|
|
* Return the length of the specified column. |
|
140
|
|
|
*/ |
|
141
|
|
|
public function width($key) |
|
142
|
|
|
{ |
|
143
|
|
|
return isset($this->widths[$key]) ? $this->widths[$key] : 0; |
|
144
|
|
|
} |
|
145
|
|
|
|
|
146
|
|
|
/** |
|
147
|
|
|
* Return all of the lengths |
|
148
|
|
|
*/ |
|
149
|
|
|
public function widths() |
|
150
|
|
|
{ |
|
151
|
|
|
return $this->widths; |
|
152
|
|
|
} |
|
153
|
|
|
|
|
154
|
|
|
/** |
|
155
|
|
|
* Return the sum of the lengths of the provided widths. |
|
156
|
|
|
*/ |
|
157
|
|
|
public function totalWidth() |
|
158
|
|
|
{ |
|
159
|
|
|
return static::sumWidth($this->widths()); |
|
160
|
|
|
} |
|
161
|
|
|
|
|
162
|
|
|
/** |
|
163
|
|
|
* Return the sum of the lengths of the provided widths. |
|
164
|
|
|
*/ |
|
165
|
|
|
public static function sumWidth($widths) |
|
166
|
|
|
{ |
|
167
|
|
|
return array_reduce( |
|
168
|
|
|
$widths, |
|
169
|
|
|
function ($carry, $item) { |
|
170
|
|
|
return $carry + $item; |
|
171
|
|
|
} |
|
172
|
|
|
); |
|
173
|
|
|
} |
|
174
|
|
|
|
|
175
|
|
|
/** |
|
176
|
|
|
* Return the length of the longest word in the string. |
|
177
|
|
|
* @param string $str |
|
178
|
|
|
* @return int |
|
179
|
|
|
*/ |
|
180
|
|
View Code Duplication |
protected static function longestWordLength($str) |
|
|
|
|
|
|
181
|
|
|
{ |
|
182
|
|
|
$words = preg_split('#[ /-]#', $str); |
|
183
|
|
|
$lengths = array_map(function ($s) { |
|
184
|
|
|
return strlen($s); |
|
185
|
|
|
}, $words); |
|
186
|
|
|
return max($lengths); |
|
187
|
|
|
} |
|
188
|
|
|
} |
|
189
|
|
|
|
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.
You can also find more detailed suggestions in the “Code” section of your repository.