Completed
Pull Request — develop (#209)
by Felipe
26:08 queued 36s
created

HTMLTableController::initialize()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 20
Code Lines 13

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
eloc 13
nc 2
nop 6
dl 0
loc 20
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
4 ignored issues
show
Coding Style introduced by
The property $controller_name is not named in camelCase.

This check marks property names that have not been written in camelCase.

In camelCase names are written without any punctuation, the start of each new word being marked by a capital letter. Thus the name database connection string becomes databaseConnectionString.

Loading history...
Coding Style introduced by
The property $plugin_functions_parameters is not named in camelCase.

This check marks property names that have not been written in camelCase.

In camelCase names are written without any punctuation, the start of each new word being marked by a capital letter. Thus the name database connection string becomes databaseConnectionString.

Loading history...
Coding Style introduced by
The property $has_ma is not named in camelCase.

This check marks property names that have not been written in camelCase.

In camelCase names are written without any punctuation, the start of each new word being marked by a capital letter. Thus the name database connection string becomes databaseConnectionString.

Loading history...
Coding Style introduced by
The property $pre_fn is not named in camelCase.

This check marks property names that have not been written in camelCase.

In camelCase names are written without any punctuation, the start of each new word being marked by a capital letter. Thus the name database connection string becomes databaseConnectionString.

Loading history...
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,
0 ignored issues
show
Documentation introduced by
Should the type for parameter $pre_fn not be callable|null?

This check looks for @param annotations where the type inferred by our type inference engine differs from the declared type.

It makes a suggestion as to what type it considers more descriptive.

Most often this is a case of a parameter that can be null in addition to its declared types.

Loading history...
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
0 ignored issues
show
Documentation introduced by
Should the return type not be string|null?

This check compares the return type specified in the @return annotation of a function or method doc comment with the types returned by the function and raises an issue if they mismatch.

Loading history...
70
     */
71
    public function initialize(&$tabledata, &$columns, &$actions, $place, $nodata = '', $pre_fn = null)
0 ignored issues
show
Coding Style Naming introduced by
The parameter $pre_fn is not named in camelCase.

This check marks parameter names that have not been written in camelCase.

In camelCase names are written without any punctuation, the start of each new word being marked by a capital letter. Thus the name database connection string becomes databaseConnectionString.

Loading history...
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)
0 ignored issues
show
Coding Style Naming introduced by
The parameter $turn_into_datatable is not named in camelCase.

This check marks parameter names that have not been written in camelCase.

In camelCase names are written without any punctuation, the start of each new word being marked by a capital letter. Thus the name database connection string becomes databaseConnectionString.

Loading history...
Coding Style Naming introduced by
The parameter $with_body is not named in camelCase.

This check marks parameter names that have not been written in camelCase.

In camelCase names are written without any punctuation, the start of each new word being marked by a capital letter. Thus the name database connection string becomes databaseConnectionString.

