Total Complexity | 61 |
Total Lines | 229 |
Duplicated Lines | 0 % |
Changes | 6 | ||
Bugs | 0 | Features | 0 |
Complex classes like table_setter often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.
Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.
While breaking up the class, it is a good idea to analyze how other classes use table_setter, and based on these observations, apply Extract Interface, too.
1 | <?php |
||
3 | class table_setter |
||
4 | { |
||
5 | /** @param array Columns (config) */ |
||
6 | public static $cols; |
||
7 | /** @param bool Export flag (for current request) */ |
||
8 | public static $export; |
||
9 | /** @param array Collector (values for current table call) */ |
||
10 | protected static $t = ['page' => 1, 'tables' => []]; |
||
11 | /** @param array Re-settable values for current table call */ |
||
12 | protected static $config; |
||
13 | |||
14 | static function assets($path = "/public/table") |
||
18 | } |
||
19 | |||
20 | /** Set/Get config value |
||
21 | * @param mixed $c (string) Get if exists, (array) Set if valid |
||
22 | * @return mixed */ |
||
23 | public static function config($c) |
||
24 | { |
||
25 | self::$config = self::$config ?: [ |
||
26 | 'DB_COLLATION_CI' => 'utf8mb4_general_ci', //UTF8_GENERAL_CI |
||
27 | 'EMPTY_TABLE_MSG' => 'No results found.', |
||
28 | 'EXPORT_FILE_NAME' => ':app - :items export (:datetime)', |
||
29 | 'FILTER_CASE_SENSITIVE' => false, |
||
30 | 'SAVES' => ['CSV', 'Excel'], |
||
31 | 'UTF8_ASC_SYMBOL' => '▲', |
||
32 | 'UTF8_DESC_SYMBOL' => '▼', |
||
33 | 'UTF8_LEFT_SYMBOL' => '‹', |
||
34 | 'UTF8_RIGHT_SYMBOL' => '›' |
||
35 | ]; |
||
36 | |||
37 | try { |
||
38 | $getValid = function($k, $v = null) { |
||
39 | if (!array_key_exists($k, self::$config)) { |
||
40 | throw new Exception('Request to undefined value: ' . $k); |
||
41 | } |
||
42 | if (isset($v)) { |
||
43 | return !empty($v) && |
||
44 | gettype($v) === gettype(self::$config[$k]) ? |
||
45 | $v : |
||
46 | self::$config[$k]; |
||
47 | } else { |
||
48 | return self::$config[$k]; |
||
49 | } |
||
50 | }; |
||
51 | } catch (Exception $e) { |
||
|
|||
52 | die('ERROR: ' . $e->getMessage()); |
||
53 | } |
||
54 | |||
55 | switch (gettype($c)) { |
||
56 | case 'array'; |
||
57 | foreach ($c as $k => $v) { |
||
58 | self::$config[$k] = $getValid($k, $v); |
||
59 | } |
||
60 | break; |
||
61 | case 'string': |
||
62 | return $getValid($c); |
||
63 | } |
||
64 | } |
||
65 | |||
66 | /** Converts array to space separated key value list |
||
67 | * @param array $attributes |
||
68 | * @return string */ |
||
69 | protected static function attributes(array $attributes) |
||
84 | } |
||
85 | |||
86 | /** Parses view to string |
||
87 | * @param string $template |
||
88 | * @param array $vars |
||
89 | * @return string */ |
||
90 | protected static function view($template, $vars = []) |
||
91 | { |
||
92 | extract($vars); |
||
93 | ob_start(); |
||
94 | require $template; |
||
95 | return (string) ob_get_clean(); |
||
96 | } |
||
97 | |||
98 | protected static function paging(&$v) |
||
99 | { |
||
100 | if (self::$t['pages'] > 1) { |
||
101 | $v['pages'] = self::$t['pages']; |
||
102 | $v['page'] = self::$t['page']; |
||
103 | $v['jumpL'] = self::pagingJumps(); |
||
104 | $v['jumpR'] = self::pagingJumps(); |
||
105 | $v['arrowL'] = self::config('UTF8_LEFT_SYMBOL'); |
||
106 | $v['arrowR'] = self::config('UTF8_RIGHT_SYMBOL'); |
||
107 | |||
108 | $limit = 10; |
||
109 | |||
110 | $v['start'] = $v['page'] > ($limit / 2) ? |
||
111 | ($v['page'] - $limit / 2) : |
||
112 | 1; |
||
113 | |||
114 | if ($v['page'] > ($v['pages'] - ($limit / 2))) { |
||
115 | $v['final'] = $v['pages']; |
||
116 | } else if ($v['page'] > ($limit / 2)) { |
||
117 | $v['final'] = $v['start'] + $limit; |
||
118 | } else { |
||
119 | $v['final'] = $limit; |
||
120 | } |
||
121 | } |
||
122 | } |
||
123 | |||
124 | /** Jump links -1M|-100K|-10K|-1K|100|{paging}|100|+1K|+10K|+100K|+1M |
||
125 | * @param string $html Code to show |
||
126 | * @param null|int $m multiplier |
||
127 | * @return string */ |
||
128 | protected static function pagingJumps($html = '', $m = null) |
||
158 | } |
||
159 | |||
160 | protected static function filterValues(&$f, &$opts = []) |
||
161 | { |
||
162 | $f = filter_input(INPUT_GET, 'filter', FILTER_SANITIZE_STRING) ?: null; |
||
163 | |||
164 | $by = filter_input(INPUT_GET, 'filter-by', FILTER_VALIDATE_INT); |
||
165 | foreach (self::$cols as $k => $v) { |
||
166 | if (isset($v[2]['sort']) && $v[2]['sort'] === false) { |
||
167 | continue; |
||
168 | } |
||
169 | if (empty($v)) { |
||
170 | $v = [null]; |
||
171 | } // fix for column requested as [] |
||
172 | $selected = $by === $k ? ' selected' : null; |
||
173 | $opts[] = "<option value=\"{$k}\"{$selected}>{$v[0]}</option>"; |
||
174 | } |
||
175 | } |
||
176 | |||
177 | protected static function requestFilter() |
||
178 | { |
||
179 | $filter = filter_input(INPUT_GET, 'filter') ?: false; |
||
180 | if ($filter) { |
||
181 | $by = filter_input(INPUT_GET, 'filter-by', FILTER_VALIDATE_INT); |
||
182 | if ($by === false || is_null($by)) { |
||
183 | $by = []; |
||
184 | foreach (self::$cols as $v) { |
||
185 | if (isset($v[2]['sort']) && $v[2]['sort'] === false) { |
||
186 | continue; |
||
187 | } |
||
188 | $by[] = 'IFNULL(' . $v[1] . ', "")'; |
||
189 | } |
||
190 | $by = 'CONCAT(' . implode(',', $by) . ')'; |
||
191 | } else { |
||
192 | $by = self::$cols[$by][1]; |
||
193 | } |
||
194 | $by = 'CONCAT(" ",' . $by . ', " ")'; |
||
195 | if (self::config('FILTER_CASE_SENSITIVE') !== true) { |
||
196 | $by .= ' COLLATE ' . self::config('DB_COLLATION_CI'); |
||
197 | } |
||
198 | $filter = $by . ' LIKE ' . '"%' . $filter . '%"'; |
||
199 | } |
||
200 | return $filter; |
||
201 | } |
||
202 | |||
203 | protected static function requestOrderCol() |
||
211 | } |
||
212 | |||
213 | protected static function requestOrderDir() |
||
214 | { |
||
215 | $reset = filter_has_var(INPUT_GET, 'col') ? 'asc' : null; |
||
216 | return in_array(filter_input(INPUT_GET, 'ord'), ['asc', 'desc']) ? |
||
217 | filter_input(INPUT_GET, 'ord') : |
||
218 | ($reset ?: self::$t['order']['dir']); |
||
219 | } |
||
220 | |||
221 | protected static function requestExport() |
||
225 | } |
||
226 | |||
227 | protected static function requestPage() |
||
228 | { |
||
229 | return filter_has_var(INPUT_GET, 'pg') && self::$export == false ? |
||
232 | } |
||
233 | } |
||
234 |
This check looks for unreachable code. It uses sophisticated control flow analysis techniques to find statements which will never be executed.
Unreachable code is most often the result of
return
,die
orexit
statements that have been added for debug purposes.In the above example, the last
return false
will never be executed, because a return statement has already been met in every possible execution path.