Passed
Push — master ( 442876...4ec1bc )
by Felipe
15:55 queued 10:33
created

Misc::setCurrentSchema()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 12
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
eloc 7
nc 2
nop 1
dl 0
loc 12
rs 9.4285
c 0
b 0
f 0
1
<?php
2
/*
0 ignored issues
show
Coding Style introduced by
You must use "/**" style comments for a file comment
Loading history...
3
 * PHPPgAdmin v6.0.0-beta.30
4
 */
5
namespace PHPPgAdmin;
6
7
use \PHPPgAdmin\Decorators\Decorator;
8
9
/**
10
 * Class to hold various commonly used functions
11
 *
12
 * $Id: Misc.php,v 1.171 2008/03/17 21:35:48 ioguix Exp $
13
 */
5 ignored issues
show
Coding Style introduced by
Missing @category tag in class comment
Loading history...
Coding Style introduced by
Missing @package 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...
14
15
class Misc
16
{
17
    use \PHPPgAdmin\HelperTrait;
18
19
    private $_connection       = null;
20
    private $_no_db_connection = false;
21
    private $_reload_browser   = false;
22
    private $_data             = null;
23
    private $_database         = null;
24
    private $_server_id        = null;
25
    private $_server_info      = null;
26
    private $_error_msg        = '';
27
28
    public $appLangFiles    = [];
29
    public $appName         = '';
30
    public $appVersion      = '';
31
    public $form            = '';
32
    public $href            = '';
33
    public $controller_name = 'Misc';
34
    public $lang            = [];
35
36
    protected $container = null;
37
38
    /**
1 ignored issue
show
Coding Style introduced by
Missing short description in doc comment
Loading history...
39
     * @param \Slim\Container  $container  The container
40
     */
41
    public function __construct(\Slim\Container $container)
42
    {
43
        $this->container = $container;
44
45
        $this->lang = $container->get('lang');
46
        $this->conf = $container->get('conf');
47
        //$this->view           = $container->get('view');
48
        $this->plugin_manager = $container->get('plugin_manager');
49
        $this->appLangFiles   = $container->get('appLangFiles');
50
51
        $this->appName          = $container->get('settings')['appName'];
52
        $this->appVersion       = $container->get('settings')['appVersion'];
53
        $this->postgresqlMinVer = $container->get('settings')['postgresqlMinVer'];
54
        $this->phpMinVer        = $container->get('settings')['phpMinVer'];
55
56
        $base_version = $container->get('settings')['base_version'];
57
58
        // Check for config file version mismatch
59
        if (!isset($this->conf['version']) || $base_version > $this->conf['version']) {
60
            $container->get('utils')->addError($this->lang['strbadconfig']);
61
        }
62
63
        // Check database support is properly compiled in
64
        if (!function_exists('pg_connect')) {
65
            $container->get('utils')->addError($this->lang['strnotloaded']);
66
        }
67
68
        // Check the version of PHP
69
        if (version_compare(phpversion(), $this->phpMinVer, '<')) {
70
            $container->get('utils')->addError(sprintf('Version of PHP not supported. Please upgrade to version %s or later.', $this->phpMinVer));
71
        }
72
73
        if (count($this->conf['servers']) === 1) {
74
            $info             = $this->conf['servers'][0];
75
            $this->_server_id = $info['host'] . ':' . $info['port'] . ':' . $info['sslmode'];
76
        } elseif (isset($_REQUEST['server'])) {
77
            $this->_server_id = $_REQUEST['server'];
78
        } elseif (isset($_SESSION['webdbLogin']) && count($_SESSION['webdbLogin']) > 0) {
79
            $this->_server_id = array_keys($_SESSION['webdbLogin'])[0];
80
        }
81
    }
82
83
    /**
84
     * Sets the view instance property of this class
85
     * @param \Slim\Views\Twig $view [description]
86
     */
87
    public function setView(\Slim\Views\Twig $view)
88
    {
89
        $this->view = $view;
90
    }
91
92
    /**
93
     * Adds or modifies a key in the $conf instance property of this class
94
     * @param string $key   name of the key to set
95
     * @param mixed $value value of the key to set
96
     *
97
     * @return $this
98
     */
99
    public function setConf(string $key, $value)
100
    {
101
        $this->conf[$key] = $value;
102
        return $this;
103
    }
104
105
    /**
106
     * 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...
107
     * @param  mixed $key value of the key to be retrieved. If null, the full array is returnes
108
     *
109
     * @return mixed the whole $conf array, the value of $conf[key] or null if said key does not exist
110
     */
111
    public function getConf($key = null)
112
    {
113
        if ($key === null) {
114
            return $this->conf;
115
        } elseif (array_key_exists($key, $this->conf)) {
116
            return $this->conf[$key];
117
        }
118
        return null;
119
    }
120
121
    public function getServerId()
1 ignored issue
show
Coding Style introduced by
Missing function doc comment
Loading history...
122
    {
123
        return $this->_server_id;
124
    }
125
126
    /**
127
     * Displays link to the context help.
128
     *
129
     * @param $str   the string that the context help is related to (already escaped)
130
     * @param $help  help section identifier
131
     * @param $do_print true to echo, false to return
132
     */
133
    public function printHelp($str, $help = null, $do_print = true)
134
    {
135
        //\PC::debug(['str' => $str, 'help' => $help], 'printHelp');
136
        if ($help !== null) {
137
            $helplink = $this->getHelpLink($help);
138
            $str .= '<a class="help" href="' . $helplink . '" title="' . $this->lang['strhelp'] . '" target="phppgadminhelp">' . $this->lang['strhelpicon'] . '</a>';
139
        }
140
        if ($do_print) {
141
            echo $str;
142
        } else {
143
            return $str;
144
        }
145
    }
146
147
    public function getHelpLink($help)
1 ignored issue
show
Coding Style introduced by
Missing function doc comment
Loading history...
148
    {
149
        return htmlspecialchars(SUBFOLDER . '/help?help=' . urlencode($help) . '&server=' . urlencode($this->getServerId()));
150
    }
151
152
    /**
153
     * Internally sets the reload browser property
154
     *
155
     * @param boolean $flag sets internal $_reload_browser var which will be passed to the footer methods
156
     *
157
     * @return $this
158
     */
159
    public function setReloadBrowser($flag)
160
    {
161
        $this->_reload_browser = boolval($flag);
162
        return $this;
163
    }
164
165
    public function getReloadBrowser()
1 ignored issue
show
Coding Style introduced by
Missing function doc comment
Loading history...
166
    {
167
        return $this->_reload_browser;
168
    }
169
170
    /**
171
     * Default Error Handler. This will be called with the following params
172
     *
173
     * @param $dbms         the RDBMS you are connecting to
174
     * @param $fn           the name of the calling function (in uppercase)
175
     * @param $errno        the native error number from the database
176
     * @param $errmsg       the native error msg from the database
177
     * @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...
178
     * @param $p2           parameter 2
179
     * @param $thisConnection connection
180
     *
181
     * @throws \PHPPgAdmin\ADOdbException
182
     * @internal param $P2 $fn specific parameter - see below
183
     */
184
    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...
185
    {
186
        if (error_reporting() == 0) {
187
            return;
188
        }
189
190
        $backtrace = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS, 2);
191
192
        $btarray0 = [
193
            'msg'      => 'ADOdbException at ',
194
            'class'    => $backtrace[1]['class'],
195
            'type'     => $backtrace[1]['type'],
196
            'function' => $backtrace[1]['function'],
197
            'spacer'   => ' ',
198
            'line'     => $backtrace[0]['line'],
199
        ];
200
201
        $errmsg = htmlspecialchars(\PHPPgAdmin\HelperTrait::br2ln($errmsg));
202
        $p1     = htmlspecialchars(\PHPPgAdmin\HelperTrait::br2ln($p1));
203
        $p2     = htmlspecialchars(\PHPPgAdmin\HelperTrait::br2ln($p2));
204
        switch ($fn) {
205
            case 'EXECUTE':
206
                $sql         = $p1;
207
                $inputparams = $p2;
208
209
                $error_msg = '<p><b>strsqlerror</b><br />' . nl2br($errmsg) . '</p> <p><b>SQL:</b><br />' . nl2br($sql) . '</p>	';
210
211
                echo '<table class="error" cellpadding="5"><tr><td>' . nl2br($error_msg) . '</td></tr></table><br />' . "\n";
212
213
                break;
214
215
            case 'PCONNECT':
216
            case 'CONNECT':
217
                // do nothing;
218
                break;
219
            default:
220
                $s = "$dbms error: [$errno: $errmsg] in $fn($p1, $p2)\n";
221
                echo "<table class=\"error\" cellpadding=\"5\"><tr><td>{$s}</td></tr></table><br />\n";
222
                break;
223
        }
224
225
        $tag = implode('', $btarray0);
226
227
        \PC::debug(['errno' => $errno, 'fn' => $fn, 'errmsg' => $errmsg], $tag);
228
229
        throw new \PHPPgAdmin\ADOdbException($dbms, $fn, $errno, $errmsg, $p1, $p2, $thisConnection);
230
    }
231
232
    public function getContainer()
1 ignored issue
show
Coding Style introduced by
Missing function doc comment
Loading history...
233
    {
234
        return $this->container;
235
    }
236
237
    /**
238
     * 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...
239
     *
240
     * @param boolean $flag true or false to allow unconnected clients to access the view
241
     *
242
     * @return $this
243
     */
244
    public function setNoDBConnection($flag)
245
    {
246
        $this->_no_db_connection = boolval($flag);
247
        return $this;
248
    }
249
250
    public function getNoDBConnection()
1 ignored issue
show
Coding Style introduced by
Missing function doc comment
Loading history...
251
    {
252
        return $this->_no_db_connection;
253
    }
254
255
    /**
256
     * Sets the last error message to display afterwards instead of just dying with the error msg
257
     * @param string $msg error message string
258
     */
259
    public function setErrorMsg($msg)
260
    {
261
        $this->_error_msg = $msg;
262
        return $this;
263
    }
264
265
    public function getErrorMsg()
1 ignored issue
show
Coding Style introduced by
Missing function doc comment
Loading history...
266
    {
267
        return $this->_error_msg;
268
    }
269
270
    /**
271
     * Creates a database accessor
272
     *
273
     * @param string $database the name of the database
274
     * @param mixed   $server_id the id of the server
275
     *
276
     * @return null
277
     */
278
    public function getDatabaseAccessor($database = '', $server_id = null)