Loading history...
93
    {
94
        $plugin_manager = $this->plugin_manager;
0 ignored issues
show
Bug introduced by
The property plugin_manager does not exist. Did you maybe forget to declare it?

In PHP it is possible to write to properties without declaring them. For example, the following is perfectly valid PHP code:

class MyClass { }

$x = new MyClass();
$x->foo = true;

Generally, it is a good practice to explictly declare properties to avoid accidental typos and provide IDE auto-completion:

class MyClass {
    public $foo;
}

$x = new MyClass();
$x->foo = true;
Loading history...
95
96
        $plugin_manager->doHook('actionbuttons', $this->plugin_functions_parameters);
97
98
        if ($this->tabledata->recordCount() <= 0) {
99
            return "<p>{$this->nodata}</p>".PHP_EOL;
100
        }
101
102
        $tablehtml = '';
103
        // Remove the 'comment' column if they have been disabled
104
        if (!$this->conf['show_comments']) {
0 ignored issues
show
Bug introduced by
The property conf does not exist. Did you maybe forget to declare it?

In PHP it is possible to write to properties without declaring them. For example, the following is perfectly valid PHP code:

class MyClass { }

$x = new MyClass();
$x->foo = true;

Generally, it is a good practice to explictly declare properties to avoid accidental typos and provide IDE auto-completion:

class MyClass {
    public $foo;
}

$x = new MyClass();
$x->foo = true;
Loading history...
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.'">'.PHP_EOL;
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>'.PHP_EOL;
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>'.PHP_EOL;
144
            $matop_html .= sprintf('<form id="multi_form" action="%s" method="post" enctype="multipart/form-data">%s', $this->ma['url'], PHP_EOL);
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 />'.PHP_EOL;
157
            $ma_bottomhtml .= '<table>'.PHP_EOL;
158
            $ma_bottomhtml .= '<tr>'.PHP_EOL;
159
            $ma_bottomhtml .= "<th class=\"data\" style=\"text-align: left\" colspan=\"3\">{$lang['stractionsonmultiplelines']}</th>".PHP_EOL;
160
            $ma_bottomhtml .= '</tr>'.PHP_EOL;
161
            $ma_bottomhtml .= '<tr class="row1">'.PHP_EOL;
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>".PHP_EOL;
165
            $ma_bottomhtml .= '<td>&nbsp;--->&nbsp;</td>'.PHP_EOL;
166
            $ma_bottomhtml .= '<td>'.PHP_EOL;
167
            $ma_bottomhtml .= "\t<select name=\"action\">".PHP_EOL;
168
            if (null == $this->ma['default']) {
169
                $ma_bottomhtml .= "\t\t<option value=\"\">--</option>".PHP_EOL;
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 .= PHP_EOL;
178
                }
179
            }
180
181
            $ma_bottomhtml .= "\t</select>".PHP_EOL;
182
            $ma_bottomhtml .= "<input type=\"submit\" value=\"{$lang['strexecute']}\" />".PHP_EOL;
183
            $ma_bottomhtml .= $this->getForm();
184
            $ma_bottomhtml .= '</td>'.PHP_EOL;
185
            $ma_bottomhtml .= '</tr>'.PHP_EOL;
186
            $ma_bottomhtml .= '</table>'.PHP_EOL;
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>'.PHP_EOL;
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>'.PHP_EOL;
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);
0 ignored issues
show
Bug introduced by
The property misc does not exist. Did you maybe forget to declare it?

In PHP it is possible to write to properties without declaring them. For example, the following is perfectly valid PHP code:

class MyClass { }

$x = new MyClass();
$x->foo = true;

Generally, it is a good practice to explictly declare properties to avoid accidental typos and provide IDE auto-completion:

class MyClass {
    public $foo;
}

$x = new MyClass();
$x->foo = true;
Loading history...
221
                    } else {
222
                        $thead_html .= $column['title'];
223
                    }
224
225
                    $thead_html .= '</th>'.PHP_EOL;
226
227
                    break;
228
            }
229
        }
230
        $thead_html .= '</tr></thead>'.PHP_EOL;
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 .= sprintf('<tr class="data%s">', $id).PHP_EOL;
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 .= sprintf('<td><input type="checkbox" name="ma[]" value="%s"/></td>', htmlentities(serialize($a), ENT_COMPAT, 'UTF-8')).PHP_EOL;
266
            }
