Passed
Push — master ( 965dbc...c6b243 )
by Felipe
11:26 queued 06:11
created

Misc::setCurrentSchema()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 14
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 14
c 0
b 0
f 0
rs 9.4285
cc 2
eloc 8
nc 2
nop 1
1
<?php
2
3
/**
4
 * PHPPgAdmin v6.0.0-beta.33
5
 */
6
7
namespace PHPPgAdmin;
8
9
use PHPPgAdmin\Decorators\Decorator;
10
11
/**
12
 * @file
13
 * Class to hold various commonly used functions
14
 *
15
 * Id: Misc.php,v 1.171 2008/03/17 21:35:48 ioguix Exp $
16
 * @package PHPPgAdmin
17
 */
18
19
/**
20
 * Class to hold various commonly used functions.
21
 *
22
 * $Id: Misc.php,v 1.171 2008/03/17 21:35:48 ioguix Exp $
23
 *
24
 * @package PHPPgAdmin
25
 */
26
class Misc
27
{
28
    use \PHPPgAdmin\HelperTrait;
29
30
    private $_connection;
31
    private $_no_db_connection = false;
32
    private $_reload_browser   = false;
33
    private $_data;
34
    private $_database;
35
    private $_server_id;
36
    private $_server_info;
37
    private $_error_msg = '';
38
39
    public $appLangFiles    = [];
40
    public $appName         = '';
41
    public $appVersion      = '';
42
    public $form            = '';
43
    public $href            = '';
44
    public $controller_name = 'Misc';
45
    public $lang            = [];
46
47
    protected $container;
48
49
    /**
50
     * @param \Slim\Container $container The container
51
     */
52
    public function __construct(\Slim\Container $container)
53
    {
54
        $this->container = $container;
55
56
        $this->lang = $container->get('lang');
57
        $this->conf = $container->get('conf');
58
59
        //$this->view           = $container->get('view');
60
        $this->plugin_manager = $container->get('plugin_manager');
61
        $this->appLangFiles   = $container->get('appLangFiles');
62
63
        $this->appName          = $container->get('settings')['appName'];
64
        $this->appVersion       = $container->get('settings')['appVersion'];
65
        $this->postgresqlMinVer = $container->get('settings')['postgresqlMinVer'];
66
        $this->phpMinVer        = $container->get('settings')['phpMinVer'];
67
68
        $base_version = $container->get('settings')['base_version'];
69
70
        // Check for config file version mismatch
71
        if (!isset($this->conf['version']) || $base_version > $this->conf['version']) {
72
            $container->get('utils')->addError($this->lang['strbadconfig']);
73
        }
74
75
        // Check database support is properly compiled in
76
        if (!function_exists('pg_connect')) {
77
            $container->get('utils')->addError($this->lang['strnotloaded']);
78
        }
79
80
        // Check the version of PHP
81
        if (version_compare(phpversion(), $this->phpMinVer, '<')) {
82
            $container->get('utils')->addError(sprintf('Version of PHP not supported. Please upgrade to version %s or later.', $this->phpMinVer));
83
        }
84
85
        $this->getServerId();
86
    }
87
88
    public function serverToSha()
89
    {
90
        $request_server = $this->container->requestobj->getParam('server');
91
        if ($request_server === null) {
92
            return null;
93
        }
94
        $srv_array = explode(':', $request_server);
95
        if (count($srv_array) === 3) {
96
            return sha1($request_server);
97
        }
98
        return $request_server;
99
    }
100
101
    public function getServerId()
102
    {
103
        if ($this->_server_id) {
104
            return $this->_server_id;
105
        }
106
107
        $request_server = $this->serverToSha();
108
109
        if (count($this->conf['servers']) === 1) {
110
            $info             = $this->conf['servers'][0];
111
            $this->_server_id = sha1($info['host'] . ':' . $info['port'] . ':' . $info['sslmode']);
112
        } elseif ($request_server !== null) {
113
            $this->_server_id = $request_server;
114
        } elseif (isset($_SESSION['webdbLogin']) && count($_SESSION['webdbLogin']) > 0) {
115
            $this->_server_id = array_keys($_SESSION['webdbLogin'])[0];
116
        }
117
        return $this->_server_id;
118
119
    }
120
121
    /**
122
     * Sets the view instance property of this class.
123
     *
124
     * @param \Slim\Views\Twig $view [description]
125
     */
126
    public function setView(\Slim\Views\Twig $view)
127
    {
128
        $this->view = $view;
129
    }
130
131
    /**
132
     * Adds or modifies a key in the $conf instance property of this class.
133
     *
134
     * @param string $key   name of the key to set
135
     * @param mixed  $value value of the key to set
136
     *
137
     * @return $this
138
     */
139
    public function setConf(string $key, $value)
140
    {
141
        $this->conf[$key] = $value;
142
143
        return $this;
144
    }
145
146
    /**
147
     * gets the value of a config property, or the array of all config properties.
1 ignored issue
show
Coding Style introduced by
Doc comment short description must start with a capital letter
Loading history...
148
     *
149
     * @param mixed $key value of the key to be retrieved. If null, the full array is returnes
150
     *
151
     * @return mixed the whole $conf array, the value of $conf[key] or null if said key does not exist
152
     */
153
    public function getConf($key = null)
154
    {
155
        if ($key === null) {
156
            return $this->conf;
157
        }
158
        if (array_key_exists($key, $this->conf)) {
159
            return $this->conf[$key];
160
        }
161
162
        return null;
163
    }
164
165
    /**
166
     * Displays link to the context help.
167
     *
168
     * @param $str   the string that the context help is related to (already escaped)
169
     * @param $help  help section identifier
170
     * @param $do_print true to echo, false to return
171
     */
172
    public function printHelp($str, $help = null, $do_print = true)
173
    {
174
        //\PC::debug(['str' => $str, 'help' => $help], 'printHelp');
175
        if ($help !== null) {
176
            $helplink = $this->getHelpLink($help);
177
            $str .= '<a class="help" href="' . $helplink . '" title="' . $this->lang['strhelp'] . '" target="phppgadminhelp">' . $this->lang['strhelpicon'] . '</a>';
178
        }
179
        if ($do_print) {
180
            echo $str;
181
        } else {
182
            return $str;
183
        }
184
    }
185
186
    public function getHelpLink($help)
187
    {
188
        return htmlspecialchars(SUBFOLDER . '/help?help=' . urlencode($help) . '&server=' . urlencode($this->getServerId()));
189
    }
190
191
    /**
192
     * Internally sets the reload browser property.
193
     *
194
     * @param bool $flag sets internal $_reload_browser var which will be passed to the footer methods
195
     *
196
     * @return $this
197
     */
198
    public function setReloadBrowser($flag)
199
    {
200
        $this->_reload_browser = (bool) $flag;
201
202
        return $this;
203
    }
204
205
    public function getReloadBrowser()
206
    {
207
        return $this->_reload_browser;
208
    }
209
210
    /**
211
     * Default Error Handler. This will be called with the following params.
212
     *
213
     * @param $dbms         the RDBMS you are connecting to
214
     * @param $fn           the name of the calling function (in uppercase)
215
     * @param $errno        the native error number from the database
216
     * @param $errmsg       the native error msg from the database
217
     * @param $p1           $fn specific parameter - see below
0 ignored issues
show
Coding Style introduced by
Doc comment for parameter $fn does not match actual variable name $p1
Loading history...
218
     * @param $p2           parameter 2
219
     * @param $thisConnection connection
220
     *
221
     * @throws \PHPPgAdmin\ADOdbException
222
     *
223
     * @internal param $P2 $fn specific parameter - see below
224
     */
225
    public static function adodb_throw($dbms, $fn, $errno, $errmsg, $p1, $p2, $thisConnection)
1 ignored issue
show
Coding Style introduced by
Public method name "Misc::adodb_throw" is not in camel caps format
Loading history...
226
    {
227
        if (error_reporting() == 0) {
228
            return;
229
        }
230
231
        $backtrace = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS, 2);
232
233
        $btarray0 = [
234
            'msg'      => 'ADOdbException at ',
235
            'class'    => $backtrace[1]['class'],
236
            'type'     => $backtrace[1]['type'],
237
            'function' => $backtrace[1]['function'],
238
            'spacer'   => ' ',
239
            'line'     => $backtrace[0]['line'],
240
        ];
241
242
        $errmsg = htmlentities(\PHPPgAdmin\HelperTrait::br2ln($errmsg), ENT_NOQUOTES);
243
        $p1     = htmlentities(\PHPPgAdmin\HelperTrait::br2ln($p1), ENT_NOQUOTES);
244
        $p2     = htmlentities(\PHPPgAdmin\HelperTrait::br2ln($p2), ENT_NOQUOTES);
245
246
        switch ($fn) {
247
            case 'EXECUTE':
248
                $sql = str_replace([
1 ignored issue
show
Coding Style introduced by
The opening parenthesis of a multi-line function call should be the last content on the line.
Loading history...
249
                    'SELECT',
250
                    'WHERE',
251
                    'GROUP BY',
252
                    'FROM',
253
                    'HAVING',
254
                    'LIMIT',
255
                ],
0 ignored issues
show
Coding Style introduced by
This line of the multi-line function call does not seem to be indented correctly. Expected 20 spaces, but found 16.
Loading history...
256
                    ["\nSELECT", "\nWHERE", "\nGROUP BY", "\nFROM", "\nHAVING", "\nLIMIT"],
257
                    $p1);
1 ignored issue
show
Coding Style introduced by
This line of the multi-line function call does not seem to be indented correctly. Expected 16 spaces, but found 20.
Loading history...
Coding Style introduced by
For multi-line function calls, the closing parenthesis should be on a new line.

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

someFunctionCall(
    $firstArgument,
    $secondArgument,
    $thirdArgument
); // Closing parenthesis on a new line.
Loading history...
258
259
                $inputparams = $p2;
260
261
                $error_msg = '<p><b>strsqlerror</b><br />' . nl2br($errmsg) . '</p> <p><b>SQL:</b><br />' . nl2br($sql) . '</p>	';
262
263
                echo '<table class="error" cellpadding="5"><tr><td>' . nl2br($error_msg) . '</td></tr></table><br />' . "\n";
264
265
                break;
266
            case 'PCONNECT':
267
            case 'CONNECT':
268
                // do nothing;
269
                break;
270
            default:
271
                $s = "${dbms} error: [${errno}: ${errmsg}] in ${fn}(${p1}, ${p2})\n";
272
                echo "<table class=\"error\" cellpadding=\"5\"><tr><td>{$s}</td></tr></table><br />\n";
273
274
                break;
275
        }
276
277
        $tag = implode('', $btarray0);
278
279
        \PC::debug(['errno' => $errno, 'fn' => $fn, 'errmsg' => $errmsg], $tag);
280
281
        throw new \PHPPgAdmin\ADOdbException($dbms, $fn, $errno, $errmsg, $p1, $p2, $thisConnection);
282
    }
