Passed
Push — develop ( eb55f7...e088af )
by Felipe
04:32
created

src/classes/Misc.php (4 issues)

1
<?php
2
3
namespace PHPPgAdmin;
4
5
use \PHPPgAdmin\Decorators\Decorator;
6
7
/**
8
 * Class to hold various commonly used functions
9
 *
10
 * $Id: Misc.php,v 1.171 2008/03/17 21:35:48 ioguix Exp $
11
 */
12
13
class Misc
14
{
15
    use \PHPPgAdmin\HelperTrait;
16
17
    private $_connection       = null;
18
    private $_no_db_connection = false;
19
    private $_reload_browser   = false;
20
    private $app               = null;
21
    private $data              = null;
22
    private $database          = null;
23
    private $server_id         = null;
24
    public $appLangFiles       = [];
25
    public $appName            = '';
26
    public $appVersion         = '';
27
    public $form               = '';
28
    public $href               = '';
29
    public $_name              = 'Misc';
30
    public $lang               = [];
31
    private $server_info       = null;
32
    private $error_msg         = '';
33
34
    private $container = null;
35
36
    /* Constructor */
37
    public function __construct(\Slim\Container $container)
38
    {
39
        $this->container = $container;
40
41
        $this->lang = $container->get('lang');
42
        $this->conf = $container->get('conf');
43
        //$this->view           = $container->get('view');
44
        $this->plugin_manager = $container->get('plugin_manager');
45
        $this->appLangFiles   = $container->get('appLangFiles');
46
47
        $this->appName          = $container->get('settings')['appName'];
48
        $this->appVersion       = $container->get('settings')['appVersion'];
49
        $this->postgresqlMinVer = $container->get('settings')['postgresqlMinVer'];
50
        $this->phpMinVer        = $container->get('settings')['phpMinVer'];
51
52
        $base_version = $container->get('settings')['base_version'];
53
54
        // Check for config file version mismatch
55
        if (!isset($this->conf['version']) || $base_version > $this->conf['version']) {
56
            $container->get('utils')->addError($this->lang['strbadconfig']);
57
        }
58
59
        // Check database support is properly compiled in
60
        if (!function_exists('pg_connect')) {
61
            $container->get('utils')->addError($this->lang['strnotloaded']);
62
        }
63
64
        // Check the version of PHP
65
        if (version_compare(phpversion(), $this->phpMinVer, '<')) {
66
            $container->get('utils')->addError(sprintf('Version of PHP not supported. Please upgrade to version %s or later.', $this->phpMinVer));
67
        }
68
69
        if (count($this->conf['servers']) === 1) {
70
            $info            = $this->conf['servers'][0];
71
            $this->server_id = $info['host'] . ':' . $info['port'] . ':' . $info['sslmode'];
72
        } elseif (isset($_REQUEST['server'])) {
73
            $this->server_id = $_REQUEST['server'];
74
        } elseif (isset($_SESSION['webdbLogin']) && count($_SESSION['webdbLogin']) > 0) {
75
            $this->server_id = array_keys($_SESSION['webdbLogin'])[0];
76
        }
77
    }
78
79
    /**
80
     * Sets the view instance property of this class
81
     * @param \Slim\Views\Twig $view [description]
82
     */
83
    public function setView(\Slim\Views\Twig $view)
84
    {
85
        $this->view = $view;
86
    }
87
88
    /**
89
     * Adds or modifies a key in the $conf instance property of this class
90
     * @param string $key   [description]
91
     * @param mixed $value [description]
92
     * @return $this
93
     */
94
    public function setConf(string $key, $value)
95
    {
96
        $this->conf[$key] = $value;
97
        return $this;
98
    }
99
100
    /**
101
     * gets the value of a config property, or the array of all config properties
102
     * @param  mixed $key value of the key to be retrieved. If null, the full array is returnes
103
     * @return mixed the whole $conf array, the value of $conf[key] or null if said key does not exist
104
     */
105
    public function getConf($key = null)
106
    {
107
        if ($key === null) {
108
            return $this->conf;
109
        } elseif (array_key_exists($key, $this->conf)) {
110
            return $this->conf[$key];
111
        }
112
        return null;
113
    }
114
115
    public function getServerId()
116
    {
117
        return $this->server_id;
118
    }
119
120
    /**
121
     * Displays link to the context help.
122
     * @param $str   - the string that the context help is related to (already escaped)
123
     * @param $help  - help section identifier
124
     * @param $do_print true to echo, false to return
125
     */
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...
126
    public function printHelp($str, $help = null, $do_print = true)
127
    {
128
        //\PC::debug(['str' => $str, 'help' => $help], 'printHelp');
129
        if ($help !== null) {
130
            $helplink = $this->getHelpLink($help);
131
            $str .= '<a class="help" href="' . $helplink . '" title="' . $this->lang['strhelp'] . '" target="phppgadminhelp">' . $this->lang['strhelpicon'] . '</a>';
132
        }
133
        if ($do_print) {
134
            echo $str;
135
        } else {
136
            return $str;
137
        }
138
    }
139
140
    public function getHelpLink($help)
141
    {
142
        return htmlspecialchars(SUBFOLDER . '/help?help=' . urlencode($help) . '&server=' . urlencode($this->getServerId()));
143
    }
144
145
    /**
146
     * [setReloadBrowser description]
147
     *
148
     * @param boolean $flag sets internal $_reload_browser var which will be passed to the footer methods
149
     * @return $this
150
     */
151
    public function setReloadBrowser($flag)
152
    {
153
        $this->_reload_browser = boolval($flag);
154
        return $this;
155
    }
156
157
    public function getReloadBrowser()
158
    {
159
        return $this->_reload_browser;
160
    }
161
162
    /**
163
     * Default Error Handler. This will be called with the following params
164
     *
165
     * @param $dbms         the RDBMS you are connecting to
166
     * @param $fn           the name of the calling function (in uppercase)
167
     * @param $errno        the native error number from the database
168
     * @param $errmsg       the native error msg from the database
169
     * @param $p1           $fn specific parameter - see below
170
     * @param $p2
171
     * @param $thisConnection
172
     * @throws \PHPPgAdmin\ADOdbException
173
     * @internal param $P2 $fn specific parameter - see below
174
     */
175
    public static function adodb_throw($dbms, $fn, $errno, $errmsg, $p1, $p2, $thisConnection)
176
    {
177
        if (error_reporting() == 0) {
178
            return;
179
        }
180
181
        $backtrace = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS, 2);
182
183
        $btarray0 = [
184
            'msg'      => 'ADOdbException at ',
185
            'class'    => $backtrace[1]['class'],
186
            'type'     => $backtrace[1]['type'],
187
            'function' => $backtrace[1]['function'],
188
            'spacer'   => ' ',
189
            'line'     => $backtrace[0]['line'],
190
        ];
191
192
        $errmsg = htmlspecialchars(\PHPPgAdmin\HelperTrait::br2ln($errmsg));
193
        $p1     = htmlspecialchars(\PHPPgAdmin\HelperTrait::br2ln($p1));
194
        $p2     = htmlspecialchars(\PHPPgAdmin\HelperTrait::br2ln($p2));
195
        switch ($fn) {
196
            case 'EXECUTE':
197
                $sql         = $p1;
198
                $inputparams = $p2;
199
200
                $error_msg = '<p><b>strsqlerror</b><br />' . nl2br($errmsg) . '</p> <p><b>SQL:</b><br />' . nl2br($sql) . '</p>	';
201
202
                echo '<table class="error" cellpadding="5"><tr><td>' . nl2br($error_msg) . '</td></tr></table><br />' . "\n";
203
204
                break;
205
206
            case 'PCONNECT':
207
            case 'CONNECT':
208
                // do nothing;
209
                break;
210
            default:
211
                $s = "$dbms error: [$errno: $errmsg] in $fn($p1, $p2)\n";
212
                echo "<table class=\"error\" cellpadding=\"5\"><tr><td>{$s}</td></tr></table><br />\n";
213
                break;
214
        }
215
216
        $tag = implode('', $btarray0);
217
218
        \PC::debug(['errno' => $errno, 'fn' => $fn, 'errmsg' => $errmsg], $tag);
219
220
        throw new \PHPPgAdmin\ADOdbException($dbms, $fn, $errno, $errmsg, $p1, $p2, $thisConnection);
221
    }
222
223
    public function getContainer()
224
    {
225
        return $this->container;
226
    }
227
228
    /**
229
     * sets $_no_db_connection boolean value, allows to render scripts that do not need an active session
230
     *
231
     * @param boolean $flag [description]
232
     * @return $this
233
     */
234
    public function setNoDBConnection($flag)
235
    {
236
        $this->_no_db_connection = boolval($flag);
237
        return $this;
238
    }
239
240
    public function getNoDBConnection()
241
    {
242
        return $this->_no_db_connection;
243
    }
244
245
    /**
246
     * Sets the last error message to display afterwards instead of just dying with the error msg
247
     * @param [string] $msg error message string
248
     */
249
    public function setErrorMsg($msg)
250
    {
251
        $this->error_msg = $msg;
252
        return $this;
253
    }
254
255
    public function getErrorMsg()
256
    {
257
        return $this->error_msg;
258
    }
259
260
    /**
261
     * Creates a database accessor
262
     *
263
     * @param string $database
264
     * @param null   $server_id
265
     * @return null
266
     */
267
    public function getDatabaseAccessor($database = '', $server_id = null)
268
    {
269
        $lang = $this->lang;
270
271
        if ($server_id !== null) {
272
            $this->server_id = $server_id;
273
        }
274
275
        $server_info = $this->getServerInfo($this->server_id);
276
277
        if ($this->_no_db_connection || !isset($server_info['username'])) {
278
            return null;
279
        }
280
281
        if ($this->data === null) {
282
            try {
283
                $_connection = $this->getConnection($database, $this->server_id);
284
            } catch (\Exception $e) {
285
                $this->setServerInfo(null, null, $this->server_id);
286
                $this->setNoDBConnection(true);
287
                $this->setErrorMsg($e->getMessage());
288
                return null;
289
            }
290
291
            //$this->prtrace('_connection', $_connection);
292
            if (!$_connection) {
293
                $this->container->utils->addError($lang['strloginfailed']);
294
                $this->setErrorMsg($lang['strloginfailed']);
295
                return null;
296
            }
297
            // Get the name of the database driver we need to use.
298
            // The description of the server is returned in $platform.
299
            $_type = $_connection->getDriver($platform);
300
301
            //$this->prtrace(['type' => $_type, 'platform' => $platform, 'pgVersion' => $_connection->conn->pgVersion]);
302
303
            if ($_type === null) {
304
                $errormsg = sprintf($lang['strpostgresqlversionnotsupported'], $this->postgresqlMinVer);
305
                $this->container->utils->addError($errormsg);
306
                $this->setErrorMsg($errormsg);
307
                return null;
308
            }
309
            $_type = '\PHPPgAdmin\Database\\' . $_type;
310
311
            $this->setServerInfo('platform', $platform, $this->server_id);
312
            $this->setServerInfo('pgVersion', $_connection->conn->pgVersion, $this->server_id);
313
314
            // Create a database wrapper class for easy manipulation of the
315
            // connection.
316
317
            $this->data              = new $_type($_connection->conn, $this->conf);
318
            $this->data->platform    = $_connection->platform;
319
            $this->data->server_info = $server_info;
320
            $this->data->conf        = $this->conf;
321
            $this->data->lang        = $this->lang;
322
323
            //$this->data->getHelpPages();
324
325
            //$this->prtrace('help_page has ' . count($this->data->help_page) . ' items');
326
327
            /* we work on UTF-8 only encoding */
328
            $this->data->execute("SET client_encoding TO 'UTF-8'");
329
330
            if ($this->data->hasByteaHexDefault()) {
331
                $this->data->execute('SET bytea_output TO escape');
332
            }
333
        }
334
335
        if ($this->_no_db_connection === false && $this->getDatabase() !== null && isset($_REQUEST['schema'])) {
336
            $status = $this->data->setSchema($_REQUEST['schema']);
337
338
            if ($status != 0) {
339
                $this->container->utils->addError($this->lang['strbadschema']);
340
                $this->setErrorMsg($this->lang['strbadschema']);
341
                return null;
342
            }
343
        }
344
345
        return $this->data;
346
    }
