Completed
Push — work-fleets ( 1920ae...cfff9f )
by SuperNova.WS
07:02
created

DBStaticMessages::db_message_insert()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 15
Code Lines 12

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 2
Bugs 0 Features 0
Metric Value
cc 1
eloc 12
c 2
b 0
f 0
nc 1
nop 1
dl 0
loc 15
rs 9.4285
ccs 0
cts 15
cp 0
crap 2
1
<?php
2
3
class DBStaticMessages {
4
  public static $snMessageClassList = array(
5
    MSG_TYPE_NEW       => array(
6
      'name'       => 'new_message',
7
      'switchable' => false,
8
      'email'      => false,
9
    ),
10
    MSG_TYPE_ADMIN     => array(
11
      'name'       => 'msg_admin',
12
      'switchable' => false,
13
      'email'      => true,
14
    ),
15
    MSG_TYPE_PLAYER    => array(
16
      'name'       => 'mnl_joueur',
17
      'switchable' => false,
18
      'email'      => true,
19
    ),
20
    MSG_TYPE_ALLIANCE  => array(
21
      'name'       => 'mnl_alliance',
22
      'switchable' => false,
23
      'email'      => true,
24
    ),
25
    MSG_TYPE_SPY       => array(
26
      'name'       => 'mnl_spy',
27
      'switchable' => true,
28
      'email'      => true,
29
    ),
30
    MSG_TYPE_COMBAT    => array(
31
      'name'       => 'mnl_attaque',
32
      'switchable' => true,
33
      'email'      => true,
34
    ),
35
    MSG_TYPE_TRANSPORT => array(
36
      'name'       => 'mnl_transport',
37
      'switchable' => true,
38
      'email'      => true,
39
    ),
40
    MSG_TYPE_RECYCLE   => array(
41
      'name'       => 'mnl_exploit',
42
      'switchable' => true,
43
      'email'      => true,
44
    ),
45
    MSG_TYPE_EXPLORE   => array(
46
      'name'       => 'mnl_expedition',
47
      'switchable' => true,
48
      'email'      => true,
49
    ),
50
    //     97 => 'mnl_general',
0 ignored issues
show
Unused Code Comprehensibility introduced by
58% 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...
51
    MSG_TYPE_QUE       => array(
52
      'name'       => 'mnl_buildlist',
53
      'switchable' => true,
54
      'email'      => true,
55
    ),
56
    MSG_TYPE_OUTBOX    => array(
57
      'name'       => 'mnl_outbox',
58
      'switchable' => false,
59
      'email'      => false,
60
    ),
61
  );
62
  public static $snMessageGroup = array(
63
    'switchable' => array(MSG_TYPE_SPY, MSG_TYPE_COMBAT, MSG_TYPE_RECYCLE, MSG_TYPE_TRANSPORT, MSG_TYPE_EXPLORE, MSG_TYPE_QUE),
64
    'email'      => array(MSG_TYPE_SPY, MSG_TYPE_PLAYER, MSG_TYPE_ALLIANCE, MSG_TYPE_COMBAT, MSG_TYPE_RECYCLE, MSG_TYPE_TRANSPORT,
65
      MSG_TYPE_ADMIN, MSG_TYPE_EXPLORE, MSG_TYPE_QUE),
66
  );
67
68
  /**
69
   * @param mixed|array $owners
70
   * @param integer     $sender
71
   * @param integer     $timestamp
72
   * @param integer     $message_type
73
   * @param string      $from_unsafe
74
   * @param string      $subject_unsafe
75
   * @param string      $text_unsafe
76
   * @param bool        $force
77
   */
78
  public static function msg_send_simple_message($owners, $sender, $timestamp, $message_type, $from_unsafe, $subject_unsafe, $text_unsafe, $force = false) {
79
    global $user;
80
81
    if (!$owners) {
82
      return;
83
    }
84
85
    $timestamp = $timestamp ? $timestamp : SN_TIME_NOW;
86
    $sender = intval($sender);
87
    if (!is_array($owners)) {
88
      $owners = array($owners);
89
    }
90
91
    // TODO - check for valid message_type ?
92
    $message_class = static::$snMessageClassList[$message_type];
93
    $message_class_name = $message_class['name'];
94
95
    $text_safe = db_escape($text_unsafe);
0 ignored issues
show
Unused Code introduced by
$text_safe is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
96
97
    $message_class_name_total = static::$snMessageClassList[MSG_TYPE_NEW]['name'];
98
99
    if ($owners[0] == '*') {
100
      if ($user['authlevel'] < 3) {
101
        return false;
102
      }
103
      // TODO Добавить $timestamp - рассылка может быть и отсроченной
104
      // TODO Добавить $sender - рассылка может быть и от кого-то
105
      static::db_message_insert_all($message_type, $from_unsafe, $subject_unsafe, $text_unsafe);
106
      $owners = array();
107
    } else {
108
      $insert_values = array();
109
      foreach ($owners as $owner) {
110
        if ($user['id'] != $owner) {
111
          $owner_row = DBStaticUser::db_user_by_id($owner);
112
        } else {
113
          $owner_row = $user;
114
        }
115
        sys_user_options_unpack($owner_row);
116
117
        if ($force || !$message_class['switchable'] || $owner_row["opt_{$message_class_name}"]) {
118
          $insert_values[] = "('" . idval($owner) . "', '{$sender}', '{$timestamp}', '{$message_type}', '" . db_escape($from_unsafe) . "', '" . db_escape($subject_unsafe) . "', '" . db_escape($text_unsafe) . "')";
119
        }
120
121
        // TODO - allow sending HTML email only from admin
122
        if ($message_class['email'] && classSupernova::$config->game_email_pm && $owner_row["opt_email_{$message_class_name}"]) {
123
          $text_unescaped = str_replace(array('\\r\\n', '\\n', "\r\n", "\n"), "<br />", $text_unsafe);
124
          @$result = mymail($owner_row['email'], $subject_unsafe, $text_unescaped, '', true);
0 ignored issues
show
Security Best Practice introduced by
It seems like you do not handle an error condition here. This can introduce security issues, and is generally not recommended.

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

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

// Better use
if (@mkdir($dir) === false) {
    throw new \RuntimeException('The directory '.$dir.' could not be created.');
}
Loading history...
125
        }
126
      }
127
128
      if (empty($insert_values)) {
129
        return;
130
      }
131
132
      classSupernova::$db->doInsertValuesDeprecated(
0 ignored issues
show
Deprecated Code introduced by
The method db_mysql::doInsertValuesDeprecated() has been deprecated.

This method has been deprecated.

Loading history...
133
        TABLE_MESSAGES,
134
        array(
135
          'message_owner',
136
          'message_sender',
137
          'message_time',
138
          'message_type',
139
          'message_from',
140
          'message_subject',
141
          'message_text',
142
        ),
143
        $insert_values
144
      );
145
    }
146
    DBStaticUser::db_user_list_set_mass_mail($owners, "`{$message_class_name}` = `{$message_class_name}` + 1, `{$message_class_name_total}` = `{$message_class_name_total}` + 1");
147
148
    if (in_array($user['id'], $owners) || $owners[0] == '*') {
149
      $user[$message_class_name]++;
150
      $user[$message_class_name_total]++;
151
    }
152
  }
153
154
  public static function msg_ali_send($message, $subject, $ally_rank_id = 0, $ally_id = 0) {
155
    global $user;
156
157
    $ally_id = $ally_id ? $ally_id : $user['ally_id'];
158
159
    $sendList = array();
160
    $list = '';
161
    $query = DBStaticUser::db_user_list(
162
      "ally_id = '{$ally_id}'" . ($ally_rank_id >= 0 ? " AND ally_rank_id = {$ally_rank_id}" : ''),
163
      false, 'id, username');
164
    foreach ($query as $u) {
165
      $sendList[] = $u['id'];
166
      $list .= "<br>{$u['username']} ";
167
    }
168
169
    static::msg_send_simple_message($sendList, $user['id'], SN_TIME_NOW, MSG_TYPE_ALLIANCE, $user['username'], $subject, $message);
170
171
    return $list;
172
  }
173
174
175
  /**
176
   * @param mixed|array $owners
177
   * @param string      $subject
178
   * @param string      $text
179
   * @param bool        $force
180
   */
181
  public static function msgSendFromAdmin($owners, $subject, $text, $force = false) {
182
    static::msg_send_simple_message($owners, 0, SN_TIME_NOW, MSG_TYPE_ADMIN, classLocale::$lang['sys_administration'], $subject, $text, $force);
183
  }
184
185
  /**
186
   * @param        $senderPlayerId
187
   * @param        $senderPlayerNameAndCoordinates
188
   * @param mixed  $recipientId
189
   * @param string $subject
190
   * @param string $text
191
   */
192
  public static function msgSendFromPlayer($senderPlayerId, $senderPlayerNameAndCoordinates, $recipientId, $subject, $text) {
193
    static::msg_send_simple_message(
194
      $recipientId, $senderPlayerId, SN_TIME_NOW, MSG_TYPE_PLAYER, $senderPlayerNameAndCoordinates, $subject, $text
195
    );
196
  }
197
198
  /**
199
   * @param \Buddy\BuddyRoutingParams $cBuddy
200
   * @param string                    $localeSubjectId
201
   * @param string                    $localeTextId
202
   */
203
  public static function msgSendFromPlayerBuddy($cBuddy, $localeSubjectId, $localeTextId) {
204
    static::msgSendFromPlayer(
205
      $cBuddy->playerId,
206
      $cBuddy->playerNameAndCoordinates,
207
      $cBuddy->newFriendIdSafe,
208
      classLocale::$lang[$localeSubjectId],
209
      sprintf(classLocale::$lang[$localeTextId], $cBuddy->playerName)
210
    );
211
  }
212
213
214
  /**
215
   * @param array $player
216
   *
217
   * @return template
218
   */
219
  public static function messageWrite($player) {
220
    $error_list = array();
221
222
    $recipientId = sys_get_param_id('id');
223
    $recipient_name_unescaped = sys_get_param_str_unsafe('recipient_name');
224
    $subject_unsafe = sys_get_param_str_unsafe('subject');
225
226
    if (!empty($recipientId)) {
227
      $recipient_row = DBStaticUser::db_user_by_id($recipientId);
228
    }
229
230
    if (empty($recipient_row)) {
231
      $recipient_row = DBStaticUser::db_user_by_username($recipient_name_unescaped);
232
    }
233
234
    if (!empty($recipient_row)) {
235
      $recipientId = $recipient_row['id'];
236
      $recipient_name_unescaped = $recipient_row['username'];
237
    } else {
238
      $recipientId = 0;
239
      $recipient_name_unescaped = '';
240
    }
241
242 View Code Duplication
    if ($recipientId == $player['id']) {
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...
243
      $error_list[] = array('MESSAGE' => classLocale::$lang['msg_err_self_send'], 'STATUS' => ERR_ERROR);
244
    }
245
246
    $re = 0;
247
    while (strpos($subject_unsafe, classLocale::$lang['msg_answer_prefix']) !== false) {
248
      $subject_unsafe = substr($subject_unsafe, strlen(classLocale::$lang['msg_answer_prefix']));
249
      $re++;
250
    }
251
    $re ? $subject_unsafe = classLocale::$lang['msg_answer_prefix'] . $subject_unsafe : false;
252
253
    $subject_unsafe = $subject_unsafe ? $subject_unsafe : classLocale::$lang['msg_subject_default'];
254
255
    $textUnsafe = sys_get_param_str_unsafe('text');
256
    if (sys_get_param_str('msg_send')) {
257 View Code Duplication
      if (!$recipientId) {
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...
258
        $error_list[] = array('MESSAGE' => classLocale::$lang['msg_err_player_not_found'], 'STATUS' => ERR_ERROR);
259
      }
260
261
      if (empty($textUnsafe)) {
262
        $error_list[] = array('MESSAGE' => classLocale::$lang['msg_err_no_text'], 'STATUS' => ERR_ERROR);
263
      }
264
265
      if (empty($error_list)) {
266
        $error_list[] = array('MESSAGE' => classLocale::$lang['msg_not_message_sent'], 'STATUS' => ERR_NONE);
267
268
        static::msgSendFromPlayer($player['id'], DBStaticUser::renderNameAndCoordinates($player), $recipientId, $subject_unsafe, $textUnsafe);
269
270
        $textUnsafe = '';
271
      }
272
    }
273
274
    $template = gettemplate('msg_message_compose', true);
275
    $template->assign_vars(array(
276
      'RECIPIENT_ID'   => $recipientId,
277
      'RECIPIENT_NAME' => htmlspecialchars($recipient_name_unescaped),
278
      'SUBJECT'        => htmlspecialchars($subject_unsafe),
279
      'TEXT'           => htmlspecialchars($textUnsafe),
280
    ));
281
282
    foreach ($error_list as $error_message) {
283
      $template->assign_block_vars('result', $error_message);
284
    }
285
286
    $message_query = static::db_message_list_get_last_20($player, $recipientId);
287
    static::messageRenderList(MSG_TYPE_OUTBOX, $template, $message_query);
288
289
    return $template;
290
  }
291
292
293
  /**
294
   * @param array  $player
295
   * @param string $current_class
296
   */
297
  public static function messageDelete($player, $current_class) {
298
    $message_range = sys_get_param_str('message_range');
299
    $marked_message_list = sys_get_param('mark', array());
0 ignored issues
show
Documentation introduced by
array() is of type array, but the function expects a string.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
300
301
    $deleteAll = false;
302
    $where = array();
303
    $not = '';
304
    switch ($message_range) {
305
      case 'unchecked':
306
        $not = 'NOT';
307
      case 'checked':
308
        if ($message_range == 'checked' && empty($marked_message_list)) {
309
          break;
310
        }
311
312
        foreach ($marked_message_list as &$messageId) {
0 ignored issues
show
Bug introduced by
The expression $marked_message_list of type string|array is not guaranteed to be traversable. How about adding an additional type check?

There are different options of fixing this problem.

  1. If you want to be on the safe side, you can add an additional type-check:

    $collection = json_decode($data, true);
    if ( ! is_array($collection)) {
        throw new \RuntimeException('$collection must be an array.');
    }
    
    foreach ($collection as $item) { /** ... */ }
    
  2. If you are sure that the expression is traversable, you might want to add a doc comment cast to improve IDE auto-completion and static analysis:

    /** @var array $collection */
    $collection = json_decode($data, true);
    
    foreach ($collection as $item) { /** .. */ }
    
  3. Mark the issue as a false-positive: Just hover the remove button, in the top-right corner of this issue for more options.

Loading history...
313
          $messageId = idval($messageId);
314
        }
315
316
        if ($query_add = implode(',', $marked_message_list)) {
317
          $where[] = "`message_id` {$not} IN ({$query_add})";
318
        }
319
320
      case 'class':
321
        if ($current_class != MSG_TYPE_OUTBOX && $current_class != MSG_TYPE_NEW) {
322
          $where['message_type'] = $current_class;
323
        }
324
      case 'all':
325
        $deleteAll = true;
326
      break;
327
    }
328
329
    if ($deleteAll || !empty($where)) {
330
      $where['message_owner'] = $player['id'];
331
      // Mallformed $where
332
      classSupernova::$gc->db->doDeleteDeprecated(TABLE_MESSAGES, $where);
0 ignored issues
show
Bug introduced by
The method doDeleteDeprecated does only exist in db_mysql, but not in Closure.

It seems like the method you are trying to call exists only in some of the possible types.

Let’s take a look at an example:

class A
{
    public function foo() { }
}

class B extends A
{
    public function bar() { }
}

/**
 * @param A|B $x
 */
function someFunction($x)
{
    $x->foo(); // This call is fine as the method exists in A and B.
    $x->bar(); // This method only exists in B and might cause an error.
}

Available Fixes

  1. Add an additional type-check:

    /**
     * @param A|B $x
     */
    function someFunction($x)
    {
        $x->foo();
    
        if ($x instanceof B) {
            $x->bar();
        }
    }
    
  2. Only allow a single type to be passed if the variable comes from a parameter:

    function someFunction(B $x) { /** ... */ }
    
Loading history...
333
    }
334
  }
335
336
  /**
337
   * @param array $player
338
   * @param int   $current_class
339
   *
340
   * @return template
341
   */
342
  public static function messageShow(&$player, $current_class) {
343
    if ($current_class == MSG_TYPE_OUTBOX) {
344
      $message_query = static::db_message_list_outbox_by_user_id($player['id']);
345
    } else {
346
      if ($current_class == MSG_TYPE_NEW) {
347
        $SubUpdateQry = array();
348
        foreach (static::$snMessageClassList as $message_class_id => $message_class) {
349
          if ($message_class_id != MSG_TYPE_OUTBOX) {
350
            $SubUpdateQry[] = "`{$message_class['name']}` = '0'";
351
            $player[$message_class['name']] = 0;
352
          }
353
        }
354
        $SubUpdateQry = implode(',', $SubUpdateQry);
355
      } else {
356
        $classFieldNameCurrent = static::$snMessageClassList[$current_class]['name'];
357
        $classFieldNameNew = static::$snMessageClassList[MSG_TYPE_NEW]['name'];
358
        $SubUpdateQry = "`{$classFieldNameCurrent}` = '0', `{$classFieldNameNew}` = `{$classFieldNameNew}` - '{$player[$classFieldNameCurrent]}'";
359
        $SubSelectQry = "AND `message_type` = '{$current_class}'";
360
361
        $player[static::$snMessageClassList[MSG_TYPE_NEW]['name']] -= $player[static::$snMessageClassList[$current_class]['name']];
362
        $player[static::$snMessageClassList[$current_class]['name']] = 0;
363
      }
364
365
      DBStaticUser::db_user_set_by_id($player['id'], $SubUpdateQry);
366
      $message_query = static::db_message_list_by_owner_and_string($player, $SubSelectQry);
0 ignored issues
show
Bug introduced by
The variable $SubSelectQry does not seem to be defined for all execution paths leading up to this point.

If you define a variable conditionally, it can happen that it is not defined for all execution paths.

Let’s take a look at an example:

function myFunction($a) {
    switch ($a) {
        case 'foo':
            $x = 1;
            break;

        case 'bar':
            $x = 2;
            break;
    }

    // $x is potentially undefined here.
    echo $x;
}

In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined.

Available Fixes

  1. Check for existence of the variable explicitly:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        if (isset($x)) { // Make sure it's always set.
            echo $x;
        }
    }
    
  2. Define a default value for the variable:

    function myFunction($a) {
        $x = ''; // Set a default which gets overridden for certain paths.
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        echo $x;
    }
    
  3. Add a value for the missing path:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
    
            // We add support for the missing case.
            default:
                $x = '';
                break;
        }
    