283
284
    public function getContainer()
285
    {
286
        return $this->container;
287
    }
288
289
    /**
290
     * sets $_no_db_connection boolean value, allows to render scripts that do not need an active session.
1 ignored issue
show
Coding Style introduced by
Doc comment short description must start with a capital letter
Loading history...
291
     *
292
     * @param bool $flag true or false to allow unconnected clients to access the view
293
     *
294
     * @return $this
295
     */
296
    public function setNoDBConnection($flag)
297
    {
298
        $this->_no_db_connection = (bool) $flag;
299
300
        return $this;
301
    }
302
303
    public function getNoDBConnection()
304
    {
305
        return $this->_no_db_connection;
306
    }
307
308
    /**
309
     * Sets the last error message to display afterwards instead of just dying with the error msg.
310
     *
311
     * @param string $msg error message string
312
     */
313
    public function setErrorMsg($msg)
314
    {
315
        $this->_error_msg = $msg;
316
317
        return $this;
318
    }
319
320
    public function getErrorMsg()
321
    {
322
        return $this->_error_msg;
323
    }
324
325
    /**
326
     * Creates a database accessor.
327
     *
328
     * @param string $database  the name of the database
329
     * @param mixed  $server_id the id of the server
330
     */
331
    public function getDatabaseAccessor($database = '', $server_id = null)
