Passed
Branchmaster (1c4710)
by Plamen
01:30
created

table_setter::err()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 7
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 5
c 1
b 0
f 0
dl 0
loc 7
rs 10
cc 3
nc 3
nop 1
1
<?php
2
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
    /** @param array Errors collector */
14
    protected static $errors = [];
15
16
    static function assets($path = "/public/table")
17
    {
18
        return "<script src=\"{$path}/table.js\"></script>\n\t" .
19
                "<link href=\"{$path}/table.css\" rel=\"stylesheet\">\n";
20
    }
21
22
    /** Set/Get config value
23
     * @param mixed $c (string) Get if exists, (array) Set if valid
24
     * @return mixed */
25
    public static function config($c)
26
    {
27
        self::$config = self::$config ?: [
28
            'DB_COLLATION_CI' => 'utf8mb4_general_ci', //UTF8_GENERAL_CI
29
            'EMPTY_TABLE_MSG' => 'No results found.',
30
            'EXPORT_FILE_NAME' => ':app - :items export (:datetime)',
31
            'FILTER_CASE_SENSITIVE' => false,
32
            'SAVES' => ['CSV', 'Excel'],
33
            'UTF8_ASC_SYMBOL' => '&#9650;',
34
            'UTF8_DESC_SYMBOL' => '&#9660;',
35
            'UTF8_LEFT_SYMBOL' => '&lsaquo;',
36
            'UTF8_RIGHT_SYMBOL' => '&rsaquo;'
37
        ];
38
39
        $getValid = function($k, $v = null) {
40
            if (!array_key_exists($k, self::$config)) {
41
                throw new Exception('Request to undefined value: ' . $k);
42
            }
43
44
            if ($v !== null) {
45
                if (empty($v) || gettype($v) !== gettype(self::$config[$k])) {
46
                    throw new Exception("Setting invalid value: $v (:$k)");
47
                }
48
            }
49
50
            return $v === null ? self::$config[$k] : $v;
51
        };
52
53
        try {
54
            switch (gettype($c)) {
55
                case 'array';
56
                    foreach ($c as $k => $v) {
57
                        self::$config[$k] = $getValid((string) $k, $v);
58
                    }
59
                    break;
60
                case 'string':
61
                    return $getValid($c);
62
                default:
63
                    throw new Exception("Invalid value type.");
64
            }
65
        } catch (Exception $e) {
66
            self::err('ERROR: ' . $e->getMessage());
67
        }
68
    }
69
70
    protected static function err($message = null)
71
    {
72
        if (isset($message)) {
73
            self::$errors[] = $message;
74
        } else {
75
            return empty(self::$errors) ? null :
76
            '<p class="tbl-err">' . implode('</br>', self::$errors) . '</p>';
77
        }
78
    }
79
80
    /** Converts array to space separated key value list
81
     * @param array $attributes
82
     * @return string */
83
    protected static function attributes(array $attributes)
84
    {
85
        $list = [];
86
        foreach ($attributes as $key => $value) {
87
            if (is_bool($value)) {
88
                if ((bool) $value) {
89
                    $list[] = $key;
90
                }
91
            } else if (empty($value) && !is_int($value)) {
92
                $list[] = $key;
93
            } else {
94
                $list[] = $key . '="' . $value . '"';
95
            }
96
        }
97
        return (count($list) > 0 ? ' ' : '') . join(' ', $list);
98
    }
99
100
    /** Parses view to string
101
     * @param string $template
102
     * @param array $vars
103
     * @return string */
104
    protected static function view($template, $vars = [])
105
    {
106
        extract($vars);
107
        ob_start();
108
        require $template;
109
        return (string) ob_get_clean();
110
    }
111
112
    protected static function paging(&$v)
113
    {
114
        if (self::$t['pages'] > 1) {
115
            $v['pages'] = self::$t['pages'];
116
            $v['page'] = self::$t['page'];
117
            $v['jumpL'] = self::pagingJumps();
118
            $v['jumpR'] = self::pagingJumps();
119
            $v['arrowL'] = self::config('UTF8_LEFT_SYMBOL');
120
            $v['arrowR'] = self::config('UTF8_RIGHT_SYMBOL');
121
122
            $limit = 10;
123
124
            $v['start'] = $v['page'] > ($limit / 2) ?
125
                    ($v['page'] - $limit / 2) :
126
                    1;
127
128
            if ($v['page'] > ($v['pages'] - ($limit / 2))) {
129
                $v['final'] = $v['pages'];
130
            } else if ($v['page'] > ($limit / 2)) {
131
                $v['final'] = $v['start'] + $limit;
132
            } else {
133
                $v['final'] = $limit;
134
            }
135
        }
136
    }