279
    {
280
        $lang = $this->lang;
281
282
        if ($server_id !== null) {
283
            $this->_server_id = $server_id;
284
        }
285
286
        $server_info = $this->getServerInfo($this->_server_id);
287
288
        if ($this->_no_db_connection || !isset($server_info['username'])) {
289
            return null;
290
        }
291
292
        if ($this->_data === null) {
293
            try {
294
                $_connection = $this->getConnection($database, $this->_server_id);
295
            } catch (\Exception $e) {
296
                $this->setServerInfo(null, null, $this->_server_id);
297
                $this->setNoDBConnection(true);
298
                $this->setErrorMsg($e->getMessage());
299
                return null;
300
            }
301
302
            //$this->prtrace('_connection', $_connection);
303
            if (!$_connection) {
304
                $this->container->utils->addError($lang['strloginfailed']);
305
                $this->setErrorMsg($lang['strloginfailed']);
306
                return null;
307
            }
308
            // Get the name of the database driver we need to use.
309
            // The description of the server is returned in $platform.
310
            $_type = $_connection->getDriver($platform);
311
312
            //$this->prtrace(['type' => $_type, 'platform' => $platform, 'pgVersion' => $_connection->conn->pgVersion]);
313
314
            if ($_type === null) {
315
                $errormsg = sprintf($lang['strpostgresqlversionnotsupported'], $this->postgresqlMinVer);
316
                $this->container->utils->addError($errormsg);
317
                $this->setErrorMsg($errormsg);
318
                return null;
319
            }
320
            $_type = '\PHPPgAdmin\Database\\' . $_type;
321
322
            $this->setServerInfo('platform', $platform, $this->_server_id);
323
            $this->setServerInfo('pgVersion', $_connection->conn->pgVersion, $this->_server_id);
324
325
            // Create a database wrapper class for easy manipulation of the
326
            // connection.
327
328
            $this->_data              = new $_type($_connection->conn, $this->conf);
329
            $this->_data->platform    = $_connection->platform;
330
            $this->_data->server_info = $server_info;
331
            $this->_data->conf        = $this->conf;
332
            $this->_data->lang        = $this->lang;
333
334
            //$this->_data->getHelpPages();
335
336
            //$this->prtrace('help_page has ' . count($this->_data->help_page) . ' items');
337
338
            /* we work on UTF-8 only encoding */
339
            $this->_data->execute("SET client_encoding TO 'UTF-8'");
340
341
            if ($this->_data->hasByteaHexDefault()) {
342
                $this->_data->execute('SET bytea_output TO escape');
343
            }
344
        }
345
346
        if ($this->_no_db_connection === false && $this->getDatabase() !== null && isset($_REQUEST['schema'])) {
347
            $status = $this->_data->setSchema($_REQUEST['schema']);
348
349
            if ($status != 0) {
350
                $this->container->utils->addError($this->lang['strbadschema']);
351
                $this->setErrorMsg($this->lang['strbadschema']);
352
                return null;
353
            }
354
        }
355
356
        return $this->_data;
357
    }
358
359
    public function getConnection($database = '', $server_id = null)
1 ignored issue
show
Coding Style introduced by
Missing function doc comment
Loading history...
360
    {
361
        $lang = $this->lang;
362
363
        if ($this->_connection === null) {
364
            if ($server_id !== null) {
365
                $this->_server_id = $server_id;
366
            }
367
            $server_info     = $this->getServerInfo($this->_server_id);
368
            $database_to_use = $this->getDatabase($database);
369
370
            // Perform extra security checks if this config option is set
371
            if ($this->conf['extra_login_security']) {
372
                // Disallowed logins if extra_login_security is enabled.
373
                // These must be lowercase.
374
                $bad_usernames = [
375
                    'pgsql'         => 'pgsql',
376
                    'postgres'      => 'postgres',
377
                    'root'          => 'root',
378
                    'administrator' => 'administrator',
379
                ];
380
381
                if (isset($server_info['username']) && array_key_exists(strtolower($server_info['username']), $bad_usernames)) {
382
                    $msg = $lang['strlogindisallowed'];
383
                    throw new \Exception($msg);
384
                }
385
386
                if (!isset($server_info['password']) || $server_info['password'] == '') {
387
                    $msg = $lang['strlogindisallowed'];
388
389
                    throw new \Exception($msg);
390
                }
391
            }
392
393
            try {
394
                // Create the connection object and make the connection
395
                $this->_connection = new \PHPPgAdmin\Database\Connection(
396
                    $server_info['host'],
397
                    $server_info['port'],
398
                    $server_info['sslmode'],
399
                    $server_info['username'],
400
                    $server_info['password'],
401
                    $database_to_use
402
                );
403
            } catch (\PHPPgAdmin\ADOdbException $e) {
404
                throw new \Exception($lang['strloginfailed']);
405
            }
406
        }
407
        return $this->_connection;
408
    }
409
410
    /**
411
     * Validate and retrieve information on a server.
412
     * If the parameter isn't supplied then the currently
413
     * connected server is returned.
414
     *
415
     * @param $server_id A server identifier (host:port)
416
     *
417
     * @return An associative array of server properties
418
     */
419
    public function getServerInfo($server_id = null)
420
    {
421
422
        //\PC::debug(['$server_id' => $server_id]);
423
424
        if ($server_id !== null) {
425
            $this->_server_id = $server_id;
426
        } elseif ($this->_server_info !== null) {
427
            return $this->_server_info;
428
        }
429
430
        // Check for the server in the logged-in list
431
        if (isset($_SESSION['webdbLogin'][$this->_server_id])) {
432
            $this->_server_info = $_SESSION['webdbLogin'][$this->_server_id];
433
            return $this->_server_info;
434
        }
435
436
        // Otherwise, look for it in the conf file
437
        foreach ($this->conf['servers'] as $idx => $info) {
438
            if ($this->_server_id == $info['host'] . ':' . $info['port'] . ':' . $info['sslmode']) {
439
                if (isset($info['username'])) {
440
                    $this->setServerInfo(null, $info, $this->_server_id);
441
                } elseif (isset($_SESSION['sharedUsername'])) {
442
                    $info['username'] = $_SESSION['sharedUsername'];
443
                    $info['password'] = $_SESSION['sharedPassword'];
444
                    $this->setReloadBrowser(true);
445
                    $this->setServerInfo(null, $info, $this->_server_id);
446
                }
447
                $this->_server_info = $info;
448
                return $this->_server_info;
449
            }
450
        }
451
452
        if ($server_id === null) {
453
            $this->_server_info = null;
454
            return $this->_server_info;
455
        }
456
457
        $this->prtrace('Invalid server param');
458
        $this->_server_info = null;
459
        // Unable to find a matching server, are we being hacked?
460
        return $this->halt($this->lang['strinvalidserverparam']);
461
    }
462
463
    /**
464
     * Set server information.
465
     * @param $key parameter name to set, or null to replace all
466
     *             params with the assoc-array in $value.
467
     * @param $value the new value, or null to unset the parameter
468
     * @param $server_id the server identifier, or null for current server
469
     */
470
    public function setServerInfo($key, $value, $server_id = null)
471
    {
472
        //\PC::debug('setsetverinfo');
473
        if ($server_id === null && isset($_REQUEST['server'])) {
474
            $server_id = $_REQUEST['server'];
475
        }
476
477
        if ($key === null) {
478
            if ($value === null) {
479
                unset($_SESSION['webdbLogin'][$server_id]);
480
            } else {
481
                //\PC::debug(['server_id' => $server_id, 'value' => $value], 'webdbLogin null key');
482
                $_SESSION['webdbLogin'][$server_id] = $value;
483
            }
484
        } else {
485
            if ($value === null) {
486
                unset($_SESSION['webdbLogin'][$server_id][$key]);
487
            } else {
488
                //\PC::debug(['server_id' => $server_id, 'key' => $key, 'value' => $value], __FILE__ . ' ' . __LINE__ . ' webdbLogin key ' . $key);
489
                $_SESSION['webdbLogin'][$server_id][$key] = $value;
490
            }
491
        }
492
    }
493
494
    public function getDatabase($database = '')
1 ignored issue
show
Coding Style introduced by
Missing function doc comment
Loading history...
495
    {
496
        if ($this->_server_id === null && !isset($_REQUEST['database'])) {
497
            return null;
498
        }
499
500
        $server_info = $this->getServerInfo($this->_server_id);
501
502
        if ($this->_server_id !== null && isset($server_info['useonlydefaultdb']) && $server_info['useonlydefaultdb'] === true) {
503
            $this->_database = $server_info['defaultdb'];
504
        } elseif ($database !== '') {
505
            $this->_database = $database;
506
        } elseif (isset($_REQUEST['database'])) {
507
            // Connect to the current database
508
            $this->_database = $_REQUEST['database'];
509
        } else {
510
            // or if one is not specified then connect to the default database.
511
            $this->_database = $server_info['defaultdb'];
512
        }
513
514
        return $this->_database;
515
    }
516
517
    /**
518
     * Get list of server groups
519
     *
520
     * @param bool $recordset return as RecordSet suitable for HTMLTableController::printTable if true, otherwise just return an array.
521
     * @param mixed $group_id     a group name to filter the returned servers using $this->conf[srv_groups]
522
     *
523
     * @return array|\PHPPgAdmin\ArrayRecordSet either an array or a Recordset suitable for HTMLTableController::printTable
524
     */
525
    public function getServersGroups($recordset = false, $group_id = false)
