Passed
Pull Request — develop (#147)
by Felipe
05:50 queued 33s
created

Misc::getServerInfo()   C

Complexity

Conditions 10
Paths 17

Size

Total Lines 47
Code Lines 26

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 47
rs 5.1578
c 0
b 0
f 0
cc 10
eloc 26
nc 17
nop 1

How to fix   Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

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

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

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

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
1849
     */
1850
    public function inisizeToBytes($strIniSize)
1851
    {
1852
        // This function will take the string value of an ini 'size' parameter,
1853
        // and return a double (64-bit float) representing the number of bytes
1854
        // that the parameter represents. Or false if $strIniSize is unparseable.
1855
        $a_IniParts = [];
1856
1857
        if (!is_string($strIniSize)) {
0 ignored issues
show
introduced by
The condition is_string($strIniSize) is always true.
Loading history...
1858
            return false;
1859
        }
1860
1861
        if (!preg_match('/^(\d+)([bkm]*)$/i', $strIniSize, $a_IniParts)) {
1862
            return false;
0 ignored issues
show
Bug Best Practice introduced by
The expression return false returns the type false which is incompatible with the documented return type PHPPgAdmin\size.
Loading history...
1863
        }
1864
1865
        $nSize   = (float) $a_IniParts[1];
1866
        $strUnit = strtolower($a_IniParts[2]);
1867
1868
        switch ($strUnit) {
1869
            case 'm':
1870
                return $nSize * (float) 1048576;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $nSize * (double)1048576 returns the type double which is incompatible with the documented return type PHPPgAdmin\size.
Loading history...
1871
            case 'k':
1872
                return $nSize * (float) 1024;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $nSize * (double)1024 returns the type double which is incompatible with the documented return type PHPPgAdmin\size.
Loading history...
1873
            case 'b':
1874
            default:
1875
                return $nSize;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $nSize returns the type double which is incompatible with the documented return type PHPPgAdmin\size.
Loading history...
1876
        }
1877
    }
1878
1879
    public function getRequestVars($subject = '')
1880
    {
1881
        $v = [];
1882
        if (!empty($subject)) {
1883
            $v['subject'] = $subject;
1884
        }
1885
1886
        if ($this->_server_id !== null && $subject != 'root') {
1887
            $v['server'] = $this->_server_id;
1888
            if ($this->_database !== null && $subject != 'server') {
1889
                $v['database'] = $this->_database;
1890
                if (isset($_REQUEST['schema']) && $subject != 'database') {
1891
                    $v['schema'] = $_REQUEST['schema'];
1892
                }
1893
            }
1894
        }
1895
        //$this->prtrace($v);
1896
        return $v;
1897
    }
1898
1899
    public function icon($icon)
1900
    {
1901
        if (is_string($icon)) {
1902
            $path = "/images/themes/{$this->conf['theme']}/{$icon}";
1903
            if (file_exists(\BASE_PATH.$path.'.png')) {
1904
                return SUBFOLDER.$path.'.png';
1905
            }
1906
1907
            if (file_exists(\BASE_PATH.$path.'.gif')) {
1908
                return SUBFOLDER.$path.'.gif';
1909
            }
1910
1911
            if (file_exists(\BASE_PATH.$path.'.ico')) {
1912
                return SUBFOLDER.$path.'.ico';
1913
            }
1914
1915
            $path = "/images/themes/default/{$icon}";
1916
            if (file_exists(\BASE_PATH.$path.'.png')) {
1917
                return SUBFOLDER.$path.'.png';
1918
            }
1919
1920
            if (file_exists(\BASE_PATH.$path.'.gif')) {
1921
                return SUBFOLDER.$path.'.gif';
1922
            }
1923
1924
            if (file_exists(\BASE_PATH.$path.'.ico')) {
1925
                return SUBFOLDER.$path.'.ico';
1926
            }
1927
        } else {
1928
            // Icon from plugins
1929
            $path = "/plugins/{$icon[0]}/images/{$icon[1]}";
1930
            if (file_exists(\BASE_PATH.$path.'.png')) {
1931
                return SUBFOLDER.$path.'.png';
1932
            }
1933
1934
            if (file_exists(\BASE_PATH.$path.'.gif')) {
1935
                return SUBFOLDER.$path.'.gif';
1936
            }
1937
1938
            if (file_exists(\BASE_PATH.$path.'.ico')) {
1939
                return SUBFOLDER.$path.'.ico';
1940
            }
1941
        }
1942
1943
        return '';
1944
    }
1945
1946
    /**
1947
     * Function to escape command line parameters.
1948
     *
1949
     * @param string $str The string to escape
1950
     *
1951
     * @return string The escaped string
1952
     */
1953
    public function escapeShellArg($str)
1954
    {
1955
        //$data = $this->getDatabaseAccessor();
1956
        $lang = $this->lang;
1957
1958
        if (strtoupper(substr(PHP_OS, 0, 3)) === 'WIN') {
1959
            // Due to annoying PHP bugs, shell arguments cannot be escaped
1960
            // (command simply fails), so we cannot allow complex objects
1961
            // to be dumped.
1962
            if (preg_match('/^[_.[:alnum:]]+$/', $str)) {
1963
                return $str;
1964
            }
1965
1966
            return $this->halt($lang['strcannotdumponwindows']);
1967
        }
1968
1969
        return escapeshellarg($str);
1970
    }
1971
1972
    /**
1973
     * Function to escape command line programs.
1974
     *
1975
     * @param string $str The string to escape
1976
     *
1977
     * @return string The escaped string
1978
     */
1979
    public function escapeShellCmd($str)
1980
    {
1981
        $data = $this->getDatabaseAccessor();
1982
1983
        if (strtoupper(substr(PHP_OS, 0, 3)) === 'WIN') {
1984
            $data->fieldClean($str);
1985
1986
            return '"'.$str.'"';
1987
        }
1988
1989
        return escapeshellcmd($str);
1990
    }
1991
1992
    /**
1993
     * Save the given SQL script in the history
0 ignored issues
show
Bug introduced by
The type PHPPgAdmin\the was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
1994
     * of the database and server.
1995
     *
1996
     * @param $script the SQL script to save
1997
     */
1998
    public function saveScriptHistory($script)
1999
    {
2000
        list($usec, $sec)                                                           = explode(' ', microtime());
2001
        $time                                                                       = ((float) $usec + (float) $sec);
2002
        $_SESSION['history'][$_REQUEST['server']][$_REQUEST['database']]["${time}"] = [
2003
            'query'    => $script,
2004
            'paginate' => !isset($_REQUEST['paginate']) ? 'f' : 't',
2005
            'queryid'  => $time,
2006
        ];
2007
    }
2008
2009
    /**
2010
     * 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...
2011
     * or by constraint.
2012
     *
2013
     * @param tring $table The table to retrieve FK contraints from
0 ignored issues
show
Bug introduced by
The type PHPPgAdmin\tring was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
2014
     *
2015
     * @return array|bool the array of FK definition:
2016
     *                    array(
2017
     *                    'byconstr' => array(
2018
     *                    constrain id => array(
2019
     *                    confrelid => foreign relation oid
2020
     *                    f_schema => foreign schema name
2021
     *                    f_table => foreign table name
2022
     *                    pattnums => array of parent's fields nums
2023
     *                    pattnames => array of parent's fields names
2024
     *                    fattnames => array of foreign attributes names
2025
     *                    )
2026
     *                    ),
2027
     *                    'byfield' => array(
2028
     *                    attribute num => array (constraint id, ...)
2029
     *                    ),
2030
     *                    'code' => HTML/js code to include in the page for auto-completion
2031
     *                    )
2032
     */
2033
    public function getAutocompleteFKProperties($table)
2034
    {
2035
        $data = $this->getDatabaseAccessor();
2036
2037
        $fksprops = [
2038
            'byconstr' => [],
2039
            'byfield'  => [],
2040
            'code'     => '',
2041
        ];
2042
2043
        $constrs = $data->getConstraintsWithFields($table);
2044
2045
        if (!$constrs->EOF) {
2046
            $conrelid = $constrs->fields['conrelid'];
0 ignored issues
show
Unused Code introduced by
The assignment to $conrelid is dead and can be removed.
Loading history...
2047
            while (!$constrs->EOF) {
2048
                if ($constrs->fields['contype'] == 'f') {
2049
                    if (!isset($fksprops['byconstr'][$constrs->fields['conid']])) {
2050
                        $fksprops['byconstr'][$constrs->fields['conid']] = [
2051
                            'confrelid' => $constrs->fields['confrelid'],
2052
                            'f_table'   => $constrs->fields['f_table'],
2053
                            'f_schema'  => $constrs->fields['f_schema'],
2054
                            'pattnums'  => [],
2055
                            'pattnames' => [],
2056
                            'fattnames' => [],
2057
                        ];
2058
                    }
2059
2060
                    $fksprops['byconstr'][$constrs->fields['conid']]['pattnums'][]  = $constrs->fields['p_attnum'];
2061
                    $fksprops['byconstr'][$constrs->fields['conid']]['pattnames'][] = $constrs->fields['p_field'];
2062
                    $fksprops['byconstr'][$constrs->fields['conid']]['fattnames'][] = $constrs->fields['f_field'];
2063
2064
                    if (!isset($fksprops['byfield'][$constrs->fields['p_attnum']])) {
2065
                        $fksprops['byfield'][$constrs->fields['p_attnum']] = [];
2066
                    }
2067
2068
                    $fksprops['byfield'][$constrs->fields['p_attnum']][] = $constrs->fields['conid'];
2069
                }
2070
                $constrs->moveNext();
2071
            }
2072
2073
            $fksprops['code'] = "<script type=\"text/javascript\">\n";
2074
            $fksprops['code'] .= "var constrs = {};\n";
2075
            foreach ($fksprops['byconstr'] as $conid => $props) {
2076
                $fksprops['code'] .= "constrs.constr_{$conid} = {\n";
2077
                $fksprops['code'] .= 'pattnums: ['.implode(',', $props['pattnums'])."],\n";
2078
                $fksprops['code'] .= "f_table:'".addslashes(htmlentities($props['f_table'], ENT_QUOTES, 'UTF-8'))."',\n";
2079
                $fksprops['code'] .= "f_schema:'".addslashes(htmlentities($props['f_schema'], ENT_QUOTES, 'UTF-8'))."',\n";
2080
                $_ = '';
2081
                foreach ($props['pattnames'] as $n) {
2082
                    $_ .= ",'".htmlentities($n, ENT_QUOTES, 'UTF-8')."'";
2083
                }
2084
                $fksprops['code'] .= 'pattnames: ['.substr($_, 1)."],\n";
2085
2086
                $_ = '';
2087
                foreach ($props['fattnames'] as $n) {
2088
                    $_ .= ",'".htmlentities($n, ENT_QUOTES, 'UTF-8')."'";
2089
                }
2090
2091
                $fksprops['code'] .= 'fattnames: ['.substr($_, 1)."]\n";
2092
                $fksprops['code'] .= "};\n";
2093
            }
2094
2095
            $fksprops['code'] .= "var attrs = {};\n";
2096
            foreach ($fksprops['byfield'] as $attnum => $cstrs) {
2097
                $fksprops['code'] .= "attrs.attr_{$attnum} = [".implode(',', $fksprops['byfield'][$attnum])."];\n";
2098
            }
2099
2100
            $fksprops['code'] .= "var table='".addslashes(htmlentities($table, ENT_QUOTES, 'UTF-8'))."';";
2101
            $fksprops['code'] .= "var server='".htmlentities($_REQUEST['server'], ENT_QUOTES, 'UTF-8')."';";
2102
            $fksprops['code'] .= "var database='".addslashes(htmlentities($_REQUEST['database'], ENT_QUOTES, 'UTF-8'))."';";
2103
            $fksprops['code'] .= "var subfolder='".SUBFOLDER."';";
2104
            $fksprops['code'] .= "</script>\n";
2105
2106
            $fksprops['code'] .= '<div id="fkbg"></div>';
2107
            $fksprops['code'] .= '<div id="fklist"></div>';
2108
            $fksprops['code'] .= '<script src="'.SUBFOLDER.'/js/ac_insert_row.js" type="text/javascript"></script>';
2109
        } else {
2110
            /* we have no foreign keys on this table */
2111
            return false;
2112
        }
2113
2114
        return $fksprops;
2115
    }
2116
}
2117