Passed
Branch develop (9a39e6)
by Felipe
14:25 queued 09:45
created

Misc::getServerId()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 1
nc 1
nop 0
dl 0
loc 3
rs 10
c 0
b 0
f 0
1
<?php
2
3
/**
4
 * PHPPgAdmin v6.0.0-beta.33
5
 */
6 ignored issues
show
Coding Style introduced by
PHP version not specified
Loading history...
Coding Style introduced by
Missing @category tag in file comment
Loading history...
Coding Style introduced by
Missing @package tag in file comment
Loading history...
Coding Style introduced by
Missing @author tag in file comment
Loading history...
Coding Style introduced by
Missing @license tag in file comment
Loading history...
Coding Style introduced by
Missing @link tag in file comment
Loading history...
6
7
namespace PHPPgAdmin;
8
9
use PHPPgAdmin\Decorators\Decorator;
10
11
/**
12
 * @file
13
 * Class to hold various commonly used functions
14
 *
15
 * $Id: Misc.php,v 1.171 2008/03/17 21:35:48 ioguix Exp $
16
 */
17
18
/**
19
 * Class to hold various commonly used functions.
20
 *
21
 * $Id: Misc.php,v 1.171 2008/03/17 21:35:48 ioguix Exp $
22
 *
23
 * @package PHPPgAdmin
24
 */
4 ignored issues
show
Coding Style introduced by
Missing @category tag in class comment
Loading history...
Coding Style introduced by
Missing @author tag in class comment
Loading history...
Coding Style introduced by
Missing @license tag in class comment
Loading history...
Coding Style introduced by
Missing @link tag in class comment
Loading history...
25
class Misc
26
{
27
    use \PHPPgAdmin\HelperTrait;
28
29
    private $_connection;
30
    private $_no_db_connection = false;
31
    private $_reload_browser = false;
32
    private $_data;
33
    private $_database;
34
    private $_server_id;
35
    private $_server_info;
36
    private $_error_msg = '';
37
38
    public $appLangFiles = [];
39
    public $appName = '';
40
    public $appVersion = '';
41
    public $form = '';
42
    public $href = '';
43
    public $controller_name = 'Misc';
44
    public $lang = [];
45
46
    protected $container;
47
48
    /**
49
     * @param \Slim\Container $container The container
50
     */
51
    public function __construct(\Slim\Container $container)
52
    {
53
        $this->container = $container;
54
55
        $this->lang = $container->get('lang');
56
        $this->conf = $container->get('conf');
57
        //$this->view           = $container->get('view');
58
        $this->plugin_manager = $container->get('plugin_manager');
59
        $this->appLangFiles = $container->get('appLangFiles');
60
61
        $this->appName = $container->get('settings')['appName'];
62
        $this->appVersion = $container->get('settings')['appVersion'];
63
        $this->postgresqlMinVer = $container->get('settings')['postgresqlMinVer'];
64
        $this->phpMinVer = $container->get('settings')['phpMinVer'];
65
66
        $base_version = $container->get('settings')['base_version'];
67
68
        // Check for config file version mismatch
69
        if (!isset($this->conf['version']) || $base_version > $this->conf['version']) {
70
            $container->get('utils')->addError($this->lang['strbadconfig']);
71
        }
72
73
        // Check database support is properly compiled in
74
        if (!function_exists('pg_connect')) {
75
            $container->get('utils')->addError($this->lang['strnotloaded']);
76
        }
77
78
        // Check the version of PHP
79
        if (version_compare(phpversion(), $this->phpMinVer, '<')) {
80
            $container->get('utils')->addError(sprintf('Version of PHP not supported. Please upgrade to version %s or later.', $this->phpMinVer));
81
        }
82
83
        if (count($this->conf['servers']) === 1) {
84
            $info = $this->conf['servers'][0];
85
            $this->_server_id = $info['host'].':'.$info['port'].':'.$info['sslmode'];
86
        } elseif (isset($_REQUEST['server'])) {
87
            $this->_server_id = $_REQUEST['server'];
88
        } elseif (isset($_SESSION['webdbLogin']) && count($_SESSION['webdbLogin']) > 0) {
89
            $this->_server_id = array_keys($_SESSION['webdbLogin'])[0];
90
        }
91
    }
92
93
    /**
94
     * Sets the view instance property of this class.
95
     *
96
     * @param \Slim\Views\Twig $view [description]
97
     */
98
    public function setView(\Slim\Views\Twig $view)
99
    {
100
        $this->view = $view;
101
    }
102
103
    /**
104
     * Adds or modifies a key in the $conf instance property of this class.
105
     *
106
     * @param string $key   name of the key to set
107
     * @param mixed  $value value of the key to set
108
     *
109
     * @return $this
110
     */
111
    public function setConf(string $key, $value)
112
    {
113
        $this->conf[$key] = $value;
114
115
        return $this;
116
    }
117
118
    /**
119
     * gets the value of a config property, or the array of all config properties.
1 ignored issue
show
Coding Style introduced by
Doc comment short description must start with a capital letter
Loading history...
120
     *
121
     * @param mixed $key value of the key to be retrieved. If null, the full array is returnes
122
     *
123
     * @return mixed the whole $conf array, the value of $conf[key] or null if said key does not exist
124
     */
125
    public function getConf($key = null)
126
    {
127
        if ($key === null) {
128
            return $this->conf;
129
        }
130
        if (array_key_exists($key, $this->conf)) {
131
            return $this->conf[$key];
132
        }
133
134
        return null;
135
    }
136
137
    public function getServerId()
1 ignored issue
show
Coding Style introduced by
Missing function doc comment
Loading history...
138
    {
139
        return $this->_server_id;
140
    }
141
142
    /**
143
     * Displays link to the context help.
144
     *
145
     * @param $str   the string that the context help is related to (already escaped)
146
     * @param $help  help section identifier
147
     * @param $do_print true to echo, false to return
148
     */
149
    public function printHelp($str, $help = null, $do_print = true)
150
    {
151
        //\PC::debug(['str' => $str, 'help' => $help], 'printHelp');
152
        if ($help !== null) {
153
            $helplink = $this->getHelpLink($help);
154
            $str .= '<a class="help" href="'.$helplink.'" title="'.$this->lang['strhelp'].'" target="phppgadminhelp">'.$this->lang['strhelpicon'].'</a>';
155
        }
156
        if ($do_print) {
157
            echo $str;
158
        } else {
159
            return $str;
160
        }
161
    }
162
163
    public function getHelpLink($help)
1 ignored issue
show
Coding Style introduced by
Missing function doc comment
Loading history...
164
    {
165
        return htmlspecialchars(SUBFOLDER.'/help?help='.urlencode($help).'&server='.urlencode($this->getServerId()));
166
    }
167
168
    /**
169
     * Internally sets the reload browser property.
170
     *
171
     * @param bool $flag sets internal $_reload_browser var which will be passed to the footer methods
172
     *
173
     * @return $this
174
     */
175
    public function setReloadBrowser($flag)
176
    {
177
        $this->_reload_browser = (bool) $flag;
178
179
        return $this;
180
    }
181
182
    public function getReloadBrowser()
1 ignored issue
show
Coding Style introduced by
Missing function doc comment
Loading history...
183
    {
184
        return $this->_reload_browser;
185
    }
186
187
    /**
188
     * Default Error Handler. This will be called with the following params.
189
     *
190
     * @param $dbms         the RDBMS you are connecting to
191
     * @param $fn           the name of the calling function (in uppercase)
192
     * @param $errno        the native error number from the database
193
     * @param $errmsg       the native error msg from the database
194
     * @param $p1           $fn specific parameter - see below
0 ignored issues
show
Coding Style introduced by
Doc comment for parameter $fn does not match actual variable name $p1
Loading history...
195
     * @param $p2           parameter 2
196
     * @param $thisConnection connection
197
     *
198
     * @throws \PHPPgAdmin\ADOdbException
199
     *
200
     * @internal param $P2 $fn specific parameter - see below
201
     */
202
    public static function adodb_throw($dbms, $fn, $errno, $errmsg, $p1, $p2, $thisConnection)
1 ignored issue
show
Coding Style introduced by
Public method name "Misc::adodb_throw" is not in camel caps format
Loading history...
203
    {
204
        if (error_reporting() == 0) {
205
            return;
206
        }
207
208
        $backtrace = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS, 2);
209
210
        $btarray0 = [
211
            'msg' => 'ADOdbException at ',
212
            'class' => $backtrace[1]['class'],
213
            'type' => $backtrace[1]['type'],
214
            'function' => $backtrace[1]['function'],
215
            'spacer' => ' ',
216
            'line' => $backtrace[0]['line'],
217
        ];
218
219
        $errmsg = htmlspecialchars(\PHPPgAdmin\HelperTrait::br2ln($errmsg));
220
        $p1 = htmlspecialchars(\PHPPgAdmin\HelperTrait::br2ln($p1));
221
        $p2 = htmlspecialchars(\PHPPgAdmin\HelperTrait::br2ln($p2));
222
        switch ($fn) {
223
            case 'EXECUTE':
224
                $sql = $p1;
225
                $inputparams = $p2;
226
227
                $error_msg = '<p><b>strsqlerror</b><br />'.nl2br($errmsg).'</p> <p><b>SQL:</b><br />'.nl2br($sql).'</p>	';
228
229
                echo '<table class="error" cellpadding="5"><tr><td>'.nl2br($error_msg).'</td></tr></table><br />'."\n";
230
231
                break;
232
            case 'PCONNECT':
233
            case 'CONNECT':
234
                // do nothing;
235
                break;
236
            default:
237
                $s = "${dbms} error: [${errno}: ${errmsg}] in ${fn}(${p1}, ${p2})\n";
238
                echo "<table class=\"error\" cellpadding=\"5\"><tr><td>{$s}</td></tr></table><br />\n";
239
240
                break;
241
        }
242
243
        $tag = implode('', $btarray0);
244
245
        \PC::debug(['errno' => $errno, 'fn' => $fn, 'errmsg' => $errmsg], $tag);
246
247
        throw new \PHPPgAdmin\ADOdbException($dbms, $fn, $errno, $errmsg, $p1, $p2, $thisConnection);
248
    }
249
250
    public function getContainer()
1 ignored issue
show
Coding Style introduced by
Missing function doc comment
Loading history...
251
    {
252
        return $this->container;
253
    }
254
255
    /**
256
     * sets $_no_db_connection boolean value, allows to render scripts that do not need an active session.
1 ignored issue
show
Coding Style introduced by
Doc comment short description must start with a capital letter
Loading history...
257
     *
258
     * @param bool $flag true or false to allow unconnected clients to access the view
259
     *
260
     * @return $this
261
     */
262
    public function setNoDBConnection($flag)
263
    {
264
        $this->_no_db_connection = (bool) $flag;
265
266
        return $this;
267
    }
268
269
    public function getNoDBConnection()
1 ignored issue
show
Coding Style introduced by
Missing function doc comment
Loading history...
270
    {
271
        return $this->_no_db_connection;
272
    }
273
274
    /**
275
     * Sets the last error message to display afterwards instead of just dying with the error msg.
276
     *
277
     * @param string $msg error message string
278
     */
279
    public function setErrorMsg($msg)
280
    {
281
        $this->_error_msg = $msg;
282
283
        return $this;
284
    }
285
286
    public function getErrorMsg()
1 ignored issue
show
Coding Style introduced by
Missing function doc comment
Loading history...
287
    {
288
        return $this->_error_msg;
289
    }
290
291
    /**
292
     * Creates a database accessor.
293
     *
294
     * @param string $database  the name of the database
295
     * @param mixed  $server_id the id of the server
296
     */
297
    public function getDatabaseAccessor($database = '', $server_id = null)