347
348
    public function getConnection($database = '', $server_id = null)
349
    {
350
        $lang = $this->lang;
351
352
        if ($this->_connection === null) {
353
            if ($server_id !== null) {
354
                $this->server_id = $server_id;
355
            }
356
            $server_info     = $this->getServerInfo($this->server_id);
357
            $database_to_use = $this->getDatabase($database);
358
359
            // Perform extra security checks if this config option is set
360
            if ($this->conf['extra_login_security']) {
361
                // Disallowed logins if extra_login_security is enabled.
362
                // These must be lowercase.
363
                $bad_usernames = [
364
                    'pgsql'         => 'pgsql',
365
                    'postgres'      => 'postgres',
366
                    'root'          => 'root',
367
                    'administrator' => 'administrator',
368
                ];
369
370
                if (isset($server_info['username']) && array_key_exists(strtolower($server_info['username']), $bad_usernames)) {
371
                    $msg = $lang['strlogindisallowed'];
372
                    throw new \Exception($msg);
373
                }
374
375
                if (!isset($server_info['password']) || $server_info['password'] == '') {
376
                    $msg = $lang['strlogindisallowed'];
377
378
                    throw new \Exception($msg);
379
                }
380
            }
381
382
            try {
383
                // Create the connection object and make the connection
384
                $this->_connection = new \PHPPgAdmin\Database\Connection(
385
                    $server_info['host'],
386
                    $server_info['port'],
387
                    $server_info['sslmode'],
388
                    $server_info['username'],
389
                    $server_info['password'],
390
                    $database_to_use
391
                );
392
            } catch (\PHPPgAdmin\ADOdbException $e) {
393
                throw new \Exception($lang['strloginfailed']);
394
            }
395
        }
396
        return $this->_connection;
397
    }
398
399
    /**
400
     * Validate and retrieve information on a server.
401
     * If the parameter isn't supplied then the currently
402
     * connected server is returned.
403
     * @param $server_id A server identifier (host:port)
404
     * @return An associative array of server properties
405
     */
406
    public function getServerInfo($server_id = null)
407
    {
408
409
        //\PC::debug(['$server_id' => $server_id]);
410
411
        if ($server_id !== null) {
412
            $this->server_id = $server_id;
413
        } elseif ($this->server_info !== null) {
414
            return $this->server_info;
415
        }
416
417
        // Check for the server in the logged-in list
418
        if (isset($_SESSION['webdbLogin'][$this->server_id])) {
419
            $this->server_info = $_SESSION['webdbLogin'][$this->server_id];
420
            return $this->server_info;
421
        }
422
423
        // Otherwise, look for it in the conf file
424
        foreach ($this->conf['servers'] as $idx => $info) {
425
            if ($this->server_id == $info['host'] . ':' . $info['port'] . ':' . $info['sslmode']) {
426
                if (isset($info['username'])) {
427
                    $this->setServerInfo(null, $info, $this->server_id);
428
                } elseif (isset($_SESSION['sharedUsername'])) {
429
                    $info['username'] = $_SESSION['sharedUsername'];
430
                    $info['password'] = $_SESSION['sharedPassword'];
431
                    $this->setReloadBrowser(true);
432
                    $this->setServerInfo(null, $info, $this->server_id);
433
                }
434
                $this->server_info = $info;
435
                return $this->server_info;
436
            }
437
        }
438
439
        if ($server_id === null) {
440
            $this->server_info = null;
441
            return $this->server_info;
442
        }
443
444
        $this->server_info = null;
445
        // Unable to find a matching server, are we being hacked?
446
        echo $this->lang['strinvalidserverparam'];
447
448
        exit;
0 ignored issues
show
Using exit here is not recommended.

In general, usage of exit should be done with care and only when running in a scripting context like a CLI script.

Loading history...
449
    }
450
451
    /**
452
     * Set server information.
453
     * @param $key parameter name to set, or null to replace all
454
     *             params with the assoc-array in $value.
455
     * @param $value the new value, or null to unset the parameter
456
     * @param $server_id the server identifier, or null for current
457
     *                   server.
458
     */
459
    public function setServerInfo($key, $value, $server_id = null)
460
    {
461
        //\PC::debug('setsetverinfo');
462
        if ($server_id === null && isset($_REQUEST['server'])) {
463
            $server_id = $_REQUEST['server'];
464
        }
465
466
        if ($key === null) {
467
            if ($value === null) {
468
                unset($_SESSION['webdbLogin'][$server_id]);
469
            } else {
470
                //\PC::debug(['server_id' => $server_id, 'value' => $value], 'webdbLogin null key');
471
                $_SESSION['webdbLogin'][$server_id] = $value;
472
            }
473
        } else {
474
            if ($value === null) {
475
                unset($_SESSION['webdbLogin'][$server_id][$key]);
476
            } else {
477
                //\PC::debug(['server_id' => $server_id, 'key' => $key, 'value' => $value], __FILE__ . ' ' . __LINE__ . ' webdbLogin key ' . $key);
478
                $_SESSION['webdbLogin'][$server_id][$key] = $value;
479
            }
480
        }
481
    }
482
483
    public function getDatabase($database = '')
484
    {
485
        if ($this->server_id === null && !isset($_REQUEST['database'])) {
486
            return null;
487
        }
488
489
        $server_info = $this->getServerInfo($this->server_id);
490
491
        if ($this->server_id !== null && isset($server_info['useonlydefaultdb']) && $server_info['useonlydefaultdb'] === true) {
492
            $this->database = $server_info['defaultdb'];
493
        } elseif ($database !== '') {
494
            $this->database = $database;
495
        } elseif (isset($_REQUEST['database'])) {
496
            // Connect to the current database
497
            $this->database = $_REQUEST['database'];
498
        } else {
499
            // or if one is not specified then connect to the default database.
500
            $this->database = $server_info['defaultdb'];
501
        }
502
503
        return $this->database;
504
    }
505
506
    /**
507
     * Get list of server groups
508
     *
509
     * @param bool $recordset return as RecordSet suitable for HTMLTableController::printTable if true, otherwise just return an array.
510
     * @param mixed $group_id     a group name to filter the returned servers using $this->conf[srv_groups]
511
     * @return array|\PHPPgAdmin\ArrayRecordSet either an array or a Recordset suitable for HTMLTableController::printTable
512
     */
513
    public function getServersGroups($recordset = false, $group_id = false)
514
    {
515
        $lang = $this->lang;
516
        $grps = [];
517
518
        if (isset($this->conf['srv_groups'])) {
519
            foreach ($this->conf['srv_groups'] as $i => $group) {
520
                if (
521
                    (($group_id === false) and (!isset($group['parents']))) /* root */
522
                    or (
523
                        ($group_id !== false)
524
                        and isset($group['parents'])
525
                        and in_array($group_id, explode(',',
526
                            preg_replace('/\s/', '', $group['parents'])
527
                        ))
528
                    ) /* nested group */
529
                ) {
530
                    $grps[$i] = [
531
                        'id'     => $i,
532
                        'desc'   => $group['desc'],
533
                        'icon'   => 'Servers',
534
                        'action' => Decorator::url('/views/servers',
535
                            [
536
                                'group' => Decorator::field('id'),
537
                            ]
538
                        ),
539
                        'branch' => Decorator::url('/tree/servers',
540
                            [
541
                                'group' => $i,
542
                            ]
543
                        ),
544
                    ];
545
                }
546
            }
547
548
            if ($group_id === false) {
549
                $grps['all'] = [
550
                    'id'     => 'all',
551
                    'desc'   => $lang['strallservers'],
552
                    'icon'   => 'Servers',
553
                    'action' => Decorator::url('/views/servers',
554
                        [
555
                            'group' => Decorator::field('id'),
556
                        ]
557
                    ),
558
                    'branch' => Decorator::url('/tree/servers',
559
                        [
560
                            'group' => 'all',
561
                        ]
562
                    ),
563
                ];
564
            }
565
        }
566
567
        if ($recordset) {
568
            return new ArrayRecordSet($grps);
569
        }
570
571
        return $grps;
572
    }
573
574
    /**
575
     * Get list of servers
576
     *
577
     * @param bool $recordset return as RecordSet suitable for HTMLTableController::printTable if true, otherwise just return an array.
578
     * @param mixed $group     a group name to filter the returned servers using $this->conf[srv_groups]
579
     * @return array|\PHPPgAdmin\ArrayRecordSet either an array or a Recordset suitable for HTMLTableController::printTable
580
     */
581
    public function getServers($recordset = false, $group = false)
582
    {
583
        $logins = isset($_SESSION['webdbLogin']) && is_array($_SESSION['webdbLogin']) ? $_SESSION['webdbLogin'] : [];
584
        $srvs   = [];
585
586
        if (($group !== false) && ($group !== 'all')) {
587
            if (isset($this->conf['srv_groups'][$group]['servers'])) {
588
                $group = array_fill_keys(explode(',', preg_replace('/\s/', '',
589
                    $this->conf['srv_groups'][$group]['servers'])), 1);
590
            } else {
591
                $group = '';
592
            }
593
        }
594
595
        foreach ($this->conf['servers'] as $idx => $info) {
596
            $server_id = $info['host'] . ':' . $info['port'] . ':' . $info['sslmode'];
597
            if ($group === false || isset($group[$idx]) || ($group === 'all')) {
598
                $server_id = $info['host'] . ':' . $info['port'] . ':' . $info['sslmode'];
599
600
                if (isset($logins[$server_id])) {
601
                    $srvs[$server_id] = $logins[$server_id];
602
                } else {
603
                    $srvs[$server_id] = $info;
604
                }
605
606
                $srvs[$server_id]['id']     = $server_id;
607
                $srvs[$server_id]['action'] = Decorator::url('/redirect/server',
608
                    [
609
                        'server' => Decorator::field('id'),
610
                    ]
611
                );
612
                if (isset($srvs[$server_id]['username'])) {
613
                    $srvs[$server_id]['icon']   = 'Server';
614
                    $srvs[$server_id]['branch'] = Decorator::url('/src/views/alldb',
615
                        [
616
                            'action'  => 'tree',
617
                            'subject' => 'server',
618
                            'server'  => Decorator::field('id'),
619
                        ]
620
                    );
621
                } else {
622
                    $srvs[$server_id]['icon']   = 'DisconnectedServer';
623
                    $srvs[$server_id]['branch'] = false;
624
                }
625
            }
626
        }
627
628
        uasort($srvs, ['self', '_cmp_desc']);
629
630
        if ($recordset) {
631
            return new ArrayRecordSet($srvs);
632
        }
633
        return $srvs;
634
    }
