Completed
Push — master ( 1be798...5156a7 )
by Lars
03:46
created

Prepare::interpolateQuery()   A

Complexity

Conditions 3
Paths 2

Size

Total Lines 23
Code Lines 14

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 16
CRAP Score 3

Importance

Changes 1
Bugs 0 Features 1
Metric Value
c 1
b 0
f 1
dl 0
loc 23
ccs 16
cts 16
cp 1
rs 9.0856
cc 3
eloc 14
nc 2
nop 0
crap 3
1
<?php
2
3
namespace voku\db;
4
5
use voku\helper\Bootup;
6
7
/**
8
 * Prepare: this handles the prepare-statement from "DB"-Class
9
 *
10
 * @package   voku\db
11
 */
12
final class Prepare extends \mysqli_stmt
13
{
14
15
  /**
16
   * @var string $_sql - the unchanged query string provided to the constructor
17
   */
18
  private $_sql;
19
20
  /**
21
   * @var string $_sql_with_bound_parameters - the query string with bound parameters interpolated
22
   */
23
  private $_sql_with_bound_parameters;
24
25
  /**
26
   * @var bool
27
   */
28
  private $_use_bound_parameters_interpolated = false;
29
30
  /**
31
   * @var array $_boundParams - array of arrays containing values that have been bound to the query as parameters
32
   */
33
  private $_boundParams = array();
34
35
  /**
36
   * @var DB
37
   */
38
  private $_db;
39
40
  /**
41
   * @var Debug
42
   */
43
  private $_debug;
44
45
  /**
46
   * Prepare constructor.
47
   *
48
   * @param DB     $db
49
   * @param string $query
50
   */
51 7
  public function __construct(DB $db, $query)
52
  {
53 7
    $this->_db = $db;
54 7
    $this->_debug = $db->getDebugger();
55
56 7
    parent::__construct($db->getLink(), $query);
57
58 7
    $this->prepare($query);
59 7
  }
60
61
  /**
62
   * Prepare destructor.
63
   */
64 7
  public function __destruct()
65
  {
66 7
    $this->close();
67 7
  }
68
69
  /**
70
   * Combines the values stored in $this->boundParams into one array suitable for pushing as the input arguments to
71
   * parent::bind_param when used with call_user_func_array
72
   *
73
   * @return array
74
   */
75 5
  private function _buildArguments()
76
  {
77 5
    $arguments = array();
78 5
    $arguments[0] = '';
79
80 5
    foreach ($this->_boundParams as $param) {
81 5
      $arguments[0] .= $param['type'];
82 5
      $arguments[] = &$param['value'];
83 5
    }
84
85 5
    return $arguments;
86
  }
87
88
  /**
89
   * Escapes the supplied value.
90
   *
91
   * @param mixed  $value
92
   * @param string $type (one of 'i', 'b', 's', 'd')
93
   *
94
   * @return array 0 => "$value" escaped and 1 => "$valueForSqlWithBoundParameters" for insertion into the interpolated
95
   *               query string
96
   */
97 5
  private function _prepareValue(&$value, $type)
98
  {
99
    /** @noinspection ReferenceMismatchInspection */
100 5
    $value = $this->_db->escape($value);
101
102 5
    if ('s' === $type) {
103 4
      $valueForSqlWithBoundParameters = "'" . $value . "'";
104 4
    } else {
105 1
      $valueForSqlWithBoundParameters = $value;
106
    }
107
108 5
    return array($value, $valueForSqlWithBoundParameters);
109
  }
110
111
  /**
112
   * @return int
113
   */
114
  public function affected_rows()
115
  {
116
    return $this->affected_rows;
117
  }
118
119
  /**
120
   * This is a wrapper for "bind_param" what binds variables to a prepared statement as parameters. If you use this
121
   * wrapper, you can debug your query with e.g. "$this->get_sql_with_bound_parameters()".
122
   *
123
   * @param string $types <strong>i<strong> corresponding variable has type integer<br />
124
   *                      <strong>d</strong> corresponding variable has type double<br />
125
   *                      <strong>s</strong> corresponding variable has type string<br />
126
   *                      <strong>b</strong> corresponding variable is a blob and will be sent in packets
127
   *
128
   * INFO: We have to explicitly declare all parameters as references, otherwise it does not seem possible to pass them
129
   * on without losing the reference property.
130
   *
131
   * @param null   $v1
132
   * @param null   $v2
133
   * @param null   $v3
134
   * @param null   $v4
135
   * @param null   $v5
136
   * @param null   $v6
137
   * @param null   $v7
138
   * @param null   $v8
139
   * @param null   $v9
140
   * @param null   $v10
141
   * @param null   $v11
142
   * @param null   $v12
143
   * @param null   $v13
144
   * @param null   $v14
145
   * @param null   $v15
146
   * @param null   $v16
147
   * @param null   $v17
148
   * @param null   $v18
149
   * @param null   $v19
150
   * @param null   $v20
151
   * @param null   $v21
152
   * @param null   $v22
153
   * @param null   $v23
154
   * @param null   $v24
155
   * @param null   $v25
156
   * @param null   $v26
157
   * @param null   $v27
158
   * @param null   $v28
159
   * @param null   $v29
160
   * @param null   $v30
161
   * @param null   $v31
162
   * @param null   $v32
163
   * @param null   $v33
164
   * @param null   $v34
165
   * @param null   $v35
166
   *
167
   * @return mixed
168
   */
169 5
  public function bind_param_debug($types, &$v1 = null, &$v2 = null, &$v3 = null, &$v4 = null, &$v5 = null, &$v6 = null, &$v7 = null, &$v8 = null, &$v9 = null, &$v10 = null, &$v11 = null, &$v12 = null, &$v13 = null, &$v14 = null, &$v15 = null, &$v16 = null, &$v17 = null, &$v18 = null, &$v19 = null, &$v20 = null, &$v21 = null, &$v22 = null, &$v23 = null, &$v24 = null, &$v25 = null, &$v26 = null, &$v27 = null, &$v28 = null, &$v29 = null, &$v30 = null, &$v31 = null, &$v32 = null, &$v33 = null, &$v34 = null, &$v35 = null)
0 ignored issues
show
Unused Code introduced by
The parameter $v1 is not used and could be removed.

This check looks from 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 $v2 is not used and could be removed.

This check looks from 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 $v3 is not used and could be removed.

This check looks from 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 $v4 is not used and could be removed.

This check looks from 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 $v5 is not used and could be removed.

This check looks from 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 $v6 is not used and could be removed.

This check looks from 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 $v7 is not used and could be removed.

This check looks from 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 $v8 is not used and could be removed.

This check looks from 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 $v9 is not used and could be removed.

This check looks from 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 $v10 is not used and could be removed.

This check looks from 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 $v11 is not used and could be removed.

This check looks from 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 $v12 is not used and could be removed.

This check looks from 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 $v13 is not used and could be removed.

This check looks from 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 $v14 is not used and could be removed.

This check looks from 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 $v15 is not used and could be removed.

This check looks from 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 $v16 is not used and could be removed.

This check looks from 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 $v17 is not used and could be removed.

This check looks from 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 $v18 is not used and could be removed.

This check looks from 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 $v19 is not used and could be removed.

This check looks from 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 $v20 is not used and could be removed.

This check looks from 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 $v21 is not used and could be removed.

This check looks from 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 $v22 is not used and could be removed.

This check looks from 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 $v23 is not used and could be removed.

This check looks from 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 $v24 is not used and could be removed.

This check looks from 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 $v25 is not used and could be removed.

This check looks from 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 $v26 is not used and could be removed.

This check looks from 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 $v27 is not used and could be removed.

This check looks from 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 $v28 is not used and could be removed.

This check looks from 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 $v29 is not used and could be removed.

This check looks from 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 $v30 is not used and could be removed.

This check looks from 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 $v31 is not used and could be removed.

This check looks from 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 $v32 is not used and could be removed.

This check looks from 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 $v33 is not used and could be removed.

This check looks from 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 $v34 is not used and could be removed.

This check looks from 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 $v35 is not used and could be removed.

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

Loading history...
170
  {
171 5
    $this->_use_bound_parameters_interpolated = true;
172
173
    // debug_backtrace returns arguments by reference, see comments at http://php.net/manual/de/function.func-get-args.php
174 5
    if (Bootup::is_php('5.4')) {
175 5
      $trace = debug_backtrace(DEBUG_BACKTRACE_PROVIDE_OBJECT, 1);
176 5
    } else {
177
      $trace = debug_backtrace();
178
    }
179
180 5
    $args = &$trace[0]['args'];
181 5
    $types = str_split($types);
182
183 5
    $args_count = count($args) - 1;
184 5
    $types_count = count($types);
185
186 5
    if ($args_count !== $types_count) {
187
      trigger_error('Number of variables doesn\'t match number of parameters in prepared statement', E_WARNING);
188
189
      return false;
190
    }
191
192 5
    $arg = 1;
193 5
    foreach ($types as $typeInner) {
194 5
      $val = &$args[$arg];
195 5
      $this->_boundParams[] = array(
196 5
          'type'  => $typeInner,
197 5
          'value' => &$val,
198
      );
199 5
      $arg++;
200 5
    }
201
202 5
    return true;
203
  }
204
205
  /**
206
   * Executes a prepared Query
207
   *
208
   * @link  http://php.net/manual/en/mysqli-stmt.execute.php
209
   * @return bool         "int" (insert_id) by "<b>INSERT / REPLACE</b>"-queries<br />
210
   *                      "int" (affected_rows) by "<b>UPDATE / DELETE</b>"-queries<br />
211
   *                      "true" by e.g. "SELECT"-queries<br />
212
   *                      "false" on error
213
   * @since 5.0
214
   */
215 7
  public function execute()
216
  {
217 7
    if ($this->_use_bound_parameters_interpolated === true) {
218 5
      $this->interpolateQuery();
219 5
      call_user_func_array(array('parent', 'bind_param'), $this->_buildArguments());
220 5
    }
221
222 7
    $query_start_time = microtime(true);
223 7
    $result = parent::execute();
224 7
    $query_duration = microtime(true) - $query_start_time;
225
226 7
    if ($result === true) {
227
228
      // "INSERT" || "REPLACE"
0 ignored issues
show
Unused Code Comprehensibility introduced by
50% 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...
229 5 View Code Duplication
      if (preg_match('/^\s*"?(INSERT|REPLACE)\s+/i', $this->_sql)) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

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

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

Loading history...
230 3
        $insert_id = (int)$this->insert_id;
231 3
        $this->_debug->logQuery($this->_sql_with_bound_parameters, $query_duration, $insert_id);
232
233 3
        return $insert_id;
0 ignored issues
show
Bug Best Practice introduced by
The return type of return $insert_id; (integer) is incompatible with the return type of the parent method mysqli_stmt::execute of type boolean.

If you return a value from a function or method, it should be a sub-type of the type that is given by the parent type f.e. an interface, or abstract method. This is more formally defined by the Lizkov substitution principle, and guarantees that classes that depend on the parent type can use any instance of a child type interchangably. This principle also belongs to the SOLID principles for object oriented design.

Let’s take a look at an example:

class Author {
    private $name;

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

    public function getName() {
        return $this->name;
    }
}

abstract class Post {
    public function getAuthor() {
        return 'Johannes';
    }
}

class BlogPost extends Post {
    public function getAuthor() {
        return new Author('Johannes');
    }
}

class ForumPost extends Post { /* ... */ }

function my_function(Post $post) {
    echo strtoupper($post->getAuthor());
}

Our function my_function expects a Post object, and outputs the author of the post. The base class Post returns a simple string and outputting a simple string will work just fine. However, the child class BlogPost which is a sub-type of Post instead decided to return an object, and is therefore violating the SOLID principles. If a BlogPost were passed to my_function, PHP would not complain, but ultimately fail when executing the strtoupper call in its body.

Loading history...
234
      }
235
236
      // "UPDATE" || "DELETE"
0 ignored issues
show
Unused Code Comprehensibility introduced by
50% 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...
237 2 View Code Duplication
      if (preg_match('/^\s*"?(UPDATE|DELETE)\s+/i', $this->_sql)) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

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

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

Loading history...
238 2
        $affected_rows = (int)$this->affected_rows;
239 2
        $this->_debug->logQuery($this->_sql_with_bound_parameters, $query_duration, $affected_rows);
240
241 2
        return $affected_rows;
0 ignored issues
show
Bug Best Practice introduced by
The return type of return $affected_rows; (integer) is incompatible with the return type of the parent method mysqli_stmt::execute of type boolean.

If you return a value from a function or method, it should be a sub-type of the type that is given by the parent type f.e. an interface, or abstract method. This is more formally defined by the Lizkov substitution principle, and guarantees that classes that depend on the parent type can use any instance of a child type interchangably. This principle also belongs to the SOLID principles for object oriented design.

Let’s take a look at an example:

class Author {
    private $name;

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

    public function getName() {
        return $this->name;
    }
}

abstract class Post {
    public function getAuthor() {
        return 'Johannes';
    }
}

class BlogPost extends Post {
    public function getAuthor() {
        return new Author('Johannes');
    }
}

class ForumPost extends Post { /* ... */ }

function my_function(Post $post) {
    echo strtoupper($post->getAuthor());
}

Our function my_function expects a Post object, and outputs the author of the post. The base class Post returns a simple string and outputting a simple string will work just fine. However, the child class BlogPost which is a sub-type of Post instead decided to return an object, and is therefore violating the SOLID principles. If a BlogPost were passed to my_function, PHP would not complain, but ultimately fail when executing the strtoupper call in its body.

Loading history...
242
      }
243
244
      // "SELECT"
245 View Code Duplication
      if (preg_match('/^\s*"?(SELECT)\s+/i', $this->_sql)) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

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

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

Loading history...
246
        $num_rows = (int)$this->num_rows;
247
        $this->_debug->logQuery($this->_sql_with_bound_parameters, $query_duration, $num_rows);
248
249
        return true;
250
      }