298
    {
299
        $lang = $this->lang;
300
301
        if ($server_id !== null) {
302
            $this->_server_id = $server_id;
303
        }
304
305
        $server_info = $this->getServerInfo($this->_server_id);
306
307
        if ($this->_no_db_connection || !isset($server_info['username'])) {
308
            return null;
309
        }
310
311
        if ($this->_data === null) {
312
            try {
313
                $_connection = $this->getConnection($database, $this->_server_id);
314
            } catch (\Exception $e) {
315
                $this->setServerInfo(null, null, $this->_server_id);
316
                $this->setNoDBConnection(true);
317
                $this->setErrorMsg($e->getMessage());
318
319
                return null;
320
            }
321
322
            //$this->prtrace('_connection', $_connection);
323
            if (!$_connection) {
324
                $this->container->utils->addError($lang['strloginfailed']);
325
                $this->setErrorMsg($lang['strloginfailed']);
326
327
                return null;
328
            }
329
            // Get the name of the database driver we need to use.
330
            // The description of the server is returned in $platform.
331
            $_type = $_connection->getDriver($platform);
332
333
            //$this->prtrace(['type' => $_type, 'platform' => $platform, 'pgVersion' => $_connection->conn->pgVersion]);
334
335
            if ($_type === null) {
336
                $errormsg = sprintf($lang['strpostgresqlversionnotsupported'], $this->postgresqlMinVer);
337
                $this->container->utils->addError($errormsg);
338
                $this->setErrorMsg($errormsg);
339
340
                return null;
341
            }
342
            $_type = '\PHPPgAdmin\Database\\'.$_type;
343
344
            $this->setServerInfo('platform', $platform, $this->_server_id);
345
            $this->setServerInfo('pgVersion', $_connection->conn->pgVersion, $this->_server_id);
346
347
            // Create a database wrapper class for easy manipulation of the
348
            // connection.
349
350
            $this->_data = new $_type($_connection->conn, $this->conf);
351
            $this->_data->platform = $_connection->platform;
352
            $this->_data->server_info = $server_info;
353
            $this->_data->conf = $this->conf;
354
            $this->_data->lang = $this->lang;
355
356
            //$this->_data->getHelpPages();
357
358
            //$this->prtrace('help_page has ' . count($this->_data->help_page) . ' items');
359
360
            /* we work on UTF-8 only encoding */
361
            $this->_data->execute("SET client_encoding TO 'UTF-8'");
362
363
            if ($this->_data->hasByteaHexDefault()) {
364
                $this->_data->execute('SET bytea_output TO escape');
365
            }
366
        }
367
368
        if ($this->_no_db_connection === false && $this->getDatabase() !== null && isset($_REQUEST['schema'])) {
369
            $status = $this->_data->setSchema($_REQUEST['schema']);
370
371
            if ($status != 0) {
372
                $this->container->utils->addError($this->lang['strbadschema']);
373
                $this->setErrorMsg($this->lang['strbadschema']);
374
375
                return null;
376
            }
377
        }
378
379
        return $this->_data;
380
    }
381
382
    public function getConnection($database = '', $server_id = null)
1 ignored issue
show
Coding Style introduced by
Missing function doc comment
Loading history...
383
    {
384
        $lang = $this->lang;
385
386
        if ($this->_connection === null) {
387
            if ($server_id !== null) {
388
                $this->_server_id = $server_id;
389
            }
390
            $server_info = $this->getServerInfo($this->_server_id);
391
            $database_to_use = $this->getDatabase($database);
392
393
            // Perform extra security checks if this config option is set
394
            if ($this->conf['extra_login_security']) {
395
                // Disallowed logins if extra_login_security is enabled.
396
                // These must be lowercase.
397
                $bad_usernames = [
398
                    'pgsql' => 'pgsql',
399
                    'postgres' => 'postgres',
400
                    'root' => 'root',
401
                    'administrator' => 'administrator',
402
                ];
403
404
                if (isset($server_info['username']) && array_key_exists(strtolower($server_info['username']), $bad_usernames)) {
405
                    $msg = $lang['strlogindisallowed'];
406
407
                    throw new \Exception($msg);
408
                }
409
410
                if (!isset($server_info['password']) || $server_info['password'] == '') {
411
                    $msg = $lang['strlogindisallowed'];
412
413
                    throw new \Exception($msg);
414
                }
415
            }
416
417
            try {
418
                // Create the connection object and make the connection
419
                $this->_connection = new \PHPPgAdmin\Database\Connection(
420
                    $server_info['host'],
421
                    $server_info['port'],
422
                    $server_info['sslmode'],
423
                    $server_info['username'],
424
                    $server_info['password'],
425
                    $database_to_use
426
                );
427
            } catch (\PHPPgAdmin\ADOdbException $e) {
428
                throw new \Exception($lang['strloginfailed']);
429
            }
430
        }
431
432
        return $this->_connection;
433
    }
434
435
    /**
436
     * Validate and retrieve information on a server.
437
     * If the parameter isn't supplied then the currently
438
     * connected server is returned.
439
     *
440
     * @param $server_id A server identifier (host:port)
441
     *
442
     * @return An associative array of server properties
443
     */
444
    public function getServerInfo($server_id = null)
445
    {
446
        //\PC::debug(['$server_id' => $server_id]);
447
448
        if ($server_id !== null) {
449
            $this->_server_id = $server_id;
450
        } elseif ($this->_server_info !== null) {
451
            return $this->_server_info;
452
        }
453
454
        // Check for the server in the logged-in list
455
        if (isset($_SESSION['webdbLogin'][$this->_server_id])) {
456
            $this->_server_info = $_SESSION['webdbLogin'][$this->_server_id];
457
458
            return $this->_server_info;
459
        }
460
461
        // Otherwise, look for it in the conf file
462
        foreach ($this->conf['servers'] as $idx => $info) {
463
            if ($this->_server_id == $info['host'].':'.$info['port'].':'.$info['sslmode']) {
464
                if (isset($info['username'])) {
465
                    $this->setServerInfo(null, $info, $this->_server_id);
466
                } elseif (isset($_SESSION['sharedUsername'])) {
467
                    $info['username'] = $_SESSION['sharedUsername'];
468
                    $info['password'] = $_SESSION['sharedPassword'];
469
                    $this->setReloadBrowser(true);
470
                    $this->setServerInfo(null, $info, $this->_server_id);
471
                }
472
                $this->_server_info = $info;
473
474
                return $this->_server_info;
475
            }
476
        }
477
478
        if ($server_id === null) {
479
            $this->_server_info = null;
480
481
            return $this->_server_info;
482
        }
483
484
        $this->prtrace('Invalid server param');
485
        $this->_server_info = null;
486
        // Unable to find a matching server, are we being hacked?
487
        return $this->halt($this->lang['strinvalidserverparam']);
488
    }
489
490
    /**
491
     * Set server information.
492
     *
493
     * @param $key parameter name to set, or null to replace all
494
     *             params with the assoc-array in $value
495
     * @param $value the new value, or null to unset the parameter
496
     * @param $server_id the server identifier, or null for current server
497
     */
498
    public function setServerInfo($key, $value, $server_id = null)
499
    {
500
        //\PC::debug('setsetverinfo');
501
        if ($server_id === null && isset($_REQUEST['server'])) {
502
            $server_id = $_REQUEST['server'];
503
        }
504
505
        if ($key === null) {
506
            if ($value === null) {
507
                unset($_SESSION['webdbLogin'][$server_id]);
508
            } else {
509
                //\PC::debug(['server_id' => $server_id, 'value' => $value], 'webdbLogin null key');
510
                $_SESSION['webdbLogin'][$server_id] = $value;
511
            }
512
        } else {
513
            if ($value === null) {
514
                unset($_SESSION['webdbLogin'][$server_id][$key]);
515
            } else {
516
                //\PC::debug(['server_id' => $server_id, 'key' => $key, 'value' => $value], __FILE__ . ' ' . __LINE__ . ' webdbLogin key ' . $key);
517
                $_SESSION['webdbLogin'][$server_id][$key] = $value;
518
            }
519
        }
520
    }
521
522
    public function getDatabase($database = '')
1 ignored issue
show
Coding Style introduced by
Missing function doc comment
Loading history...
523
    {
524
        if ($this->_server_id === null && !isset($_REQUEST['database'])) {
525
            return null;
526
        }
527
528
        $server_info = $this->getServerInfo($this->_server_id);
529
530
        if ($this->_server_id !== null && isset($server_info['useonlydefaultdb']) && $server_info['useonlydefaultdb'] === true) {
531
            $this->_database = $server_info['defaultdb'];
532
        } elseif ($database !== '') {
533
            $this->_database = $database;
534
        } elseif (isset($_REQUEST['database'])) {
535
            // Connect to the current database
536
            $this->_database = $_REQUEST['database'];
537
        } else {
538
            // or if one is not specified then connect to the default database.
539
            $this->_database = $server_info['defaultdb'];
540
        }
541
542
        return $this->_database;
543
    }
544
545
    /**
546
     * Get list of server groups.
547
     *
548
     * @param bool  $recordset return as RecordSet suitable for HTMLTableController::printTable if true, otherwise just return an array
549
     * @param mixed $group_id  a group name to filter the returned servers using $this->conf[srv_groups]
550
     *
551
     * @return array|\PHPPgAdmin\ArrayRecordSet either an array or a Recordset suitable for HTMLTableController::printTable
552
     */
553
    public function getServersGroups($recordset = false, $group_id = false)
554
    {
555
        $lang = $this->lang;
556
        $grps = [];
557
558
        if (isset($this->conf['srv_groups'])) {
559
            foreach ($this->conf['srv_groups'] as $i => $group) {
560
                if (
0 ignored issues
show
Coding Style introduced by
First condition of a multi-line IF statement must directly follow the opening parenthesis
Loading history...
561
                    (($group_id === false) and (!isset($group['parents']))) /* root */
1 ignored issue
show
Coding Style introduced by
Each line in a multi-line IF statement must begin with a boolean operator
Loading history...
562
                    or (
563
                        ($group_id !== false)
2 ignored issues
show
Coding Style introduced by
Multi-line IF statement not indented correctly; expected 20 spaces but found 24
Loading history...
Coding Style introduced by
Each line in a multi-line IF statement must begin with a boolean operator
Loading history...
564
                        and isset($group['parents'])
1 ignored issue
show
Coding Style introduced by
Multi-line IF statement not indented correctly; expected 20 spaces but found 24
Loading history...
565
                        and in_array($group_id, explode(
2 ignored issues
show
Coding Style introduced by
Multi-line IF statement not indented correctly; expected 20 spaces but found 24
Loading history...
Coding Style introduced by
The opening parenthesis of a multi-line function call should be the last content on the line.
Loading history...
566
                            ',',
567
                            preg_replace('/\s/', '', $group['parents'])
568
                        ), true)
1 ignored issue
show
Coding Style introduced by
For multi-line function calls, the closing parenthesis should be on a new line.

If a function call spawns multiple lines, the coding standard suggests to move the closing parenthesis to a new line:

someFunctionCall(
    $firstArgument,
    $secondArgument,
    $thirdArgument
); // Closing parenthesis on a new line.
Loading history...
569
                    ) /* nested group */
1 ignored issue
show
Coding Style introduced by
Each line in a multi-line IF statement must begin with a boolean operator
Loading history...
570
                ) {
571
                    $grps[$i] = [
572
                        'id' => $i,
573
                        'desc' => $group['desc'],
574
                        'icon' => 'Servers',
575
                        'action' => Decorator::url(
576
                            '/views/servers',
577
                            [
578
                                'group' => Decorator::field('id'),
579
                            ]
580
                        ),
581
                        'branch' => Decorator::url(
582
                            '/tree/servers',
583
                            [
584
                                'group' => $i,
585
                            ]
586
                        ),
587
                    ];
588
                }
589
            }
590
591
            if ($group_id === false) {
592
                $grps['all'] = [
593
                    'id' => 'all',
594
                    'desc' => $lang['strallservers'],
595
                    'icon' => 'Servers',
596
                    'action' => Decorator::url(
597
                        '/views/servers',
598
                        [
599
                            'group' => Decorator::field('id'),
600
                        ]
601
                    ),
602
                    'branch' => Decorator::url(
603
                        '/tree/servers',
604
                        [
605
                            'group' => 'all',
606
                        ]
607
                    ),
608
                ];
609
            }
610
        }
611
612
        if ($recordset) {
613
            return new ArrayRecordSet($grps);
614
        }
615
616
        return $grps;
617
    }
