Passed
Push — develop ( d51928...4c214f )
by Felipe
31:34 queued 23:49
created

Misc   D

Complexity

Total Complexity 138

Size/Duplication

Total Lines 822
Duplicated Lines 5.11 %

Coupling/Cohesion

Components 2
Dependencies 4

Importance

Changes 0
Metric Value
dl 42
loc 822
rs 4.4444
c 0
b 0
f 0
wmc 138
lcom 2
cbo 4

32 Methods

Rating   Name   Duplication   Size   Complexity  
B __construct() 0 38 5
A serverToSha() 0 13 3
B getServerId() 0 20 6
A setView() 0 6 1
A setConf() 0 6 1
A getConf() 0 11 3
A printHelp() 0 14 3
A getHelpLink() 0 4 1
A setReloadBrowser() 0 6 1
A getReloadBrowser() 0 4 1
A getContainer() 0 4 1
A setNoDBConnection() 0 6 1
A getNoDBConnection() 0 4 1
A setErrorMsg() 0 6 1
A getErrorMsg() 0 4 1
D getDatabaseAccessor() 0 85 13
C getConnection() 0 53 9
C getServerInfo() 0 50 10
B setServerInfo() 15 23 5
D getDatabase() 0 28 10
A setCurrentSchema() 0 15 2
A isDumpEnabled() 0 6 2
A setHREF() 0 6 1
F getHREF() 0 22 13
A setForm() 0 18 4
B stripVar() 0 19 5
B inisizeToBytes() 0 28 6
B getRequestVars() 0 19 8
C icon() 27 46 11
A escapeShellArg() 0 18 3
A escapeShellCmd() 0 12 2
A saveScriptHistory() 0 14 4

How to fix   Duplicated Code    Complexity   

Duplicated Code

Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.

Common duplication problems, and corresponding solutions are:

Complex Class

 Tip:   Before tackling complexity, make sure that you eliminate any duplication first. This often can reduce the size of classes significantly.

Complex classes like Misc often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes. You can also have a look at the cohesion graph to spot any un-connected, or weakly-connected components.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use Misc, and based on these observations, apply Extract Interface, too.

1
<?php
2
3
/**
4
 * PHPPgAdmin v6.0.0-beta.48
5
 */
6
7
namespace PHPPgAdmin;
8
9
/**
10
 * @file
11
 * Class to hold various commonly used functions
12
 *
13
 * Id: Misc.php,v 1.171 2008/03/17 21:35:48 ioguix Exp $
14
 *
15
 * @package PHPPgAdmin
16
 */
17
18
/**
19
 * Class to hold various commonly used functions.
20
 *
21
 * Release: Misc.php,v 1.171 2008/03/17 21:35:48 ioguix Exp $
22
 *
23
 * @package PHPPgAdmin
24
 */
25
class Misc
9 ignored issues
show
Coding Style introduced by
The property $_connection is not named in camelCase.

This check marks property names that have not been written in camelCase.

In camelCase names are written without any punctuation, the start of each new word being marked by a capital letter. Thus the name database connection string becomes databaseConnectionString.

Loading history...
Coding Style introduced by
The property $_no_db_connection is not named in camelCase.

This check marks property names that have not been written in camelCase.

In camelCase names are written without any punctuation, the start of each new word being marked by a capital letter. Thus the name database connection string becomes databaseConnectionString.

Loading history...
Coding Style introduced by
The property $_reload_browser is not named in camelCase.

This check marks property names that have not been written in camelCase.

In camelCase names are written without any punctuation, the start of each new word being marked by a capital letter. Thus the name database connection string becomes databaseConnectionString.

Loading history...
Coding Style introduced by
The property $_data is not named in camelCase.

This check marks property names that have not been written in camelCase.

In camelCase names are written without any punctuation, the start of each new word being marked by a capital letter. Thus the name database connection string becomes databaseConnectionString.

Loading history...
Coding Style introduced by
The property $_database is not named in camelCase.

This check marks property names that have not been written in camelCase.

In camelCase names are written without any punctuation, the start of each new word being marked by a capital letter. Thus the name database connection string becomes databaseConnectionString.

Loading history...
Coding Style introduced by
The property $_server_id is not named in camelCase.

This check marks property names that have not been written in camelCase.

In camelCase names are written without any punctuation, the start of each new word being marked by a capital letter. Thus the name database connection string becomes databaseConnectionString.

Loading history...
Coding Style introduced by
The property $_server_info is not named in camelCase.

This check marks property names that have not been written in camelCase.

In camelCase names are written without any punctuation, the start of each new word being marked by a capital letter. Thus the name database connection string becomes databaseConnectionString.

Loading history...
Coding Style introduced by
The property $_error_msg is not named in camelCase.

This check marks property names that have not been written in camelCase.

In camelCase names are written without any punctuation, the start of each new word being marked by a capital letter. Thus the name database connection string becomes databaseConnectionString.

Loading history...
Coding Style introduced by
The property $controller_name is not named in camelCase.