332
    {
333
        $lang = $this->lang;
334
335
        if ($server_id !== null) {
336
            $this->_server_id = $server_id;
337
        }
338
        $this->prtrace($this->_server_id);
339
340
        $server_info = $this->getServerInfo($this->_server_id);
341
342
        if ($this->_no_db_connection || !isset($server_info['username'])) {
343
            return null;
344
        }
345
346
        if ($this->_data === null) {
347
            try {
348
                $_connection = $this->getConnection($database, $this->_server_id);
349
            } catch (\Exception $e) {
350
                $this->setServerInfo(null, null, $this->_server_id);
351
                $this->setNoDBConnection(true);
352
                $this->setErrorMsg($e->getMessage());
353
354
                return null;
355
            }
356
357
            //$this->prtrace('_connection', $_connection);
358
            if (!$_connection) {
359
                $this->container->utils->addError($lang['strloginfailed']);
360
                $this->setErrorMsg($lang['strloginfailed']);
361
362
                return null;
363
            }
364
            // Get the name of the database driver we need to use.
365
            // The description of the server is returned in $platform.
366
            $_type = $_connection->getDriver($platform);
367
368
            //$this->prtrace(['type' => $_type, 'platform' => $platform, 'pgVersion' => $_connection->conn->pgVersion]);
369
370
            if ($_type === null) {
371
                $errormsg = sprintf($lang['strpostgresqlversionnotsupported'], $this->postgresqlMinVer);
372
                $this->container->utils->addError($errormsg);
373
                $this->setErrorMsg($errormsg);
374
375
                return null;
376
            }
377
            $_type = '\PHPPgAdmin\Database\\' . $_type;
378
379
            $this->setServerInfo('platform', $platform, $this->_server_id);
380
            $this->setServerInfo('pgVersion', $_connection->conn->pgVersion, $this->_server_id);
381
382
            // Create a database wrapper class for easy manipulation of the
383
            // connection.
384
385
            $this->_data              = new $_type($_connection->conn, $this->conf);
386
            $this->_data->platform    = $_connection->platform;
387
            $this->_data->server_info = $server_info;
388
            $this->_data->conf        = $this->conf;
389
            $this->_data->lang        = $this->lang;
390
391
            //$this->_data->getHelpPages();
392
393
            //$this->prtrace('help_page has ' . count($this->_data->help_page) . ' items');
394
395
            /* we work on UTF-8 only encoding */
396
            $this->_data->execute("SET client_encoding TO 'UTF-8'");
397
398
            if ($this->_data->hasByteaHexDefault()) {
399
                $this->_data->execute('SET bytea_output TO escape');
400
            }
401
        }
402
403
        if ($this->_no_db_connection === false && $this->getDatabase() !== null && isset($_REQUEST['schema'])) {
404
            $status = $this->_data->setSchema($_REQUEST['schema']);
405
406
            if ($status != 0) {
407
                $this->container->utils->addError($this->lang['strbadschema']);
408
                $this->setErrorMsg($this->lang['strbadschema']);
409
410
                return null;
411
            }
412
        }
413
414
        return $this->_data;
415
    }
416
417
    public function getConnection($database = '', $server_id = null)
418
    {
419
        $lang = $this->lang;
420
421
        if ($this->_connection === null) {
422
            if ($server_id !== null) {
423
                $this->_server_id = $server_id;
424
            }
425
            $server_info     = $this->getServerInfo($this->_server_id);
426
            $database_to_use = $this->getDatabase($database);
427
428
            // Perform extra security checks if this config option is set
429
            if ($this->conf['extra_login_security']) {
430
                // Disallowed logins if extra_login_security is enabled.
431
                // These must be lowercase.
432
                $bad_usernames = [
433
                    'pgsql'         => 'pgsql',
434
                    'postgres'      => 'postgres',
435
                    'root'          => 'root',
436
                    'administrator' => 'administrator',
437
                ];
438
439
                if (isset($server_info['username']) && array_key_exists(strtolower($server_info['username']), $bad_usernames)) {
440
                    $msg = $lang['strlogindisallowed'];
441
442
                    throw new \Exception($msg);
443
                }
444
445
                if (!isset($server_info['password']) || $server_info['password'] == '') {
446
                    $msg = $lang['strlogindisallowed'];
447
448
                    throw new \Exception($msg);
449
                }
450
            }
451
452
            try {
453
                // Create the connection object and make the connection
454
                $this->_connection = new \PHPPgAdmin\Database\Connection(
455
                    $server_info['host'],
456
                    $server_info['port'],
457
                    $server_info['sslmode'],
458
                    $server_info['username'],
459
                    $server_info['password'],
460
                    $database_to_use
461
                );
462
            } catch (\PHPPgAdmin\ADOdbException $e) {
463
                throw new \Exception($lang['strloginfailed']);
464
            }
465
        }
466
467
        return $this->_connection;
468
    }