618
619
    /**
620
     * Get list of servers.
621
     *
622
     * @param bool  $recordset return as RecordSet suitable for HTMLTableController::printTable if true, otherwise just return an array
623
     * @param mixed $group     a group name to filter the returned servers using $this->conf[srv_groups]
624
     *
625
     * @return array|\PHPPgAdmin\ArrayRecordSet either an array or a Recordset suitable for HTMLTableController::printTable
626
     */
627
    public function getServers($recordset = false, $group = false)
628
    {
629
        $logins = isset($_SESSION['webdbLogin']) && is_array($_SESSION['webdbLogin']) ? $_SESSION['webdbLogin'] : [];
630
        $srvs = [];
631
632
        if (($group !== false) && ($group !== 'all')) {
633
            if (isset($this->conf['srv_groups'][$group]['servers'])) {
634
                $group = array_fill_keys(explode(',', preg_replace(
1 ignored issue
show
Coding Style introduced by
The opening parenthesis of a multi-line function call should be the last content on the line.
Loading history...
635
                    '/\s/',
636
                    '',
637
                    $this->conf['srv_groups'][$group]['servers']
638
                )), 1);
1 ignored issue
show
Coding Style introduced by
For multi-line function calls, the closing parenthesis should be on a new line.

If a function call spawns multiple lines, the coding standard suggests to move the closing parenthesis to a new line:

someFunctionCall(
    $firstArgument,
    $secondArgument,
    $thirdArgument
); // Closing parenthesis on a new line.
Loading history...
639
            } else {
640
                $group = '';
641
            }
642
        }
643
644
        foreach ($this->conf['servers'] as $idx => $info) {
645
            $server_id = $info['host'].':'.$info['port'].':'.$info['sslmode'];
646
            if ($group === false || isset($group[$idx]) || ($group === 'all')) {
647
                $server_id = $info['host'].':'.$info['port'].':'.$info['sslmode'];
648
649
                if (isset($logins[$server_id])) {
650
                    $srvs[$server_id] = $logins[$server_id];
651
                } else {
652
                    $srvs[$server_id] = $info;
653
                }
654
655
                $srvs[$server_id]['id'] = $server_id;
656
                $srvs[$server_id]['action'] = Decorator::url(
657
                    '/redirect/server',
658
                    [
659
                        'server' => Decorator::field('id'),
660
                    ]
661
                );
662
                if (isset($srvs[$server_id]['username'])) {
663
                    $srvs[$server_id]['icon'] = 'Server';
664
                    $srvs[$server_id]['branch'] = Decorator::url(
665
                        '/src/views/alldb',
666
                        [
667
                            'action' => 'tree',
668
                            'subject' => 'server',
669
                            'server' => Decorator::field('id'),
670
                        ]
671
                    );
672
                } else {
673
                    $srvs[$server_id]['icon'] = 'DisconnectedServer';
674
                    $srvs[$server_id]['branch'] = false;
675
                }
676
            }
677
        }
678
679
        uasort($srvs, ['self', '_cmp_desc']);
680
681
        if ($recordset) {
682
            return new ArrayRecordSet($srvs);
683
        }
684
685
        return $srvs;
686
    }
687
688
    /**
689
     * Set the current schema.
690
     *
691
     * @param $schema The schema name
692
     *
693
     * @return int 0 on success
694
     */
695
    public function setCurrentSchema($schema)
696
    {
697
        $data = $this->getDatabaseAccessor();
698
699
        $status = $data->setSchema($schema);
700
        if ($status != 0) {
701
            return $status;
702
        }
703
704
        $_REQUEST['schema'] = $schema;
705
        $this->setHREF();
706
707
        return 0;
708
    }
709
710
    public static function _cmp_desc($a, $b)
2 ignored issues
show
Coding Style introduced by
Missing function doc comment
Loading history...
Coding Style introduced by
Public method name "Misc::_cmp_desc" must not be prefixed with an underscore
Loading history...
711
    {
712
        return strcmp($a['desc'], $b['desc']);
713
    }
714
715
    /**
716
     * Checks if dumps are properly set up.
717
     *
718
     * @param $all (optional) True to check pg_dumpall, false to just check pg_dump
719
     *
720
     * @return True, dumps are set up, false otherwise
721
     */
722
    public function isDumpEnabled($all = false)
723
    {
724
        $info = $this->getServerInfo();
725
726
        return !empty($info[$all ? 'pg_dumpall_path' : 'pg_dump_path']);
727
    }
728
729
    /**
730
     * Sets the href tracking variable.
731
     */
732
    public function setHREF()
733
    {
734
        $this->href = $this->getHREF();
735
        //\PC::debug($this->href, 'Misc::href');
736
        return $this;
737
    }
738
739
    /**
740
     * Get a href query string, excluding objects below the given object type (inclusive).
741
     *
742
     * @param null $exclude_from
1 ignored issue
show
Documentation Bug introduced by
Are you sure the doc-type for parameter $exclude_from is correct as it would always require null to be passed?
Loading history...
Coding Style introduced by
Missing parameter comment
Loading history...
743
     *
744
     * @return string
745
     */
746
    public function getHREF($exclude_from = null)
747
    {
748
        $href = [];
749
        if (isset($_REQUEST['server']) && $exclude_from != 'server') {
750
            $href[] = 'server='.urlencode($_REQUEST['server']);
751
        }
752
        if (isset($_REQUEST['database']) && $exclude_from != 'database') {
753
            $href[] = 'database='.urlencode($_REQUEST['database']);
754
        }
755
        if (isset($_REQUEST['schema']) && $exclude_from != 'schema') {
756
            $href[] = 'schema='.urlencode($_REQUEST['schema']);
757
        }
758
759
        return htmlentities(implode('&', $href));
760
    }
761
762
    public function getSubjectParams($subject)
1 ignored issue
show
Coding Style introduced by
Missing function doc comment
Loading history...
763
    {
764
        $plugin_manager = $this->plugin_manager;
765
766
        $vars = [];
767
768
        switch ($subject) {
769
            case 'root':
770
                $vars = [
771
                    'params' => [
772
                        'subject' => 'root',
773
                    ],
774
                ];
775
776
                break;
777
            case 'server':
778
                $vars = ['params' => [
779
                    'server' => $_REQUEST['server'],
780
                    'subject' => 'server',
781
                ]];
782
783
                break;
784
            case 'role':
785
                $vars = ['params' => [
786
                    'server' => $_REQUEST['server'],
787
                    'subject' => 'role',
788
                    'action' => 'properties',
789
                    'rolename' => $_REQUEST['rolename'],
790
                ]];
791
792
                break;
793
            case 'database':
794
                $vars = ['params' => [
795
                    'server' => $_REQUEST['server'],
796
                    'subject' => 'database',
797
                    'database' => $_REQUEST['database'],
798
                ]];
799
800
                break;
801
            case 'schema':
802
                $vars = ['params' => [
803
                    'server' => $_REQUEST['server'],
804
                    'subject' => 'schema',
805
                    'database' => $_REQUEST['database'],
806
                    'schema' => $_REQUEST['schema'],
807
                ]];
808
809
                break;
810
            case 'table':
811
                $vars = ['params' => [
812
                    'server' => $_REQUEST['server'],
813
                    'subject' => 'table',
814
                    'database' => $_REQUEST['database'],
815
                    'schema' => $_REQUEST['schema'],
816
                    'table' => $_REQUEST['table'],
817
                ]];
818
819
                break;
820
            case 'selectrows':
821
                $vars = [
822
                    'url' => 'tables.php',
823
                    'params' => [
824
                        'server' => $_REQUEST['server'],
825
                        'subject' => 'table',
826
                        'database' => $_REQUEST['database'],
827
                        'schema' => $_REQUEST['schema'],
828
                        'table' => $_REQUEST['table'],
829
                        'action' => 'confselectrows',
830
                    ], ];
831
832
                break;
833
            case 'view':
834
                $vars = ['params' => [
835
                    'server' => $_REQUEST['server'],
836
                    'subject' => 'view',
837
                    'database' => $_REQUEST['database'],
838
                    'schema' => $_REQUEST['schema'],
839
                    'view' => $_REQUEST['view'],
840
                ]];
841
842
                break;
843
            case 'matview':
844
                $vars = ['params' => [
845
                    'server' => $_REQUEST['server'],
846
                    'subject' => 'matview',
847
                    'database' => $_REQUEST['database'],
848
                    'schema' => $_REQUEST['schema'],
849
                    'matview' => $_REQUEST['matview'],
850
                ]];
851
852
                break;
853
            case 'fulltext':
854
            case 'ftscfg':
855
                $vars = ['params' => [
856
                    'server' => $_REQUEST['server'],
857
                    'subject' => 'fulltext',
858
                    'database' => $_REQUEST['database'],
859
                    'schema' => $_REQUEST['schema'],
860
                    'action' => 'viewconfig',
861
                    'ftscfg' => $_REQUEST['ftscfg'],
862
                ]];
863
864
                break;
865
            case 'function':
866
                $vars = ['params' => [
867
                    'server' => $_REQUEST['server'],
868
                    'subject' => 'function',
869
                    'database' => $_REQUEST['database'],
870
                    'schema' => $_REQUEST['schema'],
871
                    'function' => $_REQUEST['function'],
872
                    'function_oid' => $_REQUEST['function_oid'],
873
                ]];
874
875
                break;
876
            case 'aggregate':
877
                $vars = ['params' => [
878
                    'server' => $_REQUEST['server'],
879
                    'subject' => 'aggregate',
880
                    'action' => 'properties',
881
                    'database' => $_REQUEST['database'],
882
                    'schema' => $_REQUEST['schema'],
883
                    'aggrname' => $_REQUEST['aggrname'],
884
                    'aggrtype' => $_REQUEST['aggrtype'],
885
                ]];
886
887
                break;
888
            case 'column':
889
                if (isset($_REQUEST['table'])) {
890
                    $vars = ['params' => [
891
                        'server' => $_REQUEST['server'],
892
                        'subject' => 'column',
893
                        'database' => $_REQUEST['database'],
894
                        'schema' => $_REQUEST['schema'],
895
                        'table' => $_REQUEST['table'],
896
                        'column' => $_REQUEST['column'],
897
                    ]];
898
                } else {
899
                    $vars = ['params' => [
900
                        'server' => $_REQUEST['server'],
901
                        'subject' => 'column',
902
                        'database' => $_REQUEST['database'],
903
                        'schema' => $_REQUEST['schema'],
904
                        'view' => $_REQUEST['view'],
905
                        'column' => $_REQUEST['column'],
906
                    ]];
907
                }
908
909
                break;
910
            case 'plugin':
911
                $vars = [
912
                    'url' => 'plugin.php',
913
                    'params' => [
914
                        'server' => $_REQUEST['server'],
915
                        'subject' => 'plugin',
916
                        'plugin' => $_REQUEST['plugin'],
917
                    ], ];
918
919
                if (!is_null($plugin_manager->getPlugin($_REQUEST['plugin']))) {
920
                    $vars['params'] = array_merge($vars['params'], $plugin_manager->getPlugin($_REQUEST['plugin'])->get_subject_params());
921
                }
922
923
                break;
924
            default:
925
                return false;
926
        }
927
928
        if (!isset($vars['url'])) {
929
            $vars['url'] = SUBFOLDER.'/redirect';
930
        }
931
        if ($vars['url'] == SUBFOLDER.'/redirect' && isset($vars['params']['subject'])) {
932
            $vars['url'] = SUBFOLDER.'/redirect/'.$vars['params']['subject'];
933
            unset($vars['params']['subject']);
934
        }
935
936
        return $vars;
937
    }