137
138
    /** Jump links -1M|-100K|-10K|-1K|100|{paging}|100|+1K|+10K|+100K|+1M
139
     * @param string $html Code to show
140
     * @param null|int $m multiplier
141
     * @return string */
142
    protected static function pagingJumps($html = '', $m = null)
143
    {
144
        static $direction;
145
146
        if (is_null($m)) { //on self::createPaginationLinks() calls only
147
            $direction = !isset($direction) ? '-' : '+';
148
            $m = 100;
149
        }
150
        $jump2show = function($m) use ($direction) {
151
            if ($m >= 1000000) {
152
                return ($direction . ($m / 1000000) . "M");
153
            } else if ($m >= 1000) {
154
                return ($direction . ($m / 1000) . "K");
155
            } else {
156
                return ($direction . $m);
157
            }
158
        };
159
        $add = '<li class="jump"><a>' . $jump2show($m) . '</a></li>';
160
161
        if ($direction === '-') {
162
            $jump_exists = (self::$t['page'] - $m) > 0;
163
        } else {
164
            $jump_exists = (self::$t['page'] + $m) <= self::$t['pages'];
165
        }
166
167
        if ($jump_exists) {
168
            $html = $direction === '-' ? $add . $html : $html . $add;
169
        }
170
171
        return $jump_exists ? self::pagingJumps($html, ($m * 10)) : $html;
172
    }
173
174
    protected static function filterValues(&$f, &$opts = [])
175
    {
176
        $f = filter_input(INPUT_GET, 'filter', FILTER_SANITIZE_STRING) ?: null;
177
178
        $by = filter_input(INPUT_GET, 'filter-by', FILTER_VALIDATE_INT);
179
        foreach (self::$cols as $k => $v) {
180
            if (isset($v[2]['sort']) && $v[2]['sort'] === false) {
181
                continue;
182
            }
183
            if (empty($v)) {
184
                $v = [null];
185
            } // fix for column requested as []
186
            $selected = $by === $k ? ' selected' : null;
187
            $opts[] = "<option value=\"{$k}\"{$selected}>{$v[0]}</option>";
188
        }
189
    }
190
191
    protected static function requestFilter()
192
    {
193
        $filter = filter_input(INPUT_GET, 'filter') ?: false;
194
        if ($filter) {
195
            $by = filter_input(INPUT_GET, 'filter-by', FILTER_VALIDATE_INT);
196
            if ($by === false || is_null($by)) {
197
                $by = [];
198
                foreach (self::$cols as $v) {
199
                    if (isset($v[2]['sort']) && $v[2]['sort'] === false) {
200
                        continue;
201
                    }
202
                    $by[] = 'IFNULL(' . $v[1] . ', "")';
203
                }
204
                $by = 'CONCAT(' . implode(',', $by) . ')';
205
            } else {
206
                $by = self::$cols[$by][1];
207
            }
208
            $by = 'CONCAT(" ",' . $by . ', " ")';
209
            if (self::config('FILTER_CASE_SENSITIVE') !== true) {
210
                $by .= ' COLLATE ' . self::config('DB_COLLATION_CI');
211
            }
212
            $filter = $by . ' LIKE ' . '"%' . $filter . '%"';
213
        }
214
        return $filter;
215
    }
216
217
    protected static function requestOrderCol()
218
    {
219
        if (($col = filter_input(INPUT_GET, 'col', FILTER_VALIDATE_INT))) {
220
            return isset(self::$cols[$col][2]['sort']) ?
221
                    self::$cols[$col][2]['sort'] :
222
                    self::$cols[$col][1];
223
        }
224
        return self::$t['order']['col'];
225
    }
226
227
    protected static function requestOrderDir()
228
    {
229
        $reset = filter_has_var(INPUT_GET, 'col') ? 'asc' : null;
230
        return in_array(filter_input(INPUT_GET, 'ord'), ['asc', 'desc']) ?
231
                filter_input(INPUT_GET, 'ord') :
232
                ($reset ?: self::$t['order']['dir']);
233
    }
234
235
    protected static function requestExport()
236
    {
237
        $exp = filter_input(INPUT_GET, 'export', FILTER_SANITIZE_STRING);
238
        return in_array($exp, self::config('SAVES')) ? $exp : false;
0 ignored issues
show
Bug introduced by
It seems like self::config('SAVES') can also be of type null; however, parameter $haystack of in_array() does only seem to accept array, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

238
        return in_array($exp, /** @scrutinizer ignore-type */ self::config('SAVES')) ? $exp : false;
Loading history...
239
    }
240
241
    protected static function requestPage()
242
    {
243
        return filter_has_var(INPUT_GET, 'pg') && self::$export == false ?
244
                (int) filter_input(INPUT_GET, 'pg', FILTER_SANITIZE_NUMBER_INT) :
245
                self::$t['page'];
246
    }
247
}
248