526
    {
527
        $lang = $this->lang;
528
        $grps = [];
529
530
        if (isset($this->conf['srv_groups'])) {
531
            foreach ($this->conf['srv_groups'] as $i => $group) {
532
                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...
533
                    (($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...
534
                    or (
535
                        ($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...
536
                        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...
537
                        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...
538
                            preg_replace('/\s/', '', $group['parents'])
539
                        ))
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...
540
                    ) /* 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...
541
                ) {
542
                    $grps[$i] = [
543
                        'id'     => $i,
544
                        'desc'   => $group['desc'],
545
                        'icon'   => 'Servers',
546
                        'action' => Decorator::url('/views/servers',
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...
547
                            [
548
                                'group' => Decorator::field('id'),
549
                            ]
550
                        ),
551
                        'branch' => Decorator::url('/tree/servers',
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...
552
                            [
553
                                'group' => $i,
554
                            ]
555
                        ),
556
                    ];
557
                }
558
            }
559
560
            if ($group_id === false) {
561
                $grps['all'] = [
562
                    'id'     => 'all',
563
                    'desc'   => $lang['strallservers'],
564
                    'icon'   => 'Servers',
565
                    'action' => Decorator::url('/views/servers',
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...
566
                        [
567
                            'group' => Decorator::field('id'),
568
                        ]
569
                    ),
570
                    'branch' => Decorator::url('/tree/servers',
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...
571
                        [
572
                            'group' => 'all',
573
                        ]
574
                    ),
575
                ];
576
            }
577
        }
578
579
        if ($recordset) {
580
            return new ArrayRecordSet($grps);
581
        }
582
583
        return $grps;
584
    }
585
586
    /**
587
     * Get list of servers
588
     *
589
     * @param bool $recordset return as RecordSet suitable for HTMLTableController::printTable if true, otherwise just return an array.
590
     * @param mixed $group     a group name to filter the returned servers using $this->conf[srv_groups]
591
     *
592
     * @return array|\PHPPgAdmin\ArrayRecordSet either an array or a Recordset suitable for HTMLTableController::printTable
593
     */
594
    public function getServers($recordset = false, $group = false)
595
    {
596
        $logins = isset($_SESSION['webdbLogin']) && is_array($_SESSION['webdbLogin']) ? $_SESSION['webdbLogin'] : [];
597
        $srvs   = [];
598
599
        if (($group !== false) && ($group !== 'all')) {
600
            if (isset($this->conf['srv_groups'][$group]['servers'])) {
601
                $group = array_fill_keys(explode(',', preg_replace('/\s/', '',
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...
602
                    $this->conf['srv_groups'][$group]['servers'])), 1);
1 ignored issue
show
Coding Style introduced by
This line of the multi-line function call does not seem to be indented correctly. Expected 16 spaces, but found 20.
Loading history...
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...
603
            } else {
604
                $group = '';
605
            }
606
        }
607
608
        foreach ($this->conf['servers'] as $idx => $info) {
609
            $server_id = $info['host'] . ':' . $info['port'] . ':' . $info['sslmode'];
610
            if ($group === false || isset($group[$idx]) || ($group === 'all')) {
611
                $server_id = $info['host'] . ':' . $info['port'] . ':' . $info['sslmode'];
612
613
                if (isset($logins[$server_id])) {
614
                    $srvs[$server_id] = $logins[$server_id];
615
                } else {
616
                    $srvs[$server_id] = $info;
617
                }
618
619
                $srvs[$server_id]['id']     = $server_id;
620
                $srvs[$server_id]['action'] = Decorator::url('/redirect/server',
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...
621
                    [
622
                        'server' => Decorator::field('id'),
623
                    ]
624
                );
625
                if (isset($srvs[$server_id]['username'])) {
626
                    $srvs[$server_id]['icon']   = 'Server';
627
                    $srvs[$server_id]['branch'] = Decorator::url('/src/views/alldb',
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...
628
                        [
629
                            'action'  => 'tree',
630
                            'subject' => 'server',
631
                            'server'  => Decorator::field('id'),
632
                        ]
633
                    );
634
                } else {
635
                    $srvs[$server_id]['icon']   = 'DisconnectedServer';
636
                    $srvs[$server_id]['branch'] = false;
637
                }
638
            }
639
        }
640
641
        uasort($srvs, ['self', '_cmp_desc']);
642
643
        if ($recordset) {
644
            return new ArrayRecordSet($srvs);
645
        }
646
        return $srvs;
647
    }
648
649
    /**
650
     * Set the current schema
651
     *
652
     * @param $schema The schema name
653
     *
654
     * @return int 0 on success
655
     */
656
    public function setCurrentSchema($schema)
657
    {
658
        $data = $this->getDatabaseAccessor();
659
660
        $status = $data->setSchema($schema);
661
        if ($status != 0) {
662
            return $status;
663
        }
664
665
        $_REQUEST['schema'] = $schema;
666
        $this->setHREF();
667
        return 0;
668
    }
669
670
    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...
671
    {
672
        return strcmp($a['desc'], $b['desc']);
673
    }
674
675
    /**
676
     * Checks if dumps are properly set up
677
     * @param $all (optional) True to check pg_dumpall, false to just check pg_dump
678
     * @return True, dumps are set up, false otherwise
0 ignored issues
show
Coding Style introduced by
Tag cannot be grouped with parameter tags in a doc comment
Loading history...
679
     */
680
    public function isDumpEnabled($all = false)
681
    {
682
        $info = $this->getServerInfo();
683
684
        return !empty($info[$all ? 'pg_dumpall_path' : 'pg_dump_path']);
685
    }
686
687
    /**
688
     * Sets the href tracking variable
689
     */
690
    public function setHREF()
691
    {
692
        $this->href = $this->getHREF();
693
        //\PC::debug($this->href, 'Misc::href');
694
        return $this;
695
    }
696
697
    /**
698
     * Get a href query string, excluding objects below the given object type (inclusive)
699
     *
700
     * @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...
701
     * @return string
0 ignored issues
show
Coding Style introduced by
Tag cannot be grouped with parameter tags in a doc comment
Loading history...
702
     */
703
    public function getHREF($exclude_from = null)
704
    {
705
        $href = [];
706
        if (isset($_REQUEST['server']) && $exclude_from != 'server') {
707
            $href[] = 'server=' . urlencode($_REQUEST['server']);
708
        }
709
        if (isset($_REQUEST['database']) && $exclude_from != 'database') {
710
            $href[] = 'database=' . urlencode($_REQUEST['database']);
711
        }
712
        if (isset($_REQUEST['schema']) && $exclude_from != 'schema') {
713
            $href[] = 'schema=' . urlencode($_REQUEST['schema']);
714
        }
715
716
        return htmlentities(implode('&', $href));
717
    }
718
719
    public function getSubjectParams($subject)
1 ignored issue
show
Coding Style introduced by
Missing function doc comment
Loading history...
720
    {
721
        $plugin_manager = $this->plugin_manager;
722
723
        $vars = [];
724
725
        switch ($subject) {
726
            case 'root':
727
                $vars = [
728
                    'params' => [
729
                        'subject' => 'root',
730
                    ],
731
                ];
732
                break;
733
            case 'server':
734
                $vars = ['params' => [
735
                    'server'  => $_REQUEST['server'],
736
                    'subject' => 'server',
737
                ]];
738
                break;
739
            case 'role':
740
                $vars = ['params' => [
741
                    'server'   => $_REQUEST['server'],
742
                    'subject'  => 'role',
743
                    'action'   => 'properties',
744
                    'rolename' => $_REQUEST['rolename'],
745
                ]];
746
                break;
747
            case 'database':
748
                $vars = ['params' => [
749
                    'server'   => $_REQUEST['server'],
750
                    'subject'  => 'database',
751
                    'database' => $_REQUEST['database'],
752
                ]];
753
                break;
754
            case 'schema':
755
                $vars = ['params' => [
756
                    'server'   => $_REQUEST['server'],
757
                    'subject'  => 'schema',
758
                    'database' => $_REQUEST['database'],
759
                    'schema'   => $_REQUEST['schema'],
760
                ]];
761
                break;
762
            case 'table':
763
                $vars = ['params' => [
764
                    'server'   => $_REQUEST['server'],
765
                    'subject'  => 'table',
766
                    'database' => $_REQUEST['database'],
767
                    'schema'   => $_REQUEST['schema'],
768
                    'table'    => $_REQUEST['table'],
769
                ]];
770
                break;
771
            case 'selectrows':
772
                $vars = [
773
                    'url'    => 'tables.php',
774
                    'params' => [
775
                        'server'   => $_REQUEST['server'],
776
                        'subject'  => 'table',
777
                        'database' => $_REQUEST['database'],
778
                        'schema'   => $_REQUEST['schema'],
779
                        'table'    => $_REQUEST['table'],
780
                        'action'   => 'confselectrows',
781
                    ]];
782
                break;
783
            case 'view':
784
                $vars = ['params' => [
785
                    'server'   => $_REQUEST['server'],
786
                    'subject'  => 'view',
787
                    'database' => $_REQUEST['database'],
788
                    'schema'   => $_REQUEST['schema'],
789
                    'view'     => $_REQUEST['view'],
790
                ]];
791
                break;
792
            case 'matview':
793
                $vars = ['params' => [
794
                    'server'   => $_REQUEST['server'],
795
                    'subject'  => 'matview',
796
                    'database' => $_REQUEST['database'],
797
                    'schema'   => $_REQUEST['schema'],
798
                    'matview'  => $_REQUEST['matview'],
799
                ]];
800
                break;
801
802
            case 'fulltext':
803
            case 'ftscfg':
804
                $vars = ['params' => [
805
                    'server'   => $_REQUEST['server'],
806
                    'subject'  => 'fulltext',
807
                    'database' => $_REQUEST['database'],
808
                    'schema'   => $_REQUEST['schema'],
809
                    'action'   => 'viewconfig',
810
                    'ftscfg'   => $_REQUEST['ftscfg'],
811
                ]];
812
                break;
813
            case 'function':
814
                $vars = ['params' => [
815
                    'server'       => $_REQUEST['server'],
816
                    'subject'      => 'function',
817
                    'database'     => $_REQUEST['database'],
818
                    'schema'       => $_REQUEST['schema'],
819
                    'function'     => $_REQUEST['function'],
820
                    'function_oid' => $_REQUEST['function_oid'],
821
                ]];
822
                break;
823
            case 'aggregate':
824
                $vars = ['params' => [
825
                    'server'   => $_REQUEST['server'],
826
                    'subject'  => 'aggregate',
827
                    'action'   => 'properties',
828
                    'database' => $_REQUEST['database'],
829
                    'schema'   => $_REQUEST['schema'],
830
                    'aggrname' => $_REQUEST['aggrname'],
831
                    'aggrtype' => $_REQUEST['aggrtype'],
832
                ]];
833
                break;
834
            case 'column':
835
                if (isset($_REQUEST['table'])) {
836
                    $vars = ['params' => [
837
                        'server'   => $_REQUEST['server'],
838
                        'subject'  => 'column',
839
                        'database' => $_REQUEST['database'],
840
                        'schema'   => $_REQUEST['schema'],
841
                        'table'    => $_REQUEST['table'],
842
                        'column'   => $_REQUEST['column'],
843
                    ]];
844
                } else {
845
                    $vars = ['params' => [
846
                        'server'   => $_REQUEST['server'],
847
                        'subject'  => 'column',
848
                        'database' => $_REQUEST['database'],
849
                        'schema'   => $_REQUEST['schema'],
850
                        'view'     => $_REQUEST['view'],
851
                        'column'   => $_REQUEST['column'],
852
                    ]];
853
                }
854
855
                break;
856
            case 'plugin':
857
                $vars = [
858
                    'url'    => 'plugin.php',
859
                    'params' => [
860
                        'server'  => $_REQUEST['server'],
861
                        'subject' => 'plugin',
862
                        'plugin'  => $_REQUEST['plugin'],
863
                    ]];
864
865
                if (!is_null($plugin_manager->getPlugin($_REQUEST['plugin']))) {
866
                    $vars['params'] = array_merge($vars['params'], $plugin_manager->getPlugin($_REQUEST['plugin'])->get_subject_params());
867
                }
868
869
                break;
870
            default:
871
                return false;
872
        }
873
874
        if (!isset($vars['url'])) {
875
            $vars['url'] = SUBFOLDER . '/redirect';
876
        }
877
        if ($vars['url'] == SUBFOLDER . '/redirect' && isset($vars['params']['subject'])) {
878
            $vars['url'] = SUBFOLDER . '/redirect/' . $vars['params']['subject'];
879
            unset($vars['params']['subject']);
880
        }
881
882
        return $vars;
883
    }
884
885
    /**
886
     * Sets the form tracking variable
887
     */
888
    public function setForm()
889
    {
890
        $form = [];
891
        if (isset($_REQUEST['server'])) {
892
            $form[] = '<input type="hidden" name="server" value="' . htmlspecialchars($_REQUEST['server']) . '" />';
893
        }
894
        if (isset($_REQUEST['database'])) {
895
            $form[] = '<input type="hidden" name="database" value="' . htmlspecialchars($_REQUEST['database']) . '" />';
896
        }
897
898
        if (isset($_REQUEST['schema'])) {
899
            $form[] = '<input type="hidden" name="schema" value="' . htmlspecialchars($_REQUEST['schema']) . '" />';
900
        }
901
        $this->form = implode("\n", $form);
902
        return $this->form;
903
904
        //\PC::debug($this->form, 'Misc::form');
905
    }
906
907
    /**
908
     * Render a value into HTML using formatting rules specified
909
     * by a type name and parameters.
910
     *
911
     * @param                        $str    The string to change
912
     *
913
     * @param                        $type   Field type (optional), this may be an internal PostgreSQL type, or:
0 ignored issues
show
Coding Style introduced by
Parameter tags must be grouped together in a doc comment
Loading history...
914
     *                                       yesno    - same as bool, but renders as 'Yes' or 'No'.
915
     *                                       pre      - render in a <pre> block.
916
     *                                       nbsp     - replace all spaces with &nbsp;'s
917
     *                                       verbatim - render exactly as supplied, no escaping what-so-ever.
918
     *                                       callback - render using a callback function supplied in the 'function' param.
919
     *
920
     * @param array|\PHPPgAdmin\Type $params Type parameters (optional), known parameters:
0 ignored issues
show
Coding Style introduced by
Parameter tags must be grouped together in a doc comment
Loading history...
921
     *                                       null     - string to display if $str is null, or set to TRUE to use a default 'NULL' string,
922
     *                                       otherwise nothing is rendered.
923
     *                                       clip     - if true, clip the value to a fixed length, and append an ellipsis...
924
     *                                       cliplen  - the maximum length when clip is enabled (defaults to $conf['max_chars'])
925
     *                                       ellipsis - the string to append to a clipped value (defaults to $lang['strellipsis'])
926
     *                                       tag      - an HTML element name to surround the value.
927
     *                                       class    - a class attribute to apply to any surrounding HTML element.
928
     *                                       align    - an align attribute ('left','right','center' etc.)
929
     *                                       true     - (type='bool') the representation of true.
930
     *                                       false    - (type='bool') the representation of false.
931
     *                                       function - (type='callback') a function name, accepts args ($str, $params) and returns a rendering.
932
     *                                       lineno   - prefix each line with a line number.
933
     *                                       map      - an associative array.
934
     * @return \PHPPgAdmin\The HTML rendered value
935
     */
936
    public function printVal($str, $type = null, $params = [])
937
    {
938
        $lang = $this->lang;
939
        $data = $this->_data;
940
941
        // Shortcircuit for a NULL value
942
        if (is_null($str)) {
943
            return isset($params['null'])
944
            ? ($params['null'] === true ? '<i>NULL</i>' : $params['null'])
945
            : '';
946
        }
947
948
        if (isset($params['map']) && isset($params['map'][$str])) {
949
            $str = $params['map'][$str];
950
        }
951
952
        // Clip the value if the 'clip' parameter is true.
953
        if (isset($params['clip']) && $params['clip'] === true) {
954
            $maxlen   = isset($params['cliplen']) && is_integer($params['cliplen']) ? $params['cliplen'] : $this->conf['max_chars'];
955
            $ellipsis = isset($params['ellipsis']) ? $params['ellipsis'] : $lang['strellipsis'];
956
            if (strlen($str) > $maxlen) {
957
                $str = substr($str, 0, $maxlen - 1) . $ellipsis;
958
            }
959
        }
960
961
        $out = '';
962
963
        switch ($type) {
964
            case 'int2':
965
            case 'int4':
966
            case 'int8':
967
            case 'float4':
968
            case 'float8':
969
            case 'money':
970
            case 'numeric':
971
            case 'oid':
972
            case 'xid':
973
            case 'cid':
974
            case 'tid':
975
                $align = 'right';
976
                $out   = nl2br(htmlspecialchars(\PHPPgAdmin\HelperTrait::br2ln($str)));
977
                break;
978
            case 'yesno':
979
                if (!isset($params['true'])) {
980
                    $params['true'] = $lang['stryes'];
981
                }
982
983
                if (!isset($params['false'])) {
984
                    $params['false'] = $lang['strno'];
985
                }
986
987
            // No break - fall through to boolean case.
988
            case 'bool':
989
            case 'boolean':
990
                if (is_bool($str)) {
991
                    $str = $str ? 't' : 'f';
992
                }
993
994
                switch ($str) {
995
                    case 't':
996
                        $out   = (isset($params['true']) ? $params['true'] : $lang['strtrue']);
997
                        $align = 'center';
998
                        break;
999
                    case 'f':
1000
                        $out   = (isset($params['false']) ? $params['false'] : $lang['strfalse']);
1001
                        $align = 'center';
1002
                        break;
1003
                    default:
1004
                        $out = htmlspecialchars($str);
1005
                }
1006
                break;
1007
            case 'bytea':
1008
                $tag   = 'div';
1009
                $class = 'pre';
1010
                $out   = $data->escapeBytea($str);
1011
                break;
1012
            case 'errormsg':
1013
                $tag   = 'pre';
1014
                $class = 'error';
1015
                $out   = htmlspecialchars($str);
1016
                break;
1017
            case 'pre':
1018
                $tag = 'pre';
1019
                $out = htmlspecialchars($str);
1020
                break;
1021
            case 'prenoescape':
1022
                $tag = 'pre';
1023
                $out = $str;
1024
                break;
1025
            case 'nbsp':
1026
                $out = nl2br(str_replace(' ', '&nbsp;', \PHPPgAdmin\HelperTrait::br2ln($str)));
1027
1028
                break;
1029
            case 'verbatim':
1030
                $out = $str;
1031
                break;
1032
            case 'callback':
1033
                $out = $params['function']($str, $params);
1034
                break;
1035
            case 'prettysize':
1036
                if ($str == -1) {
1037
                    $out = $lang['strnoaccess'];
1038
                } else {
1039
                    $limit = 10 * 1024;
1040
                    $mult  = 1;
1041
                    if ($str < $limit * $mult) {
1042
                        $out = $str . ' ' . $lang['strbytes'];
1043
                    } else {
1044
                        $mult *= 1024;
1045
                        if ($str < $limit * $mult) {
1046
                            $out = floor(($str + $mult / 2) / $mult) . ' ' . $lang['strkb'];
1047
                        } else {
1048
                            $mult *= 1024;
1049
                            if ($str < $limit * $mult) {
1050
                                $out = floor(($str + $mult / 2) / $mult) . ' ' . $lang['strmb'];
1051
                            } else {
1052
                                $mult *= 1024;
1053
                                if ($str < $limit * $mult) {
1054
                                    $out = floor(($str + $mult / 2) / $mult) . ' ' . $lang['strgb'];
1055
                                } else {
1056
                                    $mult *= 1024;
1057
                                    if ($str < $limit * $mult) {
1058
                                        $out = floor(($str + $mult / 2) / $mult) . ' ' . $lang['strtb'];
1059
                                    }
1060
                                }
1061
                            }
1062
                        }
1063
                    }
1064
                }
1065
                break;
1066
            default:
1067
                // If the string contains at least one instance of >1 space in a row, a tab
1068
                // character, a space at the start of a line, or a space at the start of
1069
                // the whole string then render within a pre-formatted element (<pre>).
1070
                if (preg_match('/(^ |  |\t|\n )/m', $str)) {
1071
                    $tag   = 'pre';
1072
                    $class = 'data';
1073
                    $out   = htmlspecialchars($str);
1074
                } else {
1075
                    $out = nl2br(htmlspecialchars(\PHPPgAdmin\HelperTrait::br2ln($str)));
1076
                }
1077
        }
1078
1079
        if (isset($params['class'])) {
1080
            $class = $params['class'];
1081
        }
1082
1083
        if (isset($params['align'])) {
1084
            $align = $params['align'];
1085
        }
1086
1087
        if (!isset($tag) && (isset($class) || isset($align))) {
1088
            $tag = 'div';
1089
        }
1090
1091
        if (isset($tag)) {
1092
            $alignattr = isset($align) ? " style=\"text-align: {$align}\"" : '';
1093
            $classattr = isset($class) ? " class=\"{$class}\"" : '';
1094
            $out       = "<{$tag}{$alignattr}{$classattr}>{$out}</{$tag}>";
1095
        }
1096
1097
        // Add line numbers if 'lineno' param is true
1098
        if (isset($params['lineno']) && $params['lineno'] === true) {
1099
            $lines = explode("\n", $str);
1100
            $num   = count($lines);
1101
            if ($num > 0) {
1102
                $temp = "<table>\n<tr><td class=\"{$class}\" style=\"vertical-align: top; padding-right: 10px;\"><pre class=\"{$class}\">";
1103
                for ($i = 1; $i <= $num; $i++) {
1104
                    $temp .= $i . "\n";
1105
                }
1106
                $temp .= "</pre></td><td class=\"{$class}\" style=\"vertical-align: top;\">{$out}</td></tr></table>\n";
1107
                $out = $temp;
1108
            }
1109
            unset($lines);
1110
        }
1111
1112
        return $out;
1113
    }
1114
1115
    /**
1116
     * A function to recursively strip slashes.  Used to
1117
     * enforce magic_quotes_gpc being off.
1118
     * @param &var The variable to strip
1119
     */
1120
    public function stripVar(&$var)
1121
    {
1122
        if (is_array($var)) {
1123
            foreach ($var as $k => $v) {
1124
                $this->stripVar($var[$k]);
1125
1126
                /* magic_quotes_gpc escape keys as well ...*/
1127
                if (is_string($k)) {
1128
                    $ek = stripslashes($k);
1129
                    if ($ek !== $k) {
1130
                        $var[$ek] = $var[$k];
1131
                        unset($var[$k]);
1132
                    }
1133
                }
1134
            }
1135
        } else {
1136
            $var = stripslashes($var);
1137
        }
1138
    }
1139
1140
    /**
1141
     * Retrieve the tab info for a specific tab bar.
1142
     *
1143
     * @param $section The name of the tab bar.
1144
     * @return array
0 ignored issues
show
Coding Style introduced by
Tag cannot be grouped with parameter tags in a doc comment
Loading history...
1145
     */
1146
    public function getNavTabs($section)
1147
    {
1148
        $data           = $this->_data;
1149
        $lang           = $this->lang;
1150
        $plugin_manager = $this->plugin_manager;
1151
1152
        $hide_advanced = ($this->conf['show_advanced'] === false);
1153
        $tabs          = [];
1154
1155
        switch ($section) {
1156
            case 'root':
1157
                $tabs = [
1158
                    'intro'   => [
1159
                        'title' => $lang['strintroduction'],
1160
                        'url'   => 'intro.php',
1161
                        'icon'  => 'Introduction',
1162
                    ],
1163
                    'servers' => [
1164
                        'title' => $lang['strservers'],
1165
                        'url'   => 'servers.php',
1166
                        'icon'  => 'Servers',
1167
                    ],
1168
                ];
1169
                break;
1170
1171
            case 'server':
1172
                $hide_users = true;
1173
                if ($data) {
1174
                    $hide_users = !$data->isSuperUser();
1175
                }
1176
1177
                $tabs = [
1178
                    'databases' => [
1179
                        'title'   => $lang['strdatabases'],
1180
                        'url'     => 'alldb.php',
1181
                        'urlvars' => ['subject' => 'server'],
1182
                        'help'    => 'pg.database',
1183
                        'icon'    => 'Databases',
1184
                    ],
1185
                ];
1186
                if ($data && $data->hasRoles()) {
1187
                    $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...
1188
                        'roles' => [
1189
                            'title'   => $lang['strroles'],
1190
                            'url'     => 'roles.php',
1191
                            'urlvars' => ['subject' => 'server'],
1192
                            'hide'    => $hide_users,
1193
                            'help'    => 'pg.role',
1194
                            'icon'    => 'Roles',
1195
                        ],
1196
                    ]);
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...
1197
                } else {
1198
                    $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...
1199
                        'users'  => [
1200
                            'title'   => $lang['strusers'],
1201
                            'url'     => 'users.php',
1202
                            'urlvars' => ['subject' => 'server'],
1203
                            'hide'    => $hide_users,
1204
                            'help'    => 'pg.user',
1205
                            'icon'    => 'Users',
1206
                        ],
1207
                        'groups' => [
1208
                            'title'   => $lang['strgroups'],
1209
                            'url'     => 'groups.php',
1210
                            'urlvars' => ['subject' => 'server'],
1211
                            'hide'    => $hide_users,
1212
                            'help'    => 'pg.group',
1213
                            'icon'    => 'UserGroups',
1214
                        ],
1215
                    ]);
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...
1216
                }
1217
1218
                $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...
1219
                    'account'     => [
1220
                        'title'   => $lang['straccount'],
1221
                        'url'     => ($data && $data->hasRoles()) ? 'roles.php' : 'users.php',
1222
                        'urlvars' => ['subject' => 'server', 'action' => 'account'],
1223
                        'hide'    => !$hide_users,
1224
                        'help'    => 'pg.role',
1225
                        'icon'    => 'User',
1226
                    ],
1227
                    'tablespaces' => [
1228
                        'title'   => $lang['strtablespaces'],
1229
                        'url'     => 'tablespaces.php',
1230
                        'urlvars' => ['subject' => 'server'],
1231
                        'hide'    => !$data || !$data->hasTablespaces(),
1232
                        'help'    => 'pg.tablespace',
1233
                        'icon'    => 'Tablespaces',
1234
                    ],
1235
                    'export'      => [
1236
                        'title'   => $lang['strexport'],
1237
                        'url'     => 'alldb.php',
1238
                        'urlvars' => ['subject' => 'server', 'action' => 'export'],
1239
                        'hide'    => !$this->isDumpEnabled(),
1240
                        'icon'    => 'Export',
1241
                    ],
1242
                ]);
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...
1243
                break;
