Completed
Push — trunk ( 0e7a2e...6a6c5e )
by SuperNova.WS
07:28
created

db_mysql::sn_db_connect()   D

Complexity

Conditions 9
Paths 28

Size

Total Lines 29
Code Lines 16

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 90

Importance

Changes 0
Metric Value
cc 9
eloc 16
nc 28
nop 1
dl 0
loc 29
ccs 0
cts 19
cp 0
crap 90
rs 4.909
c 0
b 0
f 0
1
<?php
2
3
namespace DBAL;
4
5
use Core\GlobalContainer;
6
use DBAL\db_mysql_v5;
7
use \DBAL\DbMysqliResultIterator;
8
use mysqli_result;
9
use SN;
10
11
/**
12
 * User: Gorlum
13
 * Date: 01.09.2015
14
 * Time: 15:58
15
 */
16
class db_mysql {
17
  const DB_MYSQL_TRANSACTION_SERIALIZABLE = 'SERIALIZABLE';
18
  const DB_MYSQL_TRANSACTION_REPEATABLE_READ = 'REPEATABLE READ';
19
  const DB_MYSQL_TRANSACTION_READ_COMMITTED = 'READ COMMITTED';
20
  const DB_MYSQL_TRANSACTION_READ_UNCOMMITTED = 'READ UNCOMMITTED';
21
22
  /**
23
   * Статус соеднения с MySQL
24
   *
25
   * @var bool
26
   */
27
  public $connected = false;
28
  /**
29
   * Префикс названий таблиц в БД
30
   *
31
   * @var string
32
   */
33
  public $db_prefix = '';
34
  /**
35
   * Настройки БД
36
   *
37
   * @var array
38
   */
39
  protected $dbsettings = array();
40
  /**
41
   * Драйвер для прямого обращения к MySQL
42
   *
43
   * @var db_mysql_v5 $driver
44
   */
45
  public $driver = null;
46
47
  /**
48
   * Общее время запросов
49
   *
50
   * @var float $time_mysql_total
51
   */
52
  public $time_mysql_total = 0.0;
53
54
  /**
55
   * DB schemes
56
   *
57
   * @var \DBAL\Schema|null $schema
58
   */
59
  protected static $schema = null;
60
61
  /**
62
   * DBAL\db_mysql constructor.
63
   *
64
   * @param \Core\GlobalContainer $gc
65
   */
66
  public function __construct($gc) {
0 ignored issues
show
Unused Code introduced by
The parameter $gc is not used and could be removed. ( Ignorable by Annotation )

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

66
  public function __construct(/** @scrutinizer ignore-unused */ $gc) {

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
67
//    $this->transaction = new \DBAL\DbTransaction($gc, $this);
0 ignored issues
show
Unused Code Comprehensibility introduced by
52% 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...
68
//    $this->snCache = new $gc->snCacheClass($gc, $this);
69
//    $this->operator = new DbRowDirectOperator($this);
70
  }
71
72
  public function schema() {
73
    if (!isset(self::$schema)) {
74
      self::$schema = new \DBAL\Schema($this);
75
    }
76
77
    return self::$schema;
78
  }
79
80
  public function load_db_settings() {
81
    $dbsettings = array();
82
83
    require(SN_ROOT_PHYSICAL . "config" . DOT_PHP_EX);
84
85
    $this->dbsettings = $dbsettings;
86
  }
87
88
  public function sn_db_connect($external_db_settings = null) {
89
    $this->db_disconnect();
90
91
    if (!empty($external_db_settings) && is_array($external_db_settings)) {
92
      $this->dbsettings = $external_db_settings;
93
    }
94
95
    if (empty($this->dbsettings)) {
96
      $this->load_db_settings();
97
    }
98
99
    // TODO - фатальные (?) ошибки на каждом шагу. Хотя - скорее Эксепшны
100
    if (!empty($this->dbsettings)) {
101
      $driver_name = 'DBAL\\' . (empty($this->dbsettings['sn_driver']) ? 'db_mysql_v5' : $this->dbsettings['sn_driver']);
102
      $this->driver = new $driver_name();
103
      $this->db_prefix = $this->dbsettings['prefix'];
104
105
      $this->connected = $this->connected || $this->driver_connect();
106
107
      if ($this->connected && empty($this->schema()->getSnTables())) {
108
        die('DB error - cannot find any table. Halting...');
0 ignored issues
show
Best Practice introduced by
Using exit here is not recommended.

In general, usage of exit should be done with care and only when running in a scripting context like a CLI script.

Loading history...
109
      }
110
111
      $this->doQueryFast('SET SESSION TRANSACTION ISOLATION LEVEL ' . self::DB_MYSQL_TRANSACTION_SERIALIZABLE);
112
    } else {
113
      $this->connected = false;
114
    }
115
116
    return $this->connected;
117
  }
118
119
  public function driver_connect() {
120
    global $debug;
0 ignored issues
show
Compatibility Best Practice introduced by
Use of global functionality is not recommended; it makes your code harder to test, and less reusable.

Instead of relying on global state, we recommend one of these alternatives:

1. Pass all data via parameters

function myFunction($a, $b) {
    // Do something
}

2. Create a class that maintains your state

class MyClass {
    private $a;
    private $b;

    public function __construct($a, $b) {
        $this->a = $a;
        $this->b = $b;
    }

    public function myFunction() {
        // Do something
    }
}
Loading history...
121
122
    if (!is_object($this->driver)) {
123
      $debug->error_fatal('DB Error - No driver for MySQL found!');
124
    }
125
126
    if (!method_exists($this->driver, 'mysql_connect')) {
127
      $debug->error_fatal('DB Error - WRONG MySQL driver!');
128
    }
129
130
    return $this->driver->mysql_connect($this->dbsettings);
131
  }
132
133
  public function db_disconnect() {
134
    if ($this->connected) {
135
      $this->connected = !$this->driver_disconnect();
136
      $this->connected = false;
137
    }
138
139
    return !$this->connected;
140
  }
141
142
  /**
143
   * @param int    $errno
144
   * @param string $errstr
145
   * @param string $errfile
146
   * @param int    $errline
147
   * @param array  $errcontext
148
   */
149
  public function handlerQueryWarning($errno, $errstr, $errfile, $errline, $errcontext) {
0 ignored issues
show
Unused Code introduced by
The parameter $errstr is not used and could be removed. ( Ignorable by Annotation )

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

149
  public function handlerQueryWarning($errno, /** @scrutinizer ignore-unused */ $errstr, $errfile, $errline, $errcontext) {

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
Unused Code introduced by
The parameter $errno is not used and could be removed. ( Ignorable by Annotation )

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

149
  public function handlerQueryWarning(/** @scrutinizer ignore-unused */ $errno, $errstr, $errfile, $errline, $errcontext) {

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
Unused Code introduced by
The parameter $errcontext is not used and could be removed. ( Ignorable by Annotation )

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

149
  public function handlerQueryWarning($errno, $errstr, $errfile, $errline, /** @scrutinizer ignore-unused */ $errcontext) {

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
Unused Code introduced by
The parameter $errfile is not used and could be removed. ( Ignorable by Annotation )

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

149
  public function handlerQueryWarning($errno, $errstr, /** @scrutinizer ignore-unused */ $errfile, $errline, $errcontext) {

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
Unused Code introduced by
The parameter $errline is not used and could be removed. ( Ignorable by Annotation )

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

149
  public function handlerQueryWarning($errno, $errstr, $errfile, /** @scrutinizer ignore-unused */ $errline, $errcontext) {

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
150
    static $alreadyHandled;
151
152
    // Error was suppressed with the @-operator
153
    if (0 === error_reporting()) {
154
      return false;
155
    }
156
157
    if (!$alreadyHandled) {
158
      print(SN_TIME_SQL . '<br />Server is busy. Please try again in several minutes...<br />Сервер занят. Попробуйте снова через несколько минут...<br />Server zanyat. Poprobujte snova cherez neskolko minut...');
159
      $alreadyHandled = true;
160
    }
161
162
    return true;
163
  }
164
165
  public function prefixReplace($sql) {
166
    if (strpos($sql, '{{') !== false) {
167
      foreach ($this->schema()->getSnTables() as $tableName) {
168
        $sql = str_replace("{{{$tableName}}}", $this->db_prefix . $tableName, $sql);
169
      }
170
    }
171
172
    return $sql;
173
  }
174
175
  public function doquery($query, $table = '', $fetch = false, $skip_query_check = false) {
176
    global $numqueries, $debug, $config;
0 ignored issues
show
Compatibility Best Practice introduced by
Use of global functionality is not recommended; it makes your code harder to test, and less reusable.

Instead of relying on global state, we recommend one of these alternatives:

1. Pass all data via parameters

function myFunction($a, $b) {
    // Do something
}

2. Create a class that maintains your state

class MyClass {
    private $a;
    private $b;

    public function __construct($a, $b) {
        $this->a = $a;
        $this->b = $b;
    }

    public function myFunction() {
        // Do something
    }
}
Loading history...
177
178
    if (!is_string($table)) {
179
      $fetch = $table;
180
    }
181
182
    if (!$this->connected) {
183
      $this->sn_db_connect();
184
    }
185
186
    $query = trim($query);
187
    $this->security_watch_user_queries($query);
188
    $skip_query_check or $this->security_query_check_bad_words($query);
0 ignored issues
show
Comprehensibility Best Practice introduced by
Using logical operators such as or instead of || is generally not recommended.

PHP has two types of connecting operators (logical operators, and boolean operators):

  Logical Operators Boolean Operator
AND - meaning and &&
OR - meaning or ||

The difference between these is the order in which they are executed. In most cases, you would want to use a boolean operator like &&, or ||.

Let’s take a look at a few examples:

// Logical operators have lower precedence:
$f = false or true;

// is executed like this:
($f = false) or true;


// Boolean operators have higher precedence:
$f = false || true;

// is executed like this:
$f = (false || true);

Logical Operators are used for Control-Flow

One case where you explicitly want to use logical operators is for control-flow such as this:

$x === 5
    or die('$x must be 5.');

// Instead of
if ($x !== 5) {
    die('$x must be 5.');
}

Since die introduces problems of its own, f.e. it makes our code hardly testable, and prevents any kind of more sophisticated error handling; you probably do not want to use this in real-world code. Unfortunately, logical operators cannot be combined with throw at this point:

// The following is currently a parse error.
$x === 5
    or throw new RuntimeException('$x must be 5.');

These limitations lead to logical operators rarely being of use in current PHP code.

Loading history...
189
190
    $sql = $this->prefixReplace($query);
191
//    $sql = $query;
0 ignored issues
show
Unused Code Comprehensibility introduced by
52% 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...
192
//    if (strpos($sql, '{{') !== false) {
193
//      foreach ($this->schema()->getSnTables() as $tableName) {
194
//        $sql = str_replace("{{{$tableName}}}", $this->db_prefix . $tableName, $sql);
195
//      }
196
//    }
197
198
    if ($config->debug) {
199
      $numqueries++;
200
      $arr = debug_backtrace();
201
      $file = end(explode('/', $arr[0]['file']));
202
      $line = $arr[0]['line'];
203
      $debug->add("<tr><th>Query $numqueries: </th><th>$query</th><th>$file($line)</th><th>$table</th><th>$fetch</th></tr>");
204
    }
205
206
    if (defined('DEBUG_SQL_COMMENT')) {
207
      $backtrace = debug_backtrace();
208
      $sql_comment = $debug->compact_backtrace($backtrace, defined('DEBUG_SQL_COMMENT_LONG'));
209
210
      $sql_commented = '/* ' . implode("<br />", $sql_comment) . '<br /> */ ' . preg_replace("/\s+/", ' ', $sql);
211
      if (defined('DEBUG_SQL_ONLINE')) {
212
        $debug->warning($sql_commented, 'SQL Debug', LOG_DEBUG_SQL);
213
      }
214
215
      if (defined('DEBUG_SQL_ERROR')) {
216
        array_unshift($sql_comment, preg_replace("/\s+/", ' ', $sql));
217
        $debug->add_to_array($sql_comment);
218
        // $debug->add_to_array($sql_comment . preg_replace("/\s+/", ' ', $sql));
0 ignored issues
show
Unused Code Comprehensibility introduced by
62% 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...
219
      }
220
      $sql = $sql_commented;
221
    }
222
223
    set_error_handler([$this, 'handlerQueryWarning']);
224
    $sqlquery = $this->db_sql_query($sql) or $debug->error(db_error() . "<br />$sql<br />", 'SQL Error');
0 ignored issues
show
Comprehensibility Best Practice introduced by
Using logical operators such as or instead of || is generally not recommended.

PHP has two types of connecting operators (logical operators, and boolean operators):

  Logical Operators Boolean Operator
AND - meaning and &&
OR - meaning or ||

The difference between these is the order in which they are executed. In most cases, you would want to use a boolean operator like &&, or ||.

Let’s take a look at a few examples:

// Logical operators have lower precedence:
$f = false or true;

// is executed like this:
($f = false) or true;


// Boolean operators have higher precedence:
$f = false || true;

// is executed like this:
$f = (false || true);

Logical Operators are used for Control-Flow

One case where you explicitly want to use logical operators is for control-flow such as this:

$x === 5
    or die('$x must be 5.');

// Instead of
if ($x !== 5) {
    die('$x must be 5.');
}

Since die introduces problems of its own, f.e. it makes our code hardly testable, and prevents any kind of more sophisticated error handling; you probably do not want to use this in real-world code. Unfortunately, logical operators cannot be combined with throw at this point:

// The following is currently a parse error.
$x === 5
    or throw new RuntimeException('$x must be 5.');

These limitations lead to logical operators rarely being of use in current PHP code.

Loading history...
225
    restore_error_handler();
226
227
    return $fetch ? $this->db_fetch($sqlquery) : $sqlquery;
0 ignored issues
show
Bug introduced by
It seems like $sqlquery can also be of type boolean; however, parameter $query_result of DBAL\db_mysql::db_fetch() does only seem to accept mysqli_result, 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

227
    return $fetch ? $this->db_fetch(/** @scrutinizer ignore-type */ $sqlquery) : $sqlquery;
Loading history...
228
  }
229
230
  public function doQueryFast($query, $fetch = false) {
231
    $sql = $this->prefixReplace($query);
232
233
    set_error_handler([$this, 'handlerQueryWarning']);
234
    $sqlquery = $this->db_sql_query($sql) or SN::$debug->error(db_error() . "<br />$sql<br />", 'SQL Error');
0 ignored issues
show
Comprehensibility Best Practice introduced by
Using logical operators such as or instead of || is generally not recommended.

PHP has two types of connecting operators (logical operators, and boolean operators):

  Logical Operators Boolean Operator
AND - meaning and &&
OR - meaning or ||

The difference between these is the order in which they are executed. In most cases, you would want to use a boolean operator like &&, or ||.

Let’s take a look at a few examples:

// Logical operators have lower precedence:
$f = false or true;

// is executed like this:
($f = false) or true;


// Boolean operators have higher precedence:
$f = false || true;

// is executed like this:
$f = (false || true);

Logical Operators are used for Control-Flow

One case where you explicitly want to use logical operators is for control-flow such as this:

$x === 5
    or die('$x must be 5.');

// Instead of
if ($x !== 5) {
    die('$x must be 5.');
}

Since die introduces problems of its own, f.e. it makes our code hardly testable, and prevents any kind of more sophisticated error handling; you probably do not want to use this in real-world code. Unfortunately, logical operators cannot be combined with throw at this point:

// The following is currently a parse error.
$x === 5
    or throw new RuntimeException('$x must be 5.');

These limitations lead to logical operators rarely being of use in current PHP code.

Loading history...
235
    restore_error_handler();
236
237
    return $fetch ? $this->db_fetch($sqlquery) : $sqlquery;
0 ignored issues
show
Bug introduced by
It seems like $sqlquery can also be of type boolean; however, parameter $query_result of DBAL\db_mysql::db_fetch() does only seem to accept mysqli_result, 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

237
    return $fetch ? $this->db_fetch(/** @scrutinizer ignore-type */ $sqlquery) : $sqlquery;
Loading history...
238
  }
239
240
  /**
241
   * @param string $query
242
   * @param bool   $skip_query_check
243
   *
244
   * @return DbMysqliResultIterator
245
   */
246
  public function selectIterator($query, $skip_query_check = false) {
247
    return new DbMysqliResultIterator($this->doquery($query, '', false, $skip_query_check));
248
  }
249
250
  /**
251
   * @param string $query
252
   * @param bool   $skip_query_check
253
   *
254
   * @return int|null
255
   */
256
  public function selectValue($query, $skip_query_check = false) {
257
    $row = $this->doquery($query, '', true, $skip_query_check);
258
259
    return !empty($row) ? intval(reset($row)) : null;
260
  }
261
262
  /**
263
   * @param \DBAL\DbQuery $dbQuery
264
   *
265
   * @return array|null
266
   */
267
  public function dbqSelectAndFetch(\DBAL\DbQuery $dbQuery) {
268
    return $this->doquery($dbQuery->select(), true);
269
  }
270
271
272
  public function security_watch_user_queries($query) {
273
    // TODO Заменить это на новый логгер
274
    global $config, $is_watching, $user, $debug;
0 ignored issues
show
Compatibility Best Practice introduced by
Use of global functionality is not recommended; it makes your code harder to test, and less reusable.

Instead of relying on global state, we recommend one of these alternatives:

1. Pass all data via parameters

function myFunction($a, $b) {
    // Do something
}

2. Create a class that maintains your state

class MyClass {
    private $a;
    private $b;

    public function __construct($a, $b) {
        $this->a = $a;
        $this->b = $b;
    }

    public function myFunction() {
        // Do something
    }
}
Loading history...
275
276
    if (!$is_watching && $config->game_watchlist_array && in_array($user['id'], $config->game_watchlist_array)) {
277
      if (!preg_match('/^(select|commit|rollback|start transaction)/i', $query)) {
278
        $is_watching = true;
279
        $msg = "\$query = \"{$query}\"\n\r";
280
        if (!empty($_POST)) {
281
          $msg .= "\n\r" . dump($_POST, '$_POST');
282
        }
283
        if (!empty($_GET)) {
284
          $msg .= "\n\r" . dump($_GET, '$_GET');
285
        }
286
        $debug->warning($msg, "Watching user {$user['id']}", 399, array('base_dump' => true));
287
        $is_watching = false;
288
      }
289
    }
290
  }
291
292
293
  public function security_query_check_bad_words($query) {
294
    global $user, $dm_change_legit, $mm_change_legit;
0 ignored issues
show
Compatibility Best Practice introduced by
Use of global functionality is not recommended; it makes your code harder to test, and less reusable.

Instead of relying on global state, we recommend one of these alternatives:

1. Pass all data via parameters

function myFunction($a, $b) {
    // Do something
}

2. Create a class that maintains your state

class MyClass {
    private $a;
    private $b;

    public function __construct($a, $b) {
        $this->a = $a;
        $this->b = $b;
    }

    public function myFunction() {
        // Do something
    }
}
Loading history...
295
296
    switch (true) {
297
      case stripos($query, 'RUNCATE TABL') != false:
0 ignored issues
show
Bug Best Practice introduced by
It seems like you are loosely comparing stripos($query, 'RUNCATE TABL') of type integer to the boolean false. If you are specifically checking for non-zero, consider using something more explicit like > 0 or !== 0 instead.
Loading history...
298
      case stripos($query, 'ROP TABL') != false:
0 ignored issues
show
Bug Best Practice introduced by
It seems like you are loosely comparing stripos($query, 'ROP TABL') of type integer to the boolean false. If you are specifically checking for non-zero, consider using something more explicit like > 0 or !== 0 instead.
Loading history...
299
      case stripos($query, 'ENAME TABL') != false:
0 ignored issues
show
Bug Best Practice introduced by
It seems like you are loosely comparing stripos($query, 'ENAME TABL') of type integer to the boolean false. If you are specifically checking for non-zero, consider using something more explicit like > 0 or !== 0 instead.
Loading history...
300
      case stripos($query, 'REATE DATABAS') != false:
0 ignored issues
show
Bug Best Practice introduced by
It seems like you are loosely comparing stripos($query, 'REATE DATABAS') of type integer to the boolean false. If you are specifically checking for non-zero, consider using something more explicit like > 0 or !== 0 instead.
Loading history...
301
      case stripos($query, 'REATE TABL') != false:
0 ignored issues
show
Bug Best Practice introduced by
It seems like you are loosely comparing stripos($query, 'REATE TABL') of type integer to the boolean false. If you are specifically checking for non-zero, consider using something more explicit like > 0 or !== 0 instead.
Loading history...
302
      case stripos($query, 'ET PASSWOR') != false:
0 ignored issues
show
Bug Best Practice introduced by
It seems like you are loosely comparing stripos($query, 'ET PASSWOR') of type integer to the boolean false. If you are specifically checking for non-zero, consider using something more explicit like > 0 or !== 0 instead.
Loading history...
303
      case stripos($query, 'EOAD DAT') != false:
0 ignored issues
show
Bug Best Practice introduced by
It seems like you are loosely comparing stripos($query, 'EOAD DAT') of type integer to the boolean false. If you are specifically checking for non-zero, consider using something more explicit like > 0 or !== 0 instead.
Loading history...
304
      case stripos($query, 'RPG_POINTS') != false && stripos(trim($query), 'UPDATE ') === 0 && !$dm_change_legit:
0 ignored issues
show
Bug Best Practice introduced by
It seems like you are loosely comparing stripos($query, 'RPG_POINTS') of type integer to the boolean false. If you are specifically checking for non-zero, consider using something more explicit like > 0 or !== 0 instead.
Loading history...
305
      case stripos($query, 'METAMATTER') != false && stripos(trim($query), 'UPDATE ') === 0 && !$mm_change_legit:
0 ignored issues
show
Bug Best Practice introduced by
It seems like you are loosely comparing stripos($query, 'METAMATTER') of type integer to the boolean false. If you are specifically checking for non-zero, consider using something more explicit like > 0 or !== 0 instead.
Loading history...
306
      case stripos($query, 'AUTHLEVEL') != false && $user['authlevel'] < 3 && stripos($query, 'SELECT') !== 0:
0 ignored issues
show
Bug Best Practice introduced by
It seems like you are loosely comparing stripos($query, 'AUTHLEVEL') of type integer to the boolean false. If you are specifically checking for non-zero, consider using something more explicit like > 0 or !== 0 instead.
Loading history...
307
        $report = "Hacking attempt (" . date("d.m.Y H:i:s") . " - [" . time() . "]):\n";
308
        $report .= ">Database Inforamation\n";
309
        $report .= "\tID - " . $user['id'] . "\n";
310
        $report .= "\tUser - " . $user['username'] . "\n";
311
        $report .= "\tAuth level - " . $user['authlevel'] . "\n";
312
        $report .= "\tAdmin Notes - " . $user['adminNotes'] . "\n";
313
        $report .= "\tCurrent Planet - " . $user['current_planet'] . "\n";
314
        $report .= "\tUser IP - " . $user['user_lastip'] . "\n";
315
        $report .= "\tUser IP at Reg - " . $user['ip_at_reg'] . "\n";
316
        $report .= "\tUser Agent- " . $_SERVER['HTTP_USER_AGENT'] . "\n";
317
        $report .= "\tCurrent Page - " . $user['current_page'] . "\n";
318
        $report .= "\tRegister Time - " . $user['register_time'] . "\n";
319
        $report .= "\n";
320
321
        $report .= ">Query Information\n";
322
        $report .= "\tQuery - " . $query . "\n";
323
        $report .= "\n";
324
325
        $report .= ">\$_SERVER Information\n";
326
        $report .= "\tIP - " . $_SERVER['REMOTE_ADDR'] . "\n";
327
        $report .= "\tHost Name - " . $_SERVER['HTTP_HOST'] . "\n";
328
        $report .= "\tUser Agent - " . $_SERVER['HTTP_USER_AGENT'] . "\n";
329
        $report .= "\tRequest Method - " . $_SERVER['REQUEST_METHOD'] . "\n";
330
        $report .= "\tCame From - " . $_SERVER['HTTP_REFERER'] . "\n";
331
        $report .= "\tPage is - " . $_SERVER['SCRIPT_NAME'] . "\n";
332
        $report .= "\tUses Port - " . $_SERVER['REMOTE_PORT'] . "\n";
333
        $report .= "\tServer Protocol - " . $_SERVER['SERVER_PROTOCOL'] . "\n";
334
335
        $report .= "\n--------------------------------------------------------------------------------------------------\n";
336
337
        $fp = fopen(SN_ROOT_PHYSICAL . 'badqrys.txt', 'a');
338
        fwrite($fp, $report);
0 ignored issues
show
Bug introduced by
It seems like $fp can also be of type false; however, parameter $handle of fwrite() does only seem to accept resource, 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

338
        fwrite(/** @scrutinizer ignore-type */ $fp, $report);
Loading history...
339
        fclose($fp);
0 ignored issues
show
Bug introduced by
It seems like $fp can also be of type false; however, parameter $handle of fclose() does only seem to accept resource, 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

339
        fclose(/** @scrutinizer ignore-type */ $fp);
Loading history...
340
341
        $message = 'Привет, я не знаю то, что Вы пробовали сделать, но команда, которую Вы только послали базе данных, не выглядела очень дружественной и она была заблокированна.<br /><br />Ваш IP, и другие данные переданны администрации сервера. Удачи!.';
342
        die($message);
0 ignored issues
show
Best Practice introduced by
Using exit here is not recommended.

In general, usage of exit should be done with care and only when running in a scripting context like a CLI script.

Loading history...
343
      break;
344
    }
345
  }
346
347
  public function mysql_get_table_list() {
348
    return $this->db_sql_query('SHOW TABLES;');
349
  }
350
351
  public function mysql_get_innodb_status() {
352
    return $this->db_sql_query('SHOW ENGINE INNODB STATUS;');
353
  }
354
355
  /**
356
   * @param string $tableName_unsafe
357
   *
358
   * @return array[]
359
   */
360
  public function mysql_get_fields($tableName_unsafe) {
361
    $result = [];
362
363
    $prefixedTableName_safe = $this->db_escape($this->db_prefix . $tableName_unsafe);
364
    $q1 = $this->db_sql_query("SHOW FULL COLUMNS FROM `{$prefixedTableName_safe}`;");
365
    while ($r1 = db_fetch($q1)) {
366
      $result[$r1['Field']] = $r1;
367
    }
368
369
    return $result;
370
  }
371
372
  /**
373
   * @param string $tableName_unsafe
374
   *
375
   * @return array[]
376
   */
377
  public function mysql_get_indexes($tableName_unsafe) {
378
    $result = [];
379
380
    $prefixedTableName_safe = $this->db_escape($this->db_prefix . $tableName_unsafe);
381
    $q1 = $this->db_sql_query("SHOW INDEX FROM {$prefixedTableName_safe};");
382
    while ($r1 = db_fetch($q1)) {
383
      $indexName = $r1['Key_name'];
384
385
      $result[$indexName]['name'] = $r1['Key_name'];
386
      $result[$indexName]['signature'][] = $r1['Column_name'];
387
      $result[$indexName]['fields'][$r1['Column_name']] = $r1;
388
    }
389
390
    foreach ($result as &$indexDescription) {
391
      $indexDescription['signature'] = implode(',', $indexDescription['signature']);
392
    }
393
394
    return $result;
395
  }
396
397
  /**
398
   * @param string $tableName_unsafe
399
   *
400
   * @return array[]
401
   */
402
  public function mysql_get_constraints($tableName_unsafe) {
403
    $result = [];
404
405
    $prefixedTableName_safe = $this->db_escape($this->db_prefix . $tableName_unsafe);
406
407
    $q1 = $this->db_sql_query("SELECT * FROM `information_schema`.`KEY_COLUMN_USAGE` WHERE `TABLE_SCHEMA` = '" . db_escape(SN::$db_name) . "' AND `TABLE_NAME` = '{$prefixedTableName_safe}' AND `REFERENCED_TABLE_NAME` IS NOT NULL;");
408
    while ($r1 = db_fetch($q1)) {
409
      $indexName = $r1['CONSTRAINT_NAME'];
410
411
      $table_referenced = str_replace($this->db_prefix, '', $r1['REFERENCED_TABLE_NAME']);
412
413
      $result[$indexName]['name'] = $indexName;
414
      $result[$indexName]['signature'][] = "{$r1['COLUMN_NAME']}=>{$table_referenced}.{$r1['REFERENCED_COLUMN_NAME']}";
415
      $r1['REFERENCED_TABLE_NAME'] = $table_referenced;
416
      $r1['TABLE_NAME'] = $tableName_unsafe;
417
      $result[$indexName]['fields'][$r1['COLUMN_NAME']] = $r1;
418
    }
419
420
    foreach ($result as &$constraint) {
421
      $constraint['signature'] = implode(',', $constraint['signature']);
422
    }
423
424
    return $result;
425
  }
426
427
428
  public function db_sql_query($query_string) {
429
    $microtime = microtime(true);
430
    $result = $this->driver->mysql_query($query_string);
431
    $this->time_mysql_total += microtime(true) - $microtime;
432
433
    return $result;
434
//    return $this->driver->mysql_query($query_string);
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...
435
  }
436
437
  /**
438
   * @param mysqli_result $query_result
439
   *
440
   * @return array|null
441
   */
442
  public function db_fetch(&$query_result) {
443
    $microtime = microtime(true);
444
    $result = $this->driver->mysql_fetch_assoc($query_result);
445
    $this->time_mysql_total += microtime(true) - $microtime;
446
447
    return $result;
448
//    return $this->driver->mysql_fetch_assoc($query);
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...
449
  }
450
451
  public function db_fetch_row(&$query) {
452
    return $this->driver->mysql_fetch_row($query);
453
  }
454
455
  public function db_escape($unescaped_string) {
456
    return $this->driver->mysql_real_escape_string($unescaped_string);
457
  }
458
459
  public function driver_disconnect() {
460
    return $this->driver->mysql_close_link();
461
  }
462
463
  public function db_error() {
464
    return $this->driver->mysql_error();
465
  }
466
467
  /**
468
   * @return int|string
469
   */
470
  public function db_insert_id() {
471
    return $this->driver->mysql_insert_id();
472
  }
473
474
  public function db_num_rows(&$result) {
475
    return $this->driver->mysql_num_rows($result);
476
  }
477
478
  public function db_affected_rows() {
479
    return $this->driver->mysql_affected_rows();
480
  }
481
482
  public function db_get_client_info() {
483
    return $this->driver->mysql_get_client_info();
484
  }
485
486
  public function db_get_server_info() {
487
    return $this->driver->mysql_get_server_info();
488
  }
489
490
  public function db_get_host_info() {
491
    return $this->driver->mysql_get_host_info();
492
  }
493
494
  public function db_get_server_stat() {
495
    return $this->driver->mysql_stat();
496
  }
497
498
}
499