Passed
Push — develop ( 9a0eb6...39df77 )
by Felipe
05:13
created

Misc::getDatabaseAccessor()   D

Complexity

Conditions 13
Paths 26

Size

Total Lines 85
Code Lines 42

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 85
rs 4.9922
c 0
b 0
f 0
cc 13
eloc 42
nc 26
nop 2

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