635
636
    /**
637
     * Set the current schema
638
     *
639
     * @param $schema The schema name
640
     * @return int 0 on success
641
     */
642
    public function setCurrentSchema($schema)
643
    {
644
        $data = $this->getDatabaseAccessor();
645
646
        $status = $data->setSchema($schema);
647
        if ($status != 0) {
648
            return $status;
649
        }
650
651
        $_REQUEST['schema'] = $schema;
652
        $this->setHREF();
653
        return 0;
654
    }
655
656
    public static function _cmp_desc($a, $b)
657
    {
658
        return strcmp($a['desc'], $b['desc']);
659
    }
660
661
    /**
662
     * Checks if dumps are properly set up
663
     * @param $all (optional) True to check pg_dumpall, false to just check pg_dump
664
     * @return True, dumps are set up, false otherwise
665
     */
666
    public function isDumpEnabled($all = false)
667
    {
668
        $info = $this->getServerInfo();
669
670
        return !empty($info[$all ? 'pg_dumpall_path' : 'pg_dump_path']);
671
    }
672
673
    /**
674
     * Sets the href tracking variable
675
     */
676
    public function setHREF()
677
    {
678
        $this->href = $this->getHREF();
679
        //\PC::debug($this->href, 'Misc::href');
680
        return $this;
681
    }
682
683
    /**
684
     * Get a href query string, excluding objects below the given object type (inclusive)
685
     *
686
     * @param null $exclude_from
687
     * @return string
688
     */
689
    public function getHREF($exclude_from = null)
690
    {
691
        $href = [];
692
        if (isset($_REQUEST['server']) && $exclude_from != 'server') {
693
            $href[] = 'server=' . urlencode($_REQUEST['server']);
694
        }
695
        if (isset($_REQUEST['database']) && $exclude_from != 'database') {
696
            $href[] = 'database=' . urlencode($_REQUEST['database']);
697
        }
698
        if (isset($_REQUEST['schema']) && $exclude_from != 'schema') {
699
            $href[] = 'schema=' . urlencode($_REQUEST['schema']);
700
        }
701
702
        return htmlentities(implode('&', $href));
703
    }
704
705
    public function getSubjectParams($subject)
706
    {
707
        $plugin_manager = $this->plugin_manager;
708
709
        $vars = [];
710
711
        switch ($subject) {
712
            case 'root':
713
                $vars = [
714
                    'params' => [
715
                        'subject' => 'root',
716
                    ],
717
                ];
718
                break;
719
            case 'server':
720
                $vars = ['params' => [
721
                    'server'  => $_REQUEST['server'],
722
                    'subject' => 'server',
723
                ]];
724
                break;
725
            case 'role':
726
                $vars = ['params' => [
727
                    'server'   => $_REQUEST['server'],
728
                    'subject'  => 'role',
729
                    'action'   => 'properties',
730
                    'rolename' => $_REQUEST['rolename'],
731
                ]];
732
                break;
733
            case 'database':
734
                $vars = ['params' => [
735
                    'server'   => $_REQUEST['server'],
736
                    'subject'  => 'database',
737
                    'database' => $_REQUEST['database'],
738
                ]];
739
                break;
740
            case 'schema':
741
                $vars = ['params' => [
742
                    'server'   => $_REQUEST['server'],
743
                    'subject'  => 'schema',
744
                    'database' => $_REQUEST['database'],
745
                    'schema'   => $_REQUEST['schema'],
746
                ]];
747
                break;
748
            case 'table':
749
                $vars = ['params' => [
750
                    'server'   => $_REQUEST['server'],
751
                    'subject'  => 'table',
752
                    'database' => $_REQUEST['database'],
753
                    'schema'   => $_REQUEST['schema'],
754
                    'table'    => $_REQUEST['table'],
755
                ]];
756
                break;
757
            case 'selectrows':
758
                $vars = [
759
                    'url'    => 'tables.php',
760
                    'params' => [
761
                        'server'   => $_REQUEST['server'],
762
                        'subject'  => 'table',
763
                        'database' => $_REQUEST['database'],
764
                        'schema'   => $_REQUEST['schema'],
765
                        'table'    => $_REQUEST['table'],
766
                        'action'   => 'confselectrows',
767
                    ]];
768
                break;
769
            case 'view':
770
                $vars = ['params' => [
771
                    'server'   => $_REQUEST['server'],
772
                    'subject'  => 'view',
773
                    'database' => $_REQUEST['database'],
774
                    'schema'   => $_REQUEST['schema'],
775
                    'view'     => $_REQUEST['view'],
776
                ]];
777
                break;
778
            case 'matview':
779
                $vars = ['params' => [
780
                    'server'   => $_REQUEST['server'],
781
                    'subject'  => 'matview',
782
                    'database' => $_REQUEST['database'],
783
                    'schema'   => $_REQUEST['schema'],
784
                    'matview'  => $_REQUEST['matview'],
785
                ]];
786
                break;
787
788
            case 'fulltext':
789
            case 'ftscfg':
790
                $vars = ['params' => [
791
                    'server'   => $_REQUEST['server'],
792
                    'subject'  => 'fulltext',
793
                    'database' => $_REQUEST['database'],
794
                    'schema'   => $_REQUEST['schema'],
795
                    'action'   => 'viewconfig',
796
                    'ftscfg'   => $_REQUEST['ftscfg'],
797
                ]];
798
                break;
799
            case 'function':
800
                $vars = ['params' => [
801
                    'server'       => $_REQUEST['server'],
802
                    'subject'      => 'function',
803
                    'database'     => $_REQUEST['database'],
804
                    'schema'       => $_REQUEST['schema'],
805
                    'function'     => $_REQUEST['function'],
806
                    'function_oid' => $_REQUEST['function_oid'],
807
                ]];
808
                break;
809
            case 'aggregate':
810
                $vars = ['params' => [
811
                    'server'   => $_REQUEST['server'],
812
                    'subject'  => 'aggregate',
813
                    'action'   => 'properties',
814
                    'database' => $_REQUEST['database'],
815
                    'schema'   => $_REQUEST['schema'],
816
                    'aggrname' => $_REQUEST['aggrname'],
817
                    'aggrtype' => $_REQUEST['aggrtype'],
818
                ]];
819
                break;
820
            case 'column':
821
                if (isset($_REQUEST['table'])) {
822
                    $vars = ['params' => [
823
                        'server'   => $_REQUEST['server'],
824
                        'subject'  => 'column',
825
                        'database' => $_REQUEST['database'],
826
                        'schema'   => $_REQUEST['schema'],
827
                        'table'    => $_REQUEST['table'],
828
                        'column'   => $_REQUEST['column'],
829
                    ]];
830
                } else {
831
                    $vars = ['params' => [
832
                        'server'   => $_REQUEST['server'],
833
                        'subject'  => 'column',
834
                        'database' => $_REQUEST['database'],
835
                        'schema'   => $_REQUEST['schema'],
836
                        'view'     => $_REQUEST['view'],
837
                        'column'   => $_REQUEST['column'],
838
                    ]];
839
                }
840
841
                break;
842
            case 'plugin':
843
                $vars = [
844
                    'url'    => 'plugin.php',
845
                    'params' => [
846
                        'server'  => $_REQUEST['server'],
847
                        'subject' => 'plugin',
848
                        'plugin'  => $_REQUEST['plugin'],
849
                    ]];
850
851
                if (!is_null($plugin_manager->getPlugin($_REQUEST['plugin']))) {
852
                    $vars['params'] = array_merge($vars['params'], $plugin_manager->getPlugin($_REQUEST['plugin'])->get_subject_params());
853
                }
854
855
                break;
856
            default:
857
                return false;
858
        }
859
860
        if (!isset($vars['url'])) {
861
            $vars['url'] = SUBFOLDER . '/redirect';
862
        }
863
        if ($vars['url'] == SUBFOLDER . '/redirect' && isset($vars['params']['subject'])) {
864
            $vars['url'] = SUBFOLDER . '/redirect/' . $vars['params']['subject'];
865
            unset($vars['params']['subject']);
866
        }
867
868
        return $vars;
869
    }
870
871
    /**
872
     * Sets the form tracking variable
873
     */
874
    public function setForm()
875
    {
876
        $form = [];
877
        if (isset($_REQUEST['server'])) {
878
            $form[] = '<input type="hidden" name="server" value="' . htmlspecialchars($_REQUEST['server']) . '" />';
879
        }
880
        if (isset($_REQUEST['database'])) {
881
            $form[] = '<input type="hidden" name="database" value="' . htmlspecialchars($_REQUEST['database']) . '" />';
882
        }
883
884
        if (isset($_REQUEST['schema'])) {
885
            $form[] = '<input type="hidden" name="schema" value="' . htmlspecialchars($_REQUEST['schema']) . '" />';
886
        }
887
        $this->form = implode("\n", $form);
888
        return $this->form;
889
890
        //\PC::debug($this->form, 'Misc::form');
891
    }
892
893
    /**
894
     * Render a value into HTML using formatting rules specified
895
     * by a type name and parameters.
896
     *
897
     * @param                        $str    The string to change
898
     *
899
     * @param                        $type   Field type (optional), this may be an internal PostgreSQL type, or:
900
     *                                       yesno    - same as bool, but renders as 'Yes' or 'No'.
901
     *                                       pre      - render in a <pre> block.
902
     *                                       nbsp     - replace all spaces with &nbsp;'s
903
     *                                       verbatim - render exactly as supplied, no escaping what-so-ever.
904
     *                                       callback - render using a callback function supplied in the 'function' param.
905
     *
906
     * @param array|\PHPPgAdmin\Type $params Type parameters (optional), known parameters:
907
     *                                       null     - string to display if $str is null, or set to TRUE to use a default 'NULL' string,
908
     *                                       otherwise nothing is rendered.
909
     *                                       clip     - if true, clip the value to a fixed length, and append an ellipsis...
910
     *                                       cliplen  - the maximum length when clip is enabled (defaults to $conf['max_chars'])
911
     *                                       ellipsis - the string to append to a clipped value (defaults to $lang['strellipsis'])
912
     *                                       tag      - an HTML element name to surround the value.
913
     *                                       class    - a class attribute to apply to any surrounding HTML element.
914
     *                                       align    - an align attribute ('left','right','center' etc.)
915
     *                                       true     - (type='bool') the representation of true.
916
     *                                       false    - (type='bool') the representation of false.
917
     *                                       function - (type='callback') a function name, accepts args ($str, $params) and returns a rendering.
918
     *                                       lineno   - prefix each line with a line number.
919
     *                                       map      - an associative array.
920
     * @return \PHPPgAdmin\The HTML rendered value
921
     */