469
470
    /**
471
     * Validate and retrieve information on a server.
472
     * If the parameter isn't supplied then the currently
473
     * connected server is returned.
474
     *
475
     * @param $server_id A server identifier (host:port)
476
     *
477
     * @return An associative array of server properties
478
     */
479
    public function getServerInfo($server_id = null)
480
    {
481
        //\PC::debug(['$server_id' => $server_id]);
482
483
        if ($server_id !== null) {
484
            $this->_server_id = $server_id;
485
        } elseif ($this->_server_info !== null) {
486
            return $this->_server_info;
487
        }
488
489
        // Check for the server in the logged-in list
490
        if (isset($_SESSION['webdbLogin'][$this->_server_id])) {
491
            $this->_server_info = $_SESSION['webdbLogin'][$this->_server_id];
492
493
            return $this->_server_info;
494
        }
495
496
        // Otherwise, look for it in the conf file
497
        foreach ($this->conf['servers'] as $idx => $info) {
498
            $server_string = $info['host'] . ':' . $info['port'] . ':' . $info['sslmode'];
499
            $server_sha    = sha1($server_string);
500
501
            if ($this->_server_id === $server_string || $this->_server_id === $server_sha) {
502
                if (isset($info['username'])) {
503
                    $this->setServerInfo(null, $info, $this->_server_id);
504
                } elseif (isset($_SESSION['sharedUsername'])) {
505
                    $info['username'] = $_SESSION['sharedUsername'];
506
                    $info['password'] = $_SESSION['sharedPassword'];
507
                    $this->setReloadBrowser(true);
508
                    $this->setServerInfo(null, $info, $this->_server_id);
509
                }
510
                $this->_server_info = $info;
511
512
                return $this->_server_info;
513
            }
514
        }
515
516
        if ($server_id === null) {
517
            $this->_server_info = null;
518
519
            return $this->_server_info;
520
        }
521
522
        $this->prtrace('Invalid server param');
523
        $this->_server_info = null;
524
        // Unable to find a matching server, are we being hacked?
525
        return $this->halt($this->lang['strinvalidserverparam']);
526
    }
527
528
    /**
529
     * Set server information.
530
     *
531
     * @param $key parameter name to set, or null to replace all
532
     *             params with the assoc-array in $value
533
     * @param $value the new value, or null to unset the parameter
534
     * @param $server_id the server identifier, or null for current server
535
     */
536
    public function setServerInfo($key, $value, $server_id = null)
537
    {
538
        //\PC::debug('setsetverinfo');
539
        if ($server_id === null) {
540
            $server_id = $this->container->requestobj->getParam('server');
541
        }
542
543
        if ($key === null) {
544
            if ($value === null) {
545
                unset($_SESSION['webdbLogin'][$server_id]);
546
            } else {
547
                //\PC::debug(['server_id' => $server_id, 'value' => $value], 'webdbLogin null key');
548
                $_SESSION['webdbLogin'][$server_id] = $value;
549
            }
550
        } else {
551
            if ($value === null) {
552
                unset($_SESSION['webdbLogin'][$server_id][$key]);
553
            } else {
554
                //\PC::debug(['server_id' => $server_id, 'key' => $key, 'value' => $value], __FILE__ . ' ' . __LINE__ . ' webdbLogin key ' . $key);
555
                $_SESSION['webdbLogin'][$server_id][$key] = $value;
556
            }
557
        }
558
    }
559
560
    public function getDatabase($database = '')
561
    {
562
        if ($this->_server_id === null && !isset($_REQUEST['database'])) {
563
            return null;
564
        }
565
566
        $server_info = $this->getServerInfo($this->_server_id);
567
568
        if ($this->_server_id !== null && isset($server_info['useonlydefaultdb']) && $server_info['useonlydefaultdb'] === true) {
569
            $this->_database = $server_info['defaultdb'];
570
        } elseif ($database !== '') {
571
            $this->_database = $database;
572
        } elseif (isset($_REQUEST['database'])) {
573
            // Connect to the current database
574
            $this->_database = $_REQUEST['database'];
575
        } else {
576
            // or if one is not specified then connect to the default database.
577
            $this->_database = $server_info['defaultdb'];
578
        }
579
580
        return $this->_database;
581
    }
582
583
    /**
584
     * Set the current schema.
585
     *
586
     * @param $schema The schema name
587
     *
588
     * @return int 0 on success
589
     */
590
    public function setCurrentSchema($schema)
591
    {
592
        $data = $this->getDatabaseAccessor();
593
594
        $status = $data->setSchema($schema);
595
        if ($status != 0) {
596
            return $status;
597
        }
598
599
        $_REQUEST['schema'] = $schema;
600
        $this->container->offsetSet('schema', $schema);
601
        $this->setHREF();
602
603
        return 0;
604
    }
605
606
    /**
607
     * Checks if dumps are properly set up.
608
     *
609
     * @param $all (optional) True to check pg_dumpall, false to just check pg_dump
610
     *
611
     * @return True, dumps are set up, false otherwise
612
     */
613
    public function isDumpEnabled($all = false)
614
    {
615
        $info = $this->getServerInfo();
616
617
        return !empty($info[$all ? 'pg_dumpall_path' : 'pg_dump_path']);
618
    }