This check marks property names that have not been written in camelCase.

In camelCase names are written without any punctuation, the start of each new word being marked by a capital letter. Thus the name database connection string becomes databaseConnectionString.

Loading history...
26
{
27
    use \PHPPgAdmin\Traits\HelperTrait;
28
    use \PHPPgAdmin\Traits\MiscTrait;
29
30
    private $_connection;
31
    private $_no_db_connection = false;
32
    private $_reload_browser   = false;
33
    private $_data;
34
    private $_database;
35
    private $_server_id;
36
    private $_server_info;
37
    private $_error_msg = '';
38
39
    public $appLangFiles    = [];
40
    public $appName         = '';
41
    public $appVersion      = '';
42
    public $form            = '';
43
    public $href            = '';
44
    public $controller_name = 'Misc';
45
    public $lang            = [];
46
47
    protected $container;
48
49
    /**
50
     * @param \Slim\Container $container The container
51
     */
52
    public function __construct(\Slim\Container $container)
53
    {
54
        $this->container = $container;
55
56
        $this->lang = $container->get('lang');
0 ignored issues
show
Documentation Bug introduced by
It seems like $container->get('lang') of type * is incompatible with the declared type array of property $lang.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
57
        $this->conf = $container->get('conf');
0 ignored issues
show
Bug introduced by
The property conf does not exist. Did you maybe forget to declare it?

In PHP it is possible to write to properties without declaring them. For example, the following is perfectly valid PHP code:

class MyClass { }

$x = new MyClass();
$x->foo = true;

Generally, it is a good practice to explictly declare properties to avoid accidental typos and provide IDE auto-completion:

class MyClass {
    public $foo;
}

$x = new MyClass();
$x->foo = true;
Loading history...
58
59
        //$this->view           = $container->get('view');
60
        $this->plugin_manager = $container->get('plugin_manager');
0 ignored issues
show
Bug introduced by
The property plugin_manager does not exist. Did you maybe forget to declare it?

In PHP it is possible to write to properties without declaring them. For example, the following is perfectly valid PHP code:

class MyClass { }

$x = new MyClass();
$x->foo = true;

Generally, it is a good practice to explictly declare properties to avoid accidental typos and provide IDE auto-completion:

class MyClass {
    public $foo;
}

$x = new MyClass();
$x->foo = true;
Loading history...
61
        $this->appLangFiles   = $container->get('appLangFiles');
0 ignored issues
show
Documentation Bug introduced by
It seems like $container->get('appLangFiles') of type * is incompatible with the declared type array of property $appLangFiles.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
62
63
        $this->appName          = $container->get('settings')['appName'];
64
        $this->appVersion       = $container->get('settings')['appVersion'];
65
        $this->postgresqlMinVer = $container->get('settings')['postgresqlMinVer'];
0 ignored issues
show
Bug introduced by
The property postgresqlMinVer does not exist. Did you maybe forget to declare it?

In PHP it is possible to write to properties without declaring them. For example, the following is perfectly valid PHP code:

class MyClass { }

$x = new MyClass();
$x->foo = true;

Generally, it is a good practice to explictly declare properties to avoid accidental typos and provide IDE auto-completion:

class MyClass {
    public $foo;
}

$x = new MyClass();
$x->foo = true;
Loading history...
66
        $this->phpMinVer        = $container->get('settings')['phpMinVer'];
0 ignored issues
show
Bug introduced by
The property phpMinVer does not exist. Did you maybe forget to declare it?

In PHP it is possible to write to properties without declaring them. For example, the following is perfectly valid PHP code:

class MyClass { }

$x = new MyClass();
$x->foo = true;

Generally, it is a good practice to explictly declare properties to avoid accidental typos and provide IDE auto-completion:

class MyClass {
    public $foo;
}

$x = new MyClass();
$x->foo = true;
Loading history...
67
68
        $base_version = $container->get('settings')['base_version'];
69
70
        //$this->prtrace($base_version);
71
72
        // Check for config file version mismatch
73
        if (!isset($this->conf['version']) || $base_version > $this->conf['version']) {
74
            $container->get('utils')->addError($this->lang['strbadconfig']);
75
        }
76
77
        // Check database support is properly compiled in
78
        if (!function_exists('pg_connect')) {
79
            $container->get('utils')->addError($this->lang['strnotloaded']);
80
        }
81
82
        // Check the version of PHP
83
        if (version_compare(PHP_VERSION, $this->phpMinVer, '<')) {
84
            $container->get('utils')->addError(sprintf('Version of PHP not supported. Please upgrade to version %s or later.', $this->phpMinVer));
85
        }
86
        //$this->dumpAndDie($this);
87
88
        $this->getServerId();
89
    }
90
91
    public function serverToSha()
0 ignored issues
show
Documentation introduced by
The return type could not be reliably inferred; please add a @return annotation.

Our type inference engine in quite powerful, but sometimes the code does not provide enough clues to go by. In these cases we request you to add a @return annotation as described here.

Loading history...
92
    {
93
        $request_server = $this->container->requestobj->getParam('server');
0 ignored issues
show
Bug introduced by
The property requestobj does not seem to exist. Did you mean request?

An attempt at access to an undefined property has been detected. This may either be a typographical error or the property has been renamed but there are still references to its old name.

If you really want to allow access to undefined properties, you can define magic methods to allow access. See the php core documentation on Overloading.

Loading history...
94
        if ($request_server === null) {
95
            return null;
96
        }
97
        $srv_array = explode(':', $request_server);
98
        if (count($srv_array) === 3) {
99
            return sha1($request_server);
100
        }
101
102
        return $request_server;
103
    }
104
105
    public function getServerId()
0 ignored issues
show
Documentation introduced by
The return type could not be reliably inferred; please add a @return annotation.

Our type inference engine in quite powerful, but sometimes the code does not provide enough clues to go by. In these cases we request you to add a @return annotation as described here.

Loading history...
106
    {
107
        if ($this->_server_id) {
108
            return $this->_server_id;
109
        }
110
111
        $request_server = $this->serverToSha();
112
113
        if (count($this->conf['servers']) === 1) {
114
            $info             = $this->conf['servers'][0];
115
            $this->_server_id = sha1($info['host'].':'.$info['port'].':'.$info['sslmode']);
116
        } elseif ($request_server !== null) {
117
            $this->_server_id = $request_server;
118
        } elseif (isset($_SESSION['webdbLogin']) && count($_SESSION['webdbLogin']) > 0) {
119
            //$this->prtrace('webdbLogin', $_SESSION['webdbLogin']);
120
            $this->_server_id = array_keys($_SESSION['webdbLogin'])[0];
121
        }
122
123
        return $this->_server_id;
124
    }
125
126
    /**
127
     * Sets the view instance property of this class.
128
     *
129
     * @param \Slim\Views\Twig $view view instance
130
     *
131
     * @return \PHPPgAdmin\Misc this class instance
132
     */
133
    public function setView(\Slim\Views\Twig $view)
134
    {
135
        $this->view = $view;
0 ignored issues
show
Bug introduced by
The property view does not exist. Did you maybe forget to declare it?

In PHP it is possible to write to properties without declaring them. For example, the following is perfectly valid PHP code:

class MyClass { }

$x = new MyClass();
$x->foo = true;

Generally, it is a good practice to explictly declare properties to avoid accidental typos and provide IDE auto-completion:

class MyClass {
    public $foo;
}

$x = new MyClass();
$x->foo = true;
Loading history...
136
137
        return $this;
138
    }
139
140
    /**
141
     * Adds or modifies a key in the $conf instance property of this class.
142
     *
143
     * @param string $key   name of the key to set
144
     * @param mixed  $value value of the key to set
145
     *
146
     * @return \PHPPgAdmin\Misc this class instance
147
     */
148
    public function setConf($key, $value)
149
    {
150
        $this->conf[$key] = $value;
151
152
        return $this;
153
    }
154
155
    /**
156
     * Gets the value of a config property, or the array of all config properties.
157
     *
158
     * @param null|string $key value of the key to be retrieved. If null, the full array is returnes
159
     *
160
     * @return null|array|string the whole $conf array, the value of $conf[key] or null if said key does not exist
161
     */
162
    public function getConf($key = null)
163
    {
164
        if ($key === null) {
165
            return $this->conf;
166
        }
167
        if (array_key_exists($key, $this->conf)) {
168
            return $this->conf[$key];
169
        }
170
171
        return null;
172
    }
173
174
    /**
175
     * Displays link to the context help.
176
     *
177
     * @param string $str      the string that the context help is related to (already escaped)
178
     * @param string $help     help section identifier
0 ignored issues
show
Documentation introduced by
Should the type for parameter $help not be string|null?

This check looks for @param annotations where the type inferred by our type inference engine differs from the declared type.

It makes a suggestion as to what type it considers more descriptive.

Most often this is a case of a parameter that can be null in addition to its declared types.

Loading history...
179
     * @param bool   $do_print true to echo, false to return
180
     */
181
    public function printHelp($str, $help = null, $do_print = true)
0 ignored issues
show
Coding Style Naming introduced by
The parameter $do_print is not named in camelCase.

This check marks parameter names that have not been written in camelCase.

In camelCase names are written without any punctuation, the start of each new word being marked by a capital letter. Thus the name database connection string becomes databaseConnectionString.

Loading history...
182
    {
183
        //\PC::debug(['str' => $str, 'help' => $help], 'printHelp');
184
        if ($help !== null) {
185
            $helplink = $this->getHelpLink($help);
186
            $str .= '<a class="help" href="'.$helplink.'" title="'.$this->lang['strhelp'].'" target="phppgadminhelp">';
187
            $str .= $this->lang['strhelpicon'].'</a>';
188
        }
189
        if ($do_print) {
190
            echo $str;
191
        } else {
192
            return $str;
193
        }
194
    }
195
196
    /**
197
     * Gets the help link.
198
     *
199
     * @param string $help The help subject
200
     *
201
     * @return string the help link
202
     */
203
    public function getHelpLink($help)
204
    {
205
        return htmlspecialchars(SUBFOLDER.'/help?help='.urlencode($help).'&server='.urlencode($this->getServerId()));
206
    }
207
208
    /**
209
     * Internally sets the reload browser property.
210
     *
211
     * @param bool $flag sets internal $_reload_browser var which will be passed to the footer methods
212
     *
213
     * @return \PHPPgAdmin\Misc this class instance
214
     */
215
    public function setReloadBrowser($flag)
216
    {
217
        $this->_reload_browser = (bool) $flag;
218
219
        return $this;
220
    }
221
222
    public function getReloadBrowser()
223
    {
224
        return $this->_reload_browser;
225
    }
226
227
    public function getContainer()
228
    {
229
        return $this->container;
230
    }
231
232
    /**
233
     * Sets $_no_db_connection boolean value, allows to render scripts that do not need an active session.
234
     *
235
     * @param bool $flag true or false to allow unconnected clients to access the view
236
     *
237
     * @return \PHPPgAdmin\Misc this class instance
238
     */
239
    public function setNoDBConnection($flag)
240
    {
241
        $this->_no_db_connection = (bool) $flag;
242
243
        return $this;
244
    }
245
246
    /**
247
     * Gets member variable $_no_db_connection.
248
     *
249
     * @return bool value of member variable $_no_db_connection
250
     */
251
    public function getNoDBConnection()
252
    {
253
        return $this->_no_db_connection;
254
    }
255
256
    /**
257
     * Sets the last error message to display afterwards instead of just dying with the error msg.
258
     *
259
     * @param string $msg error message string
260
     *
261
     * @return \PHPPgAdmin\Misc this class instance
262
     */
263
    public function setErrorMsg($msg)
264
    {
265
        $this->_error_msg = $msg;
266
267
        return $this;
268
    }
269
270
    /**
271
     * Returns the error messages stored in member variable $_error_msg.
272
     *
273
     * @return string the error message
274
     */
275
    public function getErrorMsg()
276
    {
277
        return $this->_error_msg;
278
    }
279
280
    /**
281
     * Creates a database accessor.
282
     *
283
     * @param string $database  the name of the database
284
     * @param mixed  $server_id the id of the server
285
     *
286
     * @internal mixed $plaform placeholder that will receive the value of the platform
287
     */
288
    public function getDatabaseAccessor($database = '', $server_id = null)
0 ignored issues
show
Documentation introduced by
The return type could not be reliably inferred; please add a @return annotation.

Our type inference engine in quite powerful, but sometimes the code does not provide enough clues to go by. In these cases we request you to add a @return annotation as described here.

Loading history...
Coding Style Naming introduced by
The parameter $server_id is not named in camelCase.

This check marks parameter names that have not been written in camelCase.

In camelCase names are written without any punctuation, the start of each new word being marked by a capital letter. Thus the name database connection string becomes databaseConnectionString.

Loading history...
289
    {
290
        $lang = $this->lang;
291
292
        if ($server_id !== null) {
293
            $this->_server_id = $server_id;
294
        }
295
        //$this->prtrace($this->_server_id);
296
297
        $server_info = $this->getServerInfo($this->_server_id);
298
299
        if ($this->_no_db_connection || !isset($server_info['username'])) {
300
            return null;
301
        }
302
303
        if ($this->_data === null) {
304
            try {
305
                $_connection = $this->getConnection($database, $this->_server_id);
306
            } catch (\Exception $e) {
307
                $this->setServerInfo(null, null, $this->_server_id);
308
                $this->setNoDBConnection(true);
309
                $this->setErrorMsg($e->getMessage());
310
311
                return null;
312
            }
313
314
            //$this->prtrace('_connection', $_connection);
315
            if (!$_connection) {
316
                $this->container->utils->addError($lang['strloginfailed']);
317
                $this->setErrorMsg($lang['strloginfailed']);
318
319
                return null;
320
            }
321
            // Get the name of the database driver we need to use.
322
            // The description of the server is returned in $platform.
323
            $_type = $_connection->getDriver($platform);
0 ignored issues
show
Bug introduced by
The variable $platform does not exist. Did you forget to declare it?

This check marks access to variables or properties that have not been declared yet. While PHP has no explicit notion of declaring a variable, accessing it before a value is assigned to it is most likely a bug.

Loading history...
324
325
            //$this->prtrace(['type' => $_type, 'platform' => $platform, 'pgVersion' => $_connection->conn->pgVersion]);
326
327
            if ($_type === null) {
328
                $errormsg = sprintf($lang['strpostgresqlversionnotsupported'], $this->postgresqlMinVer);
329
                $this->container->utils->addError($errormsg);
330
                $this->setErrorMsg($errormsg);
331
332
                return null;
333
            }
334
            $_type = '\PHPPgAdmin\Database\\'.$_type;
335
336
            $this->setServerInfo('platform', $platform, $this->_server_id);
337
            $this->setServerInfo('pgVersion', $_connection->conn->pgVersion, $this->_server_id);
338
339
            // Create a database wrapper class for easy manipulation of the
340
            // connection.
341
342
            $this->_data           = new $_type($_connection->conn, $this->container, $server_info);
343
            $this->_data->platform = $_connection->platform;
344
345
            //$this->_data->getHelpPages();
346
347
            //$this->prtrace('help_page has ' . count($this->_data->help_page) . ' items');
348
349
            /* we work on UTF-8 only encoding */
350
            $this->_data->execute("SET client_encoding TO 'UTF-8'");
351
352
            if ($this->_data->hasByteaHexDefault()) {
353
                $this->_data->execute('SET bytea_output TO escape');
354
            }
355
        }
356
357
        if ($this->_no_db_connection === false &&
358
            $this->getDatabase() !== null &&
359
            isset($_REQUEST['schema'])
360
        ) {
361
            $status = $this->_data->setSchema($_REQUEST['schema']);
362
363
            if ($status != 0) {
364
                $this->container->utils->addError($this->lang['strbadschema']);
365
                $this->setErrorMsg($this->lang['strbadschema']);
366
367
                return null;
368
            }
369
        }
370
371
        return $this->_data;
372
    }
373
374
    public function getConnection($database = '', $server_id = null)
0 ignored issues
show
Documentation introduced by
The return type could not be reliably inferred; please add a @return annotation.

Our type inference engine in quite powerful, but sometimes the code does not provide enough clues to go by. In these cases we request you to add a @return annotation as described here.

Loading history...
Coding Style Naming introduced by
The parameter $server_id is not named in camelCase.

This check marks parameter names that have not been written in camelCase.

In camelCase names are written without any punctuation, the start of each new word being marked by a capital letter. Thus the name database connection string becomes databaseConnectionString.

Loading history...
375
    {
376
        $lang = $this->lang;
377
378
        if ($this->_connection === null) {
379
            if ($server_id !== null) {
380
                $this->_server_id = $server_id;
381
            }
382
            $server_info     = $this->getServerInfo($this->_server_id);
383
            $database_to_use = $this->getDatabase($database);
384
385
            // Perform extra security checks if this config option is set
386
            if ($this->conf['extra_login_security']) {
387
                // Disallowed logins if extra_login_security is enabled.
388
                // These must be lowercase.
389
                $bad_usernames = [
390
                    'pgsql'         => 'pgsql',
391
                    'postgres'      => 'postgres',
392
                    'root'          => 'root',
393
                    'administrator' => 'administrator',
394
                ];
395
396
                if (isset($server_info['username']) &&
397
                    array_key_exists(strtolower($server_info['username']), $bad_usernames)
398
                ) {
399
                    $msg = $lang['strlogindisallowed'];
400
401
                    throw new \Exception($msg);
402
                }
403
404
                if (!isset($server_info['password']) ||
405
                    $server_info['password'] == ''
406
                ) {
407
                    $msg = $lang['strlogindisallowed'];
408
409
                    throw new \Exception($msg);
410
                }
411
            }
412
413
            try {
414
                // Create the connection object and make the connection
415
                $this->_connection = new \PHPPgAdmin\Database\Connection(
416
                    $server_info,
417
                    $database_to_use,
418
                    $this->container
419
                );
420
            } catch (\PHPPgAdmin\ADOdbException $e) {
421
                throw new \Exception($lang['strloginfailed']);
422
            }
423
        }
424
425
        return $this->_connection;
426
    }
427
428
    /**
429
     * Validate and retrieve information on a server.
430
     * If the parameter isn't supplied then the currently
431
     * connected server is returned.
432
     *
433
     * @param string $server_id A server identifier (host:port)
0 ignored issues
show
Documentation introduced by
Should the type for parameter $server_id not be string|null?

This check looks for @param annotations where the type inferred by our type inference engine differs from the declared type.

It makes a suggestion as to what type it considers more descriptive.

Most often this is a case of a parameter that can be null in addition to its declared types.

Loading history...
434
     *
435
     * @return array An associative array of server properties
436
     */
437
    public function getServerInfo($server_id = null)
0 ignored issues
show
Coding Style Naming introduced by
The parameter $server_id is not named in camelCase.

This check marks parameter names that have not been written in camelCase.

In camelCase names are written without any punctuation, the start of each new word being marked by a capital letter. Thus the name database connection string becomes databaseConnectionString.

Loading history...
438
    {
439
        //\PC::debug(['$server_id' => $server_id]);
440
441
        if ($server_id !== null) {
442
            $this->_server_id = $server_id;
443
        } elseif ($this->_server_info !== null) {
444
            return $this->_server_info;
445
        }
446
447
        // Check for the server in the logged-in list
448
        if (isset($_SESSION['webdbLogin'][$this->_server_id])) {
449
            $this->_server_info = $_SESSION['webdbLogin'][$this->_server_id];
450
451
            return $this->_server_info;
452
        }
453
454
        // Otherwise, look for it in the conf file
455
        foreach ($this->conf['servers'] as $idx => $info) {
456
            $server_string = $info['host'].':'.$info['port'].':'.$info['sslmode'];
457
            $server_sha    = sha1($server_string);
458
459
            if ($this->_server_id === $server_string ||
460
                $this->_server_id === $server_sha
461
            ) {
462
                if (isset($info['username'])) {
463
                    $this->setServerInfo(null, $info, $this->_server_id);
464
                } elseif (isset($_SESSION['sharedUsername'])) {
465
                    $info['username'] = $_SESSION['sharedUsername'];
466
                    $info['password'] = $_SESSION['sharedPassword'];
467
                    $this->setReloadBrowser(true);
468
                    $this->setServerInfo(null, $info, $this->_server_id);
469
                }
470
                $this->_server_info = $info;
471
472
                return $this->_server_info;
473
            }
474
        }
475
476
        if ($server_id === null) {
477
            $this->_server_info = null;
478
479
            return $this->_server_info;
480
        }
481
482
        $this->prtrace('Invalid server param');
483
        $this->_server_info = null;
484
        // Unable to find a matching server, are we being hacked?
485
        return $this->halt($this->lang['strinvalidserverparam']);
486
    }
487
488
    /**
489
     * Set server information.
490
     *
491
     * @param null|string $key       parameter name to set, or null to replace all
492
     *                               params with the assoc-array in $value
493
     * @param mixed       $value     the new value, or null to unset the parameter
494
     * @param null|string $server_id the server identifier, or null for current server
495
     */
496
    public function setServerInfo($key, $value, $server_id = null)
0 ignored issues
show
Coding Style Naming introduced by
The parameter $server_id is not named in camelCase.

This check marks parameter names that have not been written in camelCase.

In camelCase names are written without any punctuation, the start of each new word being marked by a capital letter. Thus the name database connection string becomes databaseConnectionString.

Loading history...
497
    {
498
        //\PC::debug('setsetverinfo');
499
        if ($server_id === null) {
500
            $server_id = $this->container->requestobj->getParam('server');
0 ignored issues
show
Bug introduced by
The property requestobj does not seem to exist. Did you mean request?

An attempt at access to an undefined property has been detected. This may either be a typographical error or the property has been renamed but there are still references to its old name.

If you really want to allow access to undefined properties, you can define magic methods to allow access. See the php core documentation on Overloading.

Loading history...
501
        }
502
503
        if ($key === null) {
504 View Code Duplication
            if ($value === null) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
505
                unset($_SESSION['webdbLogin'][$server_id]);
506
            } else {
507
                //\PC::debug(['server_id' => $server_id, 'value' => $value], 'webdbLogin null key');
508
                $_SESSION['webdbLogin'][$server_id] = $value;
509
            }
510 View Code Duplication
        } else {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
511
            if ($value === null) {
512
                unset($_SESSION['webdbLogin'][$server_id][$key]);
513
            } else {
514
                //\PC::debug(['server_id' => $server_id, 'key' => $key, 'value' => $value], __FILE__ . ' ' . __LINE__ . ' webdbLogin key ' . $key);
515
                $_SESSION['webdbLogin'][$server_id][$key] = $value;
516
            }
517
        }
518
    }