251
252
      // log the ? query
253
      $this->_debug->logQuery($this->_sql_with_bound_parameters, $query_duration, 0);
254
255
      return true;
256
    }
257
258
    // log the error query
259 2
    $this->_debug->logQuery($this->_sql_with_bound_parameters, $query_duration, 0, true);
260
261 2
    return $this->queryErrorHandling($this->error, $this->_sql_with_bound_parameters);
0 ignored issues
show
Bug Compatibility introduced by
The expression $this->queryErrorHandlin...with_bound_parameters); of type integer|boolean adds the type integer to the return on line 261 which is incompatible with the return type of the parent method mysqli_stmt::execute of type boolean.
Loading history...
262
  }
263
264
  /**
265
   * Prepare an SQL statement for execution
266
   *
267
   * @link  http://php.net/manual/en/mysqli-stmt.prepare.php
268
   *
269
   * @param string $query <p>
270
   *                      The query, as a string. It must consist of a single SQL statement.
271
   *                      </p>
272
   *                      <p>
273
   *                      You can include one or more parameter markers in the SQL statement by
274
   *                      embedding question mark (?) characters at the
275
   *                      appropriate positions.
276
   *                      </p>
277
   *                      <p>
278
   *                      You should not add a terminating semicolon or \g
279
   *                      to the statement.
280
   *                      </p>
281
   *                      <p>
282
   *                      The markers are legal only in certain places in SQL statements.
283
   *                      For example, they are allowed in the VALUES() list of an INSERT statement
284
   *                      (to specify column values for a row), or in a comparison with a column in
285
   *                      a WHERE clause to specify a comparison value.
286
   *                      </p>
287
   *                      <p>
288
   *                      However, they are not allowed for identifiers (such as table or column names),
289
   *                      in the select list that names the columns to be returned by a SELECT statement),
290
   *                      or to specify both operands of a binary operator such as the =
291
   *                      equal sign. The latter restriction is necessary because it would be impossible
292
   *                      to determine the parameter type. In general, parameters are legal only in Data
293
   *                      Manipulation Language (DML) statements, and not in Data Definition Language
294
   *                      (DDL) statements.
295
   *                      </p>
296
   *
297
   * @return bool false on error
298
   * @since 5.0
299
   */