619
620
    /**
621
     * Sets the href tracking variable.
622
     */
623
    public function setHREF()
624
    {
625
        $this->href = $this->getHREF();
626
        //\PC::debug($this->href, 'Misc::href');
627
        return $this;
628
    }
629
630
    /**
631
     * Get a href query string, excluding objects below the given object type (inclusive).
632
     *
633
     * @param null|string $exclude_from
634
     *
635
     * @return string
636
     */
637
    public function getHREF($exclude_from = null)
638
    {
639
        $href = [];
640
641
        $server   = $this->container->server || isset($_REQUEST['server']) ? $_REQUEST['server'] : null;
642
        $database = $this->container->database || isset($_REQUEST['database']) ? $_REQUEST['database'] : null;
643
        $schema   = $this->container->schema || isset($_REQUEST['schema']) ? $_REQUEST['schema'] : null;
644
645
        if ($server && $exclude_from !== 'server') {
646
            $href[] = 'server=' . urlencode($server);
647
        }
648
        if ($database && $exclude_from !== 'database') {
649
            $href[] = 'database=' . urlencode($database);
650
        }
651
        if ($schema && $exclude_from !== 'schema') {
652
            $href[] = 'schema=' . urlencode($schema);
653
        }
654
655
        $this->href = htmlentities(implode('&', $href));
656
        return $this->href;
657
    }
658
659
    public function getSubjectParams($subject)
660
    {
661
        $plugin_manager = $this->plugin_manager;
662
663
        $vars = [];
664
665
        switch ($subject) {
666
            case 'root':
667
                $vars = [
668
                    'params' => [
669
                        'subject' => 'root',
670
                    ],
671
                ];
672
673
                break;
674
            case 'server':
675
                $vars = ['params' => [
676
                    'server'  => $_REQUEST['server'],
677
                    'subject' => 'server',
678
                ]];
679
680
                break;
681
            case 'role':
682
                $vars = ['params' => [
683
                    'server'   => $_REQUEST['server'],
684
                    'subject'  => 'role',
685
                    'action'   => 'properties',
686
                    'rolename' => $_REQUEST['rolename'],
687
                ]];
688
689
                break;
690
            case 'database':
691
                $vars = ['params' => [
692
                    'server'   => $_REQUEST['server'],
693
                    'subject'  => 'database',
694
                    'database' => $_REQUEST['database'],
695
                ]];
696
697
                break;
698
            case 'schema':
699
                $vars = ['params' => [
700
                    'server'   => $_REQUEST['server'],
701
                    'subject'  => 'schema',
702
                    'database' => $_REQUEST['database'],
703
                    'schema'   => $_REQUEST['schema'],
704
                ]];
705
706
                break;
707
            case 'table':
708
                $vars = ['params' => [
709
                    'server'   => $_REQUEST['server'],
710
                    'subject'  => 'table',
711
                    'database' => $_REQUEST['database'],
712
                    'schema'   => $_REQUEST['schema'],
713
                    'table'    => $_REQUEST['table'],
714
                ]];
715
716
                break;
717
            case 'selectrows':
718
                $vars = [
719
                    'url'    => 'tables',
720
                    'params' => [
721
                        'server'   => $_REQUEST['server'],
722
                        'subject'  => 'table',
723
                        'database' => $_REQUEST['database'],
724
                        'schema'   => $_REQUEST['schema'],
725
                        'table'    => $_REQUEST['table'],
726
                        'action'   => 'confselectrows',
727
                    ]];
728
729
                break;
730
            case 'view':
731
                $vars = ['params' => [
732
                    'server'   => $_REQUEST['server'],
733
                    'subject'  => 'view',
734
                    'database' => $_REQUEST['database'],
735
                    'schema'   => $_REQUEST['schema'],
736
                    'view'     => $_REQUEST['view'],
737
                ]];
738
739
                break;
740
            case 'matview':
741
                $vars = ['params' => [
742
                    'server'   => $_REQUEST['server'],
743
                    'subject'  => 'matview',
744
                    'database' => $_REQUEST['database'],
745
                    'schema'   => $_REQUEST['schema'],
746
                    'matview'  => $_REQUEST['matview'],
747
                ]];
748
749
                break;
750
            case 'fulltext':
751
            case 'ftscfg':
752
                $vars = ['params' => [
753
                    'server'   => $_REQUEST['server'],
754
                    'subject'  => 'fulltext',
755
                    'database' => $_REQUEST['database'],
756
                    'schema'   => $_REQUEST['schema'],
757
                    'action'   => 'viewconfig',
758
                    'ftscfg'   => $_REQUEST['ftscfg'],
759
                ]];
760
761
                break;
762
            case 'function':
763
                $vars = ['params' => [
764
                    'server'       => $_REQUEST['server'],
765
                    'subject'      => 'function',
766
                    'database'     => $_REQUEST['database'],
767
                    'schema'       => $_REQUEST['schema'],
768
                    'function'     => $_REQUEST['function'],
769
                    'function_oid' => $_REQUEST['function_oid'],
770
                ]];
771
772
                break;
773
            case 'aggregate':
774
                $vars = ['params' => [
775
                    'server'   => $_REQUEST['server'],
776
                    'subject'  => 'aggregate',
777
                    'action'   => 'properties',
778
                    'database' => $_REQUEST['database'],
779
                    'schema'   => $_REQUEST['schema'],
780
                    'aggrname' => $_REQUEST['aggrname'],
781
                    'aggrtype' => $_REQUEST['aggrtype'],
782
                ]];
783
784
                break;
785
            case 'column':
786
                if (isset($_REQUEST['table'])) {
787
                    $vars = ['params' => [
788
                        'server'   => $_REQUEST['server'],
789
                        'subject'  => 'column',
790
                        'database' => $_REQUEST['database'],
791
                        'schema'   => $_REQUEST['schema'],
792
                        'table'    => $_REQUEST['table'],
793
                        'column'   => $_REQUEST['column'],
794
                    ]];
795
                } else {
796
                    $vars = ['params' => [
797
                        'server'   => $_REQUEST['server'],
798
                        'subject'  => 'column',
799
                        'database' => $_REQUEST['database'],
800
                        'schema'   => $_REQUEST['schema'],
801
                        'view'     => $_REQUEST['view'],
802
                        'column'   => $_REQUEST['column'],
803
                    ]];
804
                }
805
806
                break;
807
            case 'plugin':
808
                $vars = [
809
                    'url'    => 'plugin',
810
                    'params' => [
811
                        'server'  => $_REQUEST['server'],
812
                        'subject' => 'plugin',
813
                        'plugin'  => $_REQUEST['plugin'],
814
                    ]];
815
816
                if (!is_null($plugin_manager->getPlugin($_REQUEST['plugin']))) {
817
                    $vars['params'] = array_merge($vars['params'], $plugin_manager->getPlugin($_REQUEST['plugin'])->get_subject_params());
818
                }
819
820
                break;
821
            default:
822
                return false;
823
        }
824
825
        if (!isset($vars['url'])) {
826
            $vars['url'] = SUBFOLDER . '/redirect';
827
        }
828
        if ($vars['url'] == SUBFOLDER . '/redirect' && isset($vars['params']['subject'])) {
829
            $vars['url'] = SUBFOLDER . '/redirect/' . $vars['params']['subject'];
830
            unset($vars['params']['subject']);
831
        }
832
833
        return $vars;
834
    }