1244
            case 'database':
1245
                $tabs = [
1246
                    'schemas'    => [
1247
                        'title'   => $lang['strschemas'],
1248
                        'url'     => 'schemas.php',
1249
                        'urlvars' => ['subject' => 'database'],
1250
                        'help'    => 'pg.schema',
1251
                        'icon'    => 'Schemas',
1252
                    ],
1253
                    'sql'        => [
1254
                        'title'   => $lang['strsql'],
1255
                        'url'     => 'database.php',
1256
                        'urlvars' => ['subject' => 'database', 'action' => 'sql', 'new' => 1],
1257
                        'help'    => 'pg.sql',
1258
                        'tree'    => false,
1259
                        'icon'    => 'SqlEditor',
1260
                    ],
1261
                    'find'       => [
1262
                        'title'   => $lang['strfind'],
1263
                        'url'     => 'database.php',
1264
                        'urlvars' => ['subject' => 'database', 'action' => 'find'],
1265
                        'tree'    => false,
1266
                        'icon'    => 'Search',
1267
                    ],
1268
                    'variables'  => [
1269
                        'title'   => $lang['strvariables'],
1270
                        'url'     => 'database.php',
1271
                        'urlvars' => ['subject' => 'database', 'action' => 'variables'],
1272
                        'help'    => 'pg.variable',
1273
                        'tree'    => false,
1274
                        'icon'    => 'Variables',
1275
                    ],
1276
                    'processes'  => [
1277
                        'title'   => $lang['strprocesses'],
1278
                        'url'     => 'database.php',
1279
                        'urlvars' => ['subject' => 'database', 'action' => 'processes'],
1280
                        'help'    => 'pg.process',
1281
                        'tree'    => false,
1282
                        'icon'    => 'Processes',
1283
                    ],
1284
                    'locks'      => [
1285
                        'title'   => $lang['strlocks'],
1286
                        'url'     => 'database.php',
1287
                        'urlvars' => ['subject' => 'database', 'action' => 'locks'],
1288
                        'help'    => 'pg.locks',
1289
                        'tree'    => false,
1290
                        'icon'    => 'Key',
1291
                    ],
1292
                    'admin'      => [
1293
                        'title'   => $lang['stradmin'],
1294
                        'url'     => 'database.php',
1295
                        'urlvars' => ['subject' => 'database', 'action' => 'admin'],
1296
                        'tree'    => false,
1297
                        'icon'    => 'Admin',
1298
                    ],
1299
                    'privileges' => [
1300
                        'title'   => $lang['strprivileges'],
1301
                        'url'     => 'privileges.php',
1302
                        'urlvars' => ['subject' => 'database'],
1303
                        'hide'    => !isset($data->privlist['database']),
1304
                        'help'    => 'pg.privilege',
1305
                        'tree'    => false,
1306
                        'icon'    => 'Privileges',
1307
                    ],
1308
                    'languages'  => [
1309
                        'title'   => $lang['strlanguages'],
1310
                        'url'     => 'languages.php',
1311
                        'urlvars' => ['subject' => 'database'],
1312
                        'hide'    => $hide_advanced,
1313
                        'help'    => 'pg.language',
1314
                        'icon'    => 'Languages',
1315
                    ],
1316
                    'casts'      => [
1317
                        'title'   => $lang['strcasts'],
1318
                        'url'     => 'casts.php',
1319
                        'urlvars' => ['subject' => 'database'],
1320
                        'hide'    => $hide_advanced,
1321
                        'help'    => 'pg.cast',
1322
                        'icon'    => 'Casts',
1323
                    ],
1324
                    'export'     => [
1325
                        'title'   => $lang['strexport'],
1326
                        'url'     => 'database.php',
1327
                        'urlvars' => ['subject' => 'database', 'action' => 'export'],
1328
                        'hide'    => !$this->isDumpEnabled(),
1329
                        'tree'    => false,
1330
                        'icon'    => 'Export',
1331
                    ],
1332
                ];