938
939
    /**
940
     * Sets the form tracking variable.
941
     */
942
    public function setForm()
943
    {
944
        $form = [];
945
        if (isset($_REQUEST['server'])) {
946
            $form[] = '<input type="hidden" name="server" value="'.htmlspecialchars($_REQUEST['server']).'" />';
947
        }
948
        if (isset($_REQUEST['database'])) {
949
            $form[] = '<input type="hidden" name="database" value="'.htmlspecialchars($_REQUEST['database']).'" />';
950
        }
951
952
        if (isset($_REQUEST['schema'])) {
953
            $form[] = '<input type="hidden" name="schema" value="'.htmlspecialchars($_REQUEST['schema']).'" />';
954
        }
955
        $this->form = implode("\n", $form);
956
957
        return $this->form;
958
        //\PC::debug($this->form, 'Misc::form');
959
    }
960
961
    /**
962
     * Render a value into HTML using formatting rules specified
963
     * by a type name and parameters.
964
     *
965
     * @param                        $str    The string to change
966
     * @param                        $type   Field type (optional), this may be an internal PostgreSQL type, or:
967
     *                                       yesno    - same as bool, but renders as 'Yes' or 'No'.
968
     *                                       pre      - render in a <pre> block.
969
     *                                       nbsp     - replace all spaces with &nbsp;'s
970
     *                                       verbatim - render exactly as supplied, no escaping what-so-ever.
971
     *                                       callback - render using a callback function supplied in the 'function' param.
972
     * @param array|\PHPPgAdmin\Type $params Type parameters (optional), known parameters:
973
     *                                       null     - string to display if $str is null, or set to TRUE to use a default 'NULL' string,
974
     *                                       otherwise nothing is rendered.
975
     *                                       clip     - if true, clip the value to a fixed length, and append an ellipsis...
976
     *                                       cliplen  - the maximum length when clip is enabled (defaults to $conf['max_chars'])
977
     *                                       ellipsis - the string to append to a clipped value (defaults to $lang['strellipsis'])
978
     *                                       tag      - an HTML element name to surround the value.
979
     *                                       class    - a class attribute to apply to any surrounding HTML element.
980
     *                                       align    - an align attribute ('left','right','center' etc.)
981
     *                                       true     - (type='bool') the representation of true.
982
     *                                       false    - (type='bool') the representation of false.
983
     *                                       function - (type='callback') a function name, accepts args ($str, $params) and returns a rendering.
984
     *                                       lineno   - prefix each line with a line number.
985
     *                                       map      - an associative array.
986
     *
987
     * @return \PHPPgAdmin\The HTML rendered value
988
     */
989
    public function printVal($str, $type = null, $params = [])
990
    {
991
        $lang = $this->lang;
992
        $data = $this->getDatabaseAccessor();
993
994
        // Shortcircuit for a NULL value
995
        if (is_null($str)) {
996
            return isset($params['null'])
997
            ? ($params['null'] === true ? '<i>NULL</i>' : $params['null'])
998
            : '';
999
        }
1000
1001
        if (isset($params['map'], $params['map'][$str])) {
1002
            $str = $params['map'][$str];
1003
        }
1004
1005
        // Clip the value if the 'clip' parameter is true.
1006
        if (isset($params['clip']) && $params['clip'] === true) {
1007
            $maxlen = isset($params['cliplen']) && is_integer($params['cliplen']) ? $params['cliplen'] : $this->conf['max_chars'];
1008
            $ellipsis = isset($params['ellipsis']) ? $params['ellipsis'] : $lang['strellipsis'];
1009
            if (strlen($str) > $maxlen) {
1010
                $str = substr($str, 0, $maxlen - 1).$ellipsis;
1011
            }
1012
        }
1013
1014
        $out = '';
1015
1016
        switch ($type) {
1017
            case 'int2':
1018
            case 'int4':
1019
            case 'int8':
1020
            case 'float4':
1021
            case 'float8':
1022
            case 'money':
1023
            case 'numeric':
1024
            case 'oid':
1025
            case 'xid':
1026
            case 'cid':
1027
            case 'tid':
1028
                $align = 'right';
1029
                $out = nl2br(htmlspecialchars(\PHPPgAdmin\HelperTrait::br2ln($str)));
1030
1031
                break;
1032
            case 'yesno':
1033
                if (!isset($params['true'])) {
1034
                    $params['true'] = $lang['stryes'];
1035
                }
1036
1037
                if (!isset($params['false'])) {
1038
                    $params['false'] = $lang['strno'];
1039
                }
1040
1041
            // no break - fall through to boolean case.
1042
            case 'bool':
1043
            case 'boolean':
1044
                if (is_bool($str)) {
1045
                    $str = $str ? 't' : 'f';
1046
                }
1047
1048
                switch ($str) {
1049
                    case 't':
1050
                        $out = (isset($params['true']) ? $params['true'] : $lang['strtrue']);
1051
                        $align = 'center';
1052
1053
                        break;
1054
                    case 'f':
1055
                        $out = (isset($params['false']) ? $params['false'] : $lang['strfalse']);
1056
                        $align = 'center';
1057
1058
                        break;
1059
                    default:
1060
                        $out = htmlspecialchars($str);
1061
                }
1062
1063
                break;
1064
            case 'bytea':
1065
                $tag = 'div';
1066
                $class = 'pre';
1067
                $out = $data->escapeBytea($str);
1068
1069
                break;
1070
            case 'errormsg':
1071
                $tag = 'pre';
1072
                $class = 'error';
1073
                $out = htmlspecialchars($str);
1074
1075
                break;
1076
            case 'pre':
1077
                $tag = 'pre';
1078
                $out = htmlspecialchars($str);
1079
1080
                break;
1081
            case 'prenoescape':
1082
                $tag = 'pre';
1083
                $out = $str;
1084
1085
                break;
1086
            case 'nbsp':
1087
                $out = nl2br(str_replace(' ', '&nbsp;', \PHPPgAdmin\HelperTrait::br2ln($str)));
1088
1089
                break;
1090
            case 'verbatim':
1091
                $out = $str;
1092
1093
                break;
1094
            case 'callback':
1095
                $out = $params['function']($str, $params);
1096
1097
                break;
1098
            case 'prettysize':
1099
                if ($str == -1) {
1100
                    $out = $lang['strnoaccess'];
1101
                } else {
1102
                    $limit = 10 * 1024;
1103
                    $mult = 1;
1104
                    if ($str < $limit * $mult) {
1105
                        $out = $str.' '.$lang['strbytes'];
1106
                    } else {
1107
                        $mult *= 1024;
1108
                        if ($str < $limit * $mult) {
1109
                            $out = floor(($str + $mult / 2) / $mult).' '.$lang['strkb'];
1110
                        } else {
1111
                            $mult *= 1024;
1112
                            if ($str < $limit * $mult) {
1113
                                $out = floor(($str + $mult / 2) / $mult).' '.$lang['strmb'];
1114
                            } else {
1115
                                $mult *= 1024;
1116
                                if ($str < $limit * $mult) {
1117
                                    $out = floor(($str + $mult / 2) / $mult).' '.$lang['strgb'];
1118
                                } else {
1119
                                    $mult *= 1024;
1120
                                    if ($str < $limit * $mult) {
1121
                                        $out = floor(($str + $mult / 2) / $mult).' '.$lang['strtb'];
1122
                                    }
1123
                                }
1124
                            }
1125
                        }
1126
                    }
1127
                }
1128
1129
                break;
1130
            default:
1131
                // If the string contains at least one instance of >1 space in a row, a tab
1132
                // character, a space at the start of a line, or a space at the start of
1133
                // the whole string then render within a pre-formatted element (<pre>).
1134
                if (preg_match('/(^ |  |\t|\n )/m', $str)) {
1135
                    $tag = 'pre';
1136
                    $class = 'data';
1137
                    $out = htmlspecialchars($str);
1138
                } else {
1139
                    $out = nl2br(htmlspecialchars(\PHPPgAdmin\HelperTrait::br2ln($str)));
1140
                }
1141
        }
1142
1143
        if (isset($params['class'])) {
1144
            $class = $params['class'];
1145
        }
1146
1147
        if (isset($params['align'])) {
1148
            $align = $params['align'];
1149
        }
1150
1151
        if (!isset($tag) && (isset($class) || isset($align))) {
1152
            $tag = 'div';
1153
        }
1154
1155
        if (isset($tag)) {
1156
            $alignattr = isset($align) ? " style=\"text-align: {$align}\"" : '';
1157
            $classattr = isset($class) ? " class=\"{$class}\"" : '';
1158
            $out = "<{$tag}{$alignattr}{$classattr}>{$out}</{$tag}>";
1159
        }
1160
1161
        // Add line numbers if 'lineno' param is true
1162
        if (isset($params['lineno']) && $params['lineno'] === true) {
1163
            $lines = explode("\n", $str);
1164
            $num = count($lines);
1165
            if ($num > 0) {
1166
                $temp = "<table>\n<tr><td class=\"{$class}\" style=\"vertical-align: top; padding-right: 10px;\"><pre class=\"{$class}\">";
1167
                for ($i = 1; $i <= $num; ++$i) {
1168
                    $temp .= $i."\n";
1169
                }
1170
                $temp .= "</pre></td><td class=\"{$class}\" style=\"vertical-align: top;\">{$out}</td></tr></table>\n";
1171
                $out = $temp;
1172
            }
1173
            unset($lines);
1174
        }
1175
1176
        return $out;
1177
    }
1178
1179
    /**
1180
     * A function to recursively strip slashes.  Used to
1181
     * enforce magic_quotes_gpc being off.
1182
     *
1183
     * @param &var The variable to strip
1184
     */
1185
    public function stripVar(&$var)
1186
    {
1187
        if (is_array($var)) {
1188
            foreach ($var as $k => $v) {
1189
                $this->stripVar($var[$k]);
1190
1191
                /* magic_quotes_gpc escape keys as well ...*/
1192
                if (is_string($k)) {
1193
                    $ek = stripslashes($k);
1194
                    if ($ek !== $k) {
1195
                        $var[$ek] = $var[$k];
1196
                        unset($var[$k]);
1197
                    }
1198
                }
1199
            }
1200
        } else {
1201
            $var = stripslashes($var);
1202
        }
1203
    }
1204
1205
    /**
1206
     * Retrieve the tab info for a specific tab bar.
1207
     *
1208
     * @param $section the name of the tab bar
1209
     *
1210
     * @return array
1211
     */
1212
    public function getNavTabs($section)
