Test Failed
Pull Request — develop (#380)
by Felipe
03:42
created

BaseController::printTable()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 7
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 3
dl 0
loc 7
c 0
b 0
f 0
rs 10
cc 1
nc 1
nop 6
1
<?php
2
3
/**
4
 * PHPPgAdmin 6.1.3
5
 */
6
7
namespace PHPPgAdmin\Controller;
8
9
use PHPPgAdmin\ADORecordSet;
10
use PHPPgAdmin\ArrayRecordSet;
11
use PHPPgAdmin\ContainerUtils;
12
use PHPPgAdmin\Misc;
13
use PHPPgAdmin\Traits\HelperTrait;
14
use PHPPgAdmin\ViewManager;
15
use PHPPgAdmin\XHtml;
16
use PHPPgAdmin\XHtml\HTMLFooterController;
17
use PHPPgAdmin\XHtml\HTMLHeaderController;
18
use PHPPgAdmin\XHtml\HTMLNavbarController;
19
use PHPPgAdmin\XHtml\HTMLTableController;
20
use Slim\Http\Response;
21
use ADORecordSet as ADODBRecordsetClass;
22
23
/**
24
 * Base controller class.
25
 */
26
class BaseController
27
{
28
    use HelperTrait;
29
30
    public $appLangFiles = [];
31
32
    public $appThemes = [];
33
34
    public $appName = '';
35
36
    public $appVersion = '';
37
38
    public $form = '';
39
40
    public $href = '';
41
42
    public $lang = [];
43
44
    public $action = '';
45
46
    public $controller_name;
47
48
    /**
49
     * Used.
50
     *
51
     * @var string
52
     */
53
    public $view_name;
54
55
    /**
56
     * Used to print the title passing its value to $lang.
57
     *
58
     * @var string
59
     */
60
    public $controller_title = 'base';
61
62
    public $msg = '';
63
64
    /**
65
     * @var ViewManager
66
     */
67
    public $view;
68
69
    /**
70
     * @var Misc
71
     */
72
    public $misc;
73
74
    public $conf;
75
76
    public $phpMinVer;
77
78
    /**
79
     * @var ContainerUtils
80
     */
81
    protected $container;
82
83
    protected $script;
84
85
    protected $data;
86
87
    protected $database;
88
89
    protected $server_id;
90
91
    /**
92
     * @var XHtml\HTMLTableController
93
     * @psalm-suppress PropertyNotSetInConstructor
94
     */
95
    protected $_table_controller;
96
97
    /**
98
     * @var XHtml\HTMLFooterController
99
     * @psalm-suppress PropertyNotSetInConstructor
100
     */
101
    protected $_footer_controller;
102
103
    /**
104
     * @var XHtml\HTMLHeaderController
105
     * @psalm-suppress PropertyNotSetInConstructor
106
     */
107
    protected $_header_controller;
108
109
    /**
110
     * @var XHtml\HTMLNavbarController
111
     * @psalm-suppress PropertyNotSetInConstructor
112
     */
113
    protected $_trail_controller;
114
115
    /**
116
     * @var TreeController
117
     * @psalm-suppress PropertyNotSetInConstructor
118
     */
119
    protected $_tree_controller;
120
121
    protected $scripts = '';
122
123
    protected $no_db_connection = false;
124
125
    /**
126
     * Constructs the base controller (common for almost all controllers).
127
     *
128
     * @param ContainerUtils $container        the $app container
129
     * @param bool           $no_db_connection [optional] if true, sets  $this->misc->setNoDBConnection(true);
130
     */
131
    public function __construct(ContainerUtils $container)
132
    {
133
        $this->container = $container;
134
        $this->lang = $container->get('lang');
135
136
        $this->controller_name = \str_replace(__NAMESPACE__ . '\\', '', \get_class($this));
137
        $this->view_name = \str_replace('controller', '', \mb_strtolower($this->controller_name));
138
        $this->script = $this->view_name;
139
140
        $this->view = $container->get('view');
141
142
        $this->msg = $container->get('msg');
143
        $this->appLangFiles = $container->get('appLangFiles');
144
145
        $this->misc = $container->get('misc');
146
        $this->conf = $this->misc->getConf();
147
148
        $this->appThemes = $container->get('appThemes');
149
        $this->action = $container->get('action');
150
151
        $this->appName = $container->get('settings')['appName'];
152
        $this->appVersion = $container->get('settings')['appVersion'];
153
        $this->postgresqlMinVer = $container->get('settings')['postgresqlMinVer'];
154
        $this->phpMinVer = $container->get('settings')['phpMinVer'];
155
156
        $msg = $container->get('msg');
157
158
        if (true === $this->no_db_connection) {
159
            $this->misc->setNoDBConnection(true);
160
        }
161
162
        if (!$this->container->IN_TEST) {
163
            $this->renderInitialPageIfNotLogged();
164
        }
165
    }
166
167
    /**
168
     * Default method to render the controller according to the action parameter. It should return with a PSR
169
     * responseObject but it prints texts whatsoeever.
170
     */
171
    public function render()
172
    {
173
        $this->misc = $this->misc;
174
175
        $this->printHeader();
176
        $this->printBody();
177
178
        switch ($this->action) {
179
            default:
180
                $this->doDefault();
181
182
                break;
183
        }
184
185
        $this->printFooter();
186
    }
187
188
    /**
189
     * @return string
190
     */
191
    public function doDefault()
192
    {
193
        $html = '<div><h2>Section title</h2> <p>Main content</p></div>';
194
        echo $html;
195
196
        return $html;
197
    }
198
199
    /**
200
     * Returns the page title for each controller.
201
     *
202
     * @param string $title  The title
203
     * @param string $prefix The prefix
204
     * @param string $suffix The suffix
205
     *
206
     * @return string the page title
207
     */
208
    public function headerTitle($title = '', $prefix = '', $suffix = '')
209
    {
210
        $title = $title ? $title : $this->controller_title;
211
212
        return $prefix . $this->lang[$title] . ($suffix ? ': ' . $suffix : '');
213
    }
214
215
    /**
216
     * @return ContainerUtils
217
     */
218
    public function getContainer()
219
    {
220
        return $this->container;
221
    }
222
223
    /**
224
     * Display a table of data.
225
     *
226
     * @param ADORecordSet|ArrayRecordSet $tabledata a set of data to be formatted
227
     * @param array                       $columns   An associative array of columns to be displayed:
228
     * @param array                       $actions   Actions that can be performed on each object:
229
     * @param string                      $place     Place where the $actions are displayed. Like 'display-browse',
230
     * @param string                      $nodata    (optional) Message to display if data set is empty
231
     * @param callable                    $pre_fn    (optional) callback closure for each row
232
     *
233
     * @return string the html of the table
234
     */
235
    public function printTable(&$tabledata, &$columns, &$actions, $place, $nodata = '', $pre_fn = null)
236
    {
237
        $html_table = $this->_getTableController();
238
239
        $html_table->initialize($tabledata, $columns, $actions, $place, $nodata, $pre_fn);
240
241
        return $html_table->printTable();
242
    }
243
244
    /**
245
     * Hides or show tree tabs according to their properties.
246
     *
247
     * @param array $tabs The tabs
248
     *
249
     * @return ADORecordSet|ArrayRecordSet filtered tabs in the form of an ArrayRecordSet
250
     */
251
    public function adjustTabsForTree(&$tabs)
252
    {
253
        $tree = $this->_getTreeController();
254
255
        return $tree->adjustTabsForTree($tabs);
256
    }
257
258
    /**
259
     * Produce JSON data for the browser tree.
260
     *
261
     * @param \PHPPgAdmin\Interfaces\Recordset|\ADORecordSet
262
     * @param array                       $attrs     Attributes for tree items
263
     * @param string                      $section   The section where the branch is linked in the tree
264
     * @param bool                        $print     either to return or echo the result
265
     *
266
     * @return Response|string the json rendered tree
267
     */
268
    public function printTree(  &$_treedata, &$attrs, $section, $print = true)
0 ignored issues
show
Coding Style introduced by
Expected 0 spaces after opening parenthesis; 2 found
Loading history...
269
    {
270
        $tree = $this->_getTreeController();
271
272
        return $tree->printTree($_treedata, $attrs, $section, $print);
0 ignored issues
show
Bug Best Practice introduced by
The expression return $tree->printTree(...ttrs, $section, $print) returns the type array<mixed,array|boolean|string> which is incompatible with the documented return type Slim\Http\Response|string.
Loading history...
273
    }
274
275
    /**
276
     * Prints a trail.
277
     *
278
     * @param array|string $trail
279
     * @param bool         $do_print The do print
280
     *
281
     * @return string ( description_of_the_return_value )
282
     */
283
    public function printTrail($trail = [], bool $do_print = true)
284
    {
285
        $from = __METHOD__;
286
        $html_trail = $this->_getNavbarController();
287
288
        return $html_trail->printTrail($trail, $do_print, $from);
289
    }
290
291
    /**
292
     * @param (array[][]|mixed)[][] $navlinks
293
     * @param string                $place
294
     * @param array                 $env
295
     * @param mixed                 $do_print
296
     */
297
    public function printNavLinks(array $navlinks, string $place, array $env = [], $do_print = true)
298
    {
299
        $from = __METHOD__;
300
        $footer_controller = $this->_getFooterController();
301
302
        return $footer_controller->printNavLinks($navlinks, $place, $env, $do_print, $from);
303
    }
304
305
    public function printTabs(string $tabs, string $activetab, bool $do_print = true)
306
    {
307
        $from = __METHOD__;
308
        $html_trail = $this->_getNavbarController();
309
310
        return $html_trail->printTabs($tabs, $activetab, $do_print, $from);
311
    }
312
313
    /**
314
     * @param true        $do_print
315
     * @param null|string $from
316
     * @param mixed       $link
317
     */
318
    public function printLink($link, bool $do_print = true, ?string $from = null)
319
    {
320
        if (null === $from) {
321
            $from = __METHOD__;
322
        }
323
324
        $html_trail = $this->_getNavbarController();
325
326
        return $html_trail->printLink($link, $do_print, $from);
327
    }
328
329
    /**
330
     * @param true $flag
331
     */
332
    public function setReloadDropDatabase(bool $flag)
333
    {
334
        $footer_controller = $this->_getFooterController();
335
336
        return $footer_controller->setReloadDropDatabase($flag);
337
    }
338
339
    /**
340
     * @param true $flag
341
     */
342
    public function setNoBottomLink(bool $flag)
343
    {
344
        $footer_controller = $this->_getFooterController();
345
346
        return $footer_controller->setNoBottomLink($flag);
347
    }
348
349
    public function printFooter(bool $doBody = true, string $template = 'footer.twig')
350
    {
351
        $footer_controller = $this->_getFooterController();
352
353
        return $footer_controller->printFooter($doBody, $template);
354
    }
355
356
    public function printReload($database, $do_print = true)
357
    {
358
        $footer_controller = $this->_getFooterController();
359
360
        return $footer_controller->printReload($database, $do_print);
0 ignored issues
show
Bug introduced by
The method printReload() does not exist on PHPPgAdmin\XHtml\HTMLFooterController. ( Ignorable by Annotation )

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

360
        return $footer_controller->/** @scrutinizer ignore-call */ printReload($database, $do_print);

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
361
    }
362
363
    /**
364
     * Outputs JavaScript to set default focus.
365
     *
366
     * @param mixed $object eg. forms[0].username
367
     */
368
    public function setFocus($object)
369
    {
370
        $footer_controller = $this->_getFooterController();
371
372
        return $footer_controller->setFocus($object);
373
    }
374
375
    /**
376
     * Outputs JavaScript to set the name of the browser window.
377
     *
378
     * @param string $name      the window name
379
     * @param bool   $addServer if true (default) then the server id is
380
     *                          attached to the name
381
     */
382
    public function setWindowName($name, $addServer = true)
383
    {
384
        $footer_controller = $this->_getFooterController();
385
386
        return $footer_controller->setWindowName($name, $addServer);
387
    }
388
389
    /**
390
     * @param true $flag
391
     */
392
    public function setNoOutput(bool $flag)
393
    {
394
        $header_controller = $this->_getHeaderController();
395
396
        return $header_controller->setNoOutput((bool) $flag);
397
    }
398
399
    /**
400
     * @param null|string $script
401
     * @param string      $title
402
     * @param bool        $do_print
403
     * @param string      $template
404
     */
405
    public function printHeader(string $title = '', ?string $script = null, bool $do_print = true, string $template = 'header.twig')
406
    {
407
        $title = $title ? $title : $this->headerTitle();
408
        $header_controller = $this->_getHeaderController();
409
410
        return $header_controller->printHeader($title, $script, $do_print, $template);
411
    }
412
413
    /**
414
     * Undocumented function
415
     *
416
     * @param boolean $doBody
417
     * @param string $bodyClass
418
     * @param boolean $onloadInit
419
     * @param boolean $includeJsTree either to add the jsTree in the root body. By default is inserted using an iframe
420
     * @return void
421
     */
422
    public function printBody(bool $doBody = true, string $bodyClass = 'detailbody', bool $onloadInit = false,bool $includeJsTree=false)
0 ignored issues
show
Coding Style introduced by
Expected 1 space between comma and type hint "bool"; 0 found
Loading history...
Coding Style introduced by
Incorrect spacing between argument "$includeJsTree" and equals sign; expected 1 but found 0
Loading history...
Coding Style introduced by
Incorrect spacing between default value and equals sign for argument "$includeJsTree"; expected 1 but found 0
Loading history...
423
    {
424
        $header_controller = $this->_getHeaderController();
425
426
        return $header_controller->printBody($doBody, $bodyClass, $onloadInit,$includeJsTree);
0 ignored issues
show
Bug Best Practice introduced by
The expression return $header_controlle...adInit, $includeJsTree) returns the type string which is incompatible with the documented return type void.
Loading history...
427
    }
428
429
    /**
430
     * @param null|string $help
431
     * @param string      $title
432
     * @param bool        $do_print
433
     */
434
    public function printTitle(string $title, ?string $help = null, bool $do_print = true)
435
    {
436
        $header_controller = $this->_getHeaderController();
437
438
        return $header_controller->printTitle($title, $help, $do_print);
439
    }
440
441
    /**
442
     * @param string      $key
443
     * @param null|string $default
444
     */
445
    public function getRequestParam(string $key, ?string $default = null)
446
    {
447
        return \requestInstance()->getParam($key, $default);
448
    }
449
450
    /**
451
     * @param string                           $key
452
     * @param null|array|bool|float|int|string $default
453
     *
454
     * @return bool| null|array|string|int|float
455
     */
456
    public function getPostParam(string $key, $default = null)
457
    {
458
        return \requestInstance()->getParsedBodyParam($key, $default);
459
    }
460
461
    /**
462
     * @param string                      $key
463
     * @param null|array|float|int|string $default
464
     *
465
     * @return null|array|float|int|string
466
     */
467
    public function getQueryStrinParam($key, $default = null)
468
    {
469
        return \requestInstance()->getQueryParam($key, $default);
470
    }
471
472
    /**
473
     * @return array
474
     */
475
    public function getAllParams(): array
476
    {
477
        return \array_merge(
478
            \requestInstance()->getQueryParams() ?? [],
479
            \requestInstance()->getParsedBody() ?? []
480
        );
481
    }
482
483
    /**
484
     * Print out a message.
485
     *
486
     * @param string $msg      The message
487
     * @param bool   $do_print if true, print the message. Return the string otherwise
488
     *
489
     * @return string a paragraph containing the message, whose linebreaks are replaced by <br> elements
490
     */
491
    public function printMsg($msg, $do_print = true)
492
    {
493
        $html = '';
494
        $msg = \htmlspecialchars(ContainerUtils::br2ln($msg));
495
496
        if ('' !== $msg) {
497
            $html .= '<p class="message">' . \nl2br($msg) . '</p>' . \PHP_EOL;
498
        }
499
500
        if ($do_print) {
501
            echo $html;
502
503
            return $html;
504
        }
505
506
        return $html;
507
    }
508
509
    private function renderInitialPageIfNotLogged(): void
510
    {
511
        if (false === $this->misc->getNoDBConnection()) {
512
            if (null === $this->misc->getServerId()) {
513
                $servers_controller = new ServersController($this->container);
514
515
                $servers_controller->render();
516
            } else {
517
                $_server_info = $this->misc->getServerInfo();
518
                // Redirect to the login form if not logged in
519
                if (!isset($_server_info['username'])) {
520
                    $msg = \sprintf(
521
                        $this->lang['strlogoutmsg'],
522
                        $_server_info['desc']
523
                    );
524
525
                    $servers_controller = new ServersController($this->container);
526
527
                    $servers_controller->render();
528
                }
529
            }
530
        }
531
    }
532
533
    /**
534
     * @return HTMLTableController
535
     */
536
    private function _getTableController()
537
    {
538
        if (null === $this->_table_controller) {
539
            $this->_table_controller = new HTMLTableController($this->getContainer(), $this->controller_name);
540
        }
541
542
        return $this->_table_controller;
543
    }
544
545
    /**
546
     * @return HTMLFooterController
547
     */
548
    private function _getFooterController()
549
    {
550
        if (null === $this->_footer_controller) {
551
            $this->_footer_controller = new HTMLFooterController($this->getContainer(), $this->controller_name);
552
        }
553
554
        return $this->_footer_controller;
555
    }
556
557
    /**
558
     * @return HTMLHeaderController
559
     */
560
    private function _getHeaderController()
561
    {
562
        if (null === $this->_header_controller) {
563
            $this->_header_controller = new HTMLHeaderController($this->getContainer(), $this->controller_name);
564
        }
565
566
        return $this->_header_controller;
567
    }
568
569
    /**
570
     * @return HTMLNavbarController
571
     */
572
    private function _getNavbarController()
573
    {
574
        if (null === $this->_trail_controller) {
575
            $this->_trail_controller = new HTMLNavbarController($this->getContainer(), $this->controller_name);
576
        }
577
578
        return $this->_trail_controller;
579
    }
580
581
    /**
582
     * @return TreeController
583
     */
584
    private function _getTreeController()
585
    {
586
        if (null === $this->_tree_controller) {
587
            $this->_tree_controller = new TreeController($this->getContainer(), $this->controller_name);
588
        }
589
590
        return $this->_tree_controller;
591
    }
592
}
593