835
836
    /**
837
     * Sets the form tracking variable.
838
     */
839
    public function setForm()
840
    {
841
        $form = [];
842
        if ($this->container->server) {
843
            $form[] = '<input type="hidden" name="server" value="' . htmlspecialchars($this->container->server) . '" />';
844
        }
845
        if ($this->container->database) {
846
            $form[] = '<input type="hidden" name="database" value="' . htmlspecialchars($this->container->database) . '" />';
847
        }
848
849
        if ($this->container->schema) {
850
            $form[] = '<input type="hidden" name="schema" value="' . htmlspecialchars($this->container->schema) . '" />';
851
        }
852
        $this->form = implode("\n", $form);
853
854
        return $this->form;
855
        //\PC::debug($this->form, 'Misc::form');
856
    }
857
858
    /**
859
     * Render a value into HTML using formatting rules specified
860
     * by a type name and parameters.
861
     *
862
     * @param                        $str    The string to change
863
     * @param                        $type   Field type (optional), this may be an internal PostgreSQL type, or:
864
     *                                       yesno    - same as bool, but renders as 'Yes' or 'No'.
865
     *                                       pre      - render in a <pre> block.
866
     *                                       nbsp     - replace all spaces with &nbsp;'s
867
     *                                       verbatim - render exactly as supplied, no escaping what-so-ever.
868
     *                                       callback - render using a callback function supplied in the 'function' param.
869
     * @param array $params Type parameters (optional), known parameters:
870
     *                                       null     - string to display if $str is null, or set to TRUE to use a default 'NULL' string,
871
     *                                       otherwise nothing is rendered.
872
     *                                       clip     - if true, clip the value to a fixed length, and append an ellipsis...
873
     *                                       cliplen  - the maximum length when clip is enabled (defaults to $conf['max_chars'])
874
     *                                       ellipsis - the string to append to a clipped value (defaults to $lang['strellipsis'])
875
     *                                       tag      - an HTML element name to surround the value.
876
     *                                       class    - a class attribute to apply to any surrounding HTML element.
877
     *                                       align    - an align attribute ('left','right','center' etc.)
878
     *                                       true     - (type='bool') the representation of true.
879
     *                                       false    - (type='bool') the representation of false.
880
     *                                       function - (type='callback') a function name, accepts args ($str, $params) and returns a rendering.
881
     *                                       lineno   - prefix each line with a line number.
882
     *                                       map      - an associative array.
883
     *
884
     * @return string The HTML rendered value
885
     */
886
    public function printVal($str, $type = null, $params = [])