1213
    {
1214
        $data = $this->getDatabaseAccessor();
1215
        $lang = $this->lang;
1216
        $plugin_manager = $this->plugin_manager;
1217
1218
        $hide_advanced = ($this->conf['show_advanced'] === false);
1219
        $tabs = [];
1220
1221
        switch ($section) {
1222
            case 'root':
1223
                $tabs = [
1224
                    'intro' => [
1225
                        'title' => $lang['strintroduction'],
1226
                        'url' => 'intro.php',
1227
                        'icon' => 'Introduction',
1228
                    ],
1229
                    'servers' => [
1230
                        'title' => $lang['strservers'],
1231
                        'url' => 'servers.php',
1232
                        'icon' => 'Servers',
1233
                    ],
1234
                ];
1235
1236
                break;
1237
            case 'server':
1238
                $hide_users = true;
1239
                if ($data) {
1240
                    $hide_users = !$data->isSuperUser();
1241
                }
1242
1243
                $tabs = [
1244
                    'databases' => [
1245
                        'title' => $lang['strdatabases'],
1246
                        'url' => 'alldb.php',
1247
                        'urlvars' => ['subject' => 'server'],
1248
                        'help' => 'pg.database',
1249
                        'icon' => 'Databases',
1250
                    ],
1251
                ];
1252
                if ($data && $data->hasRoles()) {
1253
                    $tabs = array_merge($tabs, [
1 ignored issue
show
Coding Style introduced by
The opening parenthesis of a multi-line function call should be the last content on the line.
Loading history...
1254
                        'roles' => [
1255
                            'title' => $lang['strroles'],
1256
                            'url' => 'roles.php',
1257
                            'urlvars' => ['subject' => 'server'],
1258
                            'hide' => $hide_users,
1259
                            'help' => 'pg.role',
1260
                            'icon' => 'Roles',
1261
                        ],
1262
                    ]);
1 ignored issue
show
Coding Style introduced by
For multi-line function calls, the closing parenthesis should be on a new line.

If a function call spawns multiple lines, the coding standard suggests to move the closing parenthesis to a new line:

someFunctionCall(
    $firstArgument,
    $secondArgument,
    $thirdArgument
); // Closing parenthesis on a new line.
Loading history...
1263
                } else {
1264
                    $tabs = array_merge($tabs, [
1 ignored issue
show
Coding Style introduced by
The opening parenthesis of a multi-line function call should be the last content on the line.
Loading history...
1265
                        'users' => [
1266
                            'title' => $lang['strusers'],
1267
                            'url' => 'users.php',
1268
                            'urlvars' => ['subject' => 'server'],
1269
                            'hide' => $hide_users,
1270
                            'help' => 'pg.user',
1271
                            'icon' => 'Users',
1272
                        ],
1273
                        'groups' => [
1274
                            'title' => $lang['strgroups'],
1275
                            'url' => 'groups.php',
1276
                            'urlvars' => ['subject' => 'server'],
1277
                            'hide' => $hide_users,
1278
                            'help' => 'pg.group',
1279
                            'icon' => 'UserGroups',
1280
                        ],
1281
                    ]);
1 ignored issue
show
Coding Style introduced by
For multi-line function calls, the closing parenthesis should be on a new line.

If a function call spawns multiple lines, the coding standard suggests to move the closing parenthesis to a new line:

someFunctionCall(
    $firstArgument,
    $secondArgument,
    $thirdArgument
); // Closing parenthesis on a new line.
Loading history...
1282
                }
1283
1284
                $tabs = array_merge($tabs, [
1 ignored issue
show
Coding Style introduced by
The opening parenthesis of a multi-line function call should be the last content on the line.
Loading history...
1285
                    'account' => [
1286
                        'title' => $lang['straccount'],
1287
                        'url' => ($data && $data->hasRoles()) ? 'roles.php' : 'users.php',
1288
                        'urlvars' => ['subject' => 'server', 'action' => 'account'],
1289
                        'hide' => !$hide_users,
1290
                        'help' => 'pg.role',
1291
                        'icon' => 'User',
1292
                    ],
1293
                    'tablespaces' => [
1294
                        'title' => $lang['strtablespaces'],
1295
                        'url' => 'tablespaces.php',
1296
                        'urlvars' => ['subject' => 'server'],
1297
                        'hide' => !$data || !$data->hasTablespaces(),
1298
                        'help' => 'pg.tablespace',
1299
                        'icon' => 'Tablespaces',
1300
                    ],
1301
                    'export' => [
1302
                        'title' => $lang['strexport'],
1303
                        'url' => 'alldb.php',
1304
                        'urlvars' => ['subject' => 'server', 'action' => 'export'],
1305
                        'hide' => !$this->isDumpEnabled(),
1306
                        'icon' => 'Export',
1307
                    ],
1308
                ]);
1 ignored issue
show
Coding Style introduced by
For multi-line function calls, the closing parenthesis should be on a new line.

If a function call spawns multiple lines, the coding standard suggests to move the closing parenthesis to a new line:

someFunctionCall(
    $firstArgument,
    $secondArgument,
    $thirdArgument
); // Closing parenthesis on a new line.
Loading history...
1309
1310
                break;
1311
            case 'database':
1312
                $tabs = [
1313
                    'schemas' => [
1314
                        'title' => $lang['strschemas'],
1315
                        'url' => 'schemas.php',
1316
                        'urlvars' => ['subject' => 'database'],
1317
                        'help' => 'pg.schema',
1318
                        'icon' => 'Schemas',
1319
                    ],
1320
                    'sql' => [
1321
                        'title' => $lang['strsql'],
1322
                        'url' => 'database.php',
1323
                        'urlvars' => ['subject' => 'database', 'action' => 'sql', 'new' => 1],
1324
                        'help' => 'pg.sql',
1325
                        'tree' => false,
1326
                        'icon' => 'SqlEditor',
1327
                    ],
1328
                    'find' => [
1329
                        'title' => $lang['strfind'],
1330
                        'url' => 'database.php',
1331
                        'urlvars' => ['subject' => 'database', 'action' => 'find'],
1332
                        'tree' => false,
1333
                        'icon' => 'Search',
1334
                    ],
1335
                    'variables' => [
1336
                        'title' => $lang['strvariables'],
1337
                        'url' => 'database.php',
1338
                        'urlvars' => ['subject' => 'database', 'action' => 'variables'],
1339
                        'help' => 'pg.variable',
1340
                        'tree' => false,
1341
                        'icon' => 'Variables',
1342
                    ],
1343
                    'processes' => [
1344
                        'title' => $lang['strprocesses'],
1345
                        'url' => 'database.php',
1346
                        'urlvars' => ['subject' => 'database', 'action' => 'processes'],
1347
                        'help' => 'pg.process',
1348
                        'tree' => false,
1349
                        'icon' => 'Processes',
1350
                    ],
1351
                    'locks' => [
1352
                        'title' => $lang['strlocks'],
1353
                        'url' => 'database.php',
1354
                        'urlvars' => ['subject' => 'database', 'action' => 'locks'],
1355
                        'help' => 'pg.locks',
1356
                        'tree' => false,
1357
                        'icon' => 'Key',
1358
                    ],
1359
                    'admin' => [
1360
                        'title' => $lang['stradmin'],
1361
                        'url' => 'database.php',
1362
                        'urlvars' => ['subject' => 'database', 'action' => 'admin'],
1363
                        'tree' => false,
1364
                        'icon' => 'Admin',
1365
                    ],
1366
                    'privileges' => [
1367
                        'title' => $lang['strprivileges'],
1368
                        'url' => 'privileges.php',
1369
                        'urlvars' => ['subject' => 'database'],
1370
                        'hide' => !isset($data->privlist['database']),
1371
                        'help' => 'pg.privilege',
1372
                        'tree' => false,
1373
                        'icon' => 'Privileges',
1374
                    ],
1375
                    'languages' => [
1376
                        'title' => $lang['strlanguages'],
1377
                        'url' => 'languages.php',
1378
                        'urlvars' => ['subject' => 'database'],
1379
                        'hide' => $hide_advanced,
1380
                        'help' => 'pg.language',
1381
                        'icon' => 'Languages',
1382
                    ],
1383
                    'casts' => [
1384
                        'title' => $lang['strcasts'],
1385
                        'url' => 'casts.php',
1386
                        'urlvars' => ['subject' => 'database'],
1387
                        'hide' => $hide_advanced,
1388
                        'help' => 'pg.cast',
1389
                        'icon' => 'Casts',
1390
                    ],
1391
                    'export' => [
1392
                        'title' => $lang['strexport'],
1393
                        'url' => 'database.php',
1394
                        'urlvars' => ['subject' => 'database', 'action' => 'export'],
1395
                        'hide' => !$this->isDumpEnabled(),
1396
                        'tree' => false,
1397
                        'icon' => 'Export',
1398
                    ],
1399
                ];
1400
1401
                break;
1402
            case 'schema':
1403
                $tabs = [
1404
                    'tables' => [
1405
                        'title' => $lang['strtables'],
1406
                        'url' => 'tables.php',
1407
                        'urlvars' => ['subject' => 'schema'],
1408
                        'help' => 'pg.table',
1409
                        'icon' => 'Tables',
1410
                    ],
1411
                    'views' => [
1412
                        'title' => $lang['strviews'],
1413
                        'url' => 'views.php',
1414
                        'urlvars' => ['subject' => 'schema'],
1415
                        'help' => 'pg.view',
1416
                        'icon' => 'Views',
1417
                    ],
1418
                    'matviews' => [
1419
                        'title' => 'M '.$lang['strviews'],
1420
                        'url' => 'materializedviews.php',
1421
                        'urlvars' => ['subject' => 'schema'],
1422
                        'help' => 'pg.matview',
1423
                        'icon' => 'MViews',
1424
                    ],
1425
                    'sequences' => [
1426
                        'title' => $lang['strsequences'],
1427
                        'url' => 'sequences.php',
1428
                        'urlvars' => ['subject' => 'schema'],
1429
                        'help' => 'pg.sequence',
1430
                        'icon' => 'Sequences',
1431
                    ],
1432
                    'functions' => [
1433
                        'title' => $lang['strfunctions'],
1434
                        'url' => 'functions.php',
1435
                        'urlvars' => ['subject' => 'schema'],
1436
                        'help' => 'pg.function',
1437
                        'icon' => 'Functions',
1438
                    ],
1439
                    'fulltext' => [
1440
                        'title' => $lang['strfulltext'],
1441
                        'url' => 'fulltext.php',
1442
                        'urlvars' => ['subject' => 'schema'],
1443
                        'help' => 'pg.fts',
1444
                        'tree' => true,
1445
                        'icon' => 'Fts',
1446
                    ],
1447
                    'domains' => [
1448
                        'title' => $lang['strdomains'],
1449
                        'url' => 'domains.php',
1450
                        'urlvars' => ['subject' => 'schema'],
1451
                        'help' => 'pg.domain',
1452
                        'icon' => 'Domains',
1453
                    ],
1454
                    'aggregates' => [
1455
                        'title' => $lang['straggregates'],
1456
                        'url' => 'aggregates.php',
1457
                        'urlvars' => ['subject' => 'schema'],
1458
                        'hide' => $hide_advanced,
1459
                        'help' => 'pg.aggregate',
1460
                        'icon' => 'Aggregates',
1461
                    ],
1462
                    'types' => [
1463
                        'title' => $lang['strtypes'],
1464
                        'url' => 'types.php',
1465
                        'urlvars' => ['subject' => 'schema'],
1466
                        'hide' => $hide_advanced,
1467
                        'help' => 'pg.type',
1468
                        'icon' => 'Types',
1469
                    ],
1470
                    'operators' => [
1471
                        'title' => $lang['stroperators'],
1472
                        'url' => 'operators.php',
1473
                        'urlvars' => ['subject' => 'schema'],
1474
                        'hide' => $hide_advanced,
1475
                        'help' => 'pg.operator',
1476
                        'icon' => 'Operators',
1477
                    ],
1478
                    'opclasses' => [
1479
                        'title' => $lang['stropclasses'],
1480
                        'url' => 'opclasses.php',
1481
                        'urlvars' => ['subject' => 'schema'],
1482
                        'hide' => $hide_advanced,
1483
                        'help' => 'pg.opclass',
1484
                        'icon' => 'OperatorClasses',
1485
                    ],
1486
                    'conversions' => [
1487
                        'title' => $lang['strconversions'],
1488
                        'url' => 'conversions.php',
1489
                        'urlvars' => ['subject' => 'schema'],
1490
                        'hide' => $hide_advanced,
1491
                        'help' => 'pg.conversion',
1492
                        'icon' => 'Conversions',
1493
                    ],
1494
                    'privileges' => [
1495
                        'title' => $lang['strprivileges'],
1496
                        'url' => 'privileges.php',
1497
                        'urlvars' => ['subject' => 'schema'],
1498
                        'help' => 'pg.privilege',
1499
                        'tree' => false,
1500
                        'icon' => 'Privileges',
1501
                    ],
1502
                    'export' => [
1503
                        'title' => $lang['strexport'],
1504
                        'url' => 'schemas.php',
1505
                        'urlvars' => ['subject' => 'schema', 'action' => 'export'],
1506
                        'hide' => !$this->isDumpEnabled(),
1507
                        'tree' => false,
1508
                        'icon' => 'Export',
1509
                    ],
1510
                ];
1511
                if (!$data->hasFTS()) {
1512
                    unset($tabs['fulltext']);
1513
                }
1514
1515
                break;
1516
            case 'table':
1517
                $tabs = [
1518
                    'columns' => [
1519
                        'title' => $lang['strcolumns'],
1520
                        'url' => 'tblproperties.php',
1521
                        'urlvars' => ['subject' => 'table', 'table' => Decorator::field('table')],
1522
                        'icon' => 'Columns',
1523
                        'branch' => true,
1524
                    ],
1525
                    'browse' => [
1526
                        'title' => $lang['strbrowse'],
1527
                        'icon' => 'Columns',
1528
                        'url' => 'display.php',
1529
                        'urlvars' => ['subject' => 'table', 'table' => Decorator::field('table')],
1530
                        'return' => 'table',
1531
                        'branch' => true,
1532
                    ],
1533
                    'select' => [
1534
                        'title' => $lang['strselect'],
1535
                        'icon' => 'Search',
1536
                        'url' => 'tables.php',
1537
                        'urlvars' => ['subject' => 'table', 'table' => Decorator::field('table'), 'action' => 'confselectrows'],
1538
                        'help' => 'pg.sql.select',
1539
                    ],
1540
                    'insert' => [
1541
                        'title' => $lang['strinsert'],
1542
                        'url' => 'tables.php',
1543
                        'urlvars' => [
1544
                            'action' => 'confinsertrow',
1545
                            'table' => Decorator::field('table'),
1546
                        ],
1547
                        'help' => 'pg.sql.insert',
1548
                        'icon' => 'Operator',
1549
                    ],
1550
                    'indexes' => [
1551
                        'title' => $lang['strindexes'],
1552
                        'url' => 'indexes.php',
1553
                        'urlvars' => ['subject' => 'table', 'table' => Decorator::field('table')],
1554
                        'help' => 'pg.index',
1555
                        'icon' => 'Indexes',
1556
                        'branch' => true,
1557
                    ],
1558
                    'constraints' => [
1559
                        'title' => $lang['strconstraints'],
1560
                        'url' => 'constraints.php',
1561
                        'urlvars' => ['subject' => 'table', 'table' => Decorator::field('table')],
1562
                        'help' => 'pg.constraint',
1563
                        'icon' => 'Constraints',
1564
                        'branch' => true,
1565
                    ],
1566
                    'triggers' => [
1567
                        'title' => $lang['strtriggers'],
1568
                        'url' => 'triggers.php',
1569
                        'urlvars' => ['subject' => 'table', 'table' => Decorator::field('table')],
1570
                        'help' => 'pg.trigger',
1571
                        'icon' => 'Triggers',
1572
                        'branch' => true,
1573
                    ],
1574
                    'rules' => [
1575
                        'title' => $lang['strrules'],
1576
                        'url' => 'rules.php',
1577
                        'urlvars' => ['subject' => 'table', 'table' => Decorator::field('table')],
1578
                        'help' => 'pg.rule',
1579
                        'icon' => 'Rules',
1580
                        'branch' => true,
1581
                    ],
1582
                    'admin' => [
1583
                        'title' => $lang['stradmin'],
1584
                        'url' => 'tables.php',
1585
                        'urlvars' => ['subject' => 'table', 'table' => Decorator::field('table'), 'action' => 'admin'],
1586
                        'icon' => 'Admin',
1587
                    ],
1588
                    'info' => [
1589
                        'title' => $lang['strinfo'],
1590
                        'url' => 'info.php',
1591
                        'urlvars' => ['subject' => 'table', 'table' => Decorator::field('table')],
1592
                        'icon' => 'Statistics',
1593
                    ],
1594
                    'privileges' => [
1595
                        'title' => $lang['strprivileges'],
1596
                        'url' => 'privileges.php',
1597
                        'urlvars' => ['subject' => 'table', 'table' => Decorator::field('table')],
1598
                        'help' => 'pg.privilege',
1599
                        'icon' => 'Privileges',
1600
                    ],
1601
                    'import' => [
1602
                        'title' => $lang['strimport'],
1603
                        'url' => 'tblproperties.php',
1604
                        'urlvars' => ['subject' => 'table', 'table' => Decorator::field('table'), 'action' => 'import'],
1605
                        'icon' => 'Import',
1606
                        'hide' => false,
1607
                    ],
1608
                    'export' => [
1609
                        'title' => $lang['strexport'],
1610
                        'url' => 'tblproperties.php',
1611
                        'urlvars' => ['subject' => 'table', 'table' => Decorator::field('table'), 'action' => 'export'],
1612
                        'icon' => 'Export',
1613
                        'hide' => false,
1614
                    ],
1615
                ];
1616
1617
                break;
1618
            case 'view':
1619
                $tabs = [
1620
                    'columns' => [
1621
                        'title' => $lang['strcolumns'],
1622
                        'url' => 'viewproperties.php',
1623
                        'urlvars' => ['subject' => 'view', 'view' => Decorator::field('view')],
1624
                        'icon' => 'Columns',
1625
                        'branch' => true,
1626
                    ],
1627
                    'browse' => [
1628
                        'title' => $lang['strbrowse'],
1629
                        'icon' => 'Columns',
1630
                        'url' => 'display.php',
1631
                        'urlvars' => [
1632
                            'action' => 'confselectrows',
1633
                            'return' => 'schema',
1634
                            'subject' => 'view',
1635
                            'view' => Decorator::field('view'),
1636
                        ],
1637
                        'branch' => true,
1638
                    ],
1639
                    'select' => [
1640
                        'title' => $lang['strselect'],
1641
                        'icon' => 'Search',
1642
                        'url' => 'views.php',
1643
                        'urlvars' => ['action' => 'confselectrows', 'view' => Decorator::field('view')],
1644
                        'help' => 'pg.sql.select',
1645
                    ],
1646
                    'definition' => [
1647
                        'title' => $lang['strdefinition'],
1648
                        'url' => 'viewproperties.php',
1649
                        'urlvars' => ['subject' => 'view', 'view' => Decorator::field('view'), 'action' => 'definition'],
1650
                        'icon' => 'Definition',
1651
                    ],
1652
                    'rules' => [
1653
                        'title' => $lang['strrules'],
1654
                        'url' => 'rules.php',
1655
                        'urlvars' => ['subject' => 'view', 'view' => Decorator::field('view')],
1656
                        'help' => 'pg.rule',
1657
                        'icon' => 'Rules',
1658
                        'branch' => true,
1659
                    ],
1660
                    'privileges' => [
1661
                        'title' => $lang['strprivileges'],
1662
                        'url' => 'privileges.php',
1663
                        'urlvars' => ['subject' => 'view', 'view' => Decorator::field('view')],
1664
                        'help' => 'pg.privilege',
1665
                        'icon' => 'Privileges',
1666
                    ],
1667
                    'export' => [
1668
                        'title' => $lang['strexport'],
1669
                        'url' => 'viewproperties.php',
1670
                        'urlvars' => ['subject' => 'view', 'view' => Decorator::field('view'), 'action' => 'export'],
1671
                        'icon' => 'Export',
1672
                        'hide' => false,
1673
                    ],
1674
                ];
1675
1676
                break;
1677
            case 'matview':
1678
                $tabs = [
1679
                    'columns' => [
1680
                        'title' => $lang['strcolumns'],
1681
                        'url' => 'materializedviewproperties.php',
1682
                        'urlvars' => ['subject' => 'matview', 'matview' => Decorator::field('matview')],
1683
                        'icon' => 'Columns',
1684
                        'branch' => true,
1685
                    ],
1686
                    'browse' => [
1687
                        'title' => $lang['strbrowse'],
1688
                        'icon' => 'Columns',
1689
                        'url' => 'display.php',
1690
                        'urlvars' => [
1691
                            'action' => 'confselectrows',
1692
                            'return' => 'schema',
1693
                            'subject' => 'matview',
1694
                            'matview' => Decorator::field('matview'),
1695
                        ],
1696
                        'branch' => true,
1697
                    ],
1698
                    'select' => [
1699
                        'title' => $lang['strselect'],
1700
                        'icon' => 'Search',
1701
                        'url' => 'materializedviews.php',
1702
                        'urlvars' => ['action' => 'confselectrows', 'matview' => Decorator::field('matview')],
1703
                        'help' => 'pg.sql.select',
1704
                    ],
1705
                    'definition' => [
1706
                        'title' => $lang['strdefinition'],
1707
                        'url' => 'materializedviewproperties.php',
1708
                        'urlvars' => ['subject' => 'matview', 'matview' => Decorator::field('matview'), 'action' => 'definition'],
1709
                        'icon' => 'Definition',
1710
                    ],
1711
                    'indexes' => [
1712
                        'title' => $lang['strindexes'],
1713
                        'url' => 'indexes.php',
1714
                        'urlvars' => ['subject' => 'matview', 'matview' => Decorator::field('matview')],
1715
                        'help' => 'pg.index',
1716
                        'icon' => 'Indexes',
1717
                        'branch' => true,
1718
                    ],
1719
                    /*'constraints' => [
1720
                    'title' => $lang['strconstraints'],
1721
                    'url' => 'constraints.php',
1722
                    'urlvars' => ['subject' => 'matview', 'matview' => Decorator::field('matview')],
1723
                    'help' => 'pg.constraint',
1724
                    'icon' => 'Constraints',
1725
                    'branch' => true,
1726
                     */
1727
1728
                    'rules' => [
1729
                        'title' => $lang['strrules'],
1730
                        'url' => 'rules.php',
1731
                        'urlvars' => ['subject' => 'matview', 'matview' => Decorator::field('matview')],
1732
                        'help' => 'pg.rule',
1733
                        'icon' => 'Rules',
1734
                        'branch' => true,
1735
                    ],
1736
                    'privileges' => [
1737
                        'title' => $lang['strprivileges'],
1738
                        'url' => 'privileges.php',
1739
                        'urlvars' => ['subject' => 'matview', 'matview' => Decorator::field('matview')],
1740
                        'help' => 'pg.privilege',
1741
                        'icon' => 'Privileges',
1742
                    ],
1743
                    'export' => [
1744
                        'title' => $lang['strexport'],
1745
                        'url' => 'materializedviewproperties.php',
1746
                        'urlvars' => ['subject' => 'matview', 'matview' => Decorator::field('matview'), 'action' => 'export'],
1747
                        'icon' => 'Export',
1748
                        'hide' => false,
1749
                    ],
1750
                ];
1751
1752
                break;
1753
            case 'function':
1754
                $tabs = [
1755
                    'definition' => [
1756
                        'title' => $lang['strdefinition'],
1757
                        'url' => 'functions.php',
1758
                        'urlvars' => [
1759
                            'subject' => 'function',
1760
                            'function' => Decorator::field('function'),
1761
                            'function_oid' => Decorator::field('function_oid'),
1762
                            'action' => 'properties',
1763
                        ],
1764
                        'icon' => 'Definition',
1765
                    ],
1766
                    'privileges' => [
1767
                        'title' => $lang['strprivileges'],
1768
                        'url' => 'privileges.php',
1769
                        'urlvars' => [
1770
                            'subject' => 'function',
1771
                            'function' => Decorator::field('function'),
1772
                            'function_oid' => Decorator::field('function_oid'),
1773
                        ],
1774
                        'icon' => 'Privileges',
1775
                    ],
1776
                ];
1777
1778
                break;
1779
            case 'aggregate':
1780
                $tabs = [
1781
                    'definition' => [
1782
                        'title' => $lang['strdefinition'],
1783
                        'url' => 'aggregates.php',
1784
                        'urlvars' => [
1785
                            'subject' => 'aggregate',
1786
                            'aggrname' => Decorator::field('aggrname'),
1787
                            'aggrtype' => Decorator::field('aggrtype'),
1788
                            'action' => 'properties',
1789
                        ],
1790
                        'icon' => 'Definition',
1791
                    ],
1792
                ];
1793
1794
                break;
1795
            case 'role':
1796
                $tabs = [
1797
                    'definition' => [
1798
                        'title' => $lang['strdefinition'],
1799
                        'url' => 'roles.php',
1800
                        'urlvars' => [
1801
                            'subject' => 'role',
1802
                            'rolename' => Decorator::field('rolename'),
1803
                            'action' => 'properties',
1804
                        ],
1805
                        'icon' => 'Definition',
1806
                    ],
1807
                ];
1808
1809
                break;
1810
            case 'popup':
1811
                $tabs = [
1812
                    'sql' => [
1813
                        'title' => $lang['strsql'],
1814
                        'url' => '/src/views/sqledit.php',
1815
                        'urlvars' => ['action' => 'sql', 'subject' => 'schema'],
1816
                        'help' => 'pg.sql',
1817
                        'icon' => 'SqlEditor',
1818
                    ],
1819
                    'find' => [
1820
                        'title' => $lang['strfind'],
1821
                        'url' => '/src/views/sqledit.php',
1822
                        'urlvars' => ['action' => 'find', 'subject' => 'schema'],
1823
                        'icon' => 'Search',
1824
                    ],
1825
                ];
1826
1827
                break;
1828
            case 'column':
1829
                $tabs = [
1830
                    'properties' => [
1831
                        'title' => $lang['strcolprop'],
1832
                        'url' => 'colproperties.php',
1833
                        'urlvars' => [
1834
                            'subject' => 'column',
1835
                            'table' => Decorator::field('table'),
1836
                            'column' => Decorator::field('column'),
1837
                        ],
1838
                        'icon' => 'Column',
1839
                    ],
1840
                    'privileges' => [
1841
                        'title' => $lang['strprivileges'],
1842
                        'url' => 'privileges.php',
1843
                        'urlvars' => [
1844
                            'subject' => 'column',
1845
                            'table' => Decorator::field('table'),
1846
                            'column' => Decorator::field('column'),
1847
                        ],
1848
                        'help' => 'pg.privilege',
1849
                        'icon' => 'Privileges',
1850
                    ],
1851
                ];
1852
1853
                break;
1854
            case 'fulltext':
1855
                $tabs = [
1856
                    'ftsconfigs' => [
1857
                        'title' => $lang['strftstabconfigs'],
1858
                        'url' => 'fulltext.php',
1859
                        'urlvars' => ['subject' => 'schema'],
1860
                        'hide' => !$data->hasFTS(),
1861
                        'help' => 'pg.ftscfg',
1862
                        'tree' => true,
1863
                        'icon' => 'FtsCfg',
1864
                    ],
1865
                    'ftsdicts' => [
1866
                        'title' => $lang['strftstabdicts'],
1867
                        'url' => 'fulltext.php',
1868
                        'urlvars' => ['subject' => 'schema', 'action' => 'viewdicts'],
1869
                        'hide' => !$data->hasFTS(),
1870
                        'help' => 'pg.ftsdict',
1871
                        'tree' => true,
1872
                        'icon' => 'FtsDict',
1873
                    ],
1874
                    'ftsparsers' => [
1875
                        'title' => $lang['strftstabparsers'],
1876
                        'url' => 'fulltext.php',
1877
                        'urlvars' => ['subject' => 'schema', 'action' => 'viewparsers'],
1878
                        'hide' => !$data->hasFTS(),
1879
                        'help' => 'pg.ftsparser',
1880
                        'tree' => true,
1881
                        'icon' => 'FtsParser',
1882
                    ],
1883
                ];
1884
1885
                break;
1886
        }
1887
1888
        // Tabs hook's place
1889
        $plugin_functions_parameters = [
1890
            'tabs' => &$tabs,
1891
            'section' => $section,
1892
        ];
1893
        $plugin_manager->do_hook('tabs', $plugin_functions_parameters);
1894
1895
        return $tabs;
1896
    }
