Passed
Push — develop ( 55dbd6...211bd7 )
by Felipe
04:56
created

HTMLTableController::printTable()   B

Complexity

Conditions 6
Paths 17

Size

Total Lines 42
Code Lines 17

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 42
rs 8.439
c 0
b 0
f 0
cc 6
eloc 17
nc 17
nop 2
1
<?php
2
3
/**
4
 * PHPPgAdmin v6.0.0-beta.48
5
 */
6
7
namespace PHPPgAdmin\XHtml;
8
9
use PHPPgAdmin\Decorators\Decorator;
10
11
/**
12
 * Class to render tables. Formerly part of Misc.php.
13
 */
14
class HTMLTableController extends HTMLController
15
{
16
    public $controller_name                = 'HTMLTableController';
17
    protected $ma                          = [];
18
    protected $plugin_functions_parameters = [];
19
    protected $has_ma                      = false;
20
21
    protected $tabledata;
22
    protected $columns;
23
    protected $actions;
24
    protected $place;
25
    protected $nodata;
26
    protected $pre_fn;
27
28
    /**
29
     * Display a table of data.
30
     *
31
     * @param \PHPPgAdmin\ADORecordSet|\PHPPgAdmin\ArrayRecordSet $tabledata a set of data to be formatted, as returned by $data->getDatabases() etc
32
     * @param array                                               $columns   An associative array of columns to be displayed:
33
     *                                                                       $columns = array(
34
     *                                                                       column_id => array(
35
     *                                                                       'title' => Column heading,
36
     *                                                                       'class' => The class to apply on the column cells,
37
     *                                                                       'field' => Field name for $tabledata->fields[...],
38
     *                                                                       'help'  => Help page for this column,
39
     *                                                                       ), ...
40
     *                                                                       );
41
     * @param array                                               $actions   Actions that can be performed on each object:
42
     *                                                                       $actions = array(
43
     *                                                                       * multi action support
44
     *                                                                       * parameters are serialized for each entries and given in $_REQUEST['ma']
45
     *                                                                       'multiactions' => array(
46
     *                                                                       'keycols' => Associative array of (URL variable => field name), // fields included in the form
47
     *                                                                       'url' => URL submission,
48
     *                                                                       'default' => Default selected action in the form. If null, an empty action is added & selected
49
     *                                                                       ),
50
     *                                                                       * actions *
51
     *                                                                       action_id => array(
52
     *                                                                       'title' => Action heading,
53
     *                                                                       'url'   => Static part of URL.  Often we rely
54
     *                                                                       relative urls, usually the page itself (not '' !), or just a query string,
55
     *                                                                       'vars'  => Associative array of (URL variable => field name),
56
     *                                                                       'multiaction' => Name of the action to execute.
57
     *                                                                       Add this action to the multi action form
58
     *                                                                       ), ...
59
     *                                                                       );
60
     * @param string                                              $place     Place where the $actions are displayed. Like 'display-browse',  where 'display'
61
     *                                                                       is the entrypoint (/src/views/display) and 'browse' is the action used inside its controller (in this case, doBrowse).
62
     * @param string                                              $nodata    (optional) Message to display if data set is empty
63
     * @param callable                                            $pre_fn    (optional) callback closure for each row. It will be passed two params: $rowdata and $actions,
64
     *                                                                       it may be used to derive new fields or modify actions.
65
     *                                                                       It can return an array of actions specific to the row,  or if nothing is returned then the standard actions are used.
66
     *                                                                       (see TblpropertiesController and ConstraintsController for examples)
67
     *                                                                       The function must not must not store urls because     they are relative and won't work out of context.
68
     *
69
     * @return string the html of the table
70
     */
71
    public function initialize(&$tabledata, &$columns, &$actions, $place, $nodata = '', $pre_fn = null)
72
    {
73
        // Action buttons hook's place
74
        $this->plugin_functions_parameters = [
75
            'actionbuttons' => &$actions,
76
            'place'         => $place,
77
        ];
78
79
        if ($this->has_ma = isset($actions['multiactions'])) {
80
            $this->ma = $actions['multiactions'];
81
        }
82
        unset($actions['multiactions']);
83
84
        $this->tabledata = $tabledata;
85
        $this->columns   = $columns;
86
        $this->actions   = $actions;
87
        $this->place     = $place;
88
        $this->nodata    = $nodata;
89
        $this->pre_fn    = $pre_fn;
90
    }
91
92
    public function printTable($turn_into_datatable = true, $with_body = true)
93
    {
94
        $plugin_manager = $this->plugin_manager;
95
96
        $plugin_manager->doHook('actionbuttons', $this->plugin_functions_parameters);
97
98
        if ($this->tabledata->recordCount() <= 0) {
99
            return "<p>{$this->nodata}</p>\n";
100
        }
101
102
        $tablehtml = '';
103
        // Remove the 'comment' column if they have been disabled
104
        if (!$this->conf['show_comments']) {
105
            unset($this->columns['comment']);
106
        }
107
108
        if (isset($this->columns['comment'])) {
109
            // Uncomment this for clipped comments.
110
            // TODO: This should be a user option.
111
            //$columns['comment']['params']['clip'] = true;
112
        }
113
114
        list($matop_html, $mabottom_html) = $this->_getMaHtml();
115
116
        $tablehtml .= $matop_html;
117
118
        $tablehtml .= '<table width="auto" class="'.($turn_into_datatable ? 'will_be_datatable ' : ' ').$this->place.'">'."\n";
119
120
        $tablehtml .= $this->getThead();
121
122
        //$this->prtrace($tabledata, $actions);
123
124
        $tablehtml .= $with_body ? $this->getTbody() : '';
125
126
        $tablehtml .= $this->getTfooter();
127
128
        $tablehtml .= "</table>\n";
129
130
        // Multi action table footer w/ options & [un]check'em all
131
        $tablehtml .= $mabottom_html;
132
133
        return $tablehtml;
134
    }
135
136
    private function _getMaHtml()
137
    {
138
        $matop_html    = '';
139
        $ma_bottomhtml = '';
140
        $lang          = $this->lang;
141
142
        if ($this->has_ma) {
143
            $matop_html .= '<script src="'.SUBFOLDER."/assets/js/multiactionform.js\" type=\"text/javascript\"></script>\n";
144
            $matop_html .= sprintf('<form id="multi_form" action="%s" method="post" enctype="multipart/form-data">%s', $this->ma['url'], "\n");
145
            $this->coalesceArr($this->ma, 'vars', []);
146
147
            foreach ($this->ma['vars'] as $k => $v) {
148
                $matop_html .= sprintf('<input type="hidden" name="%s" value="%s" />', $k, $v);
149
            }
150
151
            // if default is not set or doesn't exist, set it to null
152
            if (!isset($this->ma['default']) || !isset($this->actions[$this->ma['default']])) {
153
                $this->ma['default'] = null;
154
            }
155
156
            $ma_bottomhtml .= "<br />\n";
157
            $ma_bottomhtml .= "<table>\n";
158
            $ma_bottomhtml .= "<tr>\n";
159
            $ma_bottomhtml .= "<th class=\"data\" style=\"text-align: left\" colspan=\"3\">{$lang['stractionsonmultiplelines']}</th>\n";
160
            $ma_bottomhtml .= "</tr>\n";
161
            $ma_bottomhtml .= "<tr class=\"row1\">\n";
162
            $ma_bottomhtml .= '<td>';
163
            $ma_bottomhtml .= "<a href=\"#\" onclick=\"javascript:checkAll(true);\">{$lang['strselectall']}</a> / ";
164
            $ma_bottomhtml .= "<a href=\"#\" onclick=\"javascript:checkAll(false);\">{$lang['strunselectall']}</a></td>\n";
165
            $ma_bottomhtml .= "<td>&nbsp;--->&nbsp;</td>\n";
166
            $ma_bottomhtml .= "<td>\n";
167
            $ma_bottomhtml .= "\t<select name=\"action\">\n";
168
            if (null == $this->ma['default']) {
169
                $ma_bottomhtml .= "\t\t<option value=\"\">--</option>\n";
170
            }
171
172
            foreach ($this->actions as $k => $a) {
173
                if (isset($a['multiaction'])) {
174
                    $selected = $this->ma['default'] == $k ? ' selected="selected" ' : '';
175
                    $ma_bottomhtml .= "\t\t";
176
                    $ma_bottomhtml .= '<option value="'.$a['multiaction'].'" '.$selected.' rel="'.$k.'">'.$a['content'].'</option>';
177
                    $ma_bottomhtml .= "\n";
178
                }
179
            }
180
181
            $ma_bottomhtml .= "\t</select>\n";
182
            $ma_bottomhtml .= "<input type=\"submit\" value=\"{$lang['strexecute']}\" />\n";
183
            $ma_bottomhtml .= $this->getForm();
184
            $ma_bottomhtml .= "</td>\n";
185
            $ma_bottomhtml .= "</tr>\n";
186
            $ma_bottomhtml .= "</table>\n";
187
            $ma_bottomhtml .= '</form>';
188
        }
189
190
        return [$matop_html, $ma_bottomhtml];
191
    }
192
193
    public function getThead()
194
    {
195
        $columns = $this->columns;
196
        $actions = $this->actions;
197
198
        $thead_html = "<thead><tr>\n";
199
200
        // Display column headings
201
        if ($this->has_ma) {
202
            $thead_html .= '<th></th>';
203
        }
204
205
        foreach ($columns as $column_id => $column) {
206
            // Handle cases where no class has been passed
207
208
            $class = (isset($column['class']) && '' !== $column['class']) ? $column['class'] : '';
209
210
            switch ($column_id) {
211
                case 'actions':
212
                    if (sizeof($actions) > 0) {
213
                        $thead_html .= '<th class="data" >'.$column['title'].'</th>'."\n";
214
                    }
215
216
                    break;
217
                default:
218
                    $thead_html .= '<th class="data'.$class.'">';
219
                    if (isset($column['help'])) {
220
                        $thead_html .= $this->misc->printHelp($column['title'], $column['help'], false);
221
                    } else {
222
                        $thead_html .= $column['title'];
223
                    }
224
225
                    $thead_html .= "</th>\n";
226
227
                    break;
228
            }
229
        }
230
        $thead_html .= "</tr></thead>\n";
231
232
        return $thead_html;
233
    }
234
235
    private function getTbody()
236
    {
237
        $columns   = $this->columns;
238
        $actions   = $this->actions;
239
        $tabledata = $this->tabledata;
240
        $pre_fn    = $this->pre_fn;
241
242
        // Display table rows
243
        $i          = 0;
244
        $tbody_html = '<tbody>';
245
246
        while (!$tabledata->EOF) {
247
            $id = ($i % 2) + 1;
248
249
            unset($alt_actions);
250
            if (!is_null($pre_fn)) {
251
                $alt_actions = $pre_fn($tabledata, $actions);
252
            }
253
254
            if (!isset($alt_actions)) {
255
                $alt_actions = &$actions;
256
            }
257
258
            $tbody_html .= "<tr class=\"data{$id}\">\n";
259
            if ($this->has_ma) {
260
                $a = [];
261
                foreach ($this->ma['keycols'] as $k => $v) {
262
                    $a[$k] = $tabledata->fields[$v];
263
                }
264
                //\Kint::dump($a);
265
                $tbody_html .= '<td>';
266
                $tbody_html .= '<input type="checkbox" name="ma[]" value="'.htmlentities(serialize($a), ENT_COMPAT, 'UTF-8').'" />';
267
                $tbody_html .= "</td>\n";
268
            }
269
270
            foreach ($columns as $column_id => $column) {
271
                // Apply default values for missing parameters
272
                if (isset($column['url']) && !isset($column['vars'])) {
273
                    $column['vars'] = [];
274
                }
275
                $class = (isset($column['class']) && '' !== $column['class']) ? $column['class'] : '';
276
277
                switch ($column_id) {
278
                    case 'actions':
279
                        $tbody_html .= "<td class=\"opbutton{$id} {$class}\">";
280
                        foreach ($alt_actions as $action) {
281
                            if (isset($action['disable']) && true === $action['disable']) {
282
                                continue;
283
                            }
284
                            $action['fields'] = $tabledata->fields;
285
                            $tbody_html .= $this->printLink($action, false, __METHOD__);
286
                        }
287
                        $tbody_html .= "</td>\n";
288
289
                        break;
290
                    case 'comment':
291
                        $tbody_html .= "<td class='comment_cell'>";
292
                        $val = htmlentities(Decorator::get_sanitized_value($column['field'], $tabledata->fields));
0 ignored issues
show
Unused Code introduced by
The assignment to $val is dead and can be removed.
Loading history...
293
                        $tbody_html .= '</td>';
294
295
                        break;
296
                    default:
297
                        $tbody_html .= '<td class="'.$class.'"">';
298
                        $val = Decorator::get_sanitized_value($column['field'], $tabledata->fields);
299
                        if (!is_null($val)) {
300
                            if (isset($column['url'])) {
301
                                $tbody_html .= "<a href=\"{$column['url']}";
302
                                $tbody_html .= $this->printUrlVars($column['vars'], $tabledata->fields, false);
303
                                $tbody_html .= '">';
304
                            }
305
                            $type   = isset($column['type']) ? $column['type'] : null;
306
                            $params = isset($column['params']) ? $column['params'] : [];
307
                            $tbody_html .= $this->misc->printVal($val, $type, $params);
308
                            if (isset($column['url'])) {
309
                                $tbody_html .= '</a>';
310
                            }
311
                        }
312
313
                        $tbody_html .= "</td>\n";
314
315
                        break;
316
                }
317
            }
318
            $tbody_html .= "</tr>\n";
319
320
            $tabledata->moveNext();
321
            ++$i;
322
        }
323
324
        $tbody_html .= '</tbody>';
325
326
        return $tbody_html;
327
    }
328
329
    public function getTfooter()
330
    {
331
        $columns = $this->columns;
332
        $actions = $this->actions;
333
334
        $tfoot_html = "<tfoot><tr>\n";
335
336
        // Display column headings
337
        if ($this->has_ma) {
338
            $tfoot_html .= '<td></td>';
339
        }
340
341
        foreach ($columns as $column_id => $column) {
342
            // Handle cases where no class has been passed
343
344
            $class = (isset($column['class']) && '' !== $column['class']) ? $column['class'] : '';
345
346
            if ($column_id !== 'actions' || sizeof($actions) > 0) {
347
                $tfoot_html .= "<td class=\"data{$class}\"></td>\n";
348
            }
349
        }
350
        $tfoot_html .= "</tr></tfoot>\n";
351
352
        return $tfoot_html;
353
    }
354
355
    private function getForm()
356
    {
357
        if (!$this->form) {
358
            $this->form = $this->misc->setForm();
359
        }
360
361
        return $this->form;
362
    }
363
364
    private function printUrlVars(&$vars, &$fields, $do_print = true)
365
    {
366
        $url_vars_html = '';
367
        foreach ($vars as $var => $varfield) {
368
            $url_vars_html .= "{$var}=".urlencode($fields[$varfield]).'&amp;';
369
        }
370
        if ($do_print) {
371
            echo $url_vars_html;
372
        } else {
373
            return $url_vars_html;
374
        }
375
    }
376
}
377