300 7
  public function prepare($query)
301
  {
302 7
    $this->_sql = $query;
303 7
    $this->_sql_with_bound_parameters = $query;
304
305 7
    if (!$this->_db->isReady()) {
306
      return false;
307
    }
308
309 7 View Code Duplication
    if (!$query || $query === '') {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

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

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

Loading history...
310
      $this->_debug->displayError('Can\'t prepare an empty Query', false);
311
312
      return false;
313
    }
314
315 7
    $bool = parent::prepare($query);
316
317 7
    if ($bool === false) {
318 2
      $this->_debug->displayError('Can\'t prepare Query: ' . $query . ' | ' . $this->error, false);
319 2
    }
320
321 7
    return true;
322
  }
323
324
  /**
325
   * Ger the bound parameters from sql-query as array, if you use the "$this->bind_param_debug()" method.
326
   *
327
   * @return array
328
   */
329
  public function get_bound_params()
330
  {
331
    return $this->_boundParams;
332
  }
333
334
  /**
335
   * @return string
336
   */
337
  public function get_sql()
338
  {
339
    return $this->_sql;
340
  }
341
342
  /**
343
   * Get the sql-query with bound parameters, if you use the "$this->bind_param_debug()" method.
344
   *
345
   * @return string
346
   */
347 4
  public function get_sql_with_bound_parameters()