519
520
    public function getDatabase($database = '')
0 ignored issues
show
Documentation introduced by
The return type could not be reliably inferred; please add a @return annotation.

Our type inference engine in quite powerful, but sometimes the code does not provide enough clues to go by. In these cases we request you to add a @return annotation as described here.

Loading history...
521
    {
522
        if ($this->_server_id === null && !isset($_REQUEST['database'])) {
523
            return null;
524
        }
525
526
        $server_info = $this->getServerInfo($this->_server_id);
527
528
        if ($this->_server_id !== null &&
529
            isset($server_info['useonlydefaultdb']) &&
530
            $server_info['useonlydefaultdb'] === true &&
531
            isset($server_info['defaultdb'])
532
        ) {
533
            $this->_database = $server_info['defaultdb'];
534
        } elseif ($database !== '') {
535
            $this->_database = $database;
536
        } elseif (isset($_REQUEST['database'])) {
537
            // Connect to the current database
538
            $this->_database = $_REQUEST['database'];
539
        } elseif (isset($server_info['defaultdb'])) {
540
            // or if one is not specified then connect to the default database.
541
            $this->_database = $server_info['defaultdb'];
542
        } else {
543
            return null;
544
        }
545
546
        return $this->_database;
547
    }
548
549
    /**
550
     * Set the current schema.
551
     *
552
     * @param string $schema The schema name
553
     *
554
     * @return int 0 on success
555
     */
