Passed
Push — develop ( ca4520...e7398d )
by Felipe
04:50
created

HTMLTableController::getForm()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 7
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

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