1333
                break;
1334
1335
            case 'schema':
1336
                $tabs = [
1337
                    'tables'      => [
1338
                        'title'   => $lang['strtables'],
1339
                        'url'     => 'tables.php',
1340
                        'urlvars' => ['subject' => 'schema'],
1341
                        'help'    => 'pg.table',
1342
                        'icon'    => 'Tables',
1343
                    ],
1344
                    'views'       => [
1345
                        'title'   => $lang['strviews'],
1346
                        'url'     => 'views.php',
1347
                        'urlvars' => ['subject' => 'schema'],
1348
                        'help'    => 'pg.view',
1349
                        'icon'    => 'Views',
1350
                    ],
1351
                    'matviews'    => [
1352
                        'title'   => 'M ' . $lang['strviews'],
1353
                        'url'     => 'materializedviews.php',
1354
                        'urlvars' => ['subject' => 'schema'],
1355
                        'help'    => 'pg.matview',
1356
                        'icon'    => 'MViews',
1357
                    ],
1358
                    'sequences'   => [
1359
                        'title'   => $lang['strsequences'],
1360
                        'url'     => 'sequences.php',
1361
                        'urlvars' => ['subject' => 'schema'],
1362
                        'help'    => 'pg.sequence',
1363
                        'icon'    => 'Sequences',
1364
                    ],
1365
                    'functions'   => [
1366
                        'title'   => $lang['strfunctions'],
1367
                        'url'     => 'functions.php',
1368
                        'urlvars' => ['subject' => 'schema'],
1369
                        'help'    => 'pg.function',
1370
                        'icon'    => 'Functions',
1371
                    ],
1372
                    'fulltext'    => [
1373
                        'title'   => $lang['strfulltext'],
1374
                        'url'     => 'fulltext.php',
1375
                        'urlvars' => ['subject' => 'schema'],
1376
                        'help'    => 'pg.fts',
1377
                        'tree'    => true,
1378
                        'icon'    => 'Fts',
1379
                    ],
1380
                    'domains'     => [
1381
                        'title'   => $lang['strdomains'],
1382
                        'url'     => 'domains.php',
1383
                        'urlvars' => ['subject' => 'schema'],
1384
                        'help'    => 'pg.domain',
1385
                        'icon'    => 'Domains',
1386
                    ],
1387
                    'aggregates'  => [
1388
                        'title'   => $lang['straggregates'],
1389
                        'url'     => 'aggregates.php',
1390
                        'urlvars' => ['subject' => 'schema'],
1391
                        'hide'    => $hide_advanced,
1392
                        'help'    => 'pg.aggregate',
1393
                        'icon'    => 'Aggregates',
1394
                    ],
1395
                    'types'       => [
1396
                        'title'   => $lang['strtypes'],
1397
                        'url'     => 'types.php',
1398
                        'urlvars' => ['subject' => 'schema'],
1399
                        'hide'    => $hide_advanced,
1400
                        'help'    => 'pg.type',
1401
                        'icon'    => 'Types',
1402
                    ],
1403
                    'operators'   => [
1404
                        'title'   => $lang['stroperators'],
1405
                        'url'     => 'operators.php',
1406
                        'urlvars' => ['subject' => 'schema'],
1407
                        'hide'    => $hide_advanced,
1408
                        'help'    => 'pg.operator',
1409
                        'icon'    => 'Operators',
1410
                    ],
1411
                    'opclasses'   => [
1412
                        'title'   => $lang['stropclasses'],
1413
                        'url'     => 'opclasses.php',
1414
                        'urlvars' => ['subject' => 'schema'],
1415
                        'hide'    => $hide_advanced,
1416
                        'help'    => 'pg.opclass',
1417
                        'icon'    => 'OperatorClasses',
1418
                    ],
1419
                    'conversions' => [
1420
                        'title'   => $lang['strconversions'],
1421
                        'url'     => 'conversions.php',
1422
                        'urlvars' => ['subject' => 'schema'],
1423
                        'hide'    => $hide_advanced,
1424
                        'help'    => 'pg.conversion',
1425
                        'icon'    => 'Conversions',
1426
                    ],
1427
                    'privileges'  => [
1428
                        'title'   => $lang['strprivileges'],
1429
                        'url'     => 'privileges.php',
1430
                        'urlvars' => ['subject' => 'schema'],
1431
                        'help'    => 'pg.privilege',
1432
                        'tree'    => false,
1433
                        'icon'    => 'Privileges',
1434
                    ],
1435
                    'export'      => [
1436
                        'title'   => $lang['strexport'],
1437
                        'url'     => 'schemas.php',
1438
                        'urlvars' => ['subject' => 'schema', 'action' => 'export'],
1439
                        'hide'    => !$this->isDumpEnabled(),
1440
                        'tree'    => false,
1441
                        'icon'    => 'Export',
1442
                    ],
1443
                ];
1444
                if (!$data->hasFTS()) {
1445
                    unset($tabs['fulltext']);
1446
                }
1447
1448
                break;
1449
1450
            case 'table':