922
    public function printVal($str, $type = null, $params = [])
923
    {
924
        $lang = $this->lang;
925
        $data = $this->data;
926
927
        // Shortcircuit for a NULL value
928
        if (is_null($str)) {
929
            return isset($params['null'])
930
            ? ($params['null'] === true ? '<i>NULL</i>' : $params['null'])
931
            : '';
932
        }
933
934
        if (isset($params['map']) && isset($params['map'][$str])) {
935
            $str = $params['map'][$str];
936
        }
937
938
        // Clip the value if the 'clip' parameter is true.
939
        if (isset($params['clip']) && $params['clip'] === true) {
940
            $maxlen   = isset($params['cliplen']) && is_integer($params['cliplen']) ? $params['cliplen'] : $this->conf['max_chars'];
941
            $ellipsis = isset($params['ellipsis']) ? $params['ellipsis'] : $lang['strellipsis'];
942
            if (strlen($str) > $maxlen) {
943
                $str = substr($str, 0, $maxlen - 1) . $ellipsis;
944
            }
945
        }
946
947
        $out = '';
948
949
        switch ($type) {
950
            case 'int2':
951
            case 'int4':
952
            case 'int8':
953
            case 'float4':
954
            case 'float8':
955
            case 'money':
956
            case 'numeric':
957
            case 'oid':
958
            case 'xid':
959
            case 'cid':
960
            case 'tid':
961
                $align = 'right';
962
                $out   = nl2br(htmlspecialchars(\PHPPgAdmin\HelperTrait::br2ln($str)));
963
                break;
964
            case 'yesno':
965
                if (!isset($params['true'])) {
966
                    $params['true'] = $lang['stryes'];
967
                }
968
969
                if (!isset($params['false'])) {
970
                    $params['false'] = $lang['strno'];
971
                }
972
973
            // No break - fall through to boolean case.
974
            case 'bool':
975
            case 'boolean':
976
                if (is_bool($str)) {
977
                    $str = $str ? 't' : 'f';
978
                }
979
980
                switch ($str) {
981
                    case 't':
982
                        $out   = (isset($params['true']) ? $params['true'] : $lang['strtrue']);
983
                        $align = 'center';
984
                        break;
985
                    case 'f':
986
                        $out   = (isset($params['false']) ? $params['false'] : $lang['strfalse']);
987
                        $align = 'center';
988
                        break;
989
                    default:
990
                        $out = htmlspecialchars($str);
991
                }
992
                break;
993
            case 'bytea':
994
                $tag   = 'div';
995
                $class = 'pre';
996
                $out   = $data->escapeBytea($str);
997
                break;
998
            case 'errormsg':
999
                $tag   = 'pre';
1000
                $class = 'error';
1001
                $out   = htmlspecialchars($str);
1002
                break;
1003
            case 'pre':
1004
                $tag = 'pre';
1005
                $out = htmlspecialchars($str);
1006
                break;
1007
            case 'prenoescape':
1008
                $tag = 'pre';
1009
                $out = $str;
1010
                break;
1011
            case 'nbsp':
1012
                $out = nl2br(str_replace(' ', '&nbsp;', \PHPPgAdmin\HelperTrait::br2ln($str)));
1013
1014
                break;
1015
            case 'verbatim':
1016
                $out = $str;
1017
                break;
1018
            case 'callback':
1019
                $out = $params['function']($str, $params);
1020
                break;
1021
            case 'prettysize':
1022
                if ($str == -1) {
1023
                    $out = $lang['strnoaccess'];
1024
                } else {
1025
                    $limit = 10 * 1024;
1026
                    $mult  = 1;
1027
                    if ($str < $limit * $mult) {
1028
                        $out = $str . ' ' . $lang['strbytes'];
1029
                    } else {
1030
                        $mult *= 1024;
1031
                        if ($str < $limit * $mult) {
1032
                            $out = floor(($str + $mult / 2) / $mult) . ' ' . $lang['strkb'];
1033
                        } else {
1034
                            $mult *= 1024;
1035
                            if ($str < $limit * $mult) {
1036
                                $out = floor(($str + $mult / 2) / $mult) . ' ' . $lang['strmb'];
1037
                            } else {
1038
                                $mult *= 1024;
1039
                                if ($str < $limit * $mult) {
1040
                                    $out = floor(($str + $mult / 2) / $mult) . ' ' . $lang['strgb'];
1041
                                } else {
1042
                                    $mult *= 1024;
1043
                                    if ($str < $limit * $mult) {
1044
                                        $out = floor(($str + $mult / 2) / $mult) . ' ' . $lang['strtb'];
1045
                                    }
1046
                                }
1047
                            }
1048
                        }
1049
                    }
1050
                }
1051
                break;
1052
            default:
1053
                // If the string contains at least one instance of >1 space in a row, a tab
1054
                // character, a space at the start of a line, or a space at the start of
1055
                // the whole string then render within a pre-formatted element (<pre>).
1056
                if (preg_match('/(^ |  |\t|\n )/m', $str)) {
1057
                    $tag   = 'pre';
1058
                    $class = 'data';
1059
                    $out   = htmlspecialchars($str);
1060
                } else {
1061
                    $out = nl2br(htmlspecialchars(\PHPPgAdmin\HelperTrait::br2ln($str)));
1062
                }
1063
        }
1064
1065
        if (isset($params['class'])) {
1066
            $class = $params['class'];
1067
        }
1068
1069
        if (isset($params['align'])) {
1070
            $align = $params['align'];
1071
        }
1072
1073
        if (!isset($tag) && (isset($class) || isset($align))) {
1074
            $tag = 'div';
1075
        }
1076
1077
        if (isset($tag)) {
1078
            $alignattr = isset($align) ? " style=\"text-align: {$align}\"" : '';
1079
            $classattr = isset($class) ? " class=\"{$class}\"" : '';
1080
            $out       = "<{$tag}{$alignattr}{$classattr}>{$out}</{$tag}>";
1081
        }
1082
1083
        // Add line numbers if 'lineno' param is true
1084
        if (isset($params['lineno']) && $params['lineno'] === true) {
1085
            $lines = explode("\n", $str);
1086
            $num   = count($lines);
1087
            if ($num > 0) {
1088
                $temp = "<table>\n<tr><td class=\"{$class}\" style=\"vertical-align: top; padding-right: 10px;\"><pre class=\"{$class}\">";
1089
                for ($i = 1; $i <= $num; $i++) {
1090
                    $temp .= $i . "\n";
1091
                }
1092
                $temp .= "</pre></td><td class=\"{$class}\" style=\"vertical-align: top;\">{$out}</td></tr></table>\n";
1093
                $out = $temp;
1094
            }
1095
            unset($lines);
1096
        }
1097
1098
        return $out;
1099
    }
1100
1101
    /**
1102
     * A function to recursively strip slashes.  Used to
1103
     * enforce magic_quotes_gpc being off.
1104
     * @param &var The variable to strip
1105
     */
1106
    public function stripVar(&$var)
1107
    {
1108
        if (is_array($var)) {
1109
            foreach ($var as $k => $v) {
1110
                $this->stripVar($var[$k]);
1111
1112
                /* magic_quotes_gpc escape keys as well ...*/
1113
                if (is_string($k)) {
1114
                    $ek = stripslashes($k);
1115
                    if ($ek !== $k) {
1116
                        $var[$ek] = $var[$k];
1117
                        unset($var[$k]);
1118
                    }
1119
                }
1120
            }
1121
        } else {
1122
            $var = stripslashes($var);
1123
        }
1124
    }
1125
1126
    /**
1127
     * Retrieve the tab info for a specific tab bar.
1128
     *
1129
     * @param $section The name of the tab bar.
1130
     * @return array
1131
     */
1132
    public function getNavTabs($section)