887
    {
888
        $lang = $this->lang;
889
        $data = $this->getDatabaseAccessor();
890
891
        // Shortcircuit for a NULL value
892
        if (is_null($str)) {
893
            return isset($params['null'])
894
            ? ($params['null'] === true ? '<i>NULL</i>' : $params['null'])
895
            : '';
896
        }
897
898
        if (isset($params['map'], $params['map'][$str])) {
899
            $str = $params['map'][$str];
900
        }
901
902
        // Clip the value if the 'clip' parameter is true.
903
        if (isset($params['clip']) && $params['clip'] === true) {
904
            $maxlen   = isset($params['cliplen']) && is_integer($params['cliplen']) ? $params['cliplen'] : $this->conf['max_chars'];
905
            $ellipsis = isset($params['ellipsis']) ? $params['ellipsis'] : $lang['strellipsis'];
906
            if (strlen($str) > $maxlen) {
907
                $str = substr($str, 0, $maxlen - 1) . $ellipsis;
908
            }
909
        }
910
911
        $out = '';
912
913
        switch ($type) {
914
            case 'int2':
915
            case 'int4':
916
            case 'int8':
917
            case 'float4':
918
            case 'float8':
919
            case 'money':
920
            case 'numeric':
921
            case 'oid':
922
            case 'xid':
923
            case 'cid':
924
            case 'tid':
925
                $align = 'right';
926
                $out   = nl2br(htmlspecialchars(\PHPPgAdmin\HelperTrait::br2ln($str)));
927
928
                break;
929
            case 'yesno':
930
                if (!isset($params['true'])) {
931
                    $params['true'] = $lang['stryes'];
932
                }
933
934
                if (!isset($params['false'])) {
935
                    $params['false'] = $lang['strno'];
936
                }
937
938
            // no break - fall through to boolean case.
939
            case 'bool':
940
            case 'boolean':
941
                if (is_bool($str)) {
942
                    $str = $str ? 't' : 'f';
943
                }
944
945
                switch ($str) {
946
                    case 't':
947
                        $out   = (isset($params['true']) ? $params['true'] : $lang['strtrue']);
948
                        $align = 'center';
949
950
                        break;
951
                    case 'f':
952
                        $out   = (isset($params['false']) ? $params['false'] : $lang['strfalse']);
953
                        $align = 'center';
954
955
                        break;
956
                    default:
957
                        $out = htmlspecialchars($str);
958
                }
959
960
                break;
961
            case 'bytea':
962
                $tag   = 'div';
963
                $class = 'pre';
964
                $out   = $data->escapeBytea($str);
965
966
                break;
967
            case 'errormsg':
968
                $tag   = 'pre';
969
                $class = 'error';
970
                $out   = htmlspecialchars($str);
971
972
                break;
973
            case 'pre':
974
                $tag = 'pre';
975
                $out = htmlspecialchars($str);
976
977
                break;
978
            case 'prenoescape':
979
                $tag = 'pre';
980
                $out = $str;
981
982
                break;
983
            case 'nbsp':
984
                $out = nl2br(str_replace(' ', '&nbsp;', \PHPPgAdmin\HelperTrait::br2ln($str)));
985
986
                break;
987
            case 'verbatim':
988
                $out = $str;
989
990
                break;
991
            case 'callback':
992
                $out = $params['function']($str, $params);
993
994
                break;
995
            case 'prettysize':
996
                if ($str == -1) {
997
                    $out = $lang['strnoaccess'];
998
                } else {
999
                    $limit = 10 * 1024;
1000
                    $mult  = 1;
1001
                    if ($str < $limit * $mult) {
1002
                        $out = $str . ' ' . $lang['strbytes'];
1003
                    } else {
1004
                        $mult *= 1024;
1005
                        if ($str < $limit * $mult) {
1006
                            $out = floor(($str + $mult / 2) / $mult) . ' ' . $lang['strkb'];
1007
                        } else {
1008
                            $mult *= 1024;
1009
                            if ($str < $limit * $mult) {
1010
                                $out = floor(($str + $mult / 2) / $mult) . ' ' . $lang['strmb'];
1011
                            } else {
1012
                                $mult *= 1024;
1013
                                if ($str < $limit * $mult) {
1014
                                    $out = floor(($str + $mult / 2) / $mult) . ' ' . $lang['strgb'];
1015
                                } else {
1016
                                    $mult *= 1024;
1017
                                    if ($str < $limit * $mult) {
1018
                                        $out = floor(($str + $mult / 2) / $mult) . ' ' . $lang['strtb'];
1019
                                    }
1020
                                }
1021
                            }
1022
                        }
1023
                    }
1024
                }
1025
1026
                break;
1027
            default:
1028
                // If the string contains at least one instance of >1 space in a row, a tab
1029
                // character, a space at the start of a line, or a space at the start of
1030
                // the whole string then render within a pre-formatted element (<pre>).
1031
                if (preg_match('/(^ |  |\t|\n )/m', $str)) {
1032
                    $tag   = 'pre';
1033
                    $class = 'data';
1034
                    $out   = htmlspecialchars($str);
1035
                } else {
1036
                    $out = nl2br(htmlspecialchars(\PHPPgAdmin\HelperTrait::br2ln($str)));
1037
                }
1038
        }
1039
1040
        if (isset($params['class'])) {
1041
            $class = $params['class'];
1042
        }
1043
1044
        if (isset($params['align'])) {
1045
            $align = $params['align'];
1046
        }
1047
1048
        if (!isset($tag) && (isset($class) || isset($align))) {
1049
            $tag = 'div';
1050
        }
1051
1052
        if (isset($tag)) {
1053
            $alignattr = isset($align) ? " style=\"text-align: {$align}\"" : '';
1054
            $classattr = isset($class) ? " class=\"{$class}\"" : '';
1055
            $out       = "<{$tag}{$alignattr}{$classattr}>{$out}</{$tag}>";
1056
        }
1057
1058
        // Add line numbers if 'lineno' param is true
1059
        if (isset($params['lineno']) && $params['lineno'] === true) {
1060
            $lines = explode("\n", $str);
1061
            $num   = count($lines);
1062
            if ($num > 0) {
1063
                $temp = "<table>\n<tr><td class=\"{$class}\" style=\"vertical-align: top; padding-right: 10px;\"><pre class=\"{$class}\">";
1064
                for ($i = 1; $i <= $num; ++$i) {
1065
                    $temp .= $i . "\n";
1066
                }
1067
                $temp .= "</pre></td><td class=\"{$class}\" style=\"vertical-align: top;\">{$out}</td></tr></table>\n";
1068
                $out = $temp;
1069
            }
1070
            unset($lines);
1071
        }
1072
1073
        return $out;
1074
    }
1075
1076
    /**
1077
     * A function to recursively strip slashes.  Used to
1078
     * enforce magic_quotes_gpc being off.
1079
     *
1080
     * @param &var The variable to strip
1081
     */
1082
    public function stripVar(&$var)