348
  {
349 4
    return $this->_sql_with_bound_parameters;
350
  }
351
352
  /**
353
   * @return int
354
   */
355
  public function insert_id()
356
  {
357
    return $this->insert_id;
358
  }
359
360
  /**
361
   * Copies $this->_sql then replaces bound markers with associated values ($this->_sql is not modified
362
   * but the resulting query string is assigned to $this->sql_bound_parameters)
363
   *
364
   * @return string $testQuery - interpolated db query string
365
   */
366 5
  private function interpolateQuery()
367
  {
368 5
    $testQuery = $this->_sql;
369 5
    if ($this->_boundParams) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $this->_boundParams of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using ! empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
370 5
      foreach ($this->_boundParams as &$param) {
371 5
        $type = &$param['type'];
372 5
        $value = &$param['value'];
373 5
        $values = $this->_prepareValue($value, $type);
374
375
        // set new values
376 5
        $param['value'] = $values[0];
377
        // we need to replace the question mark "?" here
378 5
        $values[1] = str_replace('?', '###simple_mysqli__prepare_question_mark###', $values[1]);
379
        // build the query (only for debugging)
380 5
        $testQuery = preg_replace("/\?/", $values[1], $testQuery, 1);
381 5
      }
382 5
      unset($param);
383 5
      $testQuery = str_replace('###simple_mysqli__prepare_question_mark###', '?', $testQuery);
384 5
    }