1133
    {
1134
        $data           = $this->data;
1135
        $lang           = $this->lang;
1136
        $plugin_manager = $this->plugin_manager;
1137
1138
        $hide_advanced = ($this->conf['show_advanced'] === false);
1139
        $tabs          = [];
1140
1141
        switch ($section) {
1142
            case 'root':
1143
                $tabs = [
1144
                    'intro'   => [
1145
                        'title' => $lang['strintroduction'],
1146
                        'url'   => 'intro.php',
1147
                        'icon'  => 'Introduction',
1148
                    ],
1149
                    'servers' => [
1150
                        'title' => $lang['strservers'],
1151
                        'url'   => 'servers.php',
1152
                        'icon'  => 'Servers',
1153
                    ],
1154
                ];
1155
                break;
1156
1157
            case 'server':
1158
                $hide_users = true;
1159
                if ($data) {
1160
                    $hide_users = !$data->isSuperUser();
1161
                }
1162
1163
                $tabs = [
1164
                    'databases' => [
1165
                        'title'   => $lang['strdatabases'],
1166
                        'url'     => 'alldb.php',
1167
                        'urlvars' => ['subject' => 'server'],
1168
                        'help'    => 'pg.database',
1169
                        'icon'    => 'Databases',
1170
                    ],
1171
                ];
1172
                if ($data && $data->hasRoles()) {
1173
                    $tabs = array_merge($tabs, [
1174
                        'roles' => [
1175
                            'title'   => $lang['strroles'],
1176
                            'url'     => 'roles.php',
1177
                            'urlvars' => ['subject' => 'server'],
1178
                            'hide'    => $hide_users,
1179
                            'help'    => 'pg.role',
1180
                            'icon'    => 'Roles',
1181
                        ],
1182
                    ]);
1183
                } else {
1184
                    $tabs = array_merge($tabs, [
1185
                        'users'  => [
1186
                            'title'   => $lang['strusers'],
1187
                            'url'     => 'users.php',
1188
                            'urlvars' => ['subject' => 'server'],
1189
                            'hide'    => $hide_users,
1190
                            'help'    => 'pg.user',
1191
                            'icon'    => 'Users',
1192
                        ],
1193
                        'groups' => [
1194
                            'title'   => $lang['strgroups'],
1195
                            'url'     => 'groups.php',
1196
                            'urlvars' => ['subject' => 'server'],
1197
                            'hide'    => $hide_users,
1198
                            'help'    => 'pg.group',
1199
                            'icon'    => 'UserGroups',
1200
                        ],
1201
                    ]);
1202
                }
1203
1204
                $tabs = array_merge($tabs, [
1205
                    'account'     => [
1206
                        'title'   => $lang['straccount'],
1207
                        'url'     => ($data && $data->hasRoles()) ? 'roles.php' : 'users.php',
1208
                        'urlvars' => ['subject' => 'server', 'action' => 'account'],
1209
                        'hide'    => !$hide_users,
1210
                        'help'    => 'pg.role',
1211
                        'icon'    => 'User',
1212
                    ],
1213
                    'tablespaces' => [
1214
                        'title'   => $lang['strtablespaces'],
1215
                        'url'     => 'tablespaces.php',
1216
                        'urlvars' => ['subject' => 'server'],
1217
                        'hide'    => !$data || !$data->hasTablespaces(),
1218
                        'help'    => 'pg.tablespace',
1219
                        'icon'    => 'Tablespaces',
1220
                    ],
1221
                    'export'      => [
1222
                        'title'   => $lang['strexport'],
1223
                        'url'     => 'alldb.php',
1224
                        'urlvars' => ['subject' => 'server', 'action' => 'export'],
1225
                        'hide'    => !$this->isDumpEnabled(),
1226
                        'icon'    => 'Export',
1227
                    ],
1228
                ]);
1229
                break;
1230
            case 'database':
1231
                $tabs = [
1232
                    'schemas'    => [
1233
                        'title'   => $lang['strschemas'],
1234
                        'url'     => 'schemas.php',
1235
                        'urlvars' => ['subject' => 'database'],
1236
                        'help'    => 'pg.schema',
1237
                        'icon'    => 'Schemas',
1238
                    ],
1239
                    'sql'        => [
1240
                        'title'   => $lang['strsql'],
1241
                        'url'     => 'database.php',
1242
                        'urlvars' => ['subject' => 'database', 'action' => 'sql', 'new' => 1],
1243
                        'help'    => 'pg.sql',
1244
                        'tree'    => false,
1245
                        'icon'    => 'SqlEditor',
1246
                    ],
1247
                    'find'       => [
1248
                        'title'   => $lang['strfind'],
1249
                        'url'     => 'database.php',
1250
                        'urlvars' => ['subject' => 'database', 'action' => 'find'],
1251
                        'tree'    => false,
1252
                        'icon'    => 'Search',
1253
                    ],
1254
                    'variables'  => [
1255
                        'title'   => $lang['strvariables'],
1256
                        'url'     => 'database.php',
1257
                        'urlvars' => ['subject' => 'database', 'action' => 'variables'],
1258
                        'help'    => 'pg.variable',
1259
                        'tree'    => false,
1260
                        'icon'    => 'Variables',
1261
                    ],
1262
                    'processes'  => [
1263
                        'title'   => $lang['strprocesses'],
1264
                        'url'     => 'database.php',
1265
                        'urlvars' => ['subject' => 'database', 'action' => 'processes'],
1266
                        'help'    => 'pg.process',
1267
                        'tree'    => false,
1268
                        'icon'    => 'Processes',
1269
                    ],
1270
                    'locks'      => [
1271
                        'title'   => $lang['strlocks'],
1272
                        'url'     => 'database.php',
1273
                        'urlvars' => ['subject' => 'database', 'action' => 'locks'],
1274
                        'help'    => 'pg.locks',
1275
                        'tree'    => false,
1276
                        'icon'    => 'Key',
1277
                    ],
1278
                    'admin'      => [
1279
                        'title'   => $lang['stradmin'],
1280
                        'url'     => 'database.php',
1281
                        'urlvars' => ['subject' => 'database', 'action' => 'admin'],
1282
                        'tree'    => false,
1283
                        'icon'    => 'Admin',
1284
                    ],
1285
                    'privileges' => [
1286
                        'title'   => $lang['strprivileges'],
1287
                        'url'     => 'privileges.php',
1288
                        'urlvars' => ['subject' => 'database'],
1289
                        'hide'    => !isset($data->privlist['database']),
1290
                        'help'    => 'pg.privilege',
1291
                        'tree'    => false,
1292
                        'icon'    => 'Privileges',
1293
                    ],
1294
                    'languages'  => [
1295
                        'title'   => $lang['strlanguages'],
1296
                        'url'     => 'languages.php',
1297
                        'urlvars' => ['subject' => 'database'],
1298
                        'hide'    => $hide_advanced,
1299
                        'help'    => 'pg.language',
1300
                        'icon'    => 'Languages',
1301
                    ],
1302
                    'casts'      => [
1303
                        'title'   => $lang['strcasts'],
1304
                        'url'     => 'casts.php',
1305
                        'urlvars' => ['subject' => 'database'],
1306
                        'hide'    => $hide_advanced,
1307
                        'help'    => 'pg.cast',
1308
                        'icon'    => 'Casts',
1309
                    ],
1310
                    'export'     => [
1311
                        'title'   => $lang['strexport'],
1312
                        'url'     => 'database.php',
1313
                        'urlvars' => ['subject' => 'database', 'action' => 'export'],
1314
                        'hide'    => !$this->isDumpEnabled(),
1315
                        'tree'    => false,
1316
                        'icon'    => 'Export',
1317
                    ],
1318
                ];
1319
                break;
1320
1321
            case 'schema':
1322
                $tabs = [
1323
                    'tables'      => [
1324
                        'title'   => $lang['strtables'],
1325
                        'url'     => 'tables.php',
1326
                        'urlvars' => ['subject' => 'schema'],
1327
                        'help'    => 'pg.table',
1328
                        'icon'    => 'Tables',
1329
                    ],
1330
                    'views'       => [
1331
                        'title'   => $lang['strviews'],
1332
                        'url'     => 'views.php',
1333
                        'urlvars' => ['subject' => 'schema'],
1334
                        'help'    => 'pg.view',
1335
                        'icon'    => 'Views',
1336
                    ],
1337
                    'matviews'    => [
1338
                        'title'   => 'M ' . $lang['strviews'],
1339
                        'url'     => 'materializedviews.php',
1340
                        'urlvars' => ['subject' => 'schema'],
1341
                        'help'    => 'pg.matview',
1342
                        'icon'    => 'MViews',
1343
                    ],
1344
                    'sequences'   => [
1345
                        'title'   => $lang['strsequences'],
1346
                        'url'     => 'sequences.php',
1347
                        'urlvars' => ['subject' => 'schema'],
1348
                        'help'    => 'pg.sequence',
1349
                        'icon'    => 'Sequences',
1350
                    ],
1351
                    'functions'   => [
1352
                        'title'   => $lang['strfunctions'],
1353
                        'url'     => 'functions.php',
1354
                        'urlvars' => ['subject' => 'schema'],
1355
                        'help'    => 'pg.function',
1356
                        'icon'    => 'Functions',
1357
                    ],
1358
                    'fulltext'    => [
1359
                        'title'   => $lang['strfulltext'],
1360
                        'url'     => 'fulltext.php',
1361
                        'urlvars' => ['subject' => 'schema'],
1362
                        'help'    => 'pg.fts',
1363
                        'tree'    => true,
1364
                        'icon'    => 'Fts',
1365
                    ],
1366
                    'domains'     => [
1367
                        'title'   => $lang['strdomains'],
1368
                        'url'     => 'domains.php',
1369
                        'urlvars' => ['subject' => 'schema'],
1370
                        'help'    => 'pg.domain',
1371
                        'icon'    => 'Domains',
1372
                    ],
1373
                    'aggregates'  => [
1374
                        'title'   => $lang['straggregates'],
1375
                        'url'     => 'aggregates.php',
1376
                        'urlvars' => ['subject' => 'schema'],
1377
                        'hide'    => $hide_advanced,
1378
                        'help'    => 'pg.aggregate',
1379
                        'icon'    => 'Aggregates',
1380
                    ],
1381
                    'types'       => [
1382
                        'title'   => $lang['strtypes'],
1383
                        'url'     => 'types.php',
1384
                        'urlvars' => ['subject' => 'schema'],
1385
                        'hide'    => $hide_advanced,
1386
                        'help'    => 'pg.type',
1387
                        'icon'    => 'Types',
1388
                    ],
1389
                    'operators'   => [
1390
                        'title'   => $lang['stroperators'],
1391
                        'url'     => 'operators.php',
1392
                        'urlvars' => ['subject' => 'schema'],
1393
                        'hide'    => $hide_advanced,
1394
                        'help'    => 'pg.operator',
1395
                        'icon'    => 'Operators',
1396
                    ],
1397
                    'opclasses'   => [
1398
                        'title'   => $lang['stropclasses'],
1399
                        'url'     => 'opclasses.php',
1400
                        'urlvars' => ['subject' => 'schema'],
1401
                        'hide'    => $hide_advanced,
1402
                        'help'    => 'pg.opclass',
1403
                        'icon'    => 'OperatorClasses',
1404
                    ],
1405
                    'conversions' => [
1406
                        'title'   => $lang['strconversions'],
1407
                        'url'     => 'conversions.php',
1408
                        'urlvars' => ['subject' => 'schema'],
1409
                        'hide'    => $hide_advanced,
1410
                        'help'    => 'pg.conversion',
1411
                        'icon'    => 'Conversions',
1412
                    ],
1413
                    'privileges'  => [
1414
                        'title'   => $lang['strprivileges'],
1415
                        'url'     => 'privileges.php',
1416
                        'urlvars' => ['subject' => 'schema'],
1417
                        'help'    => 'pg.privilege',
1418
                        'tree'    => false,
1419
                        'icon'    => 'Privileges',
1420
                    ],
1421
                    'export'      => [
1422
                        'title'   => $lang['strexport'],
1423
                        'url'     => 'schemas.php',
1424
                        'urlvars' => ['subject' => 'schema', 'action' => 'export'],
1425
                        'hide'    => !$this->isDumpEnabled(),
1426
                        'tree'    => false,
1427
                        'icon'    => 'Export',
1428
                    ],
1429
                ];
1430
                if (!$data->hasFTS()) {
1431
                    unset($tabs['fulltext']);
1432
                }
1433
1434
                break;
1435
1436
            case 'table':
1437
                $tabs = [
1438
                    'columns'     => [
1439
                        'title'   => $lang['strcolumns'],
1440
                        'url'     => 'tblproperties.php',
1441
                        'urlvars' => ['subject' => 'table', 'table' => Decorator::field('table')],
1442
                        'icon'    => 'Columns',
1443
                        'branch'  => true,
1444
                    ],
1445
                    'browse'      => [
1446
                        'title'   => $lang['strbrowse'],
1447
                        'icon'    => 'Columns',
1448
                        'url'     => 'display.php',
1449
                        'urlvars' => ['subject' => 'table', 'table' => Decorator::field('table')],
1450
                        'return'  => 'table',
1451
                        'branch'  => true,
1452
                    ],
1453
                    'select'      => [
1454
                        'title'   => $lang['strselect'],
1455
                        'icon'    => 'Search',
1456
                        'url'     => 'tables.php',
1457
                        'urlvars' => ['subject' => 'table', 'table' => Decorator::field('table'), 'action' => 'confselectrows'],
1458
                        'help'    => 'pg.sql.select',
1459
                    ],
1460
                    'insert'      => [
1461
                        'title'   => $lang['strinsert'],
1462
                        'url'     => 'tables.php',
1463
                        'urlvars' => [
1464
                            'action' => 'confinsertrow',
1465
                            'table'  => Decorator::field('table'),
1466
                        ],
1467
                        'help'    => 'pg.sql.insert',
1468
                        'icon'    => 'Operator',
1469
                    ],
1470
                    'indexes'     => [
1471
                        'title'   => $lang['strindexes'],
1472
                        'url'     => 'indexes.php',
1473
                        'urlvars' => ['subject' => 'table', 'table' => Decorator::field('table')],
1474
                        'help'    => 'pg.index',
1475
                        'icon'    => 'Indexes',
1476
                        'branch'  => true,
1477
                    ],
1478
                    'constraints' => [
1479
                        'title'   => $lang['strconstraints'],
1480
                        'url'     => 'constraints.php',
1481
                        'urlvars' => ['subject' => 'table', 'table' => Decorator::field('table')],
1482
                        'help'    => 'pg.constraint',
1483
                        'icon'    => 'Constraints',
1484
                        'branch'  => true,
1485
                    ],
1486
                    'triggers'    => [
1487
                        'title'   => $lang['strtriggers'],
1488
                        'url'     => 'triggers.php',
1489
                        'urlvars' => ['subject' => 'table', 'table' => Decorator::field('table')],
1490
                        'help'    => 'pg.trigger',
1491
                        'icon'    => 'Triggers',
1492
                        'branch'  => true,
1493
                    ],
1494
                    'rules'       => [
1495
                        'title'   => $lang['strrules'],
1496
                        'url'     => 'rules.php',
1497
                        'urlvars' => ['subject' => 'table', 'table' => Decorator::field('table')],
1498
                        'help'    => 'pg.rule',
1499
                        'icon'    => 'Rules',
1500
                        'branch'  => true,
1501
                    ],
1502
                    'admin'       => [
1503
                        'title'   => $lang['stradmin'],
1504
                        'url'     => 'tables.php',
1505
                        'urlvars' => ['subject' => 'table', 'table' => Decorator::field('table'), 'action' => 'admin'],
1506
                        'icon'    => 'Admin',
1507
                    ],
1508
                    'info'        => [
1509
                        'title'   => $lang['strinfo'],
1510
                        'url'     => 'info.php',
1511
                        'urlvars' => ['subject' => 'table', 'table' => Decorator::field('table')],
1512
                        'icon'    => 'Statistics',
1513
                    ],
1514
                    'privileges'  => [
1515
                        'title'   => $lang['strprivileges'],
1516
                        'url'     => 'privileges.php',
1517
                        'urlvars' => ['subject' => 'table', 'table' => Decorator::field('table')],
1518
                        'help'    => 'pg.privilege',
1519
                        'icon'    => 'Privileges',
1520
                    ],
1521
                    'import'      => [
1522
                        'title'   => $lang['strimport'],
1523
                        'url'     => 'tblproperties.php',
1524
                        'urlvars' => ['subject' => 'table', 'table' => Decorator::field('table'), 'action' => 'import'],
1525
                        'icon'    => 'Import',
1526
                        'hide'    => false,
1527
                    ],
1528
                    'export'      => [
1529
                        'title'   => $lang['strexport'],
1530
                        'url'     => 'tblproperties.php',
1531
                        'urlvars' => ['subject' => 'table', 'table' => Decorator::field('table'), 'action' => 'export'],
1532
                        'icon'    => 'Export',
1533
                        'hide'    => false,
1534
                    ],
1535
                ];
1536
                break;
1537
1538
            case 'view':
1539
                $tabs = [
1540
                    'columns'    => [
1541
                        'title'   => $lang['strcolumns'],
1542
                        'url'     => 'viewproperties.php',
1543
                        'urlvars' => ['subject' => 'view', 'view' => Decorator::field('view')],
1544
                        'icon'    => 'Columns',
1545
                        'branch'  => true,
1546
                    ],
1547
                    'browse'     => [
1548
                        'title'   => $lang['strbrowse'],
1549
                        'icon'    => 'Columns',
1550
                        'url'     => 'display.php',
1551
                        'urlvars' => [
1552
                            'action'  => 'confselectrows',
1553
                            'return'  => 'schema',
1554
                            'subject' => 'view',
1555
                            'view'    => Decorator::field('view'),
1556
                        ],
1557
                        'branch'  => true,
1558
                    ],
1559
                    'select'     => [
1560
                        'title'   => $lang['strselect'],
1561
                        'icon'    => 'Search',
1562
                        'url'     => 'views.php',
1563
                        'urlvars' => ['action' => 'confselectrows', 'view' => Decorator::field('view')],
1564
                        'help'    => 'pg.sql.select',
1565
                    ],
1566
                    'definition' => [
1567
                        'title'   => $lang['strdefinition'],
1568
                        'url'     => 'viewproperties.php',
1569
                        'urlvars' => ['subject' => 'view', 'view' => Decorator::field('view'), 'action' => 'definition'],
1570
                        'icon'    => 'Definition',
1571
                    ],
1572
                    'rules'      => [
1573
                        'title'   => $lang['strrules'],
1574
                        'url'     => 'rules.php',
1575
                        'urlvars' => ['subject' => 'view', 'view' => Decorator::field('view')],
1576
                        'help'    => 'pg.rule',
1577
                        'icon'    => 'Rules',
1578
                        'branch'  => true,
1579
                    ],
1580
                    'privileges' => [
1581
                        'title'   => $lang['strprivileges'],
1582
                        'url'     => 'privileges.php',
1583
                        'urlvars' => ['subject' => 'view', 'view' => Decorator::field('view')],
1584
                        'help'    => 'pg.privilege',
1585
                        'icon'    => 'Privileges',
1586
                    ],
1587
                    'export'     => [
1588
                        'title'   => $lang['strexport'],
1589
                        'url'     => 'viewproperties.php',
1590
                        'urlvars' => ['subject' => 'view', 'view' => Decorator::field('view'), 'action' => 'export'],
1591
                        'icon'    => 'Export',
1592
                        'hide'    => false,
1593
                    ],
1594
                ];
1595
                break;
1596
1597
            case 'matview':
1598
                $tabs = [
1599
                    'columns'    => [
1600
                        'title'   => $lang['strcolumns'],
1601
                        'url'     => 'materializedviewproperties.php',
1602
                        'urlvars' => ['subject' => 'matview', 'matview' => Decorator::field('matview')],
1603
                        'icon'    => 'Columns',
1604
                        'branch'  => true,
1605
                    ],
1606
                    'browse'     => [
1607
                        'title'   => $lang['strbrowse'],
1608
                        'icon'    => 'Columns',
1609
                        'url'     => 'display.php',
1610
                        'urlvars' => [
1611
                            'action'  => 'confselectrows',
1612
                            'return'  => 'schema',
1613
                            'subject' => 'matview',
1614
                            'matview' => Decorator::field('matview'),
1615
                        ],
1616
                        'branch'  => true,
1617
                    ],
1618
                    'select'     => [
1619
                        'title'   => $lang['strselect'],
1620
                        'icon'    => 'Search',
1621
                        'url'     => 'materializedviews.php',
1622
                        'urlvars' => ['action' => 'confselectrows', 'matview' => Decorator::field('matview')],
1623
                        'help'    => 'pg.sql.select',
1624
                    ],
1625
                    'definition' => [
1626
                        'title'   => $lang['strdefinition'],
1627
                        'url'     => 'materializedviewproperties.php',
1628
                        'urlvars' => ['subject' => 'matview', 'matview' => Decorator::field('matview'), 'action' => 'definition'],
1629
                        'icon'    => 'Definition',
1630
                    ],
1631
                    'indexes'    => [
1632
                        'title'   => $lang['strindexes'],
1633
                        'url'     => 'indexes.php',
1634
                        'urlvars' => ['subject' => 'matview', 'matview' => Decorator::field('matview')],
1635
                        'help'    => 'pg.index',
1636
                        'icon'    => 'Indexes',
1637
                        'branch'  => true,
1638
                    ],
1639
                    /*'constraints' => [
1640
                    'title' => $lang['strconstraints'],
1641
                    'url' => 'constraints.php',
1642
                    'urlvars' => ['subject' => 'matview', 'matview' => Decorator::field('matview')],
1643
                    'help' => 'pg.constraint',
1644
                    'icon' => 'Constraints',
1645
                    'branch' => true,
1646
                     */
1647
1648
                    'rules'      => [
1649
                        'title'   => $lang['strrules'],
1650
                        'url'     => 'rules.php',
1651
                        'urlvars' => ['subject' => 'matview', 'matview' => Decorator::field('matview')],
1652
                        'help'    => 'pg.rule',
1653
                        'icon'    => 'Rules',
1654
                        'branch'  => true,
1655
                    ],
1656
                    'privileges' => [
1657
                        'title'   => $lang['strprivileges'],
1658
                        'url'     => 'privileges.php',
1659
                        'urlvars' => ['subject' => 'matview', 'matview' => Decorator::field('matview')],
1660
                        'help'    => 'pg.privilege',
1661
                        'icon'    => 'Privileges',
1662
                    ],
1663
                    'export'     => [
1664
                        'title'   => $lang['strexport'],
1665
                        'url'     => 'materializedviewproperties.php',
1666
                        'urlvars' => ['subject' => 'matview', 'matview' => Decorator::field('matview'), 'action' => 'export'],
1667
                        'icon'    => 'Export',
1668
                        'hide'    => false,
1669
                    ],
1670
                ];
1671
                break;
1672
1673
            case 'function':
1674
                $tabs = [
1675
                    'definition' => [
1676
                        'title'   => $lang['strdefinition'],
1677
                        'url'     => 'functions.php',
1678
                        'urlvars' => [
1679
                            'subject'      => 'function',
1680
                            'function'     => Decorator::field('function'),
1681
                            'function_oid' => Decorator::field('function_oid'),
1682
                            'action'       => 'properties',
1683
                        ],
1684
                        'icon'    => 'Definition',
1685
                    ],
1686
                    'privileges' => [
1687
                        'title'   => $lang['strprivileges'],
1688
                        'url'     => 'privileges.php',
1689
                        'urlvars' => [
1690
                            'subject'      => 'function',
1691
                            'function'     => Decorator::field('function'),
1692
                            'function_oid' => Decorator::field('function_oid'),
1693
                        ],
1694
                        'icon'    => 'Privileges',
1695
                    ],
1696
                ];
1697
                break;
1698
1699
            case 'aggregate':
1700
                $tabs = [
1701
                    'definition' => [
1702
                        'title'   => $lang['strdefinition'],
1703
                        'url'     => 'aggregates.php',
1704
                        'urlvars' => [
1705
                            'subject'  => 'aggregate',
1706
                            'aggrname' => Decorator::field('aggrname'),
1707
                            'aggrtype' => Decorator::field('aggrtype'),
1708
                            'action'   => 'properties',
1709
                        ],
1710
                        'icon'    => 'Definition',
1711
                    ],
1712
                ];
1713
                break;
1714
1715
            case 'role':
1716
                $tabs = [
1717
                    'definition' => [
1718
                        'title'   => $lang['strdefinition'],
1719
                        'url'     => 'roles.php',
1720
                        'urlvars' => [
1721
                            'subject'  => 'role',
1722
                            'rolename' => Decorator::field('rolename'),
1723
                            'action'   => 'properties',
1724
                        ],
1725
                        'icon'    => 'Definition',
1726
                    ],
1727
                ];
1728
                break;
1729
1730
            case 'popup':
1731
                $tabs = [
1732
                    'sql'  => [
1733
                        'title'   => $lang['strsql'],
1734
                        'url'     => '/src/views/sqledit.php',
1735
                        'urlvars' => ['action' => 'sql', 'subject' => 'schema'],
1736
                        'help'    => 'pg.sql',
1737
                        'icon'    => 'SqlEditor',
1738
                    ],
1739
                    'find' => [
1740
                        'title'   => $lang['strfind'],
1741
                        'url'     => '/src/views/sqledit.php',
1742
                        'urlvars' => ['action' => 'find', 'subject' => 'schema'],
1743
                        'icon'    => 'Search',
1744
                    ],
1745
                ];
1746
                break;
1747
1748
            case 'column':
1749
                $tabs = [
1750
                    'properties' => [
1751
                        'title'   => $lang['strcolprop'],
1752
                        'url'     => 'colproperties.php',
1753
                        'urlvars' => [
1754
                            'subject' => 'column',
1755
                            'table'   => Decorator::field('table'),
1756
                            'column'  => Decorator::field('column'),
1757
                        ],
1758
                        'icon'    => 'Column',
1759
                    ],
1760
                    'privileges' => [
1761
                        'title'   => $lang['strprivileges'],
1762
                        'url'     => 'privileges.php',
1763
                        'urlvars' => [
1764
                            'subject' => 'column',
1765
                            'table'   => Decorator::field('table'),
1766
                            'column'  => Decorator::field('column'),
1767
                        ],
1768
                        'help'    => 'pg.privilege',
1769
                        'icon'    => 'Privileges',
1770
                    ],
1771
                ];
1772
                break;
1773
1774
            case 'fulltext':
1775
                $tabs = [
1776
                    'ftsconfigs' => [
1777
                        'title'   => $lang['strftstabconfigs'],
1778
                        'url'     => 'fulltext.php',
1779
                        'urlvars' => ['subject' => 'schema'],
1780
                        'hide'    => !$data->hasFTS(),
1781
                        'help'    => 'pg.ftscfg',
1782
                        'tree'    => true,
1783
                        'icon'    => 'FtsCfg',
1784
                    ],
1785
                    'ftsdicts'   => [
1786
                        'title'   => $lang['strftstabdicts'],
1787
                        'url'     => 'fulltext.php',
1788
                        'urlvars' => ['subject' => 'schema', 'action' => 'viewdicts'],
1789
                        'hide'    => !$data->hasFTS(),
1790
                        'help'    => 'pg.ftsdict',
1791
                        'tree'    => true,
1792
                        'icon'    => 'FtsDict',
1793
                    ],
1794
                    'ftsparsers' => [
1795
                        'title'   => $lang['strftstabparsers'],
1796
                        'url'     => 'fulltext.php',
1797
                        'urlvars' => ['subject' => 'schema', 'action' => 'viewparsers'],
1798
                        'hide'    => !$data->hasFTS(),
1799
                        'help'    => 'pg.ftsparser',
1800
                        'tree'    => true,
1801
                        'icon'    => 'FtsParser',
1802
                    ],
1803
                ];
1804
                break;
1805
        }
1806
1807
        // Tabs hook's place
1808
        $plugin_functions_parameters = [
1809
            'tabs'    => &$tabs,
1810
            'section' => $section,
1811
        ];
1812
        $plugin_manager->do_hook('tabs', $plugin_functions_parameters);
1813
1814
        return $tabs;
1815
    }