556
    public function setCurrentSchema($schema)
557
    {
558
        $data = $this->getDatabaseAccessor();
559
560
        $status = $data->setSchema($schema);
561
        if ($status != 0) {
562
            return $status;
563
        }
564
565
        $_REQUEST['schema'] = $schema;
566
        $this->container->offsetSet('schema', $schema);
567
        $this->setHREF();
568
569
        return 0;
570
    }
571
572
    /**
573
     * Checks if dumps are properly set up.
574
     *
575
     * @param bool $all (optional) True to check pg_dumpall, false to just check pg_dump
576
     *
577
     * @return bool True, dumps are set up, false otherwise
578
     */
579
    public function isDumpEnabled($all = false)
580
    {
581
        $info = $this->getServerInfo();
582
583
        return !empty($info[$all ? 'pg_dumpall_path' : 'pg_dump_path']);
584
    }
585
586
    /**
587
     * Sets the href tracking variable.
588
     *
589
     * @return \PHPPgAdmin\Misc this class instance
590
     */
591
    public function setHREF()
592
    {
593
        $this->href = $this->getHREF();
594
        //\PC::debug($this->href, 'Misc::href');
595
        return $this;
596
    }
597
598
    /**
599
     * Get a href query string, excluding objects below the given object type (inclusive).
600
     *
601
     * @param null|string $exclude_from
602
     *
603
     * @return string
604
     */