1083
    {
1084
        if (is_array($var)) {
1085
            foreach ($var as $k => $v) {
1086
                $this->stripVar($var[$k]);
1087
1088
                /* magic_quotes_gpc escape keys as well ...*/
1089
                if (is_string($k)) {
1090
                    $ek = stripslashes($k);
1091
                    if ($ek !== $k) {
1092
                        $var[$ek] = $var[$k];
1093
                        unset($var[$k]);
1094
                    }
1095
                }
1096
            }
1097
        } else {
1098
            $var = stripslashes($var);
1099
        }
1100
    }
1101
1102
    /**
1103
     * Retrieve the tab info for a specific tab bar.
1104
     *
1105
     * @param $section the name of the tab bar
1106
     *
1107
     * @return array
1108
     */
1109
    public function getNavTabs($section)
1110
    {
1111
        $data           = $this->getDatabaseAccessor();
1112
        $lang           = $this->lang;
1113
        $plugin_manager = $this->plugin_manager;
1114
1115
        $hide_advanced = ($this->conf['show_advanced'] === false);
1116
        $tabs          = [];
1117
1118
        switch ($section) {
1119
            case 'root':
1120
                $tabs = [
1121
                    'intro'   => [
1122
                        'title' => $lang['strintroduction'],
1123
                        'url'   => 'intro',
1124
                        'icon'  => 'Introduction',
1125
                    ],
1126
                    'servers' => [
1127
                        'title' => $lang['strservers'],
1128
                        'url'   => 'servers',
1129
                        'icon'  => 'Servers',
1130
                    ],
1131
                ];
1132
1133
                break;
1134
            case 'server':
1135
                $hide_users = true;
1136
                if ($data) {
1137
                    $hide_users = !$data->isSuperUser();
1138
                }
1139
1140
                $tabs = [
1141
                    'databases' => [
1142
                        'title'   => $lang['strdatabases'],
1143
                        'url'     => 'alldb',
1144
                        'urlvars' => ['subject' => 'server'],
1145
                        'help'    => 'pg.database',
1146
                        'icon'    => 'Databases',
1147
                    ],
1148
                ];
1149
                if ($data && $data->hasRoles()) {
1150
                    $tabs = array_merge($tabs, [
1 ignored issue
show
Coding Style introduced by
The opening parenthesis of a multi-line function call should be the last content on the line.
Loading history...
1151
                        'roles' => [
1152
                            'title'   => $lang['strroles'],
1153
                            'url'     => 'roles',
1154
                            'urlvars' => ['subject' => 'server'],
1155
                            'hide'    => $hide_users,
1156
                            'help'    => 'pg.role',
1157
                            'icon'    => 'Roles',
1158
                        ],
1159
                    ]);
1 ignored issue
show
Coding Style introduced by
For multi-line function calls, the closing parenthesis should be on a new line.

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

someFunctionCall(
    $firstArgument,
    $secondArgument,
    $thirdArgument
); // Closing parenthesis on a new line.
Loading history...
1160
                } else {
1161
                    $tabs = array_merge($tabs, [
1 ignored issue
show
Coding Style introduced by
The opening parenthesis of a multi-line function call should be the last content on the line.
Loading history...
1162
                        'users'  => [
1163
                            'title'   => $lang['strusers'],
1164
                            'url'     => 'users',
1165
                            'urlvars' => ['subject' => 'server'],
1166
                            'hide'    => $hide_users,
1167
                            'help'    => 'pg.user',
1168
                            'icon'    => 'Users',
1169
                        ],
1170
                        'groups' => [
1171
                            'title'   => $lang['strgroups'],
1172
                            'url'     => 'groups',
1173
                            'urlvars' => ['subject' => 'server'],
1174
                            'hide'    => $hide_users,
1175
                            'help'    => 'pg.group',
1176
                            'icon'    => 'UserGroups',
1177
                        ],
1178
                    ]);
1 ignored issue
show
Coding Style introduced by
For multi-line function calls, the closing parenthesis should be on a new line.

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

someFunctionCall(
    $firstArgument,
    $secondArgument,
    $thirdArgument
); // Closing parenthesis on a new line.
Loading history...
1179
                }
1180
1181
                $tabs = array_merge($tabs, [
1 ignored issue
show
Coding Style introduced by
The opening parenthesis of a multi-line function call should be the last content on the line.
Loading history...
1182
                    'account'     => [
1183
                        'title'   => $lang['straccount'],
1184
                        'url'     => ($data && $data->hasRoles()) ? 'roles' : 'users',
1185
                        'urlvars' => ['subject' => 'server', 'action' => 'account'],
1186
                        'hide'    => !$hide_users,
1187
                        'help'    => 'pg.role',
1188
                        'icon'    => 'User',
1189
                    ],
1190
                    'tablespaces' => [
1191
                        'title'   => $lang['strtablespaces'],
1192
                        'url'     => 'tablespaces',
1193
                        'urlvars' => ['subject' => 'server'],
1194
                        'hide'    => !$data || !$data->hasTablespaces(),
1195
                        'help'    => 'pg.tablespace',
1196
                        'icon'    => 'Tablespaces',
1197
                    ],
1198
                    'export'      => [
1199
                        'title'   => $lang['strexport'],
1200
                        'url'     => 'alldb',
1201
                        'urlvars' => ['subject' => 'server', 'action' => 'export'],
1202
                        'hide'    => !$this->isDumpEnabled(),
1203
                        'icon'    => 'Export',
1204
                    ],
1205
                ]);
1 ignored issue
show
Coding Style introduced by
For multi-line function calls, the closing parenthesis should be on a new line.

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

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