1816
1817
    /**
1818
     * Get the URL for the last active tab of a particular tab bar.
1819
     *
1820
     * @param $section
1821
     * @return mixed|null
1822
     */
1823
    public function getLastTabURL($section)
1824
    {
1825
        $data = $this->getDatabaseAccessor();
1826
1827
        $tabs = $this->getNavTabs($section);
1828
1829
        if (isset($_SESSION['webdbLastTab'][$section]) && isset($tabs[$_SESSION['webdbLastTab'][$section]])) {
1830
            $tab = $tabs[$_SESSION['webdbLastTab'][$section]];
1831
        } else {
1832
            $tab = reset($tabs);
1833
        }
1834
        $this->prtrace(['section' => $section, 'tabs' => $tabs, 'tab' => $tab]);
1835
        return isset($tab['url']) ? $tab : null;
1836
    }
1837
1838
    /**
1839
     * Do multi-page navigation.  Displays the prev, next and page options.
1840
     * @param $page - the page currently viewed
1841
     * @param $pages - the maximum number of pages
1842
     * @param $gets -  the parameters to include in the link to the wanted page
1843
     * @param $max_width - the number of pages to make available at any one time (default = 20)
1844
     */
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...
1845
    public function printPages($page, $pages, $gets, $max_width = 20)