605
    public function getHREF($exclude_from = null)
0 ignored issues
show
Coding Style Naming introduced by
The parameter $exclude_from is not named in camelCase.

This check marks parameter names that have not been written in camelCase.

In camelCase names are written without any punctuation, the start of each new word being marked by a capital letter. Thus the name database connection string becomes databaseConnectionString.

Loading history...
606
    {
607
        $href = [];
608
609
        $server   = $this->container->server || isset($_REQUEST['server']) ? $_REQUEST['server'] : null;
610
        $database = $this->container->database || isset($_REQUEST['database']) ? $_REQUEST['database'] : null;
611
        $schema   = $this->container->schema || isset($_REQUEST['schema']) ? $_REQUEST['schema'] : null;
612
613
        if ($server && $exclude_from !== 'server') {
614
            $href[] = 'server='.urlencode($server);
615
        }
616
        if ($database && $exclude_from !== 'database') {
617
            $href[] = 'database='.urlencode($database);
618
        }
619
        if ($schema && $exclude_from !== 'schema') {
620
            $href[] = 'schema='.urlencode($schema);
621
        }
622
623
        $this->href = htmlentities(implode('&', $href));
624
625
        return $this->href;
626
    }
627
628
    /**
629
     * Sets the form tracking variable.
630
     */