1897
1898
    /**
1899
     * Get the URL for the last active tab of a particular tab bar.
1900
     *
1901
     * @param $section
1902
     *
1903
     * @return null|mixed
1904
     */
1905
    public function getLastTabURL($section)
1906
    {
1907
        //$data = $this->getDatabaseAccessor();
1908
1909
        $tabs = $this->getNavTabs($section);
1910
1911
        if (isset($_SESSION['webdbLastTab'][$section], $tabs[$_SESSION['webdbLastTab'][$section]])) {
1912
            $tab = $tabs[$_SESSION['webdbLastTab'][$section]];
1913
        } else {
1914
            $tab = reset($tabs);
1915
        }
1916
        //$this->prtrace(['section' => $section, 'tabs' => $tabs, 'tab' => $tab]);
1917
        return isset($tab['url']) ? $tab : null;
1918
    }
1919
1920
    /**
1921
     * Do multi-page navigation.  Displays the prev, next and page options.
1922
     *
1923
     * @param $page - the page currently viewed
1924
     * @param $pages - the maximum number of pages
1925
     * @param $gets -  the parameters to include in the link to the wanted page
1926
     * @param $max_width - the number of pages to make available at any one time (default = 20)
1927
     */
0 ignored issues
show
Documentation Bug introduced by
The doc comment - at position 0 could not be parsed: Unknown type name '-' at position 0 in -.
Loading history...
1928
    public function printPages($page, $pages, $gets, $max_width = 20)
