Completed
Pull Request — master (#55)
by Greg
02:19
created

DataCellWidths::paddingSpace()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 8
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
c 0
b 0
f 0
dl 0
loc 8
rs 9.4285
cc 1
eloc 5
nc 1
nop 3
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 __construct($widths = [])
14
    {
15
        $this->widths = $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)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

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.

Loading history...
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)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

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.

Loading history...
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
62
        return ($extraPaddingAtBeginningOfLine + $extraPaddingAtEndOfLine + (count($this->widths) * $paddingInEachCell));
63
    }
64
65
    /**
66
     * Find all columns that are shorter than the specified threshold width.
67
     * These are removed from this object, and returned as the result of
68
     * this method.
69
     */
70
    public function removeShortColumns($thresholdWidth)
71
    {
72
        $shortColWidths = $this->findShortColumns($thresholdWidth);
73
        $this->removeColumns($shortColWidths->keys());
74
        return $shortColWidths;
75
    }
76
77
    /**
78
     * Find all of the columns that are shorter than the specified threshold.
79
     */
80
    public function findShortColumns($thresholdWidth)
81
    {
82
        $shortColWidths = [];
83
84
        foreach ($this->widths as $key => $maxLength) {
85
            if ($maxLength <= $thresholdWidth) {
86
                $shortColWidths[$key] = $maxLength;
87
            }
88
        }
89
90
        return new DataCellWidths($shortColWidths);
91
    }
92
93
    /**
94
     * Remove all of the specified columns from this data structure.
95
     */
96
    public function removeColumns($columnKeys)
97
    {
98
        foreach ($columnKeys as $key) {
99
            unset($this->widths[$key]);
100
        }
101
    }
102
103
    /**
104
     * Need to think about the name of this function a bit.
105
     * Maybe second parameter is just a column count.
106
     */
107
    public function adjustMinimumWidths($availableWidth, DataCellWidths $dataCellWidths)
0 ignored issues
show
Unused Code introduced by
The parameter $availableWidth is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
Unused Code introduced by
The parameter $dataCellWidths is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
108
    {
109
    }
110
111
    /**
112
     * Return proportional weights
113
     */
114
    public function distribute($availableWidth)
115
    {
116
        $result = [];
117
        $totalWidth = $this->totalWidth();
118
        $lastColumn = $this->lastColumn();
119
        $widths = $this->widths();
120
121
        // Take off the last column, and calculate proportional weights
122
        // for the first N-1 columns.
123
        array_pop($widths);
124
        foreach ($widths as $key => $width) {
125
            $result[$key] = round(($width / $totalWidth) * $availableWidth);
126
        }
127
128
        // Give the last column the rest of the available width
129
        $usedWidth = $this->sumWidth($result);
130
        $result[$lastColumn] = $availableWidth - $usedWidth;
131
132
        return new DataCellWidths($result);
133
    }
134
135
    public function lastColumn()
136
    {
137
        $keys = $this->keys();
138
        return array_pop($keys);
139
    }
140
141
    /**
142
     * Return the available keys (column identifiers) from the calculated
143
     * data set.
144
     */
145
    public function keys()
146
    {
147
        return array_keys($this->widths);
148
    }
149
150
    /**
151
     * Set the length of the specified column.
152
     */
153
    public function setWidth($key, $width)
154
    {
155
        $this->widths[$key] = $width;
156
    }
157
158
    /**
159
     * Return the length of the specified column.
160
     */
161
    public function width($key)
162
    {
163
        return isset($this->widths[$key]) ? $this->widths[$key] : 0;
164
    }
165
166
    /**
167
     * Return all of the lengths
168
     */
169
    public function widths()
170
    {
171
        return $this->widths;
172
    }
173
174
    /**
175
     * Return true if there is no data in this object
176
     */
177
    public function isEmpty()
178
    {
179
        return empty($this->widths);
180
    }
181
182
    /**
183
     * Return the sum of the lengths of the provided widths.
184
     */
185
    public function totalWidth()
186
    {
187
        return static::sumWidth($this->widths());
188
    }
189
190
    /**
191
     * Return the sum of the lengths of the provided widths.
192
     */
193
    public static function sumWidth($widths)
194
    {
195
        return array_reduce(
196
            $widths,
197
            function ($carry, $item) {
198
                return $carry + $item;
199
            }
200
        );
201
    }
202
203
    /**
204
     * Ensure that every item in $widths that has a corresponding entry
205
     * in $minimumWidths is as least as large as the minimum value held there.
206
     */
207
    public function enforceMinimums($minimumWidths)
208
    {
209
        $result = [];
210
        if ($minimumWidths instanceof DataCellWidths) {
211
            $minimumWidths = $minimumWidths->widths();
212
        }
213
        $minimumWidths += $this->widths;
214
215
        foreach ($this->widths as $key => $value) {
216
            $result[$key] = min($value, $minimumWidths[$key]);
217
        }
218
219
        return new DataCellWidths($result);
220
    }
221
222
    /**
223
     * Combine this set of widths with another set, and return
224
     * a new set that contains the entries from both.
225
     */
226
    public function combine(DataCellWidths $combineWith)
227
    {
228
        $combined = array_merge($combineWith->widths(), $this->widths());
229
230
        return new DataCellWidths($combined);
231
    }
232
233
    /**
234
     * Return the length of the longest word in the string.
235
     * @param string $str
236
     * @return int
237
     */
238
    protected static function longestWordLength($str)
239
    {
240
        $words = preg_split('#[ /-]#', $str);
241
        $lengths = array_map(function ($s) {
242
            return strlen($s);
243
        }, $words);
244
        return max($lengths);
245
    }
246
}
247