631
    public function setForm()
632
    {
633
        $form = [];
634
        if ($this->container->server) {
635
            $form[] = '<input type="hidden" name="server" value="'.htmlspecialchars($this->container->server).'" />';
636
        }
637
        if ($this->container->database) {
638
            $form[] = '<input type="hidden" name="database" value="'.htmlspecialchars($this->container->database).'" />';
639
        }
640
641
        if ($this->container->schema) {
642
            $form[] = '<input type="hidden" name="schema" value="'.htmlspecialchars($this->container->schema).'" />';
643
        }
644
        $this->form = implode("\n", $form);
645
646
        return $this->form;
647
        //\PC::debug($this->form, 'Misc::form');
648
    }
649
650
    /**
651
     * A function to recursively strip slashes.  Used to
652
     * enforce magic_quotes_gpc being off.
653
     *
654
     * @param mixed $var The variable to strip (passed by reference)
655
     */
656
    public function stripVar(&$var)
657
    {
658
        if (is_array($var)) {
659
            foreach ($var as $k => $v) {
660
                $this->stripVar($var[$k]);
661
662
                /* magic_quotes_gpc escape keys as well ...*/
663
                if (is_string($k)) {
664
                    $ek = stripslashes($k);
665
                    if ($ek !== $k) {
666
                        $var[$ek] = $var[$k];
667
                        unset($var[$k]);
668
                    }
669
                }
670
            }
671
        } else {
672
            $var = stripslashes($var);
673
        }
674
    }
