Passed
Pull Request — develop (#340)
by Felipe
03:46
created

HTMLNavbarController::_getTrailsFromArray()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 17
Code Lines 10

Duplication

Lines 0
Ratio 0 %

Importance

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