1929
    {
1930
        $lang = $this->lang;
1931
1932
        $window = 10;
1933
1934
        if ($page < 0 || $page > $pages) {
1935
            return;
1936
        }
1937
1938
        if ($pages < 0) {
1939
            return;
1940
        }
1941
1942
        if ($max_width <= 0) {
1943
            return;
1944
        }
1945
1946
        unset($gets['page']);
1947
        $url = http_build_query($gets);
1948
1949
        if ($pages > 1) {
1950
            echo "<p style=\"text-align: center\">\n";
1951
            if ($page != 1) {
1952
                echo "<a class=\"pagenav\" href=\"?{$url}&amp;page=1\">{$lang['strfirst']}</a>\n";
1953
                $temp = $page - 1;
1954
                echo "<a class=\"pagenav\" href=\"?{$url}&amp;page={$temp}\">{$lang['strprev']}</a>\n";
1955
            }
1956
1957
            if ($page <= $window) {
1958
                $min_page = 1;
1959
                $max_page = min(2 * $window, $pages);
1960
            } elseif ($page > $window && $pages >= $page + $window) {
1961
                $min_page = ($page - $window) + 1;
1962
                $max_page = $page + $window;
1963
            } else {
1964
                $min_page = ($page - (2 * $window - ($pages - $page))) + 1;
1965
                $max_page = $pages;
1966
            }
1967
1968
            // Make sure min_page is always at least 1
1969
            // and max_page is never greater than $pages
1970
            $min_page = max($min_page, 1);
1971
            $max_page = min($max_page, $pages);
1972
1973
            for ($i = $min_page; $i <= $max_page; ++$i) {
1974
                #if ($i != $page) echo "<a class=\"pagenav\" href=\"?{$url}&amp;page={$i}\">$i</a>\n";
0 ignored issues
show
Coding Style introduced by
Perl-style comments are not allowed. Use "// Comment." or "/* comment */" instead.
Loading history...
1975
                if ($i != $page) {
1976
                    echo "<a class=\"pagenav\" href=\"display.php?{$url}&amp;page={$i}\">${i}</a>\n";
1977
                } else {
1978
                    echo "${i}\n";
1979
                }
1980
            }
1981
            if ($page != $pages) {
1982
                $temp = $page + 1;
1983
                echo "<a class=\"pagenav\" href=\"display.php?{$url}&amp;page={$temp}\">{$lang['strnext']}</a>\n";
1984
                echo "<a class=\"pagenav\" href=\"display.php?{$url}&amp;page={$pages}\">{$lang['strlast']}</a>\n";
1985
            }
1986
            echo "</p>\n";
1987
        }
1988
    }
1989
1990
    /**
1991
     * Converts a PHP.INI size variable to bytes.  Taken from publically available
1992
     * function by Chris DeRose, here: http://www.php.net/manual/en/configuration.directives.php#ini.file-uploads.
1993
     *
1994
     * @param $strIniSize The PHP.INI variable
1995
     *
1996
     * @return size in bytes, false on failure
1997
     */
1998
    public function inisizeToBytes($strIniSize)
1999
    {
2000
        // This function will take the string value of an ini 'size' parameter,
2001
        // and return a double (64-bit float) representing the number of bytes
2002
        // that the parameter represents. Or false if $strIniSize is unparseable.
2003
        $a_IniParts = [];
2004
2005
        if (!is_string($strIniSize)) {
2006
            return false;
2007
        }
2008
2009
        if (!preg_match('/^(\d+)([bkm]*)$/i', $strIniSize, $a_IniParts)) {
2010
            return false;
2011
        }
2012
2013
        $nSize = (float) $a_IniParts[1];
2014
        $strUnit = strtolower($a_IniParts[2]);
2015
2016
        switch ($strUnit) {
2017
            case 'm':
2018
                return $nSize * (float) 1048576;
2019
            case 'k':
2020
                return $nSize * (float) 1024;
2021
            case 'b':
2022
            default:
2023
                return $nSize;
2024
        }
2025
    }
2026
2027
    public function getRequestVars($subject = '')
1 ignored issue
show
Coding Style introduced by
Missing function doc comment
Loading history...
2028
    {
2029
        $v = [];
2030
        if (!empty($subject)) {
2031
            $v['subject'] = $subject;
2032
        }
2033
2034
        if ($this->_server_id !== null && $subject != 'root') {
2035
            $v['server'] = $this->_server_id;
2036
            if ($this->_database !== null && $subject != 'server') {
2037
                $v['database'] = $this->_database;
2038
                if (isset($_REQUEST['schema']) && $subject != 'database') {
2039
                    $v['schema'] = $_REQUEST['schema'];
2040
                }
2041
            }
2042
        }
2043
        //$this->prtrace($v);
2044
        return $v;
2045
    }
2046
2047
    public function icon($icon)
1 ignored issue
show
Coding Style introduced by
Missing function doc comment
Loading history...
2048
    {
2049
        if (is_string($icon)) {
2050
            $path = "/images/themes/{$this->conf['theme']}/{$icon}";
2051
            if (file_exists(\BASE_PATH.$path.'.png')) {
2052
                return SUBFOLDER.$path.'.png';
2053
            }
2054
2055
            if (file_exists(\BASE_PATH.$path.'.gif')) {
2056
                return SUBFOLDER.$path.'.gif';
2057
            }
2058
2059
            if (file_exists(\BASE_PATH.$path.'.ico')) {
2060
                return SUBFOLDER.$path.'.ico';
2061
            }
2062
2063
            $path = "/images/themes/default/{$icon}";
2064
            if (file_exists(\BASE_PATH.$path.'.png')) {
2065
                return SUBFOLDER.$path.'.png';
2066
            }
2067
2068
            if (file_exists(\BASE_PATH.$path.'.gif')) {
2069
                return SUBFOLDER.$path.'.gif';
2070
            }
2071
2072
            if (file_exists(\BASE_PATH.$path.'.ico')) {
2073
                return SUBFOLDER.$path.'.ico';
2074
            }
2075
        } else {
2076
            // Icon from plugins
2077
            $path = "/plugins/{$icon[0]}/images/{$icon[1]}";
2078
            if (file_exists(\BASE_PATH.$path.'.png')) {
2079
                return SUBFOLDER.$path.'.png';
2080
            }
2081
2082
            if (file_exists(\BASE_PATH.$path.'.gif')) {
2083
                return SUBFOLDER.$path.'.gif';
2084
            }
2085
2086
            if (file_exists(\BASE_PATH.$path.'.ico')) {
2087
                return SUBFOLDER.$path.'.ico';
2088
            }
2089
        }
2090
2091
        return '';
2092
    }