675
676
    /**
677
     * Converts a PHP.INI size variable to bytes.  Taken from publically available
678
     * function by Chris DeRose, here: http://www.php.net/manual/en/configuration.directives.php#ini.file-uploads.
679
     *
680
     * @param mixed $strIniSize The PHP.INI variable
681
     *
682
     * @return bool|float|int size in bytes, false on failure
683
     */
684
    public function inisizeToBytes($strIniSize)
685
    {
686
        // This function will take the string value of an ini 'size' parameter,
687
        // and return a double (64-bit float) representing the number of bytes
688
        // that the parameter represents. Or false if $strIniSize is unparseable.
689
        $a_IniParts = [];
690
691
        if (!is_string($strIniSize)) {
692
            return false;
693
        }
694
695
        if (!preg_match('/^(\d+)([bkm]*)$/i', $strIniSize, $a_IniParts)) {
696
            return false;
697
        }
698
699
        $nSize   = (float) $a_IniParts[1];
700
        $strUnit = strtolower($a_IniParts[2]);
701
702
        switch ($strUnit) {
703
            case 'm':
704
                return $nSize * (float) 1048576;
705
            case 'k':
706
                return $nSize * (float) 1024;
707
            case 'b':
708
            default:
709
                return $nSize;
710
        }
711
    }