1846
    {
1847
        $lang = $this->lang;
1848
1849
        $window = 10;
1850
1851
        if ($page < 0 || $page > $pages) {
1852
            return;
1853
        }
1854
1855
        if ($pages < 0) {
1856
            return;
1857
        }
1858
1859
        if ($max_width <= 0) {
1860
            return;
1861
        }
1862
1863
        unset($gets['page']);
1864
        $url = http_build_query($gets);
1865
1866
        if ($pages > 1) {
1867
            echo "<p style=\"text-align: center\">\n";
1868
            if ($page != 1) {
1869
                echo "<a class=\"pagenav\" href=\"?{$url}&amp;page=1\">{$lang['strfirst']}</a>\n";
1870
                $temp = $page - 1;
1871
                echo "<a class=\"pagenav\" href=\"?{$url}&amp;page={$temp}\">{$lang['strprev']}</a>\n";
1872
            }
1873
1874
            if ($page <= $window) {
1875
                $min_page = 1;
1876
                $max_page = min(2 * $window, $pages);
1877
            } elseif ($page > $window && $pages >= $page + $window) {
1878
                $min_page = ($page - $window) + 1;
1879
                $max_page = $page + $window;
1880
            } else {
1881
                $min_page = ($page - (2 * $window - ($pages - $page))) + 1;
1882
                $max_page = $pages;
1883
            }
1884
1885
            // Make sure min_page is always at least 1
1886
            // and max_page is never greater than $pages
1887
            $min_page = max($min_page, 1);
1888
            $max_page = min($max_page, $pages);
1889
1890
            for ($i = $min_page; $i <= $max_page; $i++) {
1891
                #if ($i != $page) echo "<a class=\"pagenav\" href=\"?{$url}&amp;page={$i}\">$i</a>\n";
1892
                if ($i != $page) {
1893
                    echo "<a class=\"pagenav\" href=\"display.php?{$url}&amp;page={$i}\">$i</a>\n";
1894
                } else {
1895
                    echo "$i\n";
1896
                }
1897
            }
1898
            if ($page != $pages) {
1899
                $temp = $page + 1;
1900
                echo "<a class=\"pagenav\" href=\"display.php?{$url}&amp;page={$temp}\">{$lang['strnext']}</a>\n";
1901
                echo "<a class=\"pagenav\" href=\"display.php?{$url}&amp;page={$pages}\">{$lang['strlast']}</a>\n";
1902
            }
1903
            echo "</p>\n";
1904
        }
1905
    }
1906
1907
    /**
1908
     * Converts a PHP.INI size variable to bytes.  Taken from publically available
1909
     * function by Chris DeRose, here: http://www.php.net/manual/en/configuration.directives.php#ini.file-uploads
1910
     * @param $strIniSize The PHP.INI variable
1911
     * @return size in bytes, false on failure
1912
     */
1913
    public function inisizeToBytes($strIniSize)
1914
    {
1915
        // This function will take the string value of an ini 'size' parameter,
1916
        // and return a double (64-bit float) representing the number of bytes
1917
        // that the parameter represents. Or false if $strIniSize is unparseable.
1918
        $a_IniParts = [];
1919
1920
        if (!is_string($strIniSize)) {
1921
            return false;
1922
        }
1923
1924
        if (!preg_match('/^(\d+)([bkm]*)$/i', $strIniSize, $a_IniParts)) {
1925
            return false;
1926
        }
1927
1928
        $nSize   = (double) $a_IniParts[1];
1929
        $strUnit = strtolower($a_IniParts[2]);
1930
1931
        switch ($strUnit) {
1932
            case 'm':
1933
                return ($nSize * (double) 1048576);
1934
            case 'k':
1935
                return ($nSize * (double) 1024);
1936
            case 'b':
1937
            default:
1938
                return $nSize;
1939
        }
1940
    }
1941
1942
    public function getRequestVars($subject = '')
1943
    {
1944
        $v = [];
1945
        if (!empty($subject)) {
1946
            $v['subject'] = $subject;
1947
        }
1948
1949
        if ($this->server_id !== null && $subject != 'root') {
1950
            $v['server'] = $this->server_id;
1951
            if ($this->database !== null && $subject != 'server') {
1952
                $v['database'] = $this->database;
1953
                if (isset($_REQUEST['schema']) && $subject != 'database') {
1954
                    $v['schema'] = $_REQUEST['schema'];
1955
                }
1956
            }
1957
        }
1958
        //$this->prtrace($v);
1959
        return $v;
1960
    }
1961
1962
    public function icon($icon)
1963
    {
1964
        if (is_string($icon)) {
1965
            $path = "/images/themes/{$this->conf['theme']}/{$icon}";
1966
            if (file_exists(BASE_PATH . $path . '.png')) {
1967
                return SUBFOLDER . $path . '.png';
1968
            }
1969
1970
            if (file_exists(BASE_PATH . $path . '.gif')) {
1971
                return SUBFOLDER . $path . '.gif';
1972
            }
1973
1974
            if (file_exists(BASE_PATH . $path . '.ico')) {
1975
                return SUBFOLDER . $path . '.ico';
1976
            }
1977
1978
            $path = "/images/themes/default/{$icon}";
1979
            if (file_exists(BASE_PATH . $path . '.png')) {
1980
                return SUBFOLDER . $path . '.png';
1981
            }
1982
1983
            if (file_exists(BASE_PATH . $path . '.gif')) {
1984
                return SUBFOLDER . $path . '.gif';
1985
            }
1986
1987
            if (file_exists(BASE_PATH . $path . '.ico')) {
1988
                return SUBFOLDER . $path . '.ico';
1989
            }
1990
        } else {
1991
            // Icon from plugins
1992
            $path = "/plugins/{$icon[0]}/images/{$icon[1]}";
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
        }
2005
        return '';
2006
    }
2007
2008
    /**
2009
     * Function to escape command line parameters
2010
     * @param string $str The string to escape
2011
     * @return string The escaped string
2012
     */
2013
    public function escapeShellArg($str)