        echo $x;
    }
    
Loading history...
367
    }
368
369
    if (sys_get_param_int('return')) {
370
      header('Location: messages.php');
371
      die();
372
    }
373
374
    $template = gettemplate('msg_message_list', true);
375
    static::messageRenderList($current_class, $template, $message_query);
376
377
    $current_class_text = classLocale::$lang['msg_class'][$current_class];
378
379
    $template->assign_vars(array(
380
      "MESSAGE_CLASS"      => $current_class,
381
      "MESSAGE_CLASS_TEXT" => $current_class_text,
382
    ));
383
384
    return $template;
385
  }
386
387
388
  /**
389
   * @param int      $current_class
390
   * @param template $template
391
   * @param          $message_query
392
   */
393
  public function messageRenderList($current_class, $template, $message_query) {
394
    while ($message_row = db_fetch($message_query)) {
395
      $template->assign_block_vars('messages', array(
396
        'ID'   => $message_row['message_id'],
397
        'DATE' => date(FMT_DATE_TIME, $message_row['message_time'] + SN_CLIENT_TIME_DIFF),
398
        'FROM' => htmlspecialchars($message_row['message_from']),
399
        'SUBJ' => htmlspecialchars($message_row['message_subject']),
400
        'TEXT' => in_array($message_row['message_type'], array(MSG_TYPE_PLAYER, MSG_TYPE_ALLIANCE)) && $message_row['message_sender']
401
          ? nl2br(htmlspecialchars($message_row['message_text']))
402
          : nl2br($message_row['message_text']),
403
404
        'FROM_ID'        => $message_row['message_sender'],
405
        'SUBJ_SANITIZED' => htmlspecialchars($message_row['message_subject']),
406
        'STYLE'          => $current_class == MSG_TYPE_OUTBOX
407
          ? static::$snMessageClassList[MSG_TYPE_OUTBOX]['name']
408
          : static::$snMessageClassList[$message_row['message_type']]['name'],
409
      ));
410
    }
411
  }
