Test Failed
Push — master ( ed0ed2...e89aac )
by Joe
04:39
created

Db::unlock()   A

Complexity

Conditions 3
Paths 2

Size

Total Lines 10
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 3

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 3
eloc 6
c 1
b 0
f 0
nc 2
nop 1
dl 0
loc 10
ccs 2
cts 2
cp 1
crap 3
rs 10
1
<?php
2
/**
3
 * MySQL Related Functionality
4
 * @author Joe Huss <[email protected]>
5
 * @copyright 2019
6
 * @package MyAdmin
7
 * @category SQL
8
 */
9
10
namespace MyDb\Mysqli;
11
12
use MyDb\Generic;
13
use MyDb\Db_Interface;
14
15
/**
16
 * Db
17
 *
18
 * @access public
19
 */
20
class Db extends Generic implements Db_Interface
21
{
22
    /**
23
     * @var string
24
     */
25
    public $type = 'mysqli';
26
27
    /**
28
     * alias function of select_db, changes the database we are working with.
29
     *
30
     * @param string $database the name of the database to use
31
     * @return void
32
     */
33 1
    public function useDb($database)
34
    {
35 1
        $this->selectDb($database);
36
    }
37
38
    /**
39
     * changes the database we are working with.
40
     *
41
     * @param string $database the name of the database to use
42
     * @return void
43
     */
44 1
    public function selectDb($database)
45
    {
46 1
        $this->connect();
47 1
        mysqli_select_db($this->linkId, $database);
48
    }
49
50
    /* public: connection management */
51
52
    /**
53
     * Db::connect()
54
     * @param string $database
55
     * @param string $host
56
     * @param string $user
57
     * @param string $password
58
     * @return int|\mysqli
59
     */
60 26
    public function connect($database = '', $host = '', $user = '', $password = '', $port = '')
61
    {
62
        /* Handle defaults */
63 26
        if ($database == '') {
64 26
            $database = $this->database;
65
        }
66 26
        if ($host == '') {
67 26
            $host = $this->host;
68
        }
69 26
        if ($user == '') {
70 26
            $user = $this->user;
71
        }
72 26
        if ($password == '') {
73 26
            $password = $this->password;
74
        }
75 26
        if ($port == '') {
76 26
            $port = $this->port;
77
        }
78
        /* establish connection, select database */
79 26
        if (!is_object($this->linkId)) {
80 26
            $this->connectionAttempt++;
81 26
            if ($this->connectionAttempt >= $this->maxConnectErrors - 1) {
82 6
                error_log("MySQLi Connection Attempt #{$this->connectionAttempt}/{$this->maxConnectErrors}");
83
            }
84 26
            if ($this->connectionAttempt >= $this->maxConnectErrors) {
85
                $this->halt("connect($host, $user, \$password) failed. ".(is_object($this->linkId) && isset( $this->linkId->connect_error) ? $this->linkId->connect_error : ''));
0 ignored issues
show
introduced by
The condition is_object($this->linkId) is always false.
Loading history...
86
                return 0;
87
            }
88 26
            //error_log("real_connect($host, $user, $password, $database, $port)");
0 ignored issues
show
Unused Code Comprehensibility introduced by
80% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
89 26
            $this->linkId = mysqli_init();
90 26
            $this->linkId->options(MYSQLI_INIT_COMMAND, "SET NAMES {$this->characterSet} COLLATE {$this->collation}, COLLATION_CONNECTION = {$this->collation}, COLLATION_DATABASE = {$this->collation}");
91
            if (!$this->linkId->real_connect($host, $user, $password, $database, $port != '' ? $port : NULL)) {
92
                $this->halt("connect($host, $user, \$password) failed. ".(is_object($this->linkId) && isset( $this->linkId->connect_error) ? $this->linkId->connect_error : ''));
93 26
                return 0;
94
            }
95 26
            $this->linkId->set_charset($this->characterSet);
96 26
            if ($this->linkId->connect_errno) {
97
                $this->halt("connect($host, $user, \$password) failed. ".(is_object($this->linkId) && isset( $this->linkId->connect_error) ? $this->linkId->connect_error : ''));
98
                return 0;
99
            }
100
        }
101 26
        return $this->linkId;
102
    }
103
104
    /**
105
     * Db::disconnect()
106
     * @return bool
107
     */
108 1
    public function disconnect()
109
    {
110 1
        $return = !is_int($this->linkId) && method_exists($this->linkId, 'close') ? $this->linkId->close() : false;
111 1
        $this->linkId = 0;
112 1
        return $return;
113
    }
114
115
    /**
116
     * @param $string
117
     * @return string
118
     */
119 2
    public function real_escape($string = '')
120
    {
121 2
        if ((!is_resource($this->linkId) || $this->linkId == 0) && !$this->connect()) {
0 ignored issues
show
introduced by
The condition is_resource($this->linkId) is always false.
Loading history...
122
            return $this->escape($string);
123
        }
124 2
        return mysqli_real_escape_string($this->linkId, $string);
0 ignored issues
show
Bug introduced by
It seems like $this->linkId can also be of type resource; however, parameter $mysql of mysqli_real_escape_string() does only seem to accept mysqli, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

124
        return mysqli_real_escape_string(/** @scrutinizer ignore-type */ $this->linkId, $string);
Loading history...
125
    }
126
127
    /**
128
     * discard the query result
129
     * @return void
130
     */
131 1
    public function free()
132
    {
133 1
        if (is_resource($this->queryId)) {
0 ignored issues
show
introduced by
The condition is_resource($this->queryId) is always false.
Loading history...
134
            @mysqli_free_result($this->queryId);
0 ignored issues
show
Security Best Practice introduced by
It seems like you do not handle an error condition for mysqli_free_result(). This can introduce security issues, and is generally not recommended. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unhandled  annotation

134
            /** @scrutinizer ignore-unhandled */ @mysqli_free_result($this->queryId);

If you suppress an error, we recommend checking for the error condition explicitly:

// For example instead of
@mkdir($dir);

// Better use
if (@mkdir($dir) === false) {
    throw new \RuntimeException('The directory '.$dir.' could not be created.');
}
Loading history...
135
        }
136 1
        $this->queryId = 0;
137
    }
138
139
    /**
140
     * Db::queryReturn()
141
     *
142
     * Sends an SQL query to the server like the normal query() command but iterates through
143
     * any rows and returns the row or rows immediately or FALSE on error
144
     *
145
     * @param mixed $query SQL Query to be used
146
     * @param string $line optionally pass __LINE__ calling the query for logging
147
     * @param string $file optionally pass __FILE__ calling the query for logging
148
     * @return mixed FALSE if no rows, if a single row it returns that, if multiple it returns an array of rows, associative responses only
149
     */
150 1
    public function queryReturn($query, $line = '', $file = '')
151
    {
152 1
        $this->query($query, $line, $file);
0 ignored issues
show
Bug introduced by
$line of type string is incompatible with the type integer expected by parameter $line of MyDb\Mysqli\Db::query(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

152
        $this->query($query, /** @scrutinizer ignore-type */ $line, $file);
Loading history...
153 1
        if ($this->num_rows() == 0) {
154 1
            return false;
155 1
        } elseif ($this->num_rows() == 1) {
156 1
            $this->next_record(MYSQLI_ASSOC);
157 1
            return $this->Record;
158
        } else {
159 1
            $out = [];
160 1
            while ($this->next_record(MYSQLI_ASSOC)) {
161 1
                $out[] = $this->Record;
162
            }
163 1
            return $out;
164
        }
165
    }
166
167
    /**
168
     * db:qr()
169
     *
170
     *  alias of queryReturn()
171
     *
172
     * @param mixed $query SQL Query to be used
173
     * @param string $line optionally pass __LINE__ calling the query for logging
174
     * @param string $file optionally pass __FILE__ calling the query for logging
175
     * @return mixed FALSE if no rows, if a single row it returns that, if multiple it returns an array of rows, associative responses only
176
     */
177 1
    public function qr($query, $line = '', $file = '')
178
    {
179 1
        return $this->queryReturn($query, $line, $file);
180
    }
181
182
    /**
183
     * creates a prepaired statement from query
184
     *
185
     * @param string $query sql query like INSERT INTO table (col) VALUES (?)  or  SELECT * from table WHERE col1 = ? and col2 = ?  or  UPDATE table SET col1 = ?, col2 = ? WHERE col3 = ?
186
     * @return int|\MyDb\Mysqli\mysqli_stmt
0 ignored issues
show
Bug introduced by
The type MyDb\Mysqli\mysqli_stmt was not found. Did you mean mysqli_stmt? If so, make sure to prefix the type with \.
Loading history...
187
     * @param string $line
188
     * @param string $file
189
     */
190 1
    public function prepare($query, $line = '', $file = '')
191
    {
192 1
        if (!$this->connect()) {
193
            return 0;
194
        }
195 1
        $haltPrev = $this->haltOnError;
0 ignored issues
show
Unused Code introduced by
The assignment to $haltPrev is dead and can be removed.
Loading history...
196 1
        $this->haltOnError = 'no';
197 1
        $start = microtime(true);
198 1
        $prepare = mysqli_prepare($this->linkId, $query);
199 1
        if (!isset($GLOBALS['disable_db_queries'])) {
200 1
            $this->addLog($query, microtime(true) - $start, $line, $file);
201
        }
202
        return $prepare;
203
    }
204
205
    /**
206
     * Db::query()
207
     *
208
     *  Sends an SQL query to the database
209
     *
210
     * @param mixed $queryString
211
     * @param int $line
212
     * @param string $file
213 10
     * @param bool $log
214
     * @return mixed 0 if no query or query id handler, safe to ignore this return
215
     */
216
    public function query($queryString, $line = '', $file = '', $log = false)
217
    {
218
        /* No empty queries, please, since PHP4 chokes on them. */
219
        /* The empty query string is passed on from the constructor,
220 10
        * when calling the class without a query, e.g. in situations
221 1
        * like these: '$db = new db_Subclass;'
222
        */
223 10
        if ($queryString == '') {
224
            return 0;
225
        }
226
        if (!$this->connect()) {
227 10
            return 0;
228 10
            /* we already complained in connect() about that. */
229
        }
230 10
        $haltPrev = $this->haltOnError;
231
        $this->haltOnError = 'no';
232
        // New query, discard previous result.
233 10
        if (is_resource($this->queryId)) {
0 ignored issues
show
introduced by
The condition is_resource($this->queryId) is always false.
Loading history...
234 1
            $this->free();
235
        }
236 10
        if ($this->Debug) {
237
            printf("Debug: query = %s<br>\n", $queryString);
238
        }
239 10
        if ($log === true || (isset($GLOBALS['log_queries']) && $GLOBALS['log_queries'] !== false)) {
240 10
            $this->log($queryString, $line, $file);
241 10
        }
242 10
        $tries = 2;
243 10
        $try = 0;
244 10
        $this->queryId = false;
245
        while ((null === $this->queryId || $this->queryId === false) && $try <= $tries) {
246
            $try++;
247
            if ($try > 1) {
248 10
                @mysqli_close($this->linkId);
0 ignored issues
show
Security Best Practice introduced by
It seems like you do not handle an error condition for mysqli_close(). This can introduce security issues, and is generally not recommended. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unhandled  annotation

248
                /** @scrutinizer ignore-unhandled */ @mysqli_close($this->linkId);

If you suppress an error, we recommend checking for the error condition explicitly:

// For example instead of
@mkdir($dir);

// Better use
if (@mkdir($dir) === false) {
    throw new \RuntimeException('The directory '.$dir.' could not be created.');
}
Loading history...
249 10
                $this->linkId = 0;
250 10
            }
251 10
            $start = microtime(true);
252
            $onlyRollback = true;
253
            $fails = -1;
254
            while ($fails < 30 && (null === $this->queryId || $this->queryId === false)) {
255
                $this->connect();
256
                $fails++;
257
                try {
258 10
                    $this->queryId = @mysqli_query($this->linkId, $queryString, MYSQLI_STORE_RESULT);
259
                    if (in_array((int)@mysqli_errno($this->linkId), [1213, 2006, 3101, 1180])) {
260
                        //error_log("got ".@mysqli_errno($this->linkId)." sql error fails {$fails} on query {$queryString} from {$line}:{$file}");
0 ignored issues
show
Unused Code Comprehensibility introduced by
67% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
261 10
                        usleep(250000); // 0.25 second
262 10
                    } else {
263 10
                        $onlyRollback = false;
264 10
                        if (in_array((int)@mysqli_errno($this->linkId), [1064])) {
265 10
                            $tries = 0;
266
                        }
267
                        break;
268
                    }
269 10
                } catch (\mysqli_sql_exception $e) {
270 10
                    if (in_array((int)$e->getCode(), [1213, 2006, 3101, 1180])) {
271
                        //error_log("got ".$e->getCode()." sql error fails {$fails}");
0 ignored issues
show
Unused Code Comprehensibility introduced by
70% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
272
                        usleep(250000); // 0.25 second
273
                    } else {
274
                        error_log('Got mysqli_sql_exception code '.$e->getCode().' error '.$e->getMessage().' on query '.$queryString.' from '.$line.':'.$file);
275 10
                        $onlyRollback = false;
276
                        if (in_array((int)@mysqli_errno($this->linkId), [1064])) {
277
                            $tries = 0;
278
                        }
279
                        break;
280
                    }
281 1
                }
282
            }
283 1
            if (!isset($GLOBALS['disable_db_queries'])) {
284 1
                $this->addLog($queryString, microtime(true) - $start, $line, $file);
285
            }
286
            $this->Row = 0;
287
            $this->Errno = @mysqli_errno($this->linkId);
0 ignored issues
show
Bug introduced by
It seems like $this->linkId can also be of type integer; however, parameter $mysql of mysqli_errno() does only seem to accept mysqli, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

287
            $this->Errno = @mysqli_errno(/** @scrutinizer ignore-type */ $this->linkId);
Loading history...
288
            $this->Error = @mysqli_error($this->linkId);
0 ignored issues
show
Bug introduced by
It seems like $this->linkId can also be of type integer; however, parameter $mysql of mysqli_error() does only seem to accept mysqli, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

288
            $this->Error = @mysqli_error(/** @scrutinizer ignore-type */ $this->linkId);
Loading history...
289
            if ($try == 1 && (null === $this->queryId || $this->queryId === false)) {
0 ignored issues
show
Unused Code introduced by
This if statement is empty and can be removed.

This check looks for the bodies of if statements that have no statements or where all statements have been commented out. This may be the result of changes for debugging or the code may simply be obsolete.

These if bodies can be removed. If you have an empty if but statements in the else branch, consider inverting the condition.

if (rand(1, 6) > 3) {
//print "Check failed";
} else {
    print "Check succeeded";
}

could be turned into

if (rand(1, 6) <= 3) {
    print "Check succeeded";
}

This is much more concise to read.

Loading history...
290
                //$this->emailError($queryString, 'Error #'.$this->Errno.': '.$this->Error, $line, $file);
0 ignored issues
show
Unused Code Comprehensibility introduced by
66% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
291
            }
292
        }
293
        $this->haltOnError = $haltPrev;
294
        if ($onlyRollback === true && false === $this->queryId) {
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $onlyRollback does not seem to be defined for all execution paths leading up to this point.
Loading history...
295 6
            error_log('Got MySQLi 3101 Rollback Error '.$fails.' Times, Giving Up on '.$queryString.' from '.$line.':'.$file.' on '.__LINE__.':'.__FILE__);
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $fails does not seem to be defined for all execution paths leading up to this point.
Loading history...
296
        }
297 6
        if (null === $this->queryId || $this->queryId === false) {
298
            $this->emailError($queryString, 'Error #'.$this->Errno.': '.$this->Error, $line, $file);
299
            $this->halt('', $line, $file);
300
        }
301
302 6
        // Will return nada if it fails. That's fine.
303 6
        return $this->queryId;
304 6
    }
305 6
306
    /**
307 6
     * @return array|null|object
308 6
     */
309
    public function fetchObject()
310
    {
311 6
        $this->Record = @mysqli_fetch_object($this->queryId);
0 ignored issues
show
Bug introduced by
$this->queryId of type integer is incompatible with the type mysqli_result expected by parameter $result of mysqli_fetch_object(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

311
        $this->Record = @mysqli_fetch_object(/** @scrutinizer ignore-type */ $this->queryId);
Loading history...
312
        return $this->Record;
313
    }
314
315
    /* public: walk result set */
316
317
    /**
318
     * Db::next_record()
319
     *
320 1
     * @param mixed $resultType
321
     * @return bool
322 1
     */
323 1
    public function next_record($resultType = MYSQLI_BOTH)
324 1
    {
325
        if ($this->queryId === false) {
0 ignored issues
show
introduced by
The condition $this->queryId === false is always false.
Loading history...
326 1
            $this->haltmsg('next_record called with no query pending.');
327
            return 0;
328 1
        }
329 1
330 1
        $this->Record = @mysqli_fetch_array($this->queryId, $resultType);
0 ignored issues
show
Bug introduced by
$this->queryId of type integer is incompatible with the type mysqli_result expected by parameter $result of mysqli_fetch_array(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

330
        $this->Record = @mysqli_fetch_array(/** @scrutinizer ignore-type */ $this->queryId, $resultType);
Loading history...
331 1
        ++$this->Row;
332
        $this->Errno = mysqli_errno($this->linkId);
0 ignored issues
show
Bug introduced by
It seems like $this->linkId can also be of type integer; however, parameter $mysql of mysqli_errno() does only seem to accept mysqli, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

332
        $this->Errno = mysqli_errno(/** @scrutinizer ignore-type */ $this->linkId);
Loading history...
333 1
        $this->Error = mysqli_error($this->linkId);
0 ignored issues
show
Bug introduced by
It seems like $this->linkId can also be of type integer; however, parameter $mysql of mysqli_error() does only seem to accept mysqli, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

333
        $this->Error = mysqli_error(/** @scrutinizer ignore-type */ $this->linkId);
Loading history...
334
335
        $stat = is_array($this->Record);
336
        if (!$stat && $this->autoFree && is_resource($this->queryId)) {
0 ignored issues
show
introduced by
The condition is_resource($this->queryId) is always false.
Loading history...
337
            $this->free();
338
        }
339
        return $stat;
340
    }
341 26
342
    /**
343 26
     * switch to position in result set
344
     *
345
     * @param integer $pos the row numbe starting at 0 to switch to
346 26
     * @return bool whetherit was successfu or not.
347
     */
348
    public function seek($pos = 0)
349 26
    {
350
        $status = @mysqli_data_seek($this->queryId, $pos);
0 ignored issues
show
Bug introduced by
$this->queryId of type integer is incompatible with the type mysqli_result expected by parameter $result of mysqli_data_seek(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

350
        $status = @mysqli_data_seek(/** @scrutinizer ignore-type */ $this->queryId, $pos);
Loading history...
351
        if ($status) {
352
            $this->Row = $pos;
353
        } else {
354
            $this->haltmsg("seek({$pos}) failed: result has ".$this->num_rows().' rows', __LINE__, __FILE__);
355
            /* half assed attempt to save the day, but do not consider this documented or even desirable behaviour. */
356
            $rows = $this->num_rows();
357 1
            @mysqli_data_seek($this->queryId, $rows);
0 ignored issues
show
Security Best Practice introduced by
It seems like you do not handle an error condition for mysqli_data_seek(). This can introduce security issues, and is generally not recommended. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unhandled  annotation

357
            /** @scrutinizer ignore-unhandled */ @mysqli_data_seek($this->queryId, $rows);

If you suppress an error, we recommend checking for the error condition explicitly:

// For example instead of
@mkdir($dir);

// Better use
if (@mkdir($dir) === false) {
    throw new \RuntimeException('The directory '.$dir.' could not be created.');
}
Loading history...
358
            $this->Row = $rows;
359 1
            return false;
360
        }
361
        return true;
362 1
    }
363
364
    /**
365
     * Initiates a transaction
366
     *
367
     * @return bool
368
     */
369
    public function transactionBegin()
370 26
    {
371
        if (version_compare(PHP_VERSION, '5.5.0') < 0) {
372 26
            return true;
373
        }
374
        if (!$this->connect()) {
375 26
            return 0;
376
        }
377
        return mysqli_begin_transaction($this->linkId);
378
    }
379
380
    /**
381
     * Commits a transaction
382
     *
383
     * @return bool
384
     */
385
    public function transactionCommit()
386
    {
387 2
        if (version_compare(PHP_VERSION, '5.5.0') < 0 || $this->linkId === 0) {
388
            return true;
389 2
        }
390
        return mysqli_commit($this->linkId);
0 ignored issues
show
Bug introduced by
It seems like $this->linkId can also be of type integer; however, parameter $mysql of mysqli_commit() does only seem to accept mysqli, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

390
        return mysqli_commit(/** @scrutinizer ignore-type */ $this->linkId);
Loading history...
391
    }
392
393 2
    /**
394
     * Rolls back a transaction
395
     *
396
     * @return bool
397
     */
398
    public function transactionAbort()
399
    {
400
        if (version_compare(PHP_VERSION, '5.5.0') < 0 || $this->linkId === 0) {
401
            return true;
402
        }
403
        return mysqli_rollback($this->linkId);
0 ignored issues
show
Bug introduced by
It seems like $this->linkId can also be of type integer; however, parameter $mysql of mysqli_rollback() does only seem to accept mysqli, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

403
        return mysqli_rollback(/** @scrutinizer ignore-type */ $this->linkId);
Loading history...
404 1
    }
405
406 1
    /**
407 1
     * This will get the last insert ID created on the current connection.  Should only be called after an insert query is
408 1
     * run on a table that has an auto incrementing field.  $table and $field are required, but unused here since it's
409 1
     * unnecessary for mysql.  For compatibility with pgsql, the params must be supplied.
410 1
     *
411
     * @param string $table
412
     * @param string $field
413 1
     * @return int|string
414
     */
415
    public function getLastInsertId($table, $field)
416 1
    {
417
        if (!isset($table) || $table == '' || !isset($field) || $field == '') {
418 1
            return -1;
419
        }
420 1
421 1
        return @mysqli_insert_id($this->linkId);
0 ignored issues
show
Bug introduced by
It seems like $this->linkId can also be of type integer; however, parameter $mysql of mysqli_insert_id() does only seem to accept mysqli, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

421
        return @mysqli_insert_id(/** @scrutinizer ignore-type */ $this->linkId);
Loading history...
422
    }
423
424
    /* public: table locking */
425 1
426
    /**
427
     * Db::lock()
428
     * @param mixed  $table
429
     * @param string $mode
430
     * @return bool|int|\mysqli_result
431
     */
432
    public function lock($table, $mode = 'write')
433 2
    {
434
        $this->connect();
435 2
        $query = 'lock tables ';
436
        if (is_array($table)) {
437 2
            foreach ($table as $key => $value) {
438 2
                if ($key == 'read' && $key != 0) {
439
                    $query .= "$value read, ";
440
                } else {
441
                    $query .= "$value $mode, ";
442 2
                }
443
            }
444
            $query = mb_substr($query, 0, -2);
445
        } else {
446
            $query .= "$table $mode";
447
        }
448
        $res = @mysqli_query($this->linkId, $query);
449
        if (!$res) {
450
            $this->halt("lock($table, $mode) failed.");
451 2
            return 0;
452
        }
453 2
        return $res;
454
    }
455
456
    /**
457
     * Db::unlock()
458
     * @param bool $haltOnError optional, defaults to TRUE, whether or not to halt on error
459
     * @return bool|int|\mysqli_result
460 6
     */
461
    public function unlock($haltOnError = true)
462 6
    {
463
        $this->connect();
464
465
        $res = @mysqli_query($this->linkId, 'unlock tables');
466
        if ($haltOnError === true && !$res) {
467
            $this->halt('unlock() failed.');
468
            return 0;
469 1
        }
470
        return $res;
471 1
    }
472
473
    /* public: evaluate the result (size, width) */
474
475
    /**
476
     * Db::affectedRows()
477
     * @return int
478
     */
479 1
    public function affectedRows()
480
    {
481 1
        return @mysqli_affected_rows($this->linkId);
0 ignored issues
show
Bug introduced by
It seems like $this->linkId can also be of type integer; however, parameter $mysql of mysqli_affected_rows() does only seem to accept mysqli, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

481
        return @mysqli_affected_rows(/** @scrutinizer ignore-type */ $this->linkId);
Loading history...
482 1
    }
483 1
484 1
    /**
485 1
     * Db::num_rows()
486 1
     * @return int
487 1
     */
488 1
    public function num_rows()
489
    {
490 1
        return @mysqli_num_rows($this->queryId);
0 ignored issues
show
Bug introduced by
$this->queryId of type integer is incompatible with the type mysqli_result expected by parameter $result of mysqli_num_rows(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

490
        return @mysqli_num_rows(/** @scrutinizer ignore-type */ $this->queryId);
Loading history...
491
    }
492
493
    /**
494
     * Db::num_fields()
495
     * @return int
496
     */
497
    public function num_fields()
498
    {
499
        return @mysqli_num_fields($this->queryId);
0 ignored issues
show
Bug introduced by
$this->queryId of type integer is incompatible with the type mysqli_result expected by parameter $result of mysqli_num_fields(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

499
        return @mysqli_num_fields(/** @scrutinizer ignore-type */ $this->queryId);
Loading history...
500
    }
501
502
    /**
503
     * gets an array of the table names in teh current datase
504
     *
505
     * @return array
506
     */
507
    public function tableNames()
508
    {
509
        $return = [];
510
        $this->query('SHOW TABLES');
511
        $i = 0;
512
        while ($info = $this->queryId->fetch_row()) {
0 ignored issues
show
Bug introduced by
The method fetch_row() does not exist on integer. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

512
        while ($info = $this->queryId->/** @scrutinizer ignore-call */ fetch_row()) {

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
513
            $return[$i]['table_name'] = $info[0];
514
            $return[$i]['tablespace_name'] = $this->database;
515
            $return[$i]['database'] = $this->database;
516
            ++$i;
517
        }
518
        return $return;
519
    }
520
}
521
522
/**
523
 * @param $result
524
 * @param $row
525
 * @param int|string $field
526
 * @return bool
527
 */
528
/*
0 ignored issues
show
Unused Code Comprehensibility introduced by
56% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
529
function mysqli_result($result, $row, $field = 0) {
530
    if ($result === false) return false;
531
    if ($row >= mysqli_num_rows($result)) return false;
532
    if (is_string($field) && !(mb_strpos($field, '.') === false)) {
533
        $tField = explode('.', $field);
534
        $field = -1;
535
        $tFields = mysqli_fetch_fields($result);
536
        for ($id = 0, $idMax = mysqli_num_fields($result); $id < $idMax; $id++) {
537
            if ($tFields[$id]->table == $tField[0] && $tFields[$id]->name == $tField[1]) {
538
                $field = $id;
539
                break;
540
            }
541
        }
542
        if ($field == -1) return false;
543
    }
544
    mysqli_data_seek($result, $row);
545
    $line = mysqli_fetch_array($result);
546
    return isset($line[$field]) ? $line[$field] : false;
547
}
548
*/
549