Passed
Push — master ( f27f2e...f3b317 )
by Felipe
04:38
created

Misc::getHREF()   D

Complexity

Conditions 13
Paths 512

Size

Total Lines 21
Code Lines 12

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 21
rs 4.6898
c 0
b 0
f 0
cc 13
eloc 12
nc 512
nop 1

How to fix   Complexity   

Long Method

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

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

Commonly applied refactorings include:

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