712
713
    public function getRequestVars($subject = '')
714
    {
715
        $v = [];
716
        if (!empty($subject)) {
717
            $v['subject'] = $subject;
718
        }
719
720
        if ($this->_server_id !== null && $subject != 'root') {
721
            $v['server'] = $this->_server_id;
722
            if ($this->_database !== null && $subject != 'server') {
723
                $v['database'] = $this->_database;
724
                if (isset($_REQUEST['schema']) && $subject != 'database') {
725
                    $v['schema'] = $_REQUEST['schema'];
726
                }
727
            }
728
        }
729
        //$this->prtrace($v);
730
        return $v;
731
    }
732
733
    public function icon($icon)
734
    {
735
        if (is_string($icon)) {
736
            $path = "/assets/images/themes/{$this->conf['theme']}/{$icon}";
737 View Code Duplication
            if (file_exists(\BASE_PATH.$path.'.png')) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
738
                return SUBFOLDER.$path.'.png';
739
            }
740
741 View Code Duplication
            if (file_exists(\BASE_PATH.$path.'.gif')) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
742
                return SUBFOLDER.$path.'.gif';
743
            }
744
745 View Code Duplication
            if (file_exists(\BASE_PATH.$path.'.ico')) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
746
                return SUBFOLDER.$path.'.ico';
747
            }
748
749
            $path = "/assets/images/themes/default/{$icon}";
750 View Code Duplication
            if (file_exists(\BASE_PATH.$path.'.png')) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
751
                return SUBFOLDER.$path.'.png';
752
            }
753
754 View Code Duplication
            if (file_exists(\BASE_PATH.$path.'.gif')) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
755
                return SUBFOLDER.$path.'.gif';
756
            }
757
758 View Code Duplication
            if (file_exists(\BASE_PATH.$path.'.ico')) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
759
                return SUBFOLDER.$path.'.ico';
760
            }
761
        } else {
762
            // Icon from plugins
763
            $path = "/plugins/{$icon[0]}/images/{$icon[1]}";
764 View Code Duplication
            if (file_exists(\BASE_PATH.$path.'.png')) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
765
                return SUBFOLDER.$path.'.png';
766
            }
767
768 View Code Duplication
            if (file_exists(\BASE_PATH.$path.'.gif')) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
769
                return SUBFOLDER.$path.'.gif';
770
            }
771
772 View Code Duplication
            if (file_exists(\BASE_PATH.$path.'.ico')) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
773
                return SUBFOLDER.$path.'.ico';
774
            }
775
        }
776
777
        return '';
778
    }
779
780
    /**
781
     * Function to escape command line parameters.
782
     *
783
     * @param string $str The string to escape
784
     *
785
     * @return string The escaped string
786
     */
787
    public function escapeShellArg($str)
788
    {
789
        //$data = $this->getDatabaseAccessor();
790
        $lang = $this->lang;
791
792
        if (strtoupper(substr(PHP_OS, 0, 3)) === 'WIN') {
793
            // Due to annoying PHP bugs, shell arguments cannot be escaped
794
            // (command simply fails), so we cannot allow complex objects
795
            // to be dumped.
796
            if (preg_match('/^[_.[:alnum:]]+$/', $str)) {
797
                return $str;
798
            }
799
800
            return $this->halt($lang['strcannotdumponwindows']);
801
        }
802
803
        return escapeshellarg($str);
804
    }
805
806
    /**
807
     * Function to escape command line programs.
808
     *
809
     * @param string $str The string to escape
810
     *
811
     * @return string The escaped string
812
     */
813
    public function escapeShellCmd($str)
814
    {
815
        $data = $this->getDatabaseAccessor();
816
817
        if (strtoupper(substr(PHP_OS, 0, 3)) === 'WIN') {
818
            $data->fieldClean($str);
819
820
            return '"'.$str.'"';
821
        }
822
823
        return escapeshellcmd($str);
824
    }
825
826
    /**
827
     * Save the given SQL script in the history
828
     * of the database and server.
829
     *
830
     * @param string $script the SQL script to save
831
     */
832
    public function saveScriptHistory($script)
833
    {
834
        list($usec, $sec) = explode(' ', microtime());
835
        $time             = ((float) $usec + (float) $sec);
836
837
        $server   = $this->container->server ? $this->container->server : $_REQUEST['server'];
838
        $database = $this->container->database ? $this->container->database : $_REQUEST['database'];
839
840
        $_SESSION['history'][$server][$database]["${time}"] = [
841
            'query'    => $script,
842
            'paginate' => !isset($_REQUEST['paginate']) ? 'f' : 't',
843
            'queryid'  => $time,
844
        ];
845
    }
846
}
847