1451
                $tabs = [
1452
                    'columns'     => [
1453
                        'title'   => $lang['strcolumns'],
1454
                        'url'     => 'tblproperties.php',
1455
                        'urlvars' => ['subject' => 'table', 'table' => Decorator::field('table')],
1456
                        'icon'    => 'Columns',
1457
                        'branch'  => true,
1458
                    ],
1459
                    'browse'      => [
1460
                        'title'   => $lang['strbrowse'],
1461
                        'icon'    => 'Columns',
1462
                        'url'     => 'display.php',
1463
                        'urlvars' => ['subject' => 'table', 'table' => Decorator::field('table')],
1464
                        'return'  => 'table',
1465
                        'branch'  => true,
1466
                    ],
1467
                    'select'      => [
1468
                        'title'   => $lang['strselect'],
1469
                        'icon'    => 'Search',
1470
                        'url'     => 'tables.php',
1471
                        'urlvars' => ['subject' => 'table', 'table' => Decorator::field('table'), 'action' => 'confselectrows'],
1472
                        'help'    => 'pg.sql.select',
1473
                    ],
1474
                    'insert'      => [
1475
                        'title'   => $lang['strinsert'],
1476
                        'url'     => 'tables.php',
1477
                        'urlvars' => [
1478
                            'action' => 'confinsertrow',
1479
                            'table'  => Decorator::field('table'),
1480
                        ],
1481
                        'help'    => 'pg.sql.insert',
1482
                        'icon'    => 'Operator',
1483
                    ],
1484
                    'indexes'     => [
1485
                        'title'   => $lang['strindexes'],
1486
                        'url'     => 'indexes.php',
1487
                        'urlvars' => ['subject' => 'table', 'table' => Decorator::field('table')],
1488
                        'help'    => 'pg.index',
1489
                        'icon'    => 'Indexes',
1490
                        'branch'  => true,
1491
                    ],
1492
                    'constraints' => [
1493
                        'title'   => $lang['strconstraints'],
1494
                        'url'     => 'constraints.php',
1495
                        'urlvars' => ['subject' => 'table', 'table' => Decorator::field('table')],
1496
                        'help'    => 'pg.constraint',
1497
                        'icon'    => 'Constraints',
1498
                        'branch'  => true,
1499
                    ],
1500
                    'triggers'    => [
1501
                        'title'   => $lang['strtriggers'],
1502
                        'url'     => 'triggers.php',
1503
                        'urlvars' => ['subject' => 'table', 'table' => Decorator::field('table')],
1504
                        'help'    => 'pg.trigger',
1505
                        'icon'    => 'Triggers',
1506
                        'branch'  => true,
1507
                    ],
1508
                    'rules'       => [
1509
                        'title'   => $lang['strrules'],
1510
                        'url'     => 'rules.php',
1511
                        'urlvars' => ['subject' => 'table', 'table' => Decorator::field('table')],
1512
                        'help'    => 'pg.rule',
1513
                        'icon'    => 'Rules',
1514
                        'branch'  => true,
1515
                    ],
1516
                    'admin'       => [
1517
                        'title'   => $lang['stradmin'],
1518
                        'url'     => 'tables.php',
1519
                        'urlvars' => ['subject' => 'table', 'table' => Decorator::field('table'), 'action' => 'admin'],
1520
                        'icon'    => 'Admin',
1521
                    ],
1522
                    'info'        => [
1523
                        'title'   => $lang['strinfo'],
1524
                        'url'     => 'info.php',
1525
                        'urlvars' => ['subject' => 'table', 'table' => Decorator::field('table')],
1526
                        'icon'    => 'Statistics',
1527
                    ],
1528
                    'privileges'  => [
1529
                        'title'   => $lang['strprivileges'],
1530
                        'url'     => 'privileges.php',
1531
                        'urlvars' => ['subject' => 'table', 'table' => Decorator::field('table')],
1532
                        'help'    => 'pg.privilege',
1533
                        'icon'    => 'Privileges',
1534
                    ],
1535
                    'import'      => [
1536
                        'title'   => $lang['strimport'],
1537
                        'url'     => 'tblproperties.php',
1538
                        'urlvars' => ['subject' => 'table', 'table' => Decorator::field('table'), 'action' => 'import'],
1539
                        'icon'    => 'Import',
1540
                        'hide'    => false,
1541
                    ],
1542
                    'export'      => [
1543
                        'title'   => $lang['strexport'],
1544
                        'url'     => 'tblproperties.php',
1545
                        'urlvars' => ['subject' => 'table', 'table' => Decorator::field('table'), 'action' => 'export'],
1546
                        'icon'    => 'Export',
1547
                        'hide'    => false,
1548
                    ],
1549
                ];
1550
                break;
1551
1552
            case 'view':
1553
                $tabs = [
1554
                    'columns'    => [
1555
                        'title'   => $lang['strcolumns'],
1556
                        'url'     => 'viewproperties.php',
1557
                        'urlvars' => ['subject' => 'view', 'view' => Decorator::field('view')],
1558
                        'icon'    => 'Columns',
1559
                        'branch'  => true,
1560
                    ],
1561
                    'browse'     => [
1562
                        'title'   => $lang['strbrowse'],
1563
                        'icon'    => 'Columns',
1564
                        'url'     => 'display.php',
1565
                        'urlvars' => [
1566
                            'action'  => 'confselectrows',
1567
                            'return'  => 'schema',
1568
                            'subject' => 'view',
1569
                            'view'    => Decorator::field('view'),
1570
                        ],
1571
                        'branch'  => true,
1572
                    ],
1573
                    'select'     => [
1574
                        'title'   => $lang['strselect'],
1575
                        'icon'    => 'Search',
1576
                        'url'     => 'views.php',
1577
                        'urlvars' => ['action' => 'confselectrows', 'view' => Decorator::field('view')],
1578
                        'help'    => 'pg.sql.select',
1579
                    ],
1580
                    'definition' => [
1581
                        'title'   => $lang['strdefinition'],
1582
                        'url'     => 'viewproperties.php',
1583
                        'urlvars' => ['subject' => 'view', 'view' => Decorator::field('view'), 'action' => 'definition'],
1584
                        'icon'    => 'Definition',
1585
                    ],
1586
                    'rules'      => [
1587
                        'title'   => $lang['strrules'],
1588
                        'url'     => 'rules.php',
1589
                        'urlvars' => ['subject' => 'view', 'view' => Decorator::field('view')],
1590
                        'help'    => 'pg.rule',
1591
                        'icon'    => 'Rules',
1592
                        'branch'  => true,
1593
                    ],
1594
                    'privileges' => [
1595
                        'title'   => $lang['strprivileges'],
1596
                        'url'     => 'privileges.php',
1597
                        'urlvars' => ['subject' => 'view', 'view' => Decorator::field('view')],
1598
                        'help'    => 'pg.privilege',
1599
                        'icon'    => 'Privileges',
1600
                    ],
1601
                    'export'     => [
1602
                        'title'   => $lang['strexport'],
1603
                        'url'     => 'viewproperties.php',
1604
                        'urlvars' => ['subject' => 'view', 'view' => Decorator::field('view'), 'action' => 'export'],
1605
                        'icon'    => 'Export',
1606
                        'hide'    => false,
1607
                    ],
1608
                ];
1609
                break;
1610
1611
            case 'matview':
1612
                $tabs = [
1613
                    'columns'    => [
1614
                        'title'   => $lang['strcolumns'],
1615
                        'url'     => 'materializedviewproperties.php',
1616
                        'urlvars' => ['subject' => 'matview', 'matview' => Decorator::field('matview')],
1617
                        'icon'    => 'Columns',
1618
                        'branch'  => true,
1619
                    ],
1620
                    'browse'     => [
1621
                        'title'   => $lang['strbrowse'],
1622
                        'icon'    => 'Columns',
1623
                        'url'     => 'display.php',
1624
                        'urlvars' => [
1625
                            'action'  => 'confselectrows',
1626
                            'return'  => 'schema',
1627
                            'subject' => 'matview',
1628
                            'matview' => Decorator::field('matview'),
1629
                        ],
1630
                        'branch'  => true,
1631
                    ],
1632
                    'select'     => [
1633
                        'title'   => $lang['strselect'],
1634
                        'icon'    => 'Search',
1635
                        'url'     => 'materializedviews.php',
1636
                        'urlvars' => ['action' => 'confselectrows', 'matview' => Decorator::field('matview')],
1637
                        'help'    => 'pg.sql.select',
1638
                    ],
1639
                    'definition' => [
1640
                        'title'   => $lang['strdefinition'],
1641
                        'url'     => 'materializedviewproperties.php',
1642
                        'urlvars' => ['subject' => 'matview', 'matview' => Decorator::field('matview'), 'action' => 'definition'],
1643
                        'icon'    => 'Definition',
1644
                    ],
1645
                    'indexes'    => [
1646
                        'title'   => $lang['strindexes'],
1647
                        'url'     => 'indexes.php',
1648
                        'urlvars' => ['subject' => 'matview', 'matview' => Decorator::field('matview')],
1649
                        'help'    => 'pg.index',
1650
                        'icon'    => 'Indexes',
1651
                        'branch'  => true,
1652
                    ],
1653
                    /*'constraints' => [
1654
                    'title' => $lang['strconstraints'],
1655
                    'url' => 'constraints.php',
1656
                    'urlvars' => ['subject' => 'matview', 'matview' => Decorator::field('matview')],
1657
                    'help' => 'pg.constraint',
1658
                    'icon' => 'Constraints',
1659
                    'branch' => true,
1660
                     */
1661
1662
                    'rules'      => [
1663
                        'title'   => $lang['strrules'],
1664
                        'url'     => 'rules.php',
1665
                        'urlvars' => ['subject' => 'matview', 'matview' => Decorator::field('matview')],
1666
                        'help'    => 'pg.rule',
1667
                        'icon'    => 'Rules',
1668
                        'branch'  => true,
1669
                    ],
1670
                    'privileges' => [
1671
                        'title'   => $lang['strprivileges'],
1672
                        'url'     => 'privileges.php',
1673
                        'urlvars' => ['subject' => 'matview', 'matview' => Decorator::field('matview')],
1674
                        'help'    => 'pg.privilege',
1675
                        'icon'    => 'Privileges',
1676
                    ],
1677
                    'export'     => [
1678
                        'title'   => $lang['strexport'],
1679
                        'url'     => 'materializedviewproperties.php',
1680
                        'urlvars' => ['subject' => 'matview', 'matview' => Decorator::field('matview'), 'action' => 'export'],
1681
                        'icon'    => 'Export',
1682
                        'hide'    => false,
1683
                    ],
1684
                ];
1685
                break;
1686
1687
            case 'function':
1688
                $tabs = [
1689
                    'definition' => [
1690
                        'title'   => $lang['strdefinition'],
1691
                        'url'     => 'functions.php',
1692
                        'urlvars' => [
1693
                            'subject'      => 'function',
1694
                            'function'     => Decorator::field('function'),
1695
                            'function_oid' => Decorator::field('function_oid'),
1696
                            'action'       => 'properties',
1697
                        ],
1698
                        'icon'    => 'Definition',
1699
                    ],
1700
                    'privileges' => [
1701
                        'title'   => $lang['strprivileges'],
1702
                        'url'     => 'privileges.php',
1703
                        'urlvars' => [
1704
                            'subject'      => 'function',
1705
                            'function'     => Decorator::field('function'),
1706
                            'function_oid' => Decorator::field('function_oid'),
1707
                        ],
1708
                        'icon'    => 'Privileges',
1709
                    ],
1710
                ];
1711
                break;
1712
1713
            case 'aggregate':
1714
                $tabs = [
1715
                    'definition' => [
1716
                        'title'   => $lang['strdefinition'],
1717
                        'url'     => 'aggregates.php',
1718
                        'urlvars' => [
1719
                            'subject'  => 'aggregate',
1720
                            'aggrname' => Decorator::field('aggrname'),
1721
                            'aggrtype' => Decorator::field('aggrtype'),
1722
                            'action'   => 'properties',
1723
                        ],
1724
                        'icon'    => 'Definition',
1725
                    ],
1726
                ];
1727
                break;
1728
1729
            case 'role':
1730
                $tabs = [
1731
                    'definition' => [
1732
                        'title'   => $lang['strdefinition'],
1733
                        'url'     => 'roles.php',
1734
                        'urlvars' => [
1735
                            'subject'  => 'role',
1736
                            'rolename' => Decorator::field('rolename'),
1737
                            'action'   => 'properties',
1738
                        ],
1739
                        'icon'    => 'Definition',
1740
                    ],
1741
                ];