2093
2094
    /**
2095
     * Function to escape command line parameters.
2096
     *
2097
     * @param string $str The string to escape
2098
     *
2099
     * @return string The escaped string
2100
     */
2101
    public function escapeShellArg($str)
2102
    {
2103
        //$data = $this->getDatabaseAccessor();
2104
        $lang = $this->lang;
2105
2106
        if (strtoupper(substr(PHP_OS, 0, 3)) === 'WIN') {
2107
            // Due to annoying PHP bugs, shell arguments cannot be escaped
2108
            // (command simply fails), so we cannot allow complex objects
2109
            // to be dumped.
2110
            if (preg_match('/^[_.[:alnum:]]+$/', $str)) {
2111
                return $str;
2112
            }
2113
2114
            return $this->halt($lang['strcannotdumponwindows']);
2115
        }
2116
2117
        return escapeshellarg($str);
2118
    }
2119
2120
    /**
2121
     * Function to escape command line programs.
2122
     *
2123
     * @param string $str The string to escape
2124
     *
2125
     * @return string The escaped string
2126
     */
2127
    public function escapeShellCmd($str)
2128
    {
2129
        $data = $this->getDatabaseAccessor();
2130
2131
        if (strtoupper(substr(PHP_OS, 0, 3)) === 'WIN') {
2132
            $data->fieldClean($str);
2133
2134
            return '"'.$str.'"';
2135
        }
2136
2137
        return escapeshellcmd($str);
2138
    }
2139
2140
    /**
2141
     * Save the given SQL script in the history
2142
     * of the database and server.
2143
     *
2144
     * @param $script the SQL script to save
2145
     */
2146
    public function saveScriptHistory($script)
2147
    {
2148
        list($usec, $sec) = explode(' ', microtime());
2149
        $time = ((float) $usec + (float) $sec);
2150
        $_SESSION['history'][$_REQUEST['server']][$_REQUEST['database']]["${time}"] = [
2151
            'query' => $script,
2152
            'paginate' => !isset($_REQUEST['paginate']) ? 'f' : 't',
2153
            'queryid' => $time,
2154
        ];
2155
    }
2156
2157
    /*
2158
     * Output dropdown list to select server and
2159
     * databases form the popups windows.
2160
     * @param $onchange Javascript action to take when selections change.
2161
     */
2162
    public function printConnection($onchange, $do_print = true)
1 ignored issue
show
Coding Style introduced by
You must use "/**" style comments for a function comment
Loading history...
2163
    {
2164
        $lang = $this->lang;
2165
2166
        $connection_html = "<table class=\"printconnection\" style=\"width: 100%\"><tr><td class=\"popup_select1\">\n";
2167
2168
        $servers = $this->getServers();
2169
        $forcedserver = null;
2170
        if (count($servers) === 1) {
2171
            $forcedserver = $this->_server_id;
2172
            $connection_html .= '<input type="hidden" readonly="readonly" value="'.$this->_server_id.'" name="server">';
2173
        } else {
2174
            $connection_html .= '<label>';
2175
            $connection_html .= $this->printHelp($lang['strserver'], 'pg.server', false);
2176
            $connection_html .= ': </label>';
2177
            $connection_html .= " <select name=\"server\" {$onchange}>\n";
2178
            foreach ($servers as $info) {
2179
                if (empty($info['username'])) {
2180
                    continue;
2181
                }
2182
                $selected = isset($_REQUEST['server']) && $info['id'] == $_REQUEST['server'] ? ' selected="selected"' : '';
2183
                // not logged on this server
2184
                $connection_html .= '<option value="'.htmlspecialchars($info['id']).'" '.$selected.'>';
2185
                $connection_html .= htmlspecialchars("{$info['desc']} ({$info['id']})");
2186
                $connection_html .= "</option>\n";
2187
            }
2188
            $connection_html .= "</select>\n";
2189
        }
2190
2191
        $connection_html .= "</td><td class=\"popup_select2\" style=\"text-align: right\">\n";
2192
2193
        if (count($servers) === 1 && isset($servers[$this->_server_id]['useonlydefaultdb']) && $servers[$this->_server_id]['useonlydefaultdb'] === true) {
2194
            $connection_html .= '<input type="hidden" name="database" value="'.htmlspecialchars($servers[$this->_server_id]['defaultdb'])."\" />\n";
2195
        } else {
2196
            // Get the list of all databases
2197
            $data = $this->getDatabaseAccessor();
2198
            $databases = $data->getDatabases();
2199
            if ($databases->recordCount() > 0) {
2200
                $connection_html .= '<label>';
2201
                $connection_html .= $this->printHelp($lang['strdatabase'], 'pg.database', false);
2202
                $connection_html .= ": <select name=\"database\" {$onchange}>\n";
2203
2204
                //if no database was selected, user should select one
2205
                if (!isset($_REQUEST['database'])) {
2206
                    $connection_html .= "<option value=\"\">--</option>\n";
2207
                }
2208
2209
                while (!$databases->EOF) {
2210
                    $dbname = $databases->fields['datname'];
2211
                    $dbselected = isset($_REQUEST['database']) && $dbname == $_REQUEST['database'] ? ' selected="selected"' : '';
2212
                    $connection_html .= '<option value="'.htmlspecialchars($dbname).'" '.$dbselected.'>'.htmlspecialchars($dbname)."</option>\n";
2213
2214
                    $databases->moveNext();
2215
                }
2216
                $connection_html .= "</select></label>\n";
2217
            } else {
2218
                $server_info = $this->misc->getServerInfo();
2219
                $connection_html .= '<input type="hidden" name="database" value="'.htmlspecialchars($server_info['defaultdb'])."\" />\n";
2220
            }
2221
        }
2222
2223
        $connection_html .= "</td></tr></table>\n";
2224
2225
        if ($do_print) {
2226
            echo $connection_html;
2227
        } else {
2228
            return $connection_html;
2229
        }
2230
    }
2231
2232
    /**
2233
     * returns an array representing FKs definition for a table, sorted by fields
1 ignored issue
show
Coding Style introduced by
Doc comment short description must start with a capital letter
Loading history...
2234
     * or by constraint.
2235
     *
2236
     * @param $table The table to retrieve FK contraints from
2237
     * @returns the array of FK definition:
0 ignored issues
show
Coding Style introduced by
Tag cannot be grouped with parameter tags in a doc comment
Loading history...
2238
     *   array(
2239
     *     'byconstr' => array(
2240
     *       constrain id => array(
2241
     *         confrelid => foreign relation oid
2242
     *         f_schema => foreign schema name
2243
     *         f_table => foreign table name
2244
     *         pattnums => array of parent's fields nums
2245
     *         pattnames => array of parent's fields names
2246
     *         fattnames => array of foreign attributes names
2247
     *       )
2248
     *     ),
2249
     *     'byfield' => array(
2250
     *       attribute num => array (constraint id, ...)
2251
     *     ),
2252
     *     'code' => HTML/js code to include in the page for auto-completion
2253
     *   )
2254
     */
2255
    public function getAutocompleteFKProperties($table)
2256
    {
2257
        $data = $this->getDatabaseAccessor();
2258
2259
        $fksprops = [
2260
            'byconstr' => [],
2261
            'byfield' => [],
2262
            'code' => '',
2263
        ];
2264
2265
        $constrs = $data->getConstraintsWithFields($table);
2266
2267
        if (!$constrs->EOF) {
2268
            $conrelid = $constrs->fields['conrelid'];
2269
            while (!$constrs->EOF) {
2270
                if ($constrs->fields['contype'] == 'f') {
2271
                    if (!isset($fksprops['byconstr'][$constrs->fields['conid']])) {
2272
                        $fksprops['byconstr'][$constrs->fields['conid']] = [
2273
                            'confrelid' => $constrs->fields['confrelid'],
2274
                            'f_table' => $constrs->fields['f_table'],
2275
                            'f_schema' => $constrs->fields['f_schema'],
2276
                            'pattnums' => [],
2277
                            'pattnames' => [],
2278
                            'fattnames' => [],
2279
                        ];
2280
                    }
2281
2282
                    $fksprops['byconstr'][$constrs->fields['conid']]['pattnums'][] = $constrs->fields['p_attnum'];
2283
                    $fksprops['byconstr'][$constrs->fields['conid']]['pattnames'][] = $constrs->fields['p_field'];
2284
                    $fksprops['byconstr'][$constrs->fields['conid']]['fattnames'][] = $constrs->fields['f_field'];
2285
2286
                    if (!isset($fksprops['byfield'][$constrs->fields['p_attnum']])) {
2287
                        $fksprops['byfield'][$constrs->fields['p_attnum']] = [];
2288
                    }
2289
2290
                    $fksprops['byfield'][$constrs->fields['p_attnum']][] = $constrs->fields['conid'];
2291
                }
2292
                $constrs->moveNext();
2293
            }
2294
2295
            $fksprops['code'] = "<script type=\"text/javascript\">\n";
2296
            $fksprops['code'] .= "var constrs = {};\n";
2297
            foreach ($fksprops['byconstr'] as $conid => $props) {
2298
                $fksprops['code'] .= "constrs.constr_{$conid} = {\n";
2299
                $fksprops['code'] .= 'pattnums: ['.implode(',', $props['pattnums'])."],\n";
2300
                $fksprops['code'] .= "f_table:'".addslashes(htmlentities($props['f_table'], ENT_QUOTES, 'UTF-8'))."',\n";
2301
                $fksprops['code'] .= "f_schema:'".addslashes(htmlentities($props['f_schema'], ENT_QUOTES, 'UTF-8'))."',\n";
2302
                $_ = '';
2303
                foreach ($props['pattnames'] as $n) {
2304
                    $_ .= ",'".htmlentities($n, ENT_QUOTES, 'UTF-8')."'";
2305
                }
2306
                $fksprops['code'] .= 'pattnames: ['.substr($_, 1)."],\n";
2307
2308
                $_ = '';
2309
                foreach ($props['fattnames'] as $n) {
2310
                    $_ .= ",'".htmlentities($n, ENT_QUOTES, 'UTF-8')."'";
2311
                }
2312
2313
                $fksprops['code'] .= 'fattnames: ['.substr($_, 1)."]\n";
2314
                $fksprops['code'] .= "};\n";
2315
            }
2316
2317
            $fksprops['code'] .= "var attrs = {};\n";
2318
            foreach ($fksprops['byfield'] as $attnum => $cstrs) {
2319
                $fksprops['code'] .= "attrs.attr_{$attnum} = [".implode(',', $fksprops['byfield'][$attnum])."];\n";
2320
            }
2321
2322
            $fksprops['code'] .= "var table='".addslashes(htmlentities($table, ENT_QUOTES, 'UTF-8'))."';";
2323
            $fksprops['code'] .= "var server='".htmlentities($_REQUEST['server'], ENT_QUOTES, 'UTF-8')."';";
2324
            $fksprops['code'] .= "var database='".addslashes(htmlentities($_REQUEST['database'], ENT_QUOTES, 'UTF-8'))."';";
2325
            $fksprops['code'] .= "var subfolder='".SUBFOLDER."';";
2326
            $fksprops['code'] .= "</script>\n";
2327
2328
            $fksprops['code'] .= '<div id="fkbg"></div>';
2329
            $fksprops['code'] .= '<div id="fklist"></div>';
2330
            $fksprops['code'] .= '<script src="'.SUBFOLDER.'/js/ac_insert_row.js" type="text/javascript"></script>';
2331
        } else /* we have no foreign keys on this table */
0 ignored issues
show
Coding Style introduced by
Expected "} else \n"; found " else /* we have no foreign keys on this table */\n {\n"
Loading history...
2332
        {
2333
            return false;
2334
        }
2335
2336
        return $fksprops;
2337
    }
2338
}
2339