Completed
Push — develop ( 48041c...eb8457 )
by Agel_Nash
06:16
created

Database::getTableName()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 5
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
eloc 3
nc 2
nop 2
dl 0
loc 5
rs 9.4285
c 0
b 0
f 0
1
<?php namespace EvolutionCMS;
2
3
use mysqli;
4
use mysqli_result;
5
6
class Database implements Interfaces\DatabaseInterface
0 ignored issues
show
Coding Style introduced by
The property $_dbconnectionmethod 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...
7
{
8
    /**
9
     * @var mysqli
10
     */
11
    public $conn;
12
    public $config;
13
    public $lastQuery;
14
    public $isConnected;
15
    public $_dbconnectionmethod;
16
17
    /**
18
     * DBAPI constructor.
19
     *
20
     * @param string $host
21
     * @param string $dbase
22
     * @param string $uid
23
     * @param string $pwd
24
     * @param null|string $pre
25
     * @param string $charset
26
     * @param string $connection_method
27
     */
28
    public function __construct(
0 ignored issues
show
Coding Style introduced by
__construct uses the super-global variable $GLOBALS which is generally not recommended.

Instead of super-globals, we recommend to explicitly inject the dependencies of your class. This makes your code less dependent on global state and it becomes generally more testable:

// Bad
class Router
{
    public function generate($path)
    {
        return $_SERVER['HOST'].$path;
    }
}

// Better
class Router
{
    private $host;

    public function __construct($host)
    {
        $this->host = $host;
    }

    public function generate($path)
    {
        return $this->host.$path;
    }
}

class Controller
{
    public function myAction(Request $request)
    {
        // Instead of
        $page = isset($_GET['page']) ? intval($_GET['page']) : 1;

        // Better (assuming you use the Symfony2 request)
        $page = $request->query->get('page', 1);
    }
}
Loading history...
Coding Style Naming introduced by
The parameter $connection_method 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...
29
        $host = '',
30
        $dbase = '',
31
        $uid = '',
32
        $pwd = '',
33
        $pre = null,
34
        $charset = '',
35
        $connection_method = 'SET CHARACTER SET'
36
    ) {
37
        $this->config['host'] = $host ? $host : $GLOBALS['database_server'];
38
        $this->config['dbase'] = $dbase ? $dbase : $GLOBALS['dbase'];
39
        $this->config['user'] = $uid ? $uid : $GLOBALS['database_user'];
40
        $this->config['pass'] = $pwd ? $pwd : $GLOBALS['database_password'];
41
        $this->config['charset'] = $charset ? $charset : $GLOBALS['database_connection_charset'];
42
        $this->config['connection_method'] = $this->_dbconnectionmethod = (isset($GLOBALS['database_connection_method']) ? $GLOBALS['database_connection_method'] : $connection_method);
43
        $this->config['table_prefix'] = ($pre !== null) ? $pre : $GLOBALS['table_prefix'];
44
    }
45
46
    /**
47
     * @param null $key
48
     * @return mixed
49
     */
50
    public function getConfig($key = null)
51
    {
52
        return $key === null ? $this->config : get_by_key($this->config, $key);
53
    }
54
55
    /**
56
     * @param string $host
57
     * @param string $dbase
58
     * @param string $uid
59
     * @param string $pwd
60
     * @return mysqli
0 ignored issues
show
Documentation introduced by
Should the return type not be mysqli|null?

This check compares the return type specified in the @return annotation of a function or method doc comment with the types returned by the function and raises an issue if they mismatch.

Loading history...
61
     */
62
    public function connect($host = '', $dbase = '', $uid = '', $pwd = '')
0 ignored issues
show
Coding Style introduced by
connect uses the super-global variable $_SERVER which is generally not recommended.

Instead of super-globals, we recommend to explicitly inject the dependencies of your class. This makes your code less dependent on global state and it becomes generally more testable:

// Bad
class Router
{
    public function generate($path)
    {
        return $_SERVER['HOST'].$path;
    }
}

// Better
class Router
{
    private $host;

    public function __construct($host)
    {
        $this->host = $host;
    }

    public function generate($path)
    {
        return $this->host.$path;
    }
}

class Controller
{
    public function myAction(Request $request)
    {
        // Instead of
        $page = isset($_GET['page']) ? intval($_GET['page']) : 1;

        // Better (assuming you use the Symfony2 request)
        $page = $request->query->get('page', 1);
    }
}
Loading history...
63
    {
64
        $modx = evolutionCMS();
65
        $uid = $uid ? $uid : $this->getConfig('user');
66
        $pwd = $pwd ? $pwd : $this->getConfig('pass');
67
        $host = $host ? $host : $this->getConfig('host');
68
        $dbase = $dbase ? $dbase : $this->getConfig('dbase');
69
        $dbase = trim($dbase, '`'); // remove the `` chars
70
        $charset = $this->getConfig('charset');
71
        $connection_method = $this->getConfig('connection_method');
72
        $tstart = $modx->getMicroTime();
73
        $safe_count = 0;
74
        do {
75
            $this->conn = new mysqli($host, $uid, $pwd, $dbase);
76
            if ($this->conn->connect_error) {
77
                $this->conn = null;
78
                if (isset($modx->config['send_errormail']) && $modx->config['send_errormail'] !== '0') {
79
                    if ($modx->config['send_errormail'] <= 2) {
80
                        $logtitle = 'Failed to create the database connection!';
81
                        $request_uri = $modx->getPhpCompat()->htmlspecialchars($_SERVER['REQUEST_URI']);
82
                        $ua = $modx->getPhpCompat()->htmlspecialchars($_SERVER['HTTP_USER_AGENT']);
0 ignored issues
show
Comprehensibility introduced by
Avoid variables with short names like $ua. Configured minimum length is 3.

Short variable names may make your code harder to understand. Variable names should be self-descriptive. This check looks for variable names who are shorter than a configured minimum.

Loading history...
83
                        $referer = $modx->getPhpCompat()->htmlspecialchars($_SERVER['HTTP_REFERER']);
84
                        $modx->sendmail(array(
85
                            'subject' => 'Missing to create the database connection! from ' . $modx->getPhpCompat()->entities($modx->config['site_name']),
86
                            'body'    => "{$logtitle}\n{$request_uri}\n{$ua}\n{$referer}",
87
                            'type'    => 'text'
88
                        ));
89
                    }
90
                }
91
                sleep(1);
92
                $safe_count++;
93
            }
94
        } while (!$this->conn && $safe_count < 3);
95
        if ($this->conn instanceof mysqli) {
96
            $this->conn->query("{$connection_method} {$charset}");
97
            $tend = $modx->getMicroTime();
98
            $totaltime = $tend - $tstart;
99
            if ($modx->dumpSQL) {
100
                $modx->queryCode .= "<fieldset style='text-align:left'><legend>Database connection</legend>" . sprintf("Database connection was created in %2.4f s",
101
                        $totaltime) . "</fieldset><br />";
102
            }
103
            $this->conn->set_charset($this->getConfig('charset'));
104
            $this->isConnected = true;
105
            $modx->queryTime += $totaltime;
106
        } else {
107
            $modx->messageQuit("Failed to create the database connection!");
108
            exit;
0 ignored issues
show
Coding Style Compatibility introduced by
The method connect() contains an exit expression.

An exit expression should only be used in rare cases. For example, if you write a short command line script.

In most cases however, using an exit expression makes the code untestable and often causes incompatibilities with other libraries. Thus, unless you are absolutely sure it is required here, we recommend to refactor your code to avoid its usage.

Loading history...
109
        }
110
        return $this->conn;
111
    }
112
113
    /**
114
     * @return void
115
     */
116
    public function disconnect()
117
    {
118
        $this->conn->close();
119
        $this->conn = null;
120
        $this->isConnected = false;
121
    }
122
123
    /**
124
     * @param array|string $s
125
     * @param int $safeCount
126
     * @return array|string
127
     */
128
    public function escape($s, $safeCount = 0)
0 ignored issues
show
Comprehensibility introduced by
Avoid variables with short names like $s. Configured minimum length is 3.

Short variable names may make your code harder to understand. Variable names should be self-descriptive. This check looks for variable names who are shorter than a configured minimum.

Loading history...
129
    {
130
        $safeCount++;
131
        if (1000 < $safeCount) {
132
            exit("Too many loops '{$safeCount}'");
0 ignored issues
show
Coding Style Compatibility introduced by
The method escape() contains an exit expression.

An exit expression should only be used in rare cases. For example, if you write a short command line script.

In most cases however, using an exit expression makes the code untestable and often causes incompatibilities with other libraries. Thus, unless you are absolutely sure it is required here, we recommend to refactor your code to avoid its usage.

Loading history...
133
        }
134
        if ( ! ($this->conn instanceof mysqli)) {
135
            $this->connect();
136
        }
137
        if (is_array($s)) {
138
            if (count($s) === 0) {
139
                $s = '';
140
            } else {
141
                foreach ($s as $i => $v) {
142
                    $s[$i] = $this->escape($v, $safeCount);
143
                }
144
            }
145
        } else {
146
            $s = $this->conn->escape_string($s);
147
        }
148
149
        return $s;
150
    }
151
152
    /**
153
     * @param string|array|mysqli_result $sql
154
     * @param bool $watchError
155
     * @return bool|mysqli_result
156
     */
157
    public function query($sql, $watchError = true)
158
    {
159
        $modx = evolutionCMS();
160
        if ( ! ($this->conn instanceof mysqli)) {
161
            $this->connect();
162
        }
163
        $tStart = $modx->getMicroTime();
164
        if (is_array($sql)) {
165
            $sql = implode("\n", $sql);
166
        }
167
        $this->lastQuery = $sql;
168
        if (!($result = $this->conn->query($sql))) {
169
            if (!$watchError) {
170
                return false;
171
            }
172
            switch (mysqli_errno($this->conn)) {
173
                case 1054:
174
                case 1060:
175
                case 1061:
176
                case 1062:
177
                case 1091:
178
                    break;
179
                default:
180
                    $modx->messageQuit('Execution of a query to the database failed - ' . $this->getLastError(), $sql);
0 ignored issues
show
Bug introduced by
It seems like $sql defined by parameter $sql on line 157 can also be of type object<mysqli_result>; however, EvolutionCMS\Core::messageQuit() does only seem to accept string, maybe add an additional type check?

This check looks at variables that have been passed in as parameters and are passed out again to other methods.

If the outgoing method call has stricter type requirements than the method itself, an issue is raised.

An additional type check may prevent trouble.

Loading history...
181
            }
182
        } else {
183
            $tend = $modx->getMicroTime();
184
            $totalTime = $tend - $tStart;
185
            $modx->queryTime += $totalTime;
186
            if ($modx->dumpSQL) {
187
                $debug = debug_backtrace();
188
                array_shift($debug);
189
                $debug_path = array();
190
                foreach ($debug as $line) {
191
                    $debug_path[] = $line['function'];
192
                }
193
                $debug_path = implode(' > ', array_reverse($debug_path));
194
                $modx->queryCode .= "<fieldset style='text-align:left'><legend>Query " . ($modx->executedQueries + 1) . " - " . sprintf("%2.2f ms",
195
                        $totalTime * 1000) . "</legend>";
196
                $modx->queryCode .= $sql . '<br><br>';
197
                if ($modx->event->name) {
198
                    $modx->queryCode .= 'Current Event  => ' . $modx->event->name . '<br>';
199
                }
200
                if ($modx->event->activePlugin) {
201
                    $modx->queryCode .= 'Current Plugin => ' . $modx->event->activePlugin . '<br>';
202
                }
203
                if ($modx->currentSnippet) {
204
                    $modx->queryCode .= 'Current Snippet => ' . $modx->currentSnippet . '<br>';
205
                }
206
                if (stripos($sql, 'select') === 0) {
207
                    $modx->queryCode .= 'Record Count => ' . $this->getRecordCount($result) . '<br>';
208
                } else {
209
                    $modx->queryCode .= 'Affected Rows => ' . $this->getAffectedRows() . '<br>';
210
                }
211
                $modx->queryCode .= 'Functions Path => ' . $debug_path . '<br>';
212
                $modx->queryCode .= "</fieldset><br />";
213
            }
214
            $modx->executedQueries++;
215
216
            return $result;
217
        }
218
        return false;
219
    }
220
221
    /**
222
     * @param string $from
223
     * @param string $where
224
     * @param string $orderBy
225
     * @param string $limit
226
     * @return bool|mysqli_result
227
     */
228
    public function delete($from, $where = '', $orderBy = '', $limit = '')
229
    {
230
        $modx = evolutionCMS();
231
        $out = false;
232
        if (!$from) {
233
            $modx->messageQuit("Empty \$from parameters in DBAPI::delete().");
234
        } else {
235
            $from = $this->replaceFullTableName($from);
236
            $where = trim($where);
237
            $orderBy = trim($orderBy);
238
            $limit = trim($limit);
239
            if ($where !== '' && stripos($where, 'WHERE') !== 0) {
240
                $where = "WHERE {$where}";
241
            }
242
            if ($orderBy !== '' && stripos($orderBy, 'ORDER BY') !== 0) {
243
                $orderBy = "ORDER BY {$orderBy}";
244
            }
245
            if ($limit !== '' && stripos($limit, 'LIMIT') !== 0) {
246
                $limit = "LIMIT {$limit}";
247
            }
248
249
            $out = $this->query("DELETE FROM {$from} {$where} {$orderBy} {$limit}");
250
        }
251
        return $out;
252
    }
253
254
    /**
255
     * @param string|array $fields
256
     * @param string|array $from
257
     * @param string|array $where
258
     * @param string $orderBy
259
     * @param string $limit
260
     * @return bool|mysqli_result
261
     */
262
    public function select($fields = "*", $from = "", $where = "", $orderBy = "", $limit = "")
263
    {
264
        $modx = evolutionCMS();
265
266
        if (is_array($fields)) {
267
            $fields = $this->_getFieldsStringFromArray($fields);
268
        }
269
        if (is_array($from)) {
270
            $from = $this->_getFromStringFromArray($from);
271
        }
272
        if (is_array($where)) {
273
            $where = implode(' ', $where);
274
        }
275
276
        if (!$from) {
277
            $modx->messageQuit("Empty \$from parameters in DBAPI::select().");
278
            exit;
0 ignored issues
show
Coding Style Compatibility introduced by
The method select() contains an exit expression.

An exit expression should only be used in rare cases. For example, if you write a short command line script.

In most cases however, using an exit expression makes the code untestable and often causes incompatibilities with other libraries. Thus, unless you are absolutely sure it is required here, we recommend to refactor your code to avoid its usage.

Loading history...
279
        }
280
281
        $fields = $this->replaceFullTableName($fields);
282
        $from = $this->replaceFullTableName($from);
283
        $where = trim($where);
284
        $orderBy = trim($orderBy);
285
        $limit = trim($limit);
286
        if ($where !== '' && stripos($where, 'WHERE') !== 0) {
287
            $where = "WHERE {$where}";
288
        }
289
        if ($orderBy !== '' && stripos($orderBy, 'ORDER') !== 0) {
290
            $orderBy = "ORDER BY {$orderBy}";
291
        }
292
        if ($limit !== '' && stripos($limit, 'LIMIT') !== 0) {
293
            $limit = "LIMIT {$limit}";
294
        }
295
296
        return $this->query("SELECT {$fields} FROM {$from} {$where} {$orderBy} {$limit}");
297
    }
298
299
    /**
300
     * @param array|string $fields
301
     * @param $table
302
     * @param string $where
303
     * @return bool|mysqli_result
304
     */
305
    public function update($fields, $table, $where = "")
306
    {
307
        $modx = evolutionCMS();
308
        $out = false;
309
        if (!$table) {
310
            $modx->messageQuit('Empty '.$table.' parameter in DBAPI::update().');
311
        } else {
312
            $table = $this->replaceFullTableName($table);
313
            if (is_array($fields)) {
314
                foreach ($fields as $key => $value) {
315
                    if ($value === null || strtolower($value) === 'null') {
316
                        $f = 'NULL';
317
                    } else {
318
                        $f = "'" . $value . "'";
319
                    }
320
                    $fields[$key] = "`{$key}` = " . $f;
321
                }
322
                $fields = implode(',', $fields);
323
            }
324
            $where = trim($where);
325
            if ($where !== '' && stripos($where, 'WHERE') !== 0) {
326
                $where = 'WHERE '.$where;
327
            }
328
329
            return $this->query('UPDATE '.$table.' SET '.$fields.' '.$where);
330
        }
331
        return $out;
332
    }
333
334
    /**
335
     * @param string|array $fields
336
     * @param string $intotable
337
     * @param string $fromfields
338
     * @param string $fromtable
339
     * @param string $where
340
     * @param string $limit
341
     * @return mixed
342
     */
343
    public function insert($fields, $intotable, $fromfields = "*", $fromtable = "", $where = "", $limit = "")
344
    {
345
        $modx = evolutionCMS();
346
        $out = false;
347
        if (!$intotable) {
348
            $modx->messageQuit("Empty \$intotable parameters in DBAPI::insert().");
349
        } else {
350
            $intotable = $this->replaceFullTableName($intotable);
351
            if (!is_array($fields)) {
352
                $this->query("INSERT INTO {$intotable} {$fields}");
353
            } else {
354
                if (empty($fromtable)) {
355
                    $fields = "(`" . implode("`, `", array_keys($fields)) . "`) VALUES('" . implode("', '",
356
                            array_values($fields)) . "')";
357
                    $this->query("INSERT INTO {$intotable} {$fields}");
358
                } else {
359
                    $fromtable = $this->replaceFullTableName($fromtable);
360
                    $fields = "(" . implode(",", array_keys($fields)) . ")";
361
                    $where = trim($where);
362
                    $limit = trim($limit);
363
                    if ($where !== '' && stripos($where, 'WHERE') !== 0) {
364
                        $where = "WHERE {$where}";
365
                    }
366
                    if ($limit !== '' && stripos($limit, 'LIMIT') !== 0) {
367
                        $limit = "LIMIT {$limit}";
368
                    }
369
                    $this->query("INSERT INTO {$intotable} {$fields} SELECT {$fromfields} FROM {$fromtable} {$where} {$limit}");
370
                }
371
            }
372
            if (($lid = $this->getInsertId()) === false) {
373
                $modx->messageQuit("Couldn't get last insert key!");
374
            }
375
376
            $out = $lid;
377
        }
378
        return $out;
379
    }
380
381
    /**
382
     * @param $fields
383
     * @param $table
384
     * @param string $where
385
     * @return bool|mixed|mysqli_result
386
     */
387
    public function save($fields, $table, $where = '')
388
    { // This is similar to "replace into table".
389
390
        if ($where === '') {
391
            $mode = 'insert';
392
        } elseif ($this->getRecordCount($this->select('*', $table, $where)) === 0) {
0 ignored issues
show
Bug introduced by
It seems like $this->select('*', $table, $where) targeting EvolutionCMS\Database::select() can also be of type boolean; however, EvolutionCMS\Database::getRecordCount() does only seem to accept object<mysqli_result>, maybe add an additional type check?

This check looks at variables that are passed out again to other methods.

If the outgoing method call has stricter type requirements than the method itself, an issue is raised.

An additional type check may prevent trouble.

Loading history...
393
            $mode = 'insert';
394
        } else {
395
            $mode = 'update';
396
        }
397
398
        return ($mode === 'insert') ? $this->insert($fields, $table) : $this->update($fields, $table, $where);
399
    }
400
401
    /**
402
     * @param mixed $rs
403
     * @return bool
404
     */
405
    public function isResult($rs)
0 ignored issues
show
Comprehensibility introduced by
Avoid variables with short names like $rs. Configured minimum length is 3.

Short variable names may make your code harder to understand. Variable names should be self-descriptive. This check looks for variable names who are shorter than a configured minimum.

Loading history...
406
    {
407
        return $rs instanceof mysqli_result;
408
    }
409
410
    /**
411
     * @param mysqli_result $rs
412
     */
413
    public function freeResult($rs)
0 ignored issues
show
Comprehensibility introduced by
Avoid variables with short names like $rs. Configured minimum length is 3.

Short variable names may make your code harder to understand. Variable names should be self-descriptive. This check looks for variable names who are shorter than a configured minimum.

Loading history...
414
    {
415
        $rs->free_result();
416
    }
417
418
    /**
419
     * @param mysqli_result $rs
420
     * @return mixed
421
     */
422
    public function numFields($rs)
0 ignored issues
show
Comprehensibility introduced by
Avoid variables with short names like $rs. Configured minimum length is 3.

Short variable names may make your code harder to understand. Variable names should be self-descriptive. This check looks for variable names who are shorter than a configured minimum.

Loading history...
423
    {
424
        return $rs->field_count;
425
    }
426
427
    /**
428
     * @param mysqli_result $rs
429
     * @param int $col
430
     * @return string|null
431
     */
432
    public function fieldName($rs, $col = 0)
0 ignored issues
show
Comprehensibility introduced by
Avoid variables with short names like $rs. Configured minimum length is 3.

Short variable names may make your code harder to understand. Variable names should be self-descriptive. This check looks for variable names who are shorter than a configured minimum.

Loading history...
433
    {
434
        $field = $rs->fetch_field_direct($col);
435
436
        return isset($field->name) ? $field->name : null;
437
    }
438
439
    /**
440
     * @param $name
441
     */
442
    public function selectDb($name)
443
    {
444
        $this->conn->select_db($name);
445
    }
446
447
448
    /**
449
     * @param null|mysqli $conn
450
     * @return mixed
451
     */
452
    public function getInsertId($conn = null)
453
    {
454
        if (! ($conn instanceof mysqli)) {
455
            $conn =& $this->conn;
456
        }
457
458
        return $conn->insert_id;
459
    }
460
461
    /**
462
     * @param null|mysqli $conn
463
     * @return int
464
     */
465
    public function getAffectedRows($conn = null)
466
    {
467
        if (! ($conn instanceof mysqli)) {
468
            $conn =& $this->conn;
469
        }
470
471
        return $conn->affected_rows;
472
    }
473
474
    /**
475
     * @param null|mysqli $conn
476
     * @return string
477
     */
478
    public function getLastError($conn = null)
479
    {
480
        if (! ($conn instanceof mysqli)) {
481
            $conn =& $this->conn;
482
        }
483
484
        return $conn->error;
485
    }
486
487
    /**
488
     * @param mysqli_result $ds
489
     * @return int
490
     */
491
    public function getRecordCount($ds)
0 ignored issues
show
Comprehensibility introduced by
Avoid variables with short names like $ds. Configured minimum length is 3.

Short variable names may make your code harder to understand. Variable names should be self-descriptive. This check looks for variable names who are shorter than a configured minimum.

Loading history...
492
    {
493
        return ($ds instanceof mysqli_result) ? $ds->num_rows : 0;
494
    }
495
496
    /**
497
     * @param mysqli_result $ds
498
     * @param string $mode
499
     * @return array|bool|mixed|object|stdClass
500
     */
501
    public function getRow($ds, $mode = 'assoc')
0 ignored issues
show
Comprehensibility introduced by
Avoid variables with short names like $ds. Configured minimum length is 3.

Short variable names may make your code harder to understand. Variable names should be self-descriptive. This check looks for variable names who are shorter than a configured minimum.

Loading history...
502
    {
503
        $out = false;
504
        if ($ds instanceof mysqli_result) {
505
            switch($mode){
506
                case 'assoc':
507
                    $out = $ds->fetch_assoc();
508
                    break;
509
                case 'num':
510
                    $out = $ds->fetch_row();
511
                    break;
512
                case 'object':
513
                    $out = $ds->fetch_object();
514
                    break;
515
                case 'both':
516
                    $out = $ds->fetch_array(MYSQLI_BOTH);
517
                    break;
518
                default:
519
                    $modx = evolutionCMS();
520
                    $modx->messageQuit("Unknown get type ($mode) specified for fetchRow - must be empty, 'assoc', 'num' or 'both'.");
521
522
            }
523
        }
524
        return $out;
525
    }
526
527
    /**
528
     * @param $name
529
     * @param mysqli_result|string $dsq
530
     * @return array
531
     */
532
    public function getColumn($name, $dsq)
533
    {
534
        $col = array();
535
        if ( ! ($dsq instanceof mysqli_result)) {
536
            $dsq = $this->query($dsq);
537
        }
538
        if ($dsq) {
539
            while ($row = $this->getRow($dsq)) {
0 ignored issues
show
Bug introduced by
It seems like $dsq can also be of type boolean; however, EvolutionCMS\Database::getRow() does only seem to accept object<mysqli_result>, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
540
                $col[] = $row[$name];
541
            }
542
        }
543
544
        return $col;
545
    }
546
547
    /**
548
     * @param mysqli_result|string $dsq
549
     * @return array
550
     */
551
    public function getColumnNames($dsq)
552
    {
553
        $names = array();
554
        if ( ! ($dsq instanceof mysqli_result)) {
555
            $dsq = $this->query($dsq);
556
        }
557
        if ($dsq) {
558
            $limit = $this->numFields($dsq);
0 ignored issues
show
Bug introduced by
It seems like $dsq can also be of type boolean; however, EvolutionCMS\Database::numFields() does only seem to accept object<mysqli_result>, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
559
            for ($i = 0; $i < $limit; $i++) {
560
                $names[] = $this->fieldName($dsq, $i);
0 ignored issues
show
Bug introduced by
It seems like $dsq can also be of type boolean; however, EvolutionCMS\Database::fieldName() does only seem to accept object<mysqli_result>, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
561
            }
562
        }
563
564
        return $names;
565
    }
566
567
    /**
568
     * @param mysqli_result|string $dsq
569
     * @return bool|string|int
570
     */
571
    public function getValue($dsq)
572
    {
573
        $out = false;
574
        if ( ! ($dsq instanceof mysqli_result)) {
575
            $dsq = $this->query($dsq);
576
        }
577
        if ($dsq) {
578
            $r = $this->getRow($dsq, 'num');
0 ignored issues
show
Bug introduced by
It seems like $dsq can also be of type boolean; however, EvolutionCMS\Database::getRow() does only seem to accept object<mysqli_result>, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
Comprehensibility introduced by
Avoid variables with short names like $r. Configured minimum length is 3.

Short variable names may make your code harder to understand. Variable names should be self-descriptive. This check looks for variable names who are shorter than a configured minimum.

Loading history...
579
            $out = isset($r[0]) ? $r[0] : false;
580
        }
581
582
        return $out;
583
    }
584
585
    /**
586
     * @param string $table
587
     * @return array
588
     */
589
    public function getTableMetaData($table)
590
    {
591
        $metadata = array();
592
        if (!empty($table) && is_scalar($table)) {
593
            $sql = 'SHOW FIELDS FROM '.$table;
594
            if ($ds = $this->query($sql)) {
0 ignored issues
show
Comprehensibility introduced by
Avoid variables with short names like $ds. Configured minimum length is 3.

Short variable names may make your code harder to understand. Variable names should be self-descriptive. This check looks for variable names who are shorter than a configured minimum.

Loading history...
595
                while ($row = $this->getRow($ds)) {
0 ignored issues
show
Bug introduced by
It seems like $ds defined by $this->query($sql) on line 594 can also be of type boolean; however, EvolutionCMS\Database::getRow() does only seem to accept object<mysqli_result>, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
596
                    $fieldName = $row['Field'];
597
                    $metadata[$fieldName] = $row;
598
                }
599
            }
600
        }
601
602
        return $metadata;
603
    }
604
605
    /**
606
     * @param int $timestamp
607
     * @param string $fieldType
608
     * @return false|string
609
     */
610
    public function prepareDate($timestamp, $fieldType = 'DATETIME')
611
    {
612
        $date = false;
613
        if (!$timestamp === false && $timestamp > 0) {
614
            switch ($fieldType) {
615
                case 'DATE' :
0 ignored issues
show
Coding Style introduced by
There must be no space before the colon in a CASE statement

As per the PSR-2 coding standard, there must not be a space in front of the colon in case statements.

switch ($selector) {
    case "A": //right
        doSomething();
        break;
    case "B" : //wrong
        doSomethingElse();
        break;
}

To learn more about the PSR-2 coding standard, please refer to the PHP-Fig.

Loading history...
616
                    $date = date('Y-m-d', $timestamp);
617
                    break;
618
                case 'TIME' :
0 ignored issues
show
Coding Style introduced by
There must be no space before the colon in a CASE statement

As per the PSR-2 coding standard, there must not be a space in front of the colon in case statements.

switch ($selector) {
    case "A": //right
        doSomething();
        break;
    case "B" : //wrong
        doSomethingElse();
        break;
}

To learn more about the PSR-2 coding standard, please refer to the PHP-Fig.

Loading history...
619
                    $date = date('H:i:s', $timestamp);
620
                    break;
621
                case 'YEAR' :
0 ignored issues
show
Coding Style introduced by
There must be no space before the colon in a CASE statement

As per the PSR-2 coding standard, there must not be a space in front of the colon in case statements.

switch ($selector) {
    case "A": //right
        doSomething();
        break;
    case "B" : //wrong
        doSomethingElse();
        break;
}

To learn more about the PSR-2 coding standard, please refer to the PHP-Fig.

Loading history...
622
                    $date = date('Y', $timestamp);
623
                    break;
624
                default :
0 ignored issues
show
Coding Style introduced by
There must be no space before the colon in a DEFAULT statement

As per the PSR-2 coding standard, there must not be a space in front of the colon in the default statement.

switch ($expr) {
    default : //wrong
        doSomething();
        break;
}

switch ($expr) {
    default: //right
        doSomething();
        break;
}

To learn more about the PSR-2 coding standard, please refer to the PHP-Fig.

Loading history...
625
                    $date = date('Y-m-d H:i:s', $timestamp);
626
                    break;
627
            }
628
        }
629
630
        return $date;
631
    }
632
633
    /**
634
     * @param string|mysqli_result $rs
635
     * @param bool $index
636
     * @return array
637
     */
638
    public function makeArray($rs = '', $index = false)
0 ignored issues
show
Comprehensibility introduced by
Avoid variables with short names like $rs. Configured minimum length is 3.

Short variable names may make your code harder to understand. Variable names should be self-descriptive. This check looks for variable names who are shorter than a configured minimum.

Loading history...
639
    {
640
        $rsArray = array();
641
        if (!$rs) {
642
            return $rsArray;
643
        }
644
        $iterator = 0;
645
        while ($row = $this->getRow($rs)) {
0 ignored issues
show
Bug introduced by
It seems like $rs defined by parameter $rs on line 638 can also be of type string; however, EvolutionCMS\Database::getRow() does only seem to accept object<mysqli_result>, maybe add an additional type check?

This check looks at variables that have been passed in as parameters and are passed out again to other methods.

If the outgoing method call has stricter type requirements than the method itself, an issue is raised.

An additional type check may prevent trouble.

Loading history...
646
            $returnIndex = $index !== false && isset($row[$index]) ? $row[$index] : $iterator;
647
            $rsArray[$returnIndex] = $row;
648
            $iterator++;
649
        }
650
651
        return $rsArray;
652
    }
653
654
    /**
655
     * @return string
656
     */
657
    public function getVersion()
658
    {
659
        return $this->conn->server_info;
660
    }
661
662
    public function getTableName($table, $escape = true)
663
    {
664
        $out = $this->getConfig('table_prefix') . $table;
665
        return $escape ? '`' . $out . '`' : $out;
666
    }
667
668
    /**
669
     * @param $tbl
670
     * @return string
671
     */
672
    public function getFullTableName($tbl)
673
    {
674
        return $this->getConfig('dbase') . "." . $this->getTableName($tbl);
675
    }
676
677
    /**
678
     * @param string $tableName
679
     * @param bool $force
680
     * @return string
681
     */
682
    public function replaceFullTableName($tableName, $force = false)
683
    {
684
        $tableName = trim($tableName);
685
        $dbase = trim($this->getConfig('dbase'), '`');
686
        $prefix = $this->getConfig('table_prefix');
687
        if ((bool)$force === true) {
688
            $result = "`{$dbase}`.`{$prefix}{$tableName}`";
689
        } elseif (strpos($tableName, '[+prefix+]') !== false) {
690
            $result = preg_replace('@\[\+prefix\+\]([0-9a-zA-Z_]+)@', "`{$dbase}`.`{$prefix}$1`", $tableName);
691
        } else {
692
            $result = $tableName;
693
        }
694
695
        return $result;
696
    }
697
698
    /**
699
     * @param string $table_name
700
     * @return bool|mysqli_result
701
     */
702
    public function optimize($table_name)
0 ignored issues
show
Coding Style Naming introduced by
The parameter $table_name 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...
703
    {
704
        $rs = $this->query('OPTIMIZE TABLE '.$table_name);
0 ignored issues
show
Comprehensibility introduced by
Avoid variables with short names like $rs. Configured minimum length is 3.

Short variable names may make your code harder to understand. Variable names should be self-descriptive. This check looks for variable names who are shorter than a configured minimum.

Loading history...
705
        if ($rs) {
706
            $rs = $this->query('ALTER TABLE '.$table_name);
707
        }
708
709
        return $rs;
710
    }
711
712
    /**
713
     * @param string $table_name
714
     * @return bool|mysqli_result
715
     */
716
    public function truncate($table_name)
0 ignored issues
show
Coding Style Naming introduced by
The parameter $table_name 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...
717
    {
718
        return $this->query('TRUNCATE '.$table_name);
719
    }
720
721
    /**
722
     * @param mysqli_result $result
723
     * @param int $row_number
724
     * @return bool
725
     */
726
    public function dataSeek($result, $row_number)
0 ignored issues
show
Coding Style Naming introduced by
The parameter $row_number 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...
727
    {
728
        return $result->data_seek($row_number);
729
    }
730
731
    /**
732
     * @param array $fields
733
     * @return string
734
     */
735
    public function _getFieldsStringFromArray($fields = array())
736
    {
737
738
        if (empty($fields)) {
739
            return '*';
740
        }
741
742
        $_ = array();
0 ignored issues
show
Comprehensibility introduced by
Avoid variables with short names like $_. Configured minimum length is 3.

Short variable names may make your code harder to understand. Variable names should be self-descriptive. This check looks for variable names who are shorter than a configured minimum.

Loading history...
743
        foreach ($fields as $k => $v) {
744
            if ($k !== $v) {
745
                $_[] = $v.' as '.$k;
746
            } else {
747
                $_[] = $v;
748
            }
749
        }
750
751
        return implode(',', $_);
752
    }
753
754
    /**
755
     * @param array $tables
756
     * @return string
757
     */
758
    public function _getFromStringFromArray($tables = array())
759
    {
760
        $_ = array();
0 ignored issues
show
Comprehensibility introduced by
Avoid variables with short names like $_. Configured minimum length is 3.

Short variable names may make your code harder to understand. Variable names should be self-descriptive. This check looks for variable names who are shorter than a configured minimum.

Loading history...
761
        foreach ($tables as $k => $v) {
762
            $_[] = $v;
763
        }
764
765
        return implode(' ', $_);
766
    }
767
}
768