1742
                break;
1743
1744
            case 'popup':
1745
                $tabs = [
1746
                    'sql'  => [
1747
                        'title'   => $lang['strsql'],
1748
                        'url'     => '/src/views/sqledit.php',
1749
                        'urlvars' => ['action' => 'sql', 'subject' => 'schema'],
1750
                        'help'    => 'pg.sql',
1751
                        'icon'    => 'SqlEditor',
1752
                    ],
1753
                    'find' => [
1754
                        'title'   => $lang['strfind'],
1755
                        'url'     => '/src/views/sqledit.php',
1756
                        'urlvars' => ['action' => 'find', 'subject' => 'schema'],
1757
                        'icon'    => 'Search',
1758
                    ],
1759
                ];
1760
                break;
1761
1762
            case 'column':
1763
                $tabs = [
1764
                    'properties' => [
1765
                        'title'   => $lang['strcolprop'],
1766
                        'url'     => 'colproperties.php',
1767
                        'urlvars' => [
1768
                            'subject' => 'column',
1769
                            'table'   => Decorator::field('table'),
1770
                            'column'  => Decorator::field('column'),
1771
                        ],
1772
                        'icon'    => 'Column',
1773
                    ],
1774
                    'privileges' => [
1775
                        'title'   => $lang['strprivileges'],
1776
                        'url'     => 'privileges.php',
1777
                        'urlvars' => [
1778
                            'subject' => 'column',
1779
                            'table'   => Decorator::field('table'),
1780
                            'column'  => Decorator::field('column'),
1781
                        ],
1782
                        'help'    => 'pg.privilege',
1783
                        'icon'    => 'Privileges',
1784
                    ],
1785
                ];
1786
                break;
1787
1788
            case 'fulltext':
1789
                $tabs = [
1790
                    'ftsconfigs' => [
1791
                        'title'   => $lang['strftstabconfigs'],
1792
                        'url'     => 'fulltext.php',
1793
                        'urlvars' => ['subject' => 'schema'],
1794
                        'hide'    => !$data->hasFTS(),
1795
                        'help'    => 'pg.ftscfg',
1796
                        'tree'    => true,
1797
                        'icon'    => 'FtsCfg',
1798
                    ],
1799
                    'ftsdicts'   => [
1800
                        'title'   => $lang['strftstabdicts'],
1801
                        'url'     => 'fulltext.php',
1802
                        'urlvars' => ['subject' => 'schema', 'action' => 'viewdicts'],
1803
                        'hide'    => !$data->hasFTS(),
1804
                        'help'    => 'pg.ftsdict',
1805
                        'tree'    => true,
1806
                        'icon'    => 'FtsDict',
1807
                    ],
1808
                    'ftsparsers' => [
1809
                        'title'   => $lang['strftstabparsers'],
1810
                        'url'     => 'fulltext.php',
1811
                        'urlvars' => ['subject' => 'schema', 'action' => 'viewparsers'],
1812
                        'hide'    => !$data->hasFTS(),
1813
                        'help'    => 'pg.ftsparser',
1814
                        'tree'    => true,
1815
                        'icon'    => 'FtsParser',
1816
                    ],
1817
                ];
1818
                break;
1819
        }
1820
1821
        // Tabs hook's place
1822
        $plugin_functions_parameters = [
1823
            'tabs'    => &$tabs,
1824
            'section' => $section,
1825
        ];
1826
        $plugin_manager->do_hook('tabs', $plugin_functions_parameters);
1827
1828
        return $tabs;
1829
    }
1830
1831
    /**
1832
     * Get the URL for the last active tab of a particular tab bar.
1833
     *
1834
     * @param $section
1835
     * @return mixed|null
0 ignored issues
show
Coding Style introduced by
Tag cannot be grouped with parameter tags in a doc comment
Loading history...
1836
     */
1837
    public function getLastTabURL($section)
1838
    {
1839
        $data = $this->getDatabaseAccessor();
1840
1841
        $tabs = $this->getNavTabs($section);
1842
1843
        if (isset($_SESSION['webdbLastTab'][$section]) && isset($tabs[$_SESSION['webdbLastTab'][$section]])) {
1844
            $tab = $tabs[$_SESSION['webdbLastTab'][$section]];
1845
        } else {
1846
            $tab = reset($tabs);
1847
        }
1848
        $this->prtrace(['section' => $section, 'tabs' => $tabs, 'tab' => $tab]);
1849
        return isset($tab['url']) ? $tab : null;
1850
    }
1851
1852
    /**
1853
     * Do multi-page navigation.  Displays the prev, next and page options.
1854
     * @param $page - the page currently viewed
1855
     * @param $pages - the maximum number of pages
1856
     * @param $gets -  the parameters to include in the link to the wanted page
1857
     * @param $max_width - the number of pages to make available at any one time (default = 20)
1858
     */
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...
1859
    public function printPages($page, $pages, $gets, $max_width = 20)
1860
    {
1861
        $lang = $this->lang;
1862
1863
        $window = 10;
1864
1865
        if ($page < 0 || $page > $pages) {
1866
            return;
1867
        }
1868
1869
        if ($pages < 0) {
1870
            return;
1871
        }
1872
1873
        if ($max_width <= 0) {
1874
            return;
1875
        }
1876
1877
        unset($gets['page']);
1878
        $url = http_build_query($gets);
1879
1880
        if ($pages > 1) {
1881
            echo "<p style=\"text-align: center\">\n";
1882
            if ($page != 1) {
1883
                echo "<a class=\"pagenav\" href=\"?{$url}&amp;page=1\">{$lang['strfirst']}</a>\n";
1884
                $temp = $page - 1;
1885
                echo "<a class=\"pagenav\" href=\"?{$url}&amp;page={$temp}\">{$lang['strprev']}</a>\n";
1886
            }
1887
1888
            if ($page <= $window) {
1889
                $min_page = 1;
1890
                $max_page = min(2 * $window, $pages);
1891
            } elseif ($page > $window && $pages >= $page + $window) {
1892
                $min_page = ($page - $window) + 1;
1893
                $max_page = $page + $window;
1894
            } else {
1895
                $min_page = ($page - (2 * $window - ($pages - $page))) + 1;
1896
                $max_page = $pages;
1897
            }
1898
1899
            // Make sure min_page is always at least 1
1900
            // and max_page is never greater than $pages
1901
            $min_page = max($min_page, 1);
1902
            $max_page = min($max_page, $pages);
1903
1904
            for ($i = $min_page; $i <= $max_page; $i++) {
1905
                #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...
1906
                if ($i != $page) {
1907
                    echo "<a class=\"pagenav\" href=\"display.php?{$url}&amp;page={$i}\">$i</a>\n";
1908
                } else {
1909
                    echo "$i\n";
1910
                }
1911
            }
1912
            if ($page != $pages) {
1913
                $temp = $page + 1;
1914
                echo "<a class=\"pagenav\" href=\"display.php?{$url}&amp;page={$temp}\">{$lang['strnext']}</a>\n";
1915
                echo "<a class=\"pagenav\" href=\"display.php?{$url}&amp;page={$pages}\">{$lang['strlast']}</a>\n";
1916
            }
1917
            echo "</p>\n";
1918
        }
1919
    }
1920
1921
    /**
1922
     * Converts a PHP.INI size variable to bytes.  Taken from publically available
1923
     * function by Chris DeRose, here: http://www.php.net/manual/en/configuration.directives.php#ini.file-uploads
1924
     * @param $strIniSize The PHP.INI variable
1925
     * @return size in bytes, false on failure
0 ignored issues
show
Coding Style introduced by
Tag cannot be grouped with parameter tags in a doc comment
Loading history...
1926
     */
1927
    public function inisizeToBytes($strIniSize)
1928
    {
1929
        // This function will take the string value of an ini 'size' parameter,
1930
        // and return a double (64-bit float) representing the number of bytes
1931
        // that the parameter represents. Or false if $strIniSize is unparseable.
1932
        $a_IniParts = [];
1933
1934
        if (!is_string($strIniSize)) {
1935
            return false;
1936
        }
1937
1938
        if (!preg_match('/^(\d+)([bkm]*)$/i', $strIniSize, $a_IniParts)) {
1939
            return false;
1940
        }
1941
1942
        $nSize   = (double) $a_IniParts[1];
1943
        $strUnit = strtolower($a_IniParts[2]);
1944
1945
        switch ($strUnit) {
1946
            case 'm':
1947
                return ($nSize * (double) 1048576);
1948
            case 'k':
1949
                return ($nSize * (double) 1024);
1950
            case 'b':
1951
            default:
1952
                return $nSize;
1953
        }
1954
    }
1955
1956
    public function getRequestVars($subject = '')
1 ignored issue
show
Coding Style introduced by
Missing function doc comment
Loading history...
1957
    {
1958
        $v = [];
1959
        if (!empty($subject)) {
1960
            $v['subject'] = $subject;
1961
        }
1962
1963
        if ($this->_server_id !== null && $subject != 'root') {
1964
            $v['server'] = $this->_server_id;
1965
            if ($this->_database !== null && $subject != 'server') {
1966
                $v['database'] = $this->_database;
1967
                if (isset($_REQUEST['schema']) && $subject != 'database') {
1968
                    $v['schema'] = $_REQUEST['schema'];
1969
                }
1970
            }
1971
        }
1972
        //$this->prtrace($v);
1973
        return $v;
1974
    }
1975
1976
    public function icon($icon)
1 ignored issue
show
Coding Style introduced by
Missing function doc comment
Loading history...
1977
    {
1978
        if (is_string($icon)) {
1979
            $path = "/images/themes/{$this->conf['theme']}/{$icon}";
1980
            if (file_exists(\BASE_PATH . $path . '.png')) {
1981
                return SUBFOLDER . $path . '.png';
1982
            }
1983
1984
            if (file_exists(\BASE_PATH . $path . '.gif')) {
1985
                return SUBFOLDER . $path . '.gif';
1986
            }
1987
1988
            if (file_exists(\BASE_PATH . $path . '.ico')) {
1989
                return SUBFOLDER . $path . '.ico';
1990
            }
1991
1992
            $path = "/images/themes/default/{$icon}";
1993
            if (file_exists(\BASE_PATH . $path . '.png')) {
1994
                return SUBFOLDER . $path . '.png';
1995
            }
1996
1997
            if (file_exists(\BASE_PATH . $path . '.gif')) {
1998
                return SUBFOLDER . $path . '.gif';
1999
            }
2000
2001
            if (file_exists(\BASE_PATH . $path . '.ico')) {
2002
                return SUBFOLDER . $path . '.ico';
2003
            }
2004
        } else {
2005
            // Icon from plugins
2006
            $path = "/plugins/{$icon[0]}/images/{$icon[1]}";
2007
            if (file_exists(\BASE_PATH . $path . '.png')) {
2008
                return SUBFOLDER . $path . '.png';
2009
            }
2010
2011
            if (file_exists(\BASE_PATH . $path . '.gif')) {
2012
                return SUBFOLDER . $path . '.gif';
2013
            }
2014
2015
            if (file_exists(\BASE_PATH . $path . '.ico')) {
2016
                return SUBFOLDER . $path . '.ico';
2017
            }
2018
        }
2019
        return '';
2020
    }