2014
    {
2015
        $data = $this->getDatabaseAccessor();
2016
        $lang = $this->lang;
2017
2018
        if (strtoupper(substr(PHP_OS, 0, 3)) === 'WIN') {
2019
            // Due to annoying PHP bugs, shell arguments cannot be escaped
2020
            // (command simply fails), so we cannot allow complex objects
2021
            // to be dumped.
2022
            if (preg_match('/^[_.[:alnum:]]+$/', $str)) {
2023
                return $str;
2024
            }
2025
2026
            echo $lang['strcannotdumponwindows'];
2027
            exit;
0 ignored issues
show
Using exit here is not recommended.

In general, usage of exit should be done with care and only when running in a scripting context like a CLI script.

Loading history...
2028
        } else {
2029
            return escapeshellarg($str);
2030
        }
2031
    }
2032
2033
    /**
2034
     * Function to escape command line programs
2035
     * @param string $str The string to escape
2036
     * @return string The escaped string
2037
     */
2038
    public function escapeShellCmd($str)
2039
    {
2040
        $data = $this->getDatabaseAccessor();
2041
2042
        if (strtoupper(substr(PHP_OS, 0, 3)) === 'WIN') {
2043
            $data->fieldClean($str);
2044
            return '"' . $str . '"';
2045
        }
2046
2047
        return escapeshellcmd($str);
2048
    }
2049
2050
    /**
2051
     * Save the given SQL script in the history
2052
     * of the database and server.
2053
     * @param $script the SQL script to save.
2054
     */
2055
    public function saveScriptHistory($script)
2056
    {
2057
        list($usec, $sec)                                                         = explode(' ', microtime());
2058
        $time                                                                     = ((float) $usec + (float) $sec);
2059
        $_SESSION['history'][$_REQUEST['server']][$_REQUEST['database']]["$time"] = [
2060
            'query'    => $script,
2061
            'paginate' => !isset($_REQUEST['paginate']) ? 'f' : 't',
2062
            'queryid'  => $time,
2063
        ];
2064
    }
2065
2066
    /*
2067
     * Output dropdown list to select server and
2068
     * databases form the popups windows.
2069
     * @param $onchange Javascript action to take when selections change.
2070
     */
2071
    public function printConnection($onchange, $do_print = true)
2072
    {
2073
        $lang = $this->lang;
2074
2075
        $connection_html = "<table class=\"printconnection\" style=\"width: 100%\"><tr><td class=\"popup_select1\">\n";
2076
2077
        $servers      = $this->getServers();
2078
        $forcedserver = null;
2079
        if (count($servers) === 1) {
2080
            $forcedserver = $this->server_id;
2081
            $connection_html .= '<input type="hidden" readonly="readonly" value="' . $this->server_id . '" name="server">';
2082
        } else {
2083
            $connection_html .= '<label>';
2084
            $connection_html .= $this->printHelp($lang['strserver'], 'pg.server', false);
2085
            $connection_html .= ': </label>';
2086
            $connection_html .= " <select name=\"server\" {$onchange}>\n";
2087
            foreach ($servers as $info) {
2088
                if (empty($info['username'])) {
2089
                    continue;
2090
                }
2091
                $selected = isset($_REQUEST['server']) && $info['id'] == $_REQUEST['server'] ? ' selected="selected"' : '';
2092
                // not logged on this server
2093
                $connection_html .= '<option value="' . htmlspecialchars($info['id']) . '" ' . $selected . '>';
2094
                $connection_html .= htmlspecialchars("{$info['desc']} ({$info['id']})");
2095
                $connection_html .= "</option>\n";
2096
            }
2097
            $connection_html .= "</select>\n";
2098
        }
2099
2100
        $connection_html .= "</td><td class=\"popup_select2\" style=\"text-align: right\">\n";
2101
2102
        if (count($servers) === 1 && isset($servers[$this->server_id]['useonlydefaultdb']) && $servers[$this->server_id]['useonlydefaultdb'] === true) {
2103
            $connection_html .= '<input type="hidden" name="database" value="' . htmlspecialchars($servers[$this->server_id]['defaultdb']) . "\" />\n";
2104
        } else {
2105
2106
            // Get the list of all databases
2107
            $data      = $this->getDatabaseAccessor();
2108
            $databases = $data->getDatabases();
2109
            if ($databases->recordCount() > 0) {
2110
                $connection_html .= '<label>';
2111
                $connection_html .= $this->printHelp($lang['strdatabase'], 'pg.database', false);
2112
                $connection_html .= ": <select name=\"database\" {$onchange}>\n";
2113
2114
                //if no database was selected, user should select one
2115
                if (!isset($_REQUEST['database'])) {
2116
                    $connection_html .= "<option value=\"\">--</option>\n";
2117
                }
2118
2119
                while (!$databases->EOF) {
2120
                    $dbname     = $databases->fields['datname'];
2121
                    $dbselected = isset($_REQUEST['database']) && $dbname == $_REQUEST['database'] ? ' selected="selected"' : '';
2122
                    $connection_html .= '<option value="' . htmlspecialchars($dbname) . '" ' . $dbselected . '>' . htmlspecialchars($dbname) . "</option>\n";
2123
2124
                    $databases->moveNext();
2125
                }
2126
                $connection_html .= "</select></label>\n";
2127
            } else {
2128
                $server_info = $misc->getServerInfo();
2129
                $connection_html .= '<input type="hidden" name="database" value="' . htmlspecialchars($server_info['defaultdb']) . "\" />\n";
2130
            }
2131
        }
2132
2133
        $connection_html .= "</td></tr></table>\n";
2134
2135
        if ($do_print) {
2136
            echo $connection_html;
2137
        } else {
2138
            return $connection_html;
2139
        }
2140
    }
2141
2142
    /**
2143
     * returns an array representing FKs definition for a table, sorted by fields
2144
     * or by constraint.
2145
     * @param $table The table to retrieve FK contraints from
2146
     * @returns the array of FK definition:
2147
     *   array(
2148
     *     'byconstr' => array(
2149
     *       constrain id => array(
2150
     *         confrelid => foreign relation oid
2151
     *         f_schema => foreign schema name
2152
     *         f_table => foreign table name
2153
     *         pattnums => array of parent's fields nums
2154
     *         pattnames => array of parent's fields names
2155
     *         fattnames => array of foreign attributes names
2156
     *       )
2157
     *     ),
2158
     *     'byfield' => array(
2159
     *       attribute num => array (constraint id, ...)
2160
     *     ),
2161
     *     'code' => HTML/js code to include in the page for auto-completion
2162
     *   )
2163
     **/
2164
    public function getAutocompleteFKProperties($table)
2165
    {
2166
        $data = $this->getDatabaseAccessor();
2167
2168
        $fksprops = [
2169
            'byconstr' => [],
2170
            'byfield'  => [],
2171
            'code'     => '',
2172
        ];
2173
2174
        $constrs = $data->getConstraintsWithFields($table);
2175
2176
        if (!$constrs->EOF) {
2177
            $conrelid = $constrs->fields['conrelid'];
2178
            while (!$constrs->EOF) {
2179
                if ($constrs->fields['contype'] == 'f') {
2180
                    if (!isset($fksprops['byconstr'][$constrs->fields['conid']])) {
2181
                        $fksprops['byconstr'][$constrs->fields['conid']] = [
2182
                            'confrelid' => $constrs->fields['confrelid'],
2183
                            'f_table'   => $constrs->fields['f_table'],
2184
                            'f_schema'  => $constrs->fields['f_schema'],
2185
                            'pattnums'  => [],
2186
                            'pattnames' => [],
2187
                            'fattnames' => [],
2188
                        ];
2189
                    }
2190
2191
                    $fksprops['byconstr'][$constrs->fields['conid']]['pattnums'][]  = $constrs->fields['p_attnum'];
2192
                    $fksprops['byconstr'][$constrs->fields['conid']]['pattnames'][] = $constrs->fields['p_field'];
2193
                    $fksprops['byconstr'][$constrs->fields['conid']]['fattnames'][] = $constrs->fields['f_field'];
2194
2195
                    if (!isset($fksprops['byfield'][$constrs->fields['p_attnum']])) {
2196
                        $fksprops['byfield'][$constrs->fields['p_attnum']] = [];
2197
                    }
2198
2199
                    $fksprops['byfield'][$constrs->fields['p_attnum']][] = $constrs->fields['conid'];
2200
                }
2201
                $constrs->moveNext();
2202
            }
2203
2204
            $fksprops['code'] = "<script type=\"text/javascript\">\n";
2205
            $fksprops['code'] .= "var constrs = {};\n";
2206
            foreach ($fksprops['byconstr'] as $conid => $props) {
2207
                $fksprops['code'] .= "constrs.constr_{$conid} = {\n";
2208
                $fksprops['code'] .= 'pattnums: [' . implode(',', $props['pattnums']) . "],\n";
2209
                $fksprops['code'] .= "f_table:'" . addslashes(htmlentities($props['f_table'], ENT_QUOTES, 'UTF-8')) . "',\n";
2210
                $fksprops['code'] .= "f_schema:'" . addslashes(htmlentities($props['f_schema'], ENT_QUOTES, 'UTF-8')) . "',\n";
2211
                $_ = '';
2212
                foreach ($props['pattnames'] as $n) {
2213
                    $_ .= ",'" . htmlentities($n, ENT_QUOTES, 'UTF-8') . "'";
2214
                }
2215
                $fksprops['code'] .= 'pattnames: [' . substr($_, 1) . "],\n";
2216
2217
                $_ = '';
2218
                foreach ($props['fattnames'] as $n) {
2219
                    $_ .= ",'" . htmlentities($n, ENT_QUOTES, 'UTF-8') . "'";
2220
                }
2221
2222
                $fksprops['code'] .= 'fattnames: [' . substr($_, 1) . "]\n";
2223
                $fksprops['code'] .= "};\n";
2224
            }
2225
2226
            $fksprops['code'] .= "var attrs = {};\n";
2227
            foreach ($fksprops['byfield'] as $attnum => $cstrs) {
2228
                $fksprops['code'] .= "attrs.attr_{$attnum} = [" . implode(',', $fksprops['byfield'][$attnum]) . "];\n";
2229
            }
2230
2231
            $fksprops['code'] .= "var table='" . addslashes(htmlentities($table, ENT_QUOTES, 'UTF-8')) . "';";
2232
            $fksprops['code'] .= "var server='" . htmlentities($_REQUEST['server'], ENT_QUOTES, 'UTF-8') . "';";
2233
            $fksprops['code'] .= "var database='" . addslashes(htmlentities($_REQUEST['database'], ENT_QUOTES, 'UTF-8')) . "';";
2234
            $fksprops['code'] .= "var subfolder='" . SUBFOLDER . "';";
2235
            $fksprops['code'] .= "</script>\n";
2236
2237
            $fksprops['code'] .= '<div id="fkbg"></div>';
2238
            $fksprops['code'] .= '<div id="fklist"></div>';
2239
            $fksprops['code'] .= '<script src="' . SUBFOLDER . '/js/ac_insert_row.js" type="text/javascript"></script>';
2240
        } else /* we have no foreign keys on this table */
2241
        {
2242
            return false;
2243
        }
2244
2245
        return $fksprops;
2246
    }
2247
}
2248