412
413
414
// Messages *************************************************************************************************************
415
  public static function db_message_list_get_last_20($user, $recipient_id) {
416
    return classSupernova::$db->doSelect(
417
      "SELECT * FROM {{messages}}
418
        WHERE
419
          `message_type` = '" . MSG_TYPE_PLAYER . "' AND
420
          ((`message_owner` = '{$user['id']}' AND `message_sender` = '{$recipient_id}')
421
          OR
422
          (`message_sender` = '{$user['id']}' AND `message_owner` = '{$recipient_id}')) ORDER BY `message_time` DESC LIMIT 20;");
423
  }
424
425
  public static function db_message_list_outbox_by_user_id($user_id) {
426
    $user_id = idval($user_id);
427
    if (empty($user_id)) {
428
      return false;
429
    }
430
431
    return classSupernova::$db->doSelect("SELECT {{messages}}.message_id, {{messages}}.message_owner, {{users}}.id AS message_sender, {{messages}}.message_time,
432
          {{messages}}.message_type, {{users}}.username AS message_from, {{messages}}.message_subject, {{messages}}.message_text
433
       FROM
434
         {{messages}} LEFT JOIN {{users}} ON {{users}}.id = {{messages}}.message_owner WHERE `message_sender` = '{$user_id}' AND `message_type` = 1
435
       ORDER BY `message_time` DESC;");
436
  }
437
438
  public static function db_message_list_by_owner_and_string($user, $SubSelectQry) {
439
    return classSupernova::$db->doSelect("SELECT * FROM {{messages}} WHERE `message_owner` = '{$user['id']}' {$SubSelectQry} ORDER BY `message_time` DESC;");
440
  }
441
442
  public static function db_message_count_by_owner_and_type($user) {
443
    return classSupernova::$db->doSelect("SELECT message_owner, message_type, COUNT(message_owner) AS message_count FROM {{messages}} WHERE `message_owner` = {$user['id']} GROUP BY message_owner, message_type ORDER BY message_owner ASC, message_type;");
444
  }
445
446
  public static function db_message_count_outbox($user) {
447
    $row = classSupernova::$db->doSelectFetch("SELECT COUNT(message_sender) AS message_count FROM {{messages}} WHERE `message_sender` = '{$user['id']}' AND message_type = 1 GROUP BY message_sender;");
448
449
    return intval($row['message_count']);
450
  }
451
452
  public static function db_message_list_admin_by_type($int_type_selected, $StartRec) {
453
    return classSupernova::$db->doSelect("SELECT
454
  message_id as `ID`,
455
  message_from as `FROM`,
456
  message_owner as `OWNER_ID`,
457
  u.username as `OWNER_NAME`,
458
  message_text as `TEXT`,
459
  FROM_UNIXTIME(message_time) as `TIME`
460
FROM
461
  {{messages}} AS m
462
  LEFT JOIN {{users}} AS u ON u.id = m.message_owner " .
463
      ($int_type_selected >= 0 ? "WHERE `message_type` = {$int_type_selected} " : '') .
464
      "ORDER BY
465
  `message_id` DESC
466
LIMIT
467
  {$StartRec}, 25;");
468
  }
469
470
  public static function db_message_insert_all($message_type, $from_unsafe, $subject_unsafe, $text_unsafe) {
471
    $message_type_safe = intval($message_type);
472
    $from_safe = db_escape($from_unsafe);
473
    $subject_safe = db_escape($subject_unsafe);
474
    $text_safe = db_escape($text_unsafe);
475
476
    return classSupernova::$db->doInsertComplex('INSERT INTO {{messages}} (`message_owner`, `message_sender`, `message_time`, `message_type`, `message_from`, `message_subject`, `message_text`) ' .
477
      "SELECT `id`, 0, unix_timestamp(now()), {$message_type_safe}, '{$from_safe}', '{$subject_safe}', '{$text_safe}' FROM {{users}}");
478
  }
479
480
  /**
481
   * @param $int_type_selected
482
   *
483
   * @return array|bool|mysqli_result|null
484
   */
485
  public static function db_message_count_by_type($int_type_selected) {
486
    $page_max = classSupernova::$db->doSelectFetch('SELECT COUNT(*) AS `max` FROM `{{messages}}`' . ($int_type_selected >= 0 ? " WHERE `message_type` = {$int_type_selected};" : ''));
487
488
    return $page_max;
489
  }
490
491
  /**
492
   * @param string $message_delete
493
   */
494
  public static function db_message_list_delete_set($message_delete) {
495
    classSupernova::$db->doDeleteDeprecated(TABLE_MESSAGES, array(0 => "`message_id` in ({$message_delete})",));
0 ignored issues
show
Deprecated Code introduced by
The method db_mysql::doDeleteDeprecated() has been deprecated.

This method has been deprecated.

Loading history...
496
  }
497
498
  public static function db_message_delete_by_id($messageId) {
499
    classSupernova::$gc->db->doDeleteRowWhere(TABLE_MESSAGES, array('message_id' => $messageId));
0 ignored issues
show
Bug introduced by
The method doDeleteRowWhere does only exist in db_mysql, but not in Closure.

It seems like the method you are trying to call exists only in some of the possible types.

Let’s take a look at an example:

class A
{
    public function foo() { }
}

class B extends A
{
    public function bar() { }
}

/**
 * @param A|B $x
 */
function someFunction($x)
{
    $x->foo(); // This call is fine as the method exists in A and B.
    $x->bar(); // This method only exists in B and might cause an error.
}

Available Fixes

  1. Add an additional type-check:

    /**
     * @param A|B $x
     */
    function someFunction($x)
    {
        $x->foo();
    
        if ($x instanceof B) {
            $x->bar();
        }
    }
    
  2. Only allow a single type to be passed if the variable comes from a parameter:

    function someFunction(B $x) { /** ... */ }
    
Loading history...
500
  }
501
502
503
504
  /**
505
   * @param $delete_date
506
   * @param $int_type_selected
507
   */
508
  public static function db_message_list_delete_by_date($delete_date, $int_type_selected) {
509
    $where[] = "message_time <= UNIX_TIMESTAMP('{$delete_date}')";
0 ignored issues
show
Coding Style Comprehensibility introduced by
$where was never initialized. Although not strictly required by PHP, it is generally a good practice to add $where = array(); before regardless.

Adding an explicit array definition is generally preferable to implicit array definition as it guarantees a stable state of the code.

Let’s take a look at an example:

foreach ($collection as $item) {
    $myArray['foo'] = $item->getFoo();

    if ($item->hasBar()) {
        $myArray['bar'] = $item->getBar();
    }

    // do something with $myArray
}

As you can see in this example, the array $myArray is initialized the first time when the foreach loop is entered. You can also see that the value of the bar key is only written conditionally; thus, its value might result from a previous iteration.

This might or might not be intended. To make your intention clear, your code more readible and to avoid accidental bugs, we recommend to add an explicit initialization $myArray = array() either outside or inside the foreach loop.

Loading history...
510
    if($int_type_selected >= 0) {
511
      $where['message_type'] = $int_type_selected;
512
    }
513
    classSupernova::$db->doDeleteDeprecated(TABLE_MESSAGES, $where);
0 ignored issues
show
Deprecated Code introduced by
The method db_mysql::doDeleteDeprecated() has been deprecated.

This method has been deprecated.

Loading history...
514
  }
515
516
}
517