2021
2022
    /**
2023
     * Function to escape command line parameters
2024
     * @param string $str The string to escape
2025
     * @return string The escaped string
0 ignored issues
show
Coding Style introduced by
Tag cannot be grouped with parameter tags in a doc comment
Loading history...
2026
     */
2027
    public function escapeShellArg($str)
2028
    {
2029
        $data = $this->getDatabaseAccessor();
2030
        $lang = $this->lang;
2031
2032
        if (strtoupper(substr(PHP_OS, 0, 3)) === 'WIN') {
2033
            // Due to annoying PHP bugs, shell arguments cannot be escaped
2034
            // (command simply fails), so we cannot allow complex objects
2035
            // to be dumped.
2036
            if (preg_match('/^[_.[:alnum:]]+$/', $str)) {
2037
                return $str;
2038
            }
2039
2040
            return $this->halt($lang['strcannotdumponwindows']);
2041
        } else {
2042
            return escapeshellarg($str);
2043
        }
2044
    }
2045
2046
    /**
2047
     * Function to escape command line programs
2048
     * @param string $str The string to escape
2049
     * @return string The escaped string
0 ignored issues
show
Coding Style introduced by
Tag cannot be grouped with parameter tags in a doc comment
Loading history...
2050
     */
2051
    public function escapeShellCmd($str)
2052
    {
2053
        $data = $this->getDatabaseAccessor();
2054
2055
        if (strtoupper(substr(PHP_OS, 0, 3)) === 'WIN') {
2056
            $data->fieldClean($str);
2057
            return '"' . $str . '"';
2058
        }
2059
2060
        return escapeshellcmd($str);
2061
    }
2062
2063
    /**
2064
     * Save the given SQL script in the history
2065
     * of the database and server.
2066
     * @param $script the SQL script to save.
2067
     */
2068
    public function saveScriptHistory($script)
2069
    {
2070
        list($usec, $sec)                                                         = explode(' ', microtime());
2071
        $time                                                                     = ((float) $usec + (float) $sec);
2072
        $_SESSION['history'][$_REQUEST['server']][$_REQUEST['database']]["$time"] = [
2073
            'query'    => $script,
2074
            'paginate' => !isset($_REQUEST['paginate']) ? 'f' : 't',
2075
            'queryid'  => $time,
2076
        ];
2077
    }
2078
2079
    /*
2080
     * Output dropdown list to select server and
2081
     * databases form the popups windows.
2082
     * @param $onchange Javascript action to take when selections change.
2083
     */
2084
    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...
2085
    {
2086
        $lang = $this->lang;
2087
2088
        $connection_html = "<table class=\"printconnection\" style=\"width: 100%\"><tr><td class=\"popup_select1\">\n";
2089
2090
        $servers      = $this->getServers();
2091
        $forcedserver = null;
2092
        if (count($servers) === 1) {
2093
            $forcedserver = $this->_server_id;
2094
            $connection_html .= '<input type="hidden" readonly="readonly" value="' . $this->_server_id . '" name="server">';
2095
        } else {
2096
            $connection_html .= '<label>';
2097
            $connection_html .= $this->printHelp($lang['strserver'], 'pg.server', false);
2098
            $connection_html .= ': </label>';
2099
            $connection_html .= " <select name=\"server\" {$onchange}>\n";
2100
            foreach ($servers as $info) {
2101
                if (empty($info['username'])) {
2102
                    continue;
2103
                }
2104
                $selected = isset($_REQUEST['server']) && $info['id'] == $_REQUEST['server'] ? ' selected="selected"' : '';
2105
                // not logged on this server
2106
                $connection_html .= '<option value="' . htmlspecialchars($info['id']) . '" ' . $selected . '>';
2107
                $connection_html .= htmlspecialchars("{$info['desc']} ({$info['id']})");
2108
                $connection_html .= "</option>\n";
2109
            }
2110
            $connection_html .= "</select>\n";
2111
        }
2112
2113
        $connection_html .= "</td><td class=\"popup_select2\" style=\"text-align: right\">\n";
2114
2115
        if (count($servers) === 1 && isset($servers[$this->_server_id]['useonlydefaultdb']) && $servers[$this->_server_id]['useonlydefaultdb'] === true) {
2116
            $connection_html .= '<input type="hidden" name="database" value="' . htmlspecialchars($servers[$this->_server_id]['defaultdb']) . "\" />\n";
2117
        } else {
2118
2119
            // Get the list of all databases
2120
            $data      = $this->getDatabaseAccessor();
2121
            $databases = $data->getDatabases();
2122
            if ($databases->recordCount() > 0) {
2123
                $connection_html .= '<label>';
2124
                $connection_html .= $this->printHelp($lang['strdatabase'], 'pg.database', false);
2125
                $connection_html .= ": <select name=\"database\" {$onchange}>\n";
2126
2127
                //if no database was selected, user should select one
2128
                if (!isset($_REQUEST['database'])) {
2129
                    $connection_html .= "<option value=\"\">--</option>\n";
2130
                }
2131
2132
                while (!$databases->EOF) {
2133
                    $dbname     = $databases->fields['datname'];
2134
                    $dbselected = isset($_REQUEST['database']) && $dbname == $_REQUEST['database'] ? ' selected="selected"' : '';
2135
                    $connection_html .= '<option value="' . htmlspecialchars($dbname) . '" ' . $dbselected . '>' . htmlspecialchars($dbname) . "</option>\n";
2136
2137
                    $databases->moveNext();
2138
                }
2139
                $connection_html .= "</select></label>\n";
2140
            } else {
2141
                $server_info = $this->misc->getServerInfo();
2142
                $connection_html .= '<input type="hidden" name="database" value="' . htmlspecialchars($server_info['defaultdb']) . "\" />\n";
2143
            }
2144
        }
2145
2146
        $connection_html .= "</td></tr></table>\n";
2147
2148
        if ($do_print) {
2149
            echo $connection_html;
2150
        } else {
2151
            return $connection_html;
2152
        }
2153
    }
2154
2155
    /**
2156
     * 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...
2157
     * or by constraint.
2158
     * @param $table The table to retrieve FK contraints from
2159
     * @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...
2160
     *   array(
2161
     *     'byconstr' => array(
2162
     *       constrain id => array(
2163
     *         confrelid => foreign relation oid
2164
     *         f_schema => foreign schema name
2165
     *         f_table => foreign table name
2166
     *         pattnums => array of parent's fields nums
2167
     *         pattnames => array of parent's fields names
2168
     *         fattnames => array of foreign attributes names
2169
     *       )
2170
     *     ),
2171
     *     'byfield' => array(
2172
     *       attribute num => array (constraint id, ...)
2173
     *     ),
2174
     *     'code' => HTML/js code to include in the page for auto-completion
2175
     *   )
2176
     **/
2177
    public function getAutocompleteFKProperties($table)
2178
    {
2179
        $data = $this->getDatabaseAccessor();
2180
2181
        $fksprops = [
2182
            'byconstr' => [],
2183
            'byfield'  => [],
2184
            'code'     => '',
2185
        ];
2186
2187
        $constrs = $data->getConstraintsWithFields($table);
2188
2189
        if (!$constrs->EOF) {
2190
            $conrelid = $constrs->fields['conrelid'];
2191
            while (!$constrs->EOF) {
2192
                if ($constrs->fields['contype'] == 'f') {
2193
                    if (!isset($fksprops['byconstr'][$constrs->fields['conid']])) {
2194
                        $fksprops['byconstr'][$constrs->fields['conid']] = [
2195
                            'confrelid' => $constrs->fields['confrelid'],
2196
                            'f_table'   => $constrs->fields['f_table'],
2197
                            'f_schema'  => $constrs->fields['f_schema'],
2198
                            'pattnums'  => [],
2199
                            'pattnames' => [],
2200
                            'fattnames' => [],
2201
                        ];
2202
                    }
2203
2204
                    $fksprops['byconstr'][$constrs->fields['conid']]['pattnums'][]  = $constrs->fields['p_attnum'];
2205
                    $fksprops['byconstr'][$constrs->fields['conid']]['pattnames'][] = $constrs->fields['p_field'];
2206
                    $fksprops['byconstr'][$constrs->fields['conid']]['fattnames'][] = $constrs->fields['f_field'];
2207
2208
                    if (!isset($fksprops['byfield'][$constrs->fields['p_attnum']])) {
2209
                        $fksprops['byfield'][$constrs->fields['p_attnum']] = [];
2210
                    }
2211
2212
                    $fksprops['byfield'][$constrs->fields['p_attnum']][] = $constrs->fields['conid'];
2213
                }
2214
                $constrs->moveNext();
2215
            }
2216
2217
            $fksprops['code'] = "<script type=\"text/javascript\">\n";
2218
            $fksprops['code'] .= "var constrs = {};\n";
2219
            foreach ($fksprops['byconstr'] as $conid => $props) {
2220
                $fksprops['code'] .= "constrs.constr_{$conid} = {\n";
2221
                $fksprops['code'] .= 'pattnums: [' . implode(',', $props['pattnums']) . "],\n";
2222
                $fksprops['code'] .= "f_table:'" . addslashes(htmlentities($props['f_table'], ENT_QUOTES, 'UTF-8')) . "',\n";
2223
                $fksprops['code'] .= "f_schema:'" . addslashes(htmlentities($props['f_schema'], ENT_QUOTES, 'UTF-8')) . "',\n";
2224
                $_ = '';
2225
                foreach ($props['pattnames'] as $n) {
2226
                    $_ .= ",'" . htmlentities($n, ENT_QUOTES, 'UTF-8') . "'";
2227
                }
2228
                $fksprops['code'] .= 'pattnames: [' . substr($_, 1) . "],\n";
2229
2230
                $_ = '';
2231
                foreach ($props['fattnames'] as $n) {
2232
                    $_ .= ",'" . htmlentities($n, ENT_QUOTES, 'UTF-8') . "'";
2233
                }
2234
2235
                $fksprops['code'] .= 'fattnames: [' . substr($_, 1) . "]\n";
2236
                $fksprops['code'] .= "};\n";
2237
            }
2238
2239
            $fksprops['code'] .= "var attrs = {};\n";
2240
            foreach ($fksprops['byfield'] as $attnum => $cstrs) {
2241
                $fksprops['code'] .= "attrs.attr_{$attnum} = [" . implode(',', $fksprops['byfield'][$attnum]) . "];\n";
2242
            }
2243
2244
            $fksprops['code'] .= "var table='" . addslashes(htmlentities($table, ENT_QUOTES, 'UTF-8')) . "';";
2245
            $fksprops['code'] .= "var server='" . htmlentities($_REQUEST['server'], ENT_QUOTES, 'UTF-8') . "';";
2246
            $fksprops['code'] .= "var database='" . addslashes(htmlentities($_REQUEST['database'], ENT_QUOTES, 'UTF-8')) . "';";
2247
            $fksprops['code'] .= "var subfolder='" . SUBFOLDER . "';";
2248
            $fksprops['code'] .= "</script>\n";
2249
2250
            $fksprops['code'] .= '<div id="fkbg"></div>';
2251
            $fksprops['code'] .= '<div id="fklist"></div>';
2252
            $fksprops['code'] .= '<script src="' . SUBFOLDER . '/js/ac_insert_row.js" type="text/javascript"></script>';
2253
        } 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...
2254
        {
2255
            return false;
2256
        }
2257
2258
        return $fksprops;
2259
    }
2260
}
2261