267
268
            foreach ($columns as $column_id => $column) {
269
                // Apply default values for missing parameters
270
                if (isset($column['url']) && !isset($column['vars'])) {
271
                    $column['vars'] = [];
272
                }
273
                $class = (isset($column['class']) && '' !== $column['class']) ? $column['class'] : '';
274
275
                switch ($column_id) {
276
                    case 'actions':
277
                        $tbody_html .= "<td class=\"opbutton{$id} {$class}\">";
278
                        foreach ($alt_actions as $action) {
279
                            if (isset($action['disable']) && true === $action['disable']) {
280
                                continue;
281
                            }
282
                            $action['fields'] = $tabledata->fields;
283
                            $tbody_html .= $this->printLink($action, false, __METHOD__);
284
                        }
285
                        $tbody_html .= '</td>'.PHP_EOL;
286
287
                        break;
288
                    case 'comment':
289
                        $tbody_html .= "<td class='comment_cell'>";
290
                        $tbody_html .= htmlentities(Decorator::get_sanitized_value($column['field'], $tabledata->fields));
291
                        $tbody_html .= '</td>';
292
293
                        break;
294
                    default:
295
                        $tbody_html .= '<td class="'.$class.'">';
296
                        $val = Decorator::get_sanitized_value($column['field'], $tabledata->fields);
297
                        if (!is_null($val)) {
298
                            if (isset($column['url'])) {
299
                                $tbody_html .= "<a href=\"{$column['url']}";
300
                                $tbody_html .= $this->printUrlVars($column['vars'], $tabledata->fields, false);
301
                                $tbody_html .= '">';
302
                            }
303
                            $type   = isset($column['type']) ? $column['type'] : null;
304
                            $params = isset($column['params']) ? $column['params'] : [];
305
                            $tbody_html .= $this->misc->printVal($val, $type, $params);
306
                            if (isset($column['url'])) {
307
                                $tbody_html .= '</a>';
308
                            }
309
                        }
310
311
                        $tbody_html .= '</td>'.PHP_EOL;
312
313
                        break;
314
                }
315
            }
316
            $tbody_html .= '</tr>'.PHP_EOL;
317
318
            $tabledata->moveNext();
319
            ++$i;
320
        }
321
322
        $tbody_html .= '</tbody>';
323
324
        return $tbody_html;
325
    }
326
327
    public function getTfooter()
328
    {
329
        $columns = $this->columns;
330
        $actions = $this->actions;
331
332
        $tfoot_html = '<tfoot><tr>'.PHP_EOL;
333
334
        // Display column headings
335
        if ($this->has_ma) {
336
            $tfoot_html .= '<td></td>';
337
        }
338
339
        foreach ($columns as $column_id => $column) {
340
            // Handle cases where no class has been passed
341
342
            $class = (isset($column['class']) && '' !== $column['class']) ? $column['class'] : '';
343
344
            if ($column_id !== 'actions' || sizeof($actions) > 0) {
345
                $tfoot_html .= "<td class=\"data{$class}\"></td>".PHP_EOL;
346
            }
347
        }
348
        $tfoot_html .= '</tr></tfoot>'.PHP_EOL;
349
350
        return $tfoot_html;
351
    }
352
353
    private function getForm()
0 ignored issues
show
Documentation introduced by
The return type could not be reliably inferred; please add a @return annotation.

Our type inference engine in quite powerful, but sometimes the code does not provide enough clues to go by. In these cases we request you to add a @return annotation as described here.

Loading history...
354
    {
355
        if (!$this->form) {
356
            $this->form = $this->misc->setForm();
357
        }
358
359
        return $this->form;
360
    }
361
362
    private function printUrlVars(&$vars, &$fields, $do_print = true)
0 ignored issues
show
Coding Style Naming introduced by
The parameter $do_print is not named in camelCase.

This check marks parameter names that have not been written in camelCase.

In camelCase names are written without any punctuation, the start of each new word being marked by a capital letter. Thus the name database connection string becomes databaseConnectionString.

Loading history...
363
    {
364
        $url_vars_html = '';
365
        foreach ($vars as $var => $varfield) {
366
            $url_vars_html .= "{$var}=".urlencode($fields[$varfield]).'&amp;';
367
        }
368
        if ($do_print) {
369
            echo $url_vars_html;
370
        } else {
371
            return $url_vars_html;
372
        }
373
    }
374
}
375