Test Failed
Push — master ( 8382ce...3db190 )
by Joe
15:49
created
src/Generic.php 1 patch
Indentation   +384 added lines, -384 removed lines patch added patch discarded remove patch
@@ -14,388 +14,388 @@
 block discarded – undo
14 14
  */
15 15
 abstract class Generic
16 16
 {
17
-    /* public: connection parameters */
18
-    public $host = 'localhost';
19
-    public $database = '';
20
-    public $user = '';
21
-    public $password = '';
22
-    public $port = '';
23
-
24
-    /* public: configuration parameters */
25
-    public $autoStripslashes = false;
26
-    public $Debug = 0; // Set to 1 for debugging messages.
27
-    public $haltOnError = 'yes'; // "yes" (halt with message), "no" (ignore errors quietly), "report" (ignore error, but spit a warning)
28
-
29
-    public $maxConnectErrors = 5;
30
-    public $connectionAttempt = 0;
31
-    public $maxMatches = 10000000;
32
-
33
-    public $connection_attempt = 0;
34
-    public $Type = 'mysql';
35
-
36
-    /**
37
-     * @var int
38
-     */
39
-    public $autoFree = 0; // Set to 1 for automatic mysql_free_result()
40
-
41
-    /* public: result array and current row number */
42
-    public $Record = [];
43
-    public $Row;
44
-
45
-    /* public: current error number and error text */
46
-    public $Errno = 0;
47
-    public $Error = '';
48
-
49
-    /* public: this is an api revision, not a CVS revision. */
50
-    public $type = 'generic';
51
-
52
-    /**
53
-     * @var int|object
54
-     */
55
-    public $linkId = 0;
56
-    public $queryId = 0;
57
-
58
-    public $characterSet = 'utf8mb4';
59
-    public $collation = 'utf8mb4_unicode_ci';
60
-
61
-    /**
62
-     * Logged queries.
63
-     * @var array
64
-     */
65
-    protected $log = [];
66
-
67
-    /**
68
-     * Constructs the db handler, can optionally specify connection parameters
69
-     *
70
-     * @param string $database Optional The database name
71
-     * @param string $user Optional The username to connect with
72
-     * @param string $password Optional The password to use
73
-     * @param string $host Optional The hostname where the server is, or default to localhost
74
-     * @param string $query Optional query to perform immediately
75
-     * @param string $port optional port for the connection
76
-     */
77
-    public function __construct($database = '', $user = '', $password = '', $host = 'localhost', $query = '', $port = '')
78
-    {
79
-        $this->database = $database;
80
-        $this->user = $user;
81
-        $this->password = $password;
82
-        $this->host = $host;
83
-        $this->port = $port;
84
-        if ($query != '') {
85
-            $this->query($query);
86
-        }
87
-        $this->connection_atttempt = 0;
88
-    }
89
-
90
-    /**
91
-     * @param string $message
92
-     * @param string $line
93
-     * @param string $file
94
-     * @return void
95
-     */
96
-    public function log($message, $line = '', $file = '', $level = 'info')
97
-    {
98
-        error_log($message);
99
-    }
100
-
101
-    /**
102
-     * @return int|object
103
-     */
104
-    public function linkId()
105
-    {
106
-        return $this->linkId;
107
-    }
108
-
109
-    /**
110
-     * @return int|object
111
-     */
112
-    public function queryId()
113
-    {
114
-        return $this->queryId;
115
-    }
116
-
117
-    /**
118
-     * @param $string
119
-     * @return string
120
-     */
121
-    public function real_escape($string = '')
122
-    {
123
-        if ((!is_resource($this->linkId) || $this->linkId == 0) && !$this->connect()) {
124
-            return $this->escape($string);
125
-        }
126
-        return mysqli_real_escape_string($this->linkId, $string);
127
-    }
128
-
129
-    /**
130
-     * @param $string
131
-     * @return string
132
-     */
133
-    public function escape($string = '')
134
-    {
135
-        //if (function_exists('mysql_escape_string'))
136
-        //return mysql_escape_string($string);
137
-        return str_replace(['\\', "\0", "\n", "\r", "'", '"', "\x1a"], ['\\\\', '\\0', '\\n', '\\r', "\\'", '\\"', '\\Z'], $string);
138
-    }
139
-
140
-    /**
141
-     * @param mixed $str
142
-     * @return string
143
-     */
144
-    public function dbAddslashes($str = '')
145
-    {
146
-        if (!isset($str) || $str == '') {
147
-            return '';
148
-        }
149
-        return addslashes($str);
150
-    }
151
-
152
-    /**
153
-     * Db::toTimestamp()
154
-     * @param mixed $epoch
155
-     * @return bool|string
156
-     */
157
-    public function toTimestamp($epoch)
158
-    {
159
-        return date('Y-m-d H:i:s', is_float($epoch) ? intval($epoch) : $epoch);
160
-    }
161
-
162
-    /**
163
-     * Db::fromTimestamp()
164
-     * @param mixed $timestamp
165
-     * @return bool|int|mixed
166
-     */
167
-    public function fromTimestamp($timestamp)
168
-    {
169
-        if (preg_match('/([0-9]{4})-([0-9]{2})-([0-9]{2}) ([0-9]{2}):([0-9]{2}):([0-9]{2})/', $timestamp, $parts)) {
170
-            $time = mktime($parts[4], $parts[5], $parts[6], $parts[2], $parts[3], $parts[1]);
171
-        } elseif (preg_match('/([0-9]{4})([0-9]{2})([0-9]{2})([0-9]{2})([0-9]{2})([0-9]{2})/', $timestamp, $parts)) {
172
-            $time = mktime($parts[4], $parts[5], $parts[6], $parts[2], $parts[3], $parts[1]);
173
-        } elseif (preg_match('/([0-9]{4})([0-9]{2})([0-9]{2})/', $timestamp, $parts)) {
174
-            $time = mktime(1, 1, 1, $parts[2], $parts[3], $parts[1]);
175
-        } elseif (is_numeric($timestamp) && $timestamp >= 943938000) {
176
-            $time = $timestamp;
177
-        } else {
178
-            $this->log('Cannot Match Timestamp from '.$timestamp, __LINE__, __FILE__);
179
-            $time = false;
180
-        }
181
-        return $time;
182
-    }
183
-
184
-    /**
185
-     * perform a query with limited result set
186
-     *
187
-     * @param string $queryString
188
-     * @param string|int $numRows
189
-     * @param int $offset
190
-     * @param string|int $line
191
-     * @param string $file
192
-     * @return mixed
193
-     */
194
-    public function limitQuery($queryString, $numRows = '', $offset = 0, $line = '', $file = '')
195
-    {
196
-        if (!$numRows) {
197
-            $numRows = $this->maxMatches;
198
-        }
199
-        if ($offset == 0) {
200
-            $queryString .= ' LIMIT '.(int) $numRows;
201
-        } else {
202
-            $queryString .= ' LIMIT '.(int) $offset.','.(int) $numRows;
203
-        }
204
-
205
-        if ($this->Debug) {
206
-            printf("Debug: limitQuery = %s<br>offset=%d, num_rows=%d<br>\n", $queryString, $offset, $numRows);
207
-        }
208
-
209
-        return $this->query($queryString, $line, $file);
210
-    }
211
-
212
-    /**
213
-     * db:qr()
214
-     *
215
-     *  alias of queryReturn()
216
-     *
217
-     * @param mixed $query SQL Query to be used
218
-     * @param string $line optionally pass __LINE__ calling the query for logging
219
-     * @param string $file optionally pass __FILE__ calling the query for logging
220
-     * @return mixed FALSE if no rows, if a single row it returns that, if multiple it returns an array of rows, associative responses only
221
-     */
222
-    public function qr($query, $line = '', $file = '')
223
-    {
224
-        return $this->queryReturn($query, $line, $file);
225
-    }
226
-
227
-    /**
228
-     * gets a field
229
-     *
230
-     * @param mixed  $name
231
-     * @param string $stripSlashes
232
-     * @return string
233
-     */
234
-    public function f($name, $stripSlashes = '')
235
-    {
236
-        if (is_null($this->Record)) {
237
-            return null;
238
-        } elseif ($stripSlashes || ($this->autoStripslashes && !$stripSlashes)) {
239
-            return stripslashes($this->Record[$name]);
240
-        } else {
241
-            return $this->Record[$name];
242
-        }
243
-    }
244
-
245
-    /**
246
-     * error handling
247
-     *
248
-     * @param mixed $msg
249
-     * @param string $line
250
-     * @param string $file
251
-     * @return void
252
-     */
253
-    public function halt($msg, $line = '', $file = '')
254
-    {
255
-        $this->unlock(false);
256
-        /* Just in case there is a table currently locked */
257
-
258
-        //$this->Error = @$this->linkId->error;
259
-        //$this->Errno = @$this->linkId->errno;
260
-        if ($this->haltOnError == 'no') {
261
-            return true;
262
-        }
263
-        if ($msg != '') {
264
-            $this->haltmsg($msg, $line, $file);
265
-        }
266
-        if ($this->haltOnError != 'report') {
267
-            echo '<p><b>Session halted.</b>';
268
-            //if (isset($GLOBALS['tf']))
269
-            //$GLOBALS['tf']->terminate();
270
-            die();
271
-        }
272
-        return true;
273
-    }
274
-
275
-    /**
276
-     * @param mixed $msg
277
-     * @param string $line
278
-     * @param string $file
279
-     * @return mixed|void
280
-     */
281
-    public function logBackTrace($msg, $line = '', $file = '')
282
-    {
283
-        $backtrace = (function_exists('debug_backtrace') ? debug_backtrace() : []);
284
-        $this->log(
285
-            ('' !== getenv('REQUEST_URI') ? ' '.getenv('REQUEST_URI') : '').
286
-            ((isset($_POST) && count($_POST)) ? ' POST='.json_encode($_POST) : '').
287
-            ((isset($_GET) && count($_GET)) ? ' GET='.json_encode($_GET) : '').
288
-            ((isset($_FILES) && count($_FILES)) ? ' FILES='.json_encode($_FILES) : '').
289
-            ('' !== getenv('HTTP_USER_AGENT') ? ' AGENT="'.getenv('HTTP_USER_AGENT').'"' : '').
290
-            (isset($_SERVER['REQUEST_METHOD']) ? ' METHOD="'.$_SERVER['REQUEST_METHOD'].'"'.
291
-                ($_SERVER['REQUEST_METHOD'] === 'POST' ? ' POST="'.json_encode($_POST).'"' : '') : ''),
292
-            $line,
293
-            $file,
294
-            'error'
295
-        );
296
-        for ($level = 1, $levelMax = count($backtrace); $level < $levelMax; $level++) {
297
-            $message = (isset($backtrace[$level]['file']) ? 'File: '.$backtrace[$level]['file'] : '').
298
-                (isset($backtrace[$level]['line']) ? ' Line: '.$backtrace[$level]['line'] : '').
299
-                ' Function: '.(isset($backtrace[$level] ['class']) ? '(class '.$backtrace[$level] ['class'].') ' : '').
300
-                (isset($backtrace[$level] ['type']) ? $backtrace[$level] ['type'].' ' : '').
301
-                $backtrace[$level] ['function'].'(';
302
-            if (isset($backtrace[$level] ['args'])) {
303
-                for ($argument = 0, $argumentMax = count($backtrace[$level]['args']); $argument < $argumentMax; $argument++) {
304
-                    $message .= ($argument > 0 ? ', ' : '').
305
-                        (is_object($backtrace[$level]['args'][$argument]) ? 'class '.get_class($backtrace[$level]['args'][$argument]) : json_encode($backtrace[$level]['args'][$argument]));
306
-                }
307
-            }
308
-            $message .= ')';
309
-            $this->log($message, $line, $file, 'error');
310
-        }
311
-    }
312
-
313
-    public function emailError($queryString, $error, $line, $file)
314
-    {
315
-        $subject = php_uname('n').' MySQLi Error '.$queryString;
316
-        if (class_exists('\\TFSmarty')) {
317
-            $smarty = new \TFSmarty();
318
-            $smarty->assign([
319
-                'type' => $this->type,
320
-                'queryString' => $queryString,
321
-                'error' => $error,
322
-                'line' => $line,
323
-                'file' => $file,
324
-                'request' => $_REQUEST,
325
-                'server' => $_SERVER,
326
-            ]);
327
-            if (isset($GLOBALS['tf'])) {
328
-                $smarty->assign('account_id', $GLOBALS['tf']->session->account_id);
329
-            }
330
-            $email = $smarty->fetch('email/admin/sql_error.tpl');
331
-            (new \MyAdmin\Mail())->adminMail($subject, $email, '[email protected]', '');
332
-            (new \MyAdmin\Mail())->adminMail($subject, $email, '[email protected]', '');
333
-        }
334
-        $this->haltmsg('Invalid SQL: '.$queryString, $line, $file);
335
-    }
336
-
337
-    /**
338
-     * @param mixed $msg
339
-     * @param string $line
340
-     * @param string $file
341
-     * @return mixed|void
342
-     */
343
-    public function haltmsg($msg, $line = '', $file = '')
344
-    {
345
-        $email = "DB Error {$msg} {$file}:{$line}";
346
-        if (class_exists('\\MyAdmin\Mail')) {
347
-            \MyAdmin\Mail::failsafeMail($email, $email, ['[email protected]', '[email protected]']);
348
-            return;
349
-        }
350
-        $this->log("Database error: $msg", $line, $file, 'error');
351
-        if ($this->Errno != '0' || !in_array($this->Error, ['', '()'])) {
352
-            $sqlstate = mysqli_sqlstate($this->linkId);
353
-            $this->log("MySQLi SQLState: {$sqlstate}. Error: ".$this->Errno.' ('.$this->Error.')', $line, $file, 'error');
354
-        }
355
-        $this->logBackTrace($msg, $line, $file);
356
-    }
357
-
358
-    /**
359
-     * @return array
360
-     */
361
-    public function indexNames()
362
-    {
363
-        return [];
364
-    }
365
-
366
-
367
-    /**
368
-     * Add query to logged queries.
369
-     * @param string $statement
370
-     * @param float $time Elapsed seconds with microseconds
371
-     * @param string|int $line Line Number
372
-     * @param string $file File Name
373
-     */
374
-    public function addLog($statement, $time, $line = '', $file = '')
375
-    {
376
-        $query = [
377
-            'statement' => $statement,
378
-            'time' => $time * 1000
379
-        ];
380
-        if ($line != '') {
381
-            $query['line'] = $line;
382
-        }
383
-        if ($file != '') {
384
-            $query['file'] = $file;
385
-        }
386
-        if (!isset($GLOBALS['db_queries'])) {
387
-            $GLOBALS['db_queries'] = [];
388
-        }
389
-        $GLOBALS['db_queries'][] = $query;
390
-        array_push($this->log, $query);
391
-    }
392
-
393
-    /**
394
-     * Return logged queries.
395
-     * @return array Logged queries
396
-     */
397
-    public function getLog()
398
-    {
399
-        return $this->log;
400
-    }
17
+	/* public: connection parameters */
18
+	public $host = 'localhost';
19
+	public $database = '';
20
+	public $user = '';
21
+	public $password = '';
22
+	public $port = '';
23
+
24
+	/* public: configuration parameters */
25
+	public $autoStripslashes = false;
26
+	public $Debug = 0; // Set to 1 for debugging messages.
27
+	public $haltOnError = 'yes'; // "yes" (halt with message), "no" (ignore errors quietly), "report" (ignore error, but spit a warning)
28
+
29
+	public $maxConnectErrors = 5;
30
+	public $connectionAttempt = 0;
31
+	public $maxMatches = 10000000;
32
+
33
+	public $connection_attempt = 0;
34
+	public $Type = 'mysql';
35
+
36
+	/**
37
+	 * @var int
38
+	 */
39
+	public $autoFree = 0; // Set to 1 for automatic mysql_free_result()
40
+
41
+	/* public: result array and current row number */
42
+	public $Record = [];
43
+	public $Row;
44
+
45
+	/* public: current error number and error text */
46
+	public $Errno = 0;
47
+	public $Error = '';
48
+
49
+	/* public: this is an api revision, not a CVS revision. */
50
+	public $type = 'generic';
51
+
52
+	/**
53
+	 * @var int|object
54
+	 */
55
+	public $linkId = 0;
56
+	public $queryId = 0;
57
+
58
+	public $characterSet = 'utf8mb4';
59
+	public $collation = 'utf8mb4_unicode_ci';
60
+
61
+	/**
62
+	 * Logged queries.
63
+	 * @var array
64
+	 */
65
+	protected $log = [];
66
+
67
+	/**
68
+	 * Constructs the db handler, can optionally specify connection parameters
69
+	 *
70
+	 * @param string $database Optional The database name
71
+	 * @param string $user Optional The username to connect with
72
+	 * @param string $password Optional The password to use
73
+	 * @param string $host Optional The hostname where the server is, or default to localhost
74
+	 * @param string $query Optional query to perform immediately
75
+	 * @param string $port optional port for the connection
76
+	 */
77
+	public function __construct($database = '', $user = '', $password = '', $host = 'localhost', $query = '', $port = '')
78
+	{
79
+		$this->database = $database;
80
+		$this->user = $user;
81
+		$this->password = $password;
82
+		$this->host = $host;
83
+		$this->port = $port;
84
+		if ($query != '') {
85
+			$this->query($query);
86
+		}
87
+		$this->connection_atttempt = 0;
88
+	}
89
+
90
+	/**
91
+	 * @param string $message
92
+	 * @param string $line
93
+	 * @param string $file
94
+	 * @return void
95
+	 */
96
+	public function log($message, $line = '', $file = '', $level = 'info')
97
+	{
98
+		error_log($message);
99
+	}
100
+
101
+	/**
102
+	 * @return int|object
103
+	 */
104
+	public function linkId()
105
+	{
106
+		return $this->linkId;
107
+	}
108
+
109
+	/**
110
+	 * @return int|object
111
+	 */
112
+	public function queryId()
113
+	{
114
+		return $this->queryId;
115
+	}
116
+
117
+	/**
118
+	 * @param $string
119
+	 * @return string
120
+	 */
121
+	public function real_escape($string = '')
122
+	{
123
+		if ((!is_resource($this->linkId) || $this->linkId == 0) && !$this->connect()) {
124
+			return $this->escape($string);
125
+		}
126
+		return mysqli_real_escape_string($this->linkId, $string);
127
+	}
128
+
129
+	/**
130
+	 * @param $string
131
+	 * @return string
132
+	 */
133
+	public function escape($string = '')
134
+	{
135
+		//if (function_exists('mysql_escape_string'))
136
+		//return mysql_escape_string($string);
137
+		return str_replace(['\\', "\0", "\n", "\r", "'", '"', "\x1a"], ['\\\\', '\\0', '\\n', '\\r', "\\'", '\\"', '\\Z'], $string);
138
+	}
139
+
140
+	/**
141
+	 * @param mixed $str
142
+	 * @return string
143
+	 */
144
+	public function dbAddslashes($str = '')
145
+	{
146
+		if (!isset($str) || $str == '') {
147
+			return '';
148
+		}
149
+		return addslashes($str);
150
+	}
151
+
152
+	/**
153
+	 * Db::toTimestamp()
154
+	 * @param mixed $epoch
155
+	 * @return bool|string
156
+	 */
157
+	public function toTimestamp($epoch)
158
+	{
159
+		return date('Y-m-d H:i:s', is_float($epoch) ? intval($epoch) : $epoch);
160
+	}
161
+
162
+	/**
163
+	 * Db::fromTimestamp()
164
+	 * @param mixed $timestamp
165
+	 * @return bool|int|mixed
166
+	 */
167
+	public function fromTimestamp($timestamp)
168
+	{
169
+		if (preg_match('/([0-9]{4})-([0-9]{2})-([0-9]{2}) ([0-9]{2}):([0-9]{2}):([0-9]{2})/', $timestamp, $parts)) {
170
+			$time = mktime($parts[4], $parts[5], $parts[6], $parts[2], $parts[3], $parts[1]);
171
+		} elseif (preg_match('/([0-9]{4})([0-9]{2})([0-9]{2})([0-9]{2})([0-9]{2})([0-9]{2})/', $timestamp, $parts)) {
172
+			$time = mktime($parts[4], $parts[5], $parts[6], $parts[2], $parts[3], $parts[1]);
173
+		} elseif (preg_match('/([0-9]{4})([0-9]{2})([0-9]{2})/', $timestamp, $parts)) {
174
+			$time = mktime(1, 1, 1, $parts[2], $parts[3], $parts[1]);
175
+		} elseif (is_numeric($timestamp) && $timestamp >= 943938000) {
176
+			$time = $timestamp;
177
+		} else {
178
+			$this->log('Cannot Match Timestamp from '.$timestamp, __LINE__, __FILE__);
179
+			$time = false;
180
+		}
181
+		return $time;
182
+	}
183
+
184
+	/**
185
+	 * perform a query with limited result set
186
+	 *
187
+	 * @param string $queryString
188
+	 * @param string|int $numRows
189
+	 * @param int $offset
190
+	 * @param string|int $line
191
+	 * @param string $file
192
+	 * @return mixed
193
+	 */
194
+	public function limitQuery($queryString, $numRows = '', $offset = 0, $line = '', $file = '')
195
+	{
196
+		if (!$numRows) {
197
+			$numRows = $this->maxMatches;
198
+		}
199
+		if ($offset == 0) {
200
+			$queryString .= ' LIMIT '.(int) $numRows;
201
+		} else {
202
+			$queryString .= ' LIMIT '.(int) $offset.','.(int) $numRows;
203
+		}
204
+
205
+		if ($this->Debug) {
206
+			printf("Debug: limitQuery = %s<br>offset=%d, num_rows=%d<br>\n", $queryString, $offset, $numRows);
207
+		}
208
+
209
+		return $this->query($queryString, $line, $file);
210
+	}
211
+
212
+	/**
213
+	 * db:qr()
214
+	 *
215
+	 *  alias of queryReturn()
216
+	 *
217
+	 * @param mixed $query SQL Query to be used
218
+	 * @param string $line optionally pass __LINE__ calling the query for logging
219
+	 * @param string $file optionally pass __FILE__ calling the query for logging
220
+	 * @return mixed FALSE if no rows, if a single row it returns that, if multiple it returns an array of rows, associative responses only
221
+	 */
222
+	public function qr($query, $line = '', $file = '')
223
+	{
224
+		return $this->queryReturn($query, $line, $file);
225
+	}
226
+
227
+	/**
228
+	 * gets a field
229
+	 *
230
+	 * @param mixed  $name
231
+	 * @param string $stripSlashes
232
+	 * @return string
233
+	 */
234
+	public function f($name, $stripSlashes = '')
235
+	{
236
+		if (is_null($this->Record)) {
237
+			return null;
238
+		} elseif ($stripSlashes || ($this->autoStripslashes && !$stripSlashes)) {
239
+			return stripslashes($this->Record[$name]);
240
+		} else {
241
+			return $this->Record[$name];
242
+		}
243
+	}
244
+
245
+	/**
246
+	 * error handling
247
+	 *
248
+	 * @param mixed $msg
249
+	 * @param string $line
250
+	 * @param string $file
251
+	 * @return void
252
+	 */
253
+	public function halt($msg, $line = '', $file = '')
254
+	{
255
+		$this->unlock(false);
256
+		/* Just in case there is a table currently locked */
257
+
258
+		//$this->Error = @$this->linkId->error;
259
+		//$this->Errno = @$this->linkId->errno;
260
+		if ($this->haltOnError == 'no') {
261
+			return true;
262
+		}
263
+		if ($msg != '') {
264
+			$this->haltmsg($msg, $line, $file);
265
+		}
266
+		if ($this->haltOnError != 'report') {
267
+			echo '<p><b>Session halted.</b>';
268
+			//if (isset($GLOBALS['tf']))
269
+			//$GLOBALS['tf']->terminate();
270
+			die();
271
+		}
272
+		return true;
273
+	}
274
+
275
+	/**
276
+	 * @param mixed $msg
277
+	 * @param string $line
278
+	 * @param string $file
279
+	 * @return mixed|void
280
+	 */
281
+	public function logBackTrace($msg, $line = '', $file = '')
282
+	{
283
+		$backtrace = (function_exists('debug_backtrace') ? debug_backtrace() : []);
284
+		$this->log(
285
+			('' !== getenv('REQUEST_URI') ? ' '.getenv('REQUEST_URI') : '').
286
+			((isset($_POST) && count($_POST)) ? ' POST='.json_encode($_POST) : '').
287
+			((isset($_GET) && count($_GET)) ? ' GET='.json_encode($_GET) : '').
288
+			((isset($_FILES) && count($_FILES)) ? ' FILES='.json_encode($_FILES) : '').
289
+			('' !== getenv('HTTP_USER_AGENT') ? ' AGENT="'.getenv('HTTP_USER_AGENT').'"' : '').
290
+			(isset($_SERVER['REQUEST_METHOD']) ? ' METHOD="'.$_SERVER['REQUEST_METHOD'].'"'.
291
+				($_SERVER['REQUEST_METHOD'] === 'POST' ? ' POST="'.json_encode($_POST).'"' : '') : ''),
292
+			$line,
293
+			$file,
294
+			'error'
295
+		);
296
+		for ($level = 1, $levelMax = count($backtrace); $level < $levelMax; $level++) {
297
+			$message = (isset($backtrace[$level]['file']) ? 'File: '.$backtrace[$level]['file'] : '').
298
+				(isset($backtrace[$level]['line']) ? ' Line: '.$backtrace[$level]['line'] : '').
299
+				' Function: '.(isset($backtrace[$level] ['class']) ? '(class '.$backtrace[$level] ['class'].') ' : '').
300
+				(isset($backtrace[$level] ['type']) ? $backtrace[$level] ['type'].' ' : '').
301
+				$backtrace[$level] ['function'].'(';
302
+			if (isset($backtrace[$level] ['args'])) {
303
+				for ($argument = 0, $argumentMax = count($backtrace[$level]['args']); $argument < $argumentMax; $argument++) {
304
+					$message .= ($argument > 0 ? ', ' : '').
305
+						(is_object($backtrace[$level]['args'][$argument]) ? 'class '.get_class($backtrace[$level]['args'][$argument]) : json_encode($backtrace[$level]['args'][$argument]));
306
+				}
307
+			}
308
+			$message .= ')';
309
+			$this->log($message, $line, $file, 'error');
310
+		}
311
+	}
312
+
313
+	public function emailError($queryString, $error, $line, $file)
314
+	{
315
+		$subject = php_uname('n').' MySQLi Error '.$queryString;
316
+		if (class_exists('\\TFSmarty')) {
317
+			$smarty = new \TFSmarty();
318
+			$smarty->assign([
319
+				'type' => $this->type,
320
+				'queryString' => $queryString,
321
+				'error' => $error,
322
+				'line' => $line,
323
+				'file' => $file,
324
+				'request' => $_REQUEST,
325
+				'server' => $_SERVER,
326
+			]);
327
+			if (isset($GLOBALS['tf'])) {
328
+				$smarty->assign('account_id', $GLOBALS['tf']->session->account_id);
329
+			}
330
+			$email = $smarty->fetch('email/admin/sql_error.tpl');
331
+			(new \MyAdmin\Mail())->adminMail($subject, $email, '[email protected]', '');
332
+			(new \MyAdmin\Mail())->adminMail($subject, $email, '[email protected]', '');
333
+		}
334
+		$this->haltmsg('Invalid SQL: '.$queryString, $line, $file);
335
+	}
336
+
337
+	/**
338
+	 * @param mixed $msg
339
+	 * @param string $line
340
+	 * @param string $file
341
+	 * @return mixed|void
342
+	 */
343
+	public function haltmsg($msg, $line = '', $file = '')
344
+	{
345
+		$email = "DB Error {$msg} {$file}:{$line}";
346
+		if (class_exists('\\MyAdmin\Mail')) {
347
+			\MyAdmin\Mail::failsafeMail($email, $email, ['[email protected]', '[email protected]']);
348
+			return;
349
+		}
350
+		$this->log("Database error: $msg", $line, $file, 'error');
351
+		if ($this->Errno != '0' || !in_array($this->Error, ['', '()'])) {
352
+			$sqlstate = mysqli_sqlstate($this->linkId);
353
+			$this->log("MySQLi SQLState: {$sqlstate}. Error: ".$this->Errno.' ('.$this->Error.')', $line, $file, 'error');
354
+		}
355
+		$this->logBackTrace($msg, $line, $file);
356
+	}
357
+
358
+	/**
359
+	 * @return array
360
+	 */
361
+	public function indexNames()
362
+	{
363
+		return [];
364
+	}
365
+
366
+
367
+	/**
368
+	 * Add query to logged queries.
369
+	 * @param string $statement
370
+	 * @param float $time Elapsed seconds with microseconds
371
+	 * @param string|int $line Line Number
372
+	 * @param string $file File Name
373
+	 */
374
+	public function addLog($statement, $time, $line = '', $file = '')
375
+	{
376
+		$query = [
377
+			'statement' => $statement,
378
+			'time' => $time * 1000
379
+		];
380
+		if ($line != '') {
381
+			$query['line'] = $line;
382
+		}
383
+		if ($file != '') {
384
+			$query['file'] = $file;
385
+		}
386
+		if (!isset($GLOBALS['db_queries'])) {
387
+			$GLOBALS['db_queries'] = [];
388
+		}
389
+		$GLOBALS['db_queries'][] = $query;
390
+		array_push($this->log, $query);
391
+	}
392
+
393
+	/**
394
+	 * Return logged queries.
395
+	 * @return array Logged queries
396
+	 */
397
+	public function getLog()
398
+	{
399
+		return $this->log;
400
+	}
401 401
 }
Please login to merge, or discard this patch.