385 5
    $this->_sql_with_bound_parameters = $testQuery;
386
387 5
    return $testQuery;
388
  }
389
390
  /**
391
   * Error-handling for the sql-query.
392
   *
393
   * @param string $errorMsg
394
   * @param string $sql
395
   *
396
   * @throws \Exception
397
   *
398
   * @return bool
399
   */
400 2 View Code Duplication
  private function queryErrorHandling($errorMsg, $sql)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

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

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

Loading history...
401
  {
402 2
    if ($errorMsg === 'DB server has gone away' || $errorMsg === 'MySQL server has gone away') {
403
      static $reconnectCounter;
404
405
      // exit if we have more then 3 "DB server has gone away"-errors
406
      if ($reconnectCounter > 3) {
407
        $this->_debug->mailToAdmin('SQL-Fatal-Error', $errorMsg . ":\n<br />" . $sql, 5);
408
        throw new \Exception($errorMsg);
409
      } else {
410
        $this->_debug->mailToAdmin('SQL-Error', $errorMsg . ":\n<br />" . $sql);
411
412
        // reconnect
413
        $reconnectCounter++;
414
        $this->_db->reconnect(true);
415
416
        // re-run the current query
417
        return $this->execute();
418
      }
419
    } else {
420 2
      $this->_debug->mailToAdmin('SQL-Warning', $errorMsg . ":\n<br />" . $sql);
421
422
      // this query returned an error, we must display it (only for dev) !!!
423 2
      $this->_debug->displayError($errorMsg . ' | ' . $sql);
424
    }
425
426 2
    return false;
427
  }
428
429
}
430