Test Failed
Pull Request — develop (#340)
by Felipe
03:49
created

HTMLNavbarController::getLastTabURL()   A

Complexity

Conditions 3
Paths 4

Size

Total Lines 14
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 3
eloc 6
c 1
b 0
f 0
nc 4
nop 1
dl 0
loc 14
rs 10
1
<?php
2
3
/**
4
 * PHPPgAdmin 6.0.0
5
 */
6
7
namespace PHPPgAdmin\XHtml;
8
9
/**
10
 * Class to render tables. Formerly part of Misc.php.
11
 */
12
class HTMLNavbarController extends HTMLController
13
{
14
    public $controller_name = 'HTMLNavbarController';
15
16
    /**
17
     * Display a bread crumb trail.
18
     *
19
     * @param array|string $trail    an array of breadcrumb items, or a string to identify one of them
20
     * @param bool         $do_print true  to echo, false to return html
21
     * @param null|string  $from
22
     *
23
     * @return string ( description_of_the_return_value )
24
     */
25
    public function printTrail($trail = [], $do_print = true, $from = null)
26
    {
27
        $from = $from ? $from : __METHOD__;
28
29
        $trail_html = $this->printTopbar(false, $from);
30
31
        if (\is_string($trail)) {
32
            $subject = $trail;
33
            $trail = $this->_getTrail($subject);
34
            // Trail hook's place
35
            $plugin_functions_parameters = [
0 ignored issues
show
Unused Code introduced by
The assignment to $plugin_functions_parameters is dead and can be removed.
Loading history...
36
                'trail' => &$trail,
37
                'section' => $subject,
38
            ];
39
        }
40
41
        $crumbs = $this->_getCrumbs($trail);
42
43
        $viewVars = [
44
            'crumbs' => $crumbs,
45
            'controller_name' => $this->controller_name,
46
        ];
47
        $viewVars = $this->_getSearchPathsCrumbs($crumbs, $viewVars);
48
49
        //\Kint::dump($viewVars);
50
51
        $trail_html .= $this->getContainer()->view->fetch('components/trail.twig', $viewVars);
52
53
        if ($do_print) {
54
            echo $trail_html;
55
56
            return '';
57
        }
58
59
        return $trail_html;
60
    }
61
62
    /**
63
     * Get the URL for the last active tab of a particular tab bar.
64
     *
65
     * @param string $section
66
     *
67
     * @return null|mixed
68
     */
69
    public function getLastTabURL($section)
70
    {
71
        //$data = $this->getDatabaseAccessor();
72
73
        $tabs = $this->misc->getNavTabs($section);
74
75
        if (isset($_SESSION['webdbLastTab'][$section], $tabs[$_SESSION['webdbLastTab'][$section]])) {
76
            $tab = $tabs[$_SESSION['webdbLastTab'][$section]];
77
        } else {
78
            $tab = \reset($tabs);
79
        }
80
        // $this->prtrace(['section' => $section, 'tabs' => $tabs, 'tab' => $tab]);
81
82
        return isset($tab['url']) ? $tab : null;
83
    }
84
85
    /**
86
     * Display navigation tabs.
87
     *
88
     * @param string      $alltabs   The name of current section (Ex: intro, server, ...),
89
     *                               or an array with tabs (Ex: sqledit::doFind function)
90
     * @param string      $activetab the name of the tab to be highlighted
91
     * @param bool        $do_print  true to print html, false to return html
92
     * @param null|string $from      whichi method is calling this one
93
     */
94
    public function printTabs($alltabs, $activetab, $do_print = true, $from = null)
95
    {
96
        $from = $from ? $from : __METHOD__;
97
98
        $this->misc = $this->misc;
99
        $_SESSION['webdbLastTab'] = $_SESSION['webdbLastTab'] ?? [];
100
101
        if (!\is_array($_SESSION['webdbLastTab'])) {
102
            $_SESSION['webdbLastTab'] = [$alltabs => $activetab];
103
        }
104
105
        if (\is_string($alltabs)) {
0 ignored issues
show
introduced by
The condition is_string($alltabs) is always true.
Loading history...
106
            $_SESSION['webdbLastTab'][$alltabs] = $activetab;
107
            $alltabs = $this->misc->getNavTabs($alltabs);
108
        }
109
        $tabs_html = '';
110
111
        //Getting only visible tabs
112
        $tabs = [];
113
114
        if (0 < \count($alltabs)) {
115
            foreach ($alltabs as $tab_id => $tab) {
116
                if (!isset($tab['hide']) || true !== $tab['hide']) {
117
                    $tabs[$tab_id] = $tab;
118
                    $tabs[$tab_id]['active'] = ($tab_id === $activetab) ? ' active' : '';
119
                    $tabs[$tab_id]['tablink'] = \str_replace(['&amp;', '.php'], ['&', ''], \htmlentities($this->getActionUrl($tab, $_REQUEST, $from)));
120
121
                    if (isset($tab['icon']) && $icon = $this->view->icon($tab['icon'])) {
122
                        $tabs[$tab_id]['iconurl'] = $icon;
123
                    }
124
125
                    if (isset($tab['help'])) {
126
                        $tabs[$tab_id]['helpurl'] = \str_replace('&amp;', '&', $this->view->getHelpLink($tab['help']));
127
                    }
128
                }
129
            }
130
        }
131
132
        if (0 < \count($tabs)) {
133
            $width = (int) (100 / \count($tabs)) . '%';
134
135
            $viewVars = [
136
                'width' => $width,
137
                'tabs' => $tabs,
138
                'controller_name' => $this->controller_name,
139
            ];
140
141
            $tabs_html = $this->getContainer()->view->fetch('components/tabs.twig', $viewVars);
142
        }
143
144
        if ($do_print) {
145
            echo $tabs_html;
146
        } else {
147
            return $tabs_html;
148
        }
149
    }
150
151
    private function _getCrumbs($trail)
152
    {
153
        $crumbs = [];
154
155
        foreach ($trail as $crumb_id => $crumb) {
156
            if (isset($crumb['url'])) {
157
                $crumbs[$crumb_id]['url'] = \str_replace('&amp;', '&', $crumb['url']);
158
            }
159
160
            if (isset($crumb['title'])) {
161
                $crumbs[$crumb_id]['title'] = $crumb['title'];
162
                $crumbs[$crumb_id]['iconalt'] = $crumb['title'];
163
            } else {
164
                $crumbs[$crumb_id]['iconalt'] = 'Database Root';
165
            }
166
167
            if (isset($crumb['icon']) && $icon = $this->view->icon($crumb['icon'])) {
168
                $crumbs[$crumb_id]['icon'] = $icon;
169
            }
170
171
            $crumbs[$crumb_id]['text'] = $crumb['text'];
172
173
            if (isset($crumb['help'])) {
174
                $crumbs[$crumb_id]['helpurl'] = \str_replace('&amp;', '&', $this->view->getHelpLink($crumb['help']));
175
            }
176
        }
177
178
        return $crumbs;
179
    }
180
181
    /**
182
     * @param mixed $crumbs
183
     * @param array $viewVars
184
     */
185
    private function _getSearchPathsCrumbs($crumbs, array $viewVars)
186
    {
187
        $data = $this->misc->getDatabaseAccessor();
188
        $lang = $this->lang;
189
190
        if (isset($crumbs['database'])) {
191
            $search_path_crumbs = [];
192
            $dburl = $crumbs['database']['url'];
193
            $search_paths = $data->getSearchPath();
194
195
            foreach ($search_paths as $schema) {
196
                $url = \str_replace(['&amp;', 'redirect/database'], ['&', 'redirect/schema'], $dburl . '&schema=' . $schema);
197
                $destination = $this->container->getDestinationWithLastTab('database');
0 ignored issues
show
Unused Code introduced by
The assignment to $destination is dead and can be removed.
Loading history...
198
                //$this->dump(['url' => $url, 'destination' => $destination]);
199
                $search_path_crumbs[$schema] = [
200
                    'title' => $lang['strschema'],
201
                    'text' => $schema,
202
                    'icon' => $this->view->icon('Schema'),
203
                    'iconalt' => $lang['strschema'],
204
                    'url' => $url,
205
                ];
206
            }
207
            $viewVars['search_paths'] = $search_path_crumbs;
208
        }
209
210
        return $viewVars;
211
    }
212
213
    /**
214
     * [printTopbar description].
215
     *
216
     * @param bool       $do_print true to print, false to return html
217
     * @param null|mixed $from     which method is calling this one
218
     */
219
    private function printTopbar($do_print = true, $from = null): ?string
220
    {
221
        $from = $from ? $from : __METHOD__;
222
223
        $lang = $this->lang;
224
225
        $this->misc = $this->misc;
226
        $appName = $this->misc->appName;
227
        $appVersion = $this->misc->appVersion;
228
229
        $server_info = $this->misc->getServerInfo();
230
        $server_id = $this->misc->getServerId();
231
        $reqvars = $this->misc->getRequestVars('table');
232
233
        $topbar_html = '<div class="topbar" data-controller="' . $this->controller_name . '"><table style="width: 100%"><tr><td>';
234
235
        if ($server_info && isset($server_info['platform'], $server_info['username'])) {
236
            // top left informations when connected
237
            $topbar_html .= \sprintf(
238
                $lang['strtopbar'],
239
                '<span class="platform">' . \htmlspecialchars($server_info['platform']) . '</span>',
240
                '<span class="host">' . \htmlspecialchars((empty($server_info['host'])) ? 'localhost' : $server_info['host']) . '</span>',
241
                '<span class="port">' . \htmlspecialchars($server_info['port']) . '</span>',
242
                '<span class="username">' . \htmlspecialchars($server_info['username']) . '</span>'
243
            );
244
245
            $topbar_html .= '</td>';
246
247
            // top right informations when connected
248
249
            $toplinks = [
250
                'sql' => [
251
                    'attr' => [
252
                        'href' => [
253
                            'url' => \containerInstance()->subFolder . '/src/views/sqledit',
254
                            'urlvars' => \array_merge($reqvars, [
255
                                'action' => 'sql',
256
                            ]),
257
                        ],
258
                        'target' => 'sqledit',
259
                        'id' => 'toplink_sql',
260
                        'class' => 'toplink_popup',
261
                    ],
262
                    'content' => $lang['strsql'],
263
                ],
264
                'history' => [
265
                    'attr' => [
266
                        'href' => [
267
                            'url' => \containerInstance()->subFolder . '/src/views/history',
268
                            'urlvars' => \array_merge($reqvars, [
269
                                'action' => 'pophistory',
270
                            ]),
271
                        ],
272
                        'id' => 'toplink_history',
273
                        'class' => 'toplink_popup',
274
                    ],
275
                    'content' => $lang['strhistory'],
276
                ],
277
                'find' => [
278
                    'attr' => [
279
                        'href' => [
280
                            'url' => \containerInstance()->subFolder . '/src/views/sqledit',
281
                            'urlvars' => \array_merge($reqvars, [
282
                                'action' => 'find',
283
                            ]),
284
                        ],
285
                        'target' => 'sqledit',
286
                        'id' => 'toplink_find',
287
                        'class' => 'toplink_popup',
288
                    ],
289
                    'content' => $lang['strfind'],
290
                ],
291
                'logout' => [
292
                    'attr' => [
293
                        'href' => [
294
                            'url' => \containerInstance()->subFolder . '/src/views/servers',
295
                            'urlvars' => [
296
                                'action' => 'logout',
297
                                'logoutServer' => \sha1("{$server_info['host']}:{$server_info['port']}:{$server_info['sslmode']}"),
298
                            ],
299
                        ],
300
                        'id' => 'toplink_logout',
301
                    ],
302
                    'content' => $lang['strlogout'],
303
                ],
304
            ];
305
306
            // Toplink hook's place
307
            $plugin_functions_parameters = [
0 ignored issues
show
Unused Code introduced by
The assignment to $plugin_functions_parameters is dead and can be removed.
Loading history...
308
                'toplinks' => &$toplinks,
309
            ];
310
311
            $topbar_html .= '<td style="text-align: right">';
312
313
            $topbar_html .= $this->printLinksList($toplinks, 'toplink', false, $from);
314
315
            $topbar_html .= '</td>';
316
        } else {
317
            $topbar_html .= "<span class=\"appname\">{$appName}</span> <span class=\"version\">{$appVersion}</span>";
318
        }
319
320
        $topbar_html .= '</tr></table></div>' . \PHP_EOL;
321
322
        if ($do_print) {
323
            echo $topbar_html;
324
325
            return '';
326
        }
327
328
        return $topbar_html;
329
    }
330
331
    private function getHREFSubject(string $subject)
332
    {
333
        $vars = $this->misc->getSubjectParams($subject);
334
        \ksort($vars['params']);
335
336
        return "{$vars['url']}?" . \http_build_query($vars['params'], '', '&amp;');
337
    }
338
339
    /**
340
     * Create a bread crumb trail of the object hierarchy.
341
     *
342
     * @param null|string $subject sunkect of the trail
343
     *
344
     * @return array the trail array
345
     */
346
    private function _getTrail($subject = null)
347
    {
348
        $lang = $this->lang;
349
350
        $appName = $this->misc->appName;
351
352
        $trail = [];
353
354
        $trail['root'] = [
355
            'text' => $appName,
356
            'url' => \containerInstance()->subFolder . '/src/views/servers',
357
            'icon' => 'Introduction',
358
        ];
359
360
        if ('root' === $subject) {
361
            return $trail;
362
        }
363
364
        $server_info = $this->misc->getServerInfo();
365
        $trail['server'] = [
366
            'title' => $lang['strserver'],
367
            'text' => $server_info['desc'],
368
            'url' => $this->getHREFSubject('server'),
369
            'help' => 'pg.server',
370
            'icon' => 'Server',
371
        ];
372
373
        if ('server' === $subject) {
374
            return $trail;
375
        }
376
377
        $database_rolename = [
378
            'database' => [
379
                'title' => $lang['strdatabase'],
380
                'subject' => 'database',
381
                'help' => 'pg.database',
382
                'icon' => 'Database',
383
            ],
384
            'rolename' => [
385
                'title' => $lang['strrole'],
386
                'subject' => 'role',
387
                'help' => 'pg.role',
388
                'icon' => 'Roles',
389
            ],
390
        ];
391
392
        $trail = $this->_getTrailsFromArray($trail, $database_rolename);
393
394
        if (\in_array($subject, ['database', 'role'], true)) {
395
            return $trail;
396
        }
397
398
        $schema = [
399
            'schema' => [
400
                'title' => $lang['strschema'],
401
                'subject' => 'schema',
402
                'help' => 'pg.schema',
403
                'icon' => 'Schema',
404
            ],
405
        ];
406
407
        $trail = $this->_getTrailsFromArray($trail, $schema);
408
409
        if ('schema' === $subject) {
410
            return $trail;
411
        }
412
413
        $table_view_matview_fts = [
414
            'table' => [
415
                'title' => $lang['strtable'],
416
                'subject' => 'table',
417
                'help' => 'pg.table',
418
                'icon' => 'Table',
419
            ],
420
            'view' => [
421
                'title' => $lang['strview'],
422
                'subject' => 'view',
423
                'help' => 'pg.view',
424
                'icon' => 'View',
425
            ],
426
            'matview' => [
427
                'title' => 'M' . $lang['strview'],
428
                'subject' => 'matview',
429
                'help' => 'pg.matview',
430
                'icon' => 'MViews',
431
            ],
432
            'ftscfg' => [
433
                'title' => $lang['strftsconfig'],
434
                'subject' => 'ftscfg',
435
                'help' => 'pg.ftscfg.example',
436
                'icon' => 'Fts',
437
            ],
438
        ];
439
440
        $trail = $this->_getTrailsFromArray($trail, $table_view_matview_fts);
441
442
        if (\in_array($subject, ['table', 'view', 'matview', 'ftscfg'], true)) {
443
            return $trail;
444
        }
445
446
        if (null !== $subject) {
447
            $trail = $this->_getLastTrailPart($subject, $trail);
448
        }
449
450
        return $trail;
451
    }
452
453
    /**
454
     * @param (mixed|string)[][] $trail
455
     * @param (mixed|string)[][] $the_array
456
     */
457
    private function _getTrailsFromArray(array $trail, array $the_array)
458
    {
459
        foreach ($the_array as $key => $value) {
460
            if (isset($_REQUEST[$key])) {
461
                $trail[$key] = [
462
                    'title' => $value['title'],
463
                    'text' => $_REQUEST[$key],
464
                    'url' => $this->getHREFSubject($value['subject']),
465
                    'help' => $value['help'],
466
                    'icon' => $value['icon'],
467
                ];
468
469
                break;
470
            }
471
        }
472
473
        return $trail;
474
    }
475
476
    private function _getLastTrailPart(string $subject, $trail)
477
    {
478
        $lang = $this->lang;
479
480
        switch ($subject) {
481
            case 'function':
482
                $trail[$subject] = [
483
                    'title' => $lang['str' . $subject],
484
                    'text' => $_REQUEST[$subject],
485
                    'url' => $this->getHREFSubject('function'),
486
                    'help' => 'pg.function',
487
                    'icon' => 'Function',
488
                ];
489
490
                break;
491
            case 'aggregate':
492
                $trail[$subject] = [
493
                    'title' => $lang['straggregate'],
494
                    'text' => $_REQUEST['aggrname'],
495
                    'url' => $this->getHREFSubject('aggregate'),
496
                    'help' => 'pg.aggregate',
497
                    'icon' => 'Aggregate',
498
                ];
499
500
                break;
501
            case 'column':
502
                $trail['column'] = [
503
                    'title' => $lang['strcolumn'],
504
                    'text' => $_REQUEST['column'],
505
                    'icon' => 'Column',
506
                    'url' => $this->getHREFSubject('column'),
507
                ];
508
509
                break;
510
511
            default:
512
                if (isset($_REQUEST[$subject])) {
513
                    switch ($subject) {
514
                        case 'domain':
515
                            $icon = 'Domain';
516
517
                            break;
518
                        case 'sequence':
519
                            $icon = 'Sequence';
520
521
                            break;
522
                        case 'type':
523
                            $icon = 'Type';
524
525
                            break;
526
                        case 'operator':
527
                            $icon = 'Operator';
528
529
                            break;
530
                        case 'index':
531
                            $icon = 'Index';
532
533
                            break;
534
535
                        default:
536
                            $icon = null;
537
538
                            break;
539
                    }
540
                    $trail[$subject] = [
541
                        'title' => \array_key_exists('str' . $subject, $lang) ? $lang['str' . $subject] : $subject,
542
                        'text' => $_REQUEST[$subject],
543
                        'help' => 'pg.' . $subject,
544
                        'icon' => $icon,
545
                    ];
546
                }
547
        }
548
549
        return $trail;
550
    }
551
}
552