Completed
Push — work-fleets ( 22b024...7f5906 )
by SuperNova.WS
06:37
created

DBStaticMessages   C

Complexity

Total Complexity 78

Size/Duplication

Total Lines 522
Duplicated Lines 1.15 %

Coupling/Cohesion

Components 1
Dependencies 8

Test Coverage

Coverage 0%

Importance

Changes 11
Bugs 0 Features 0
Metric Value
dl 6
loc 522
rs 5.4563
c 11
b 0
f 0
ccs 0
cts 308
cp 0
wmc 78
lcom 1
cbo 8

21 Methods

Rating   Name   Duplication   Size   Complexity  
C msg_send_simple_message() 0 70 18
A msg_ali_send() 0 19 4
A msgSendFromAdmin() 0 3 1
A msgSendFromPlayer() 0 13 1
A msgSendFromPlayerBuddy() 0 9 1
F messageWrite() 6 72 13
C messageDelete() 0 38 13
B messageShow() 0 44 6
B messageRenderList() 0 19 5
A db_message_list_get_last_20() 0 9 1
A db_message_list_outbox_by_user_id() 0 12 2
A db_message_list_by_owner_and_string() 0 3 1
A db_message_count_by_owner_and_type() 0 3 1
A db_message_count_outbox() 0 5 1
A db_message_list_admin_by_type() 0 17 2
A db_message_insert_all() 0 4 1
A db_message_count_by_type() 0 5 2
A db_message_list_delete_set() 0 3 1
A db_message_delete_by_id() 0 3 1
A db_message_list_delete_by_date() 0 7 2
A db_message_insert() 0 4 1

How to fix   Duplicated Code    Complexity   

Duplicated Code

Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.

Common duplication problems, and corresponding solutions are:

Complex Class

 Tip:   Before tackling complexity, make sure that you eliminate any duplication first. This often can reduce the size of classes significantly.

Complex classes like DBStaticMessages often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes. You can also have a look at the cohesion graph to spot any un-connected, or weakly-connected components.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use DBStaticMessages, and based on these observations, apply Extract Interface, too.

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
74
   * @param string      $subject
75
   * @param string      $text
76
   * @param bool        $escaped
77
   * @param bool        $force
78
   */
79
  public static function msg_send_simple_message($owners, $sender, $timestamp, $message_type, $from, $subject, $text, $escaped = false, $force = false) {
80
    global $user;
81
82
    if (!$owners) {
83
      return;
84
    }
85
86
    $timestamp = $timestamp ? $timestamp : SN_TIME_NOW;
87
    $sender = intval($sender);
88
    if (!is_array($owners)) {
89
      $owners = array($owners);
90
    }
91
92
    if (!$escaped) {
93
      $from = db_escape($from);
94
      $subject = db_escape($subject);
95
      $text = db_escape($text);
96
    }
97
98
    $text_unescaped = stripslashes(str_replace(array('\r\n', "\r\n"), "<br />", $text));
99
100
    $message_class = static::$snMessageClassList[$message_type];
101
    $message_class_email = $message_class['email'];
102
    $message_class_switchable = $message_class['switchable'];
103
    $message_class_name = $message_class['name'];
104
105
    $message_class_name_total = static::$snMessageClassList[MSG_TYPE_NEW]['name'];
106
107
    if ($owners[0] == '*') {
108
      if ($user['authlevel'] < 3) {
109
        return false;
110
      }
111
      // TODO Добавить $timestamp - рассылка может быть и отсроченной
112
      // TODO Добавить $sender - рассылка может быть и от кого-то
113
      static::db_message_insert_all($message_type, $from, $subject, $text);
114
      $owners = array();
115
    } else {
116
      $insert_values = array();
117
      $insert_template = "('%u'," . str_replace('%', '%%', " '{$sender}', '{$timestamp}', '{$message_type}', '{$from}', '{$subject}', '{$text}')");
118
119
      foreach ($owners as $owner) {
120
        if ($user['id'] != $owner) {
121
          $owner_row = DBStaticUser::db_user_by_id($owner);
122
        } else {
123
          $owner_row = $user;
124
        }
125
        sys_user_options_unpack($owner_row);
126
127
        if ($force || !$message_class_switchable || $owner_row["opt_{$message_class_name}"]) {
128
          $insert_values[] = sprintf($insert_template, $owner);
129
        }
130
131
        if ($message_class_email && classSupernova::$config->game_email_pm && $owner_row["opt_email_{$message_class_name}"]) {
132
          @$result = mymail($owner_row['email'], $subject, $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...
133
        }
134
      }
135
136
      if (empty($insert_values)) {
137
        return;
138
      }
139
140
      static::db_message_insert($insert_values);
141
    }
142
    DBStaticUser::db_user_list_set_mass_mail($owners, "`{$message_class_name}` = `{$message_class_name}` + 1, `{$message_class_name_total}` = `{$message_class_name_total}` + 1");
143
144
    if (in_array($user['id'], $owners) || $owners[0] == '*') {
145
      $user[$message_class_name]++;
146
      $user[$message_class_name_total]++;
147
    }
148
  }
149
150
  public static function msg_ali_send($message, $subject, $ally_rank_id = 0, $ally_id = 0) {
151
    global $user;
152
153
    $ally_id = $ally_id ? $ally_id : $user['ally_id'];
154
155
    $sendList = array();
156
    $list = '';
157
    $query = DBStaticUser::db_user_list(
158
      "ally_id = '{$ally_id}'" . ($ally_rank_id >= 0 ? " AND ally_rank_id = {$ally_rank_id}" : ''),
159
      false, 'id, username');
160
    foreach ($query as $u) {
161
      $sendList[] = $u['id'];
162
      $list .= "<br>{$u['username']} ";
163
    }
164
165
    static::msg_send_simple_message($sendList, $user['id'], SN_TIME_NOW, MSG_TYPE_ALLIANCE, $user['username'], $subject, $message, true);
166
167
    return $list;
168
  }
169
170
171
  /**
172
   * @param mixed|array $owners
173
   * @param string      $subject
174
   * @param string      $text
175
   * @param bool        $escaped
176
   * @param bool        $force
177
   */
178
  public static function msgSendFromAdmin($owners, $subject, $text, $escaped = false, $force = false) {
179
    static::msg_send_simple_message($owners, 0, SN_TIME_NOW, MSG_TYPE_ADMIN, classLocale::$lang['sys_administration'], $subject, $text, $escaped, $force);
180
  }
181
182
  /**
183
   * @param        $senderPlayerId
184
   * @param        $senderPlayerNameAndCoordinates
185
   * @param mixed  $recipientId
186
   * @param string $subject
187
   * @param string $text
188
   */
189
  public static function msgSendFromPlayer($senderPlayerId, $senderPlayerNameAndCoordinates, $recipientId, $subject, $text) {
190
    static::msg_send_simple_message(
191
      $recipientId,
192
      $senderPlayerId,
193
      SN_TIME_NOW,
194
      MSG_TYPE_PLAYER,
195
      $senderPlayerNameAndCoordinates,
196
      $subject,
197
      $text,
198
      false,
199
      false
200
    );
201
  }
202
203
  /**
204
   * @param \Buddy\BuddyRoutingParams $cBuddy
205
   * @param string                    $localeSubjectId
206
   * @param string                    $localeTextId
207
   */
208
  public static function msgSendFromPlayerBuddy($cBuddy, $localeSubjectId, $localeTextId) {
209
    static::msgSendFromPlayer(
210
      $cBuddy->playerId,
211
      $cBuddy->playerNameAndCoordinates,
212
      $cBuddy->newFriendIdSafe,
213
      classLocale::$lang[$localeSubjectId],
214
      sprintf(classLocale::$lang[$localeTextId], $cBuddy->playerName)
215
    );
216
  }
217
218
219
  /**
220
   * @param array $player
221
   *
222
   * @return template
223
   */
224
  public static function messageWrite($player) {
225
    $error_list = array();
226
227
    $recipientId = sys_get_param_id('id');
228
    $recipient_name_unescaped = sys_get_param_str_unsafe('recipient_name');
229
    $subject_unsafe = sys_get_param_str_unsafe('subject');
230
231
    if (!empty($recipientId)) {
232
      $recipient_row = DBStaticUser::db_user_by_id($recipientId);
233
    }
234
235
    if (empty($recipient_row)) {
236
      $recipient_row = DBStaticUser::db_user_by_username($recipient_name_unescaped);
237
    }
238
239
    if (!empty($recipient_row)) {
240
      $recipientId = $recipient_row['id'];
241
      $recipient_name_unescaped = $recipient_row['username'];
242
    } else {
243
      $recipientId = 0;
244
      $recipient_name_unescaped = '';
245
    }
246
247 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...
248
      $error_list[] = array('MESSAGE' => classLocale::$lang['msg_err_self_send'], 'STATUS' => ERR_ERROR);
249
    }
250
251
    $re = 0;
252
    while (strpos($subject_unsafe, classLocale::$lang['msg_answer_prefix']) !== false) {
253
      $subject_unsafe = substr($subject_unsafe, strlen(classLocale::$lang['msg_answer_prefix']));
254
      $re++;
255
    }
256
    $re ? $subject_unsafe = classLocale::$lang['msg_answer_prefix'] . $subject_unsafe : false;
257
258
    $subject_unsafe = $subject_unsafe ? $subject_unsafe : classLocale::$lang['msg_subject_default'];
259
260
    $textUnsafe = sys_get_param_str_unsafe('text');
261
    if (sys_get_param_str('msg_send')) {
262 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...
263
        $error_list[] = array('MESSAGE' => classLocale::$lang['msg_err_player_not_found'], 'STATUS' => ERR_ERROR);
264
      }
265
266
      if (empty($textUnsafe)) {
267
        $error_list[] = array('MESSAGE' => classLocale::$lang['msg_err_no_text'], 'STATUS' => ERR_ERROR);
268
      }
269
270
      if (empty($error_list)) {
271
        $error_list[] = array('MESSAGE' => classLocale::$lang['msg_not_message_sent'], 'STATUS' => ERR_NONE);
272
273
        static::msgSendFromPlayer($player['id'], DBStaticUser::renderNameAndCoordinates($player), $recipientId, $subject_unsafe, $textUnsafe);
274
275
        $textUnsafe = '';
276
      }
277
    }
278
279
    $template = gettemplate('msg_message_compose', true);
280
    $template->assign_vars(array(
281
      'RECIPIENT_ID'   => $recipientId,
282
      'RECIPIENT_NAME' => htmlspecialchars($recipient_name_unescaped),
283
      'SUBJECT'        => htmlspecialchars($subject_unsafe),
284
      'TEXT'           => htmlspecialchars($textUnsafe),
285
    ));
286
287
    foreach ($error_list as $error_message) {
288
      $template->assign_block_vars('result', $error_message);
289
    }
290
291
    $message_query = static::db_message_list_get_last_20($player, $recipientId);
292
    static::messageRenderList(MSG_TYPE_OUTBOX, $template, $message_query);
293
294
    return $template;
295
  }
296
297
298
  /**
299
   * @param array  $player
300
   * @param string $current_class
301
   */
302
  public static function messageDelete($player, $current_class) {
303
    $message_range = sys_get_param_str('message_range');
304
    $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...
305
306
    $deleteAll = false;
307
    $where = array();
308
    $not = '';
309
    switch ($message_range) {
310
      case 'unchecked':
311
        $not = 'NOT';
312
      case 'checked':
313
        if ($message_range == 'checked' && empty($marked_message_list)) {
314
          break;
315
        }
316
317
        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...
318
          $messageId = idval($messageId);
319
        }
320
321
        if ($query_add = implode(',', $marked_message_list)) {
322
          $where[] = "`message_id` {$not} IN ({$query_add})";
323
        }
324
325
      case 'class':
326
        if ($current_class != MSG_TYPE_OUTBOX && $current_class != MSG_TYPE_NEW) {
327
          $where['message_type'] = $current_class;
328
        }
329
      case 'all':
330
        $deleteAll = true;
331
      break;
332
    }
333
334
    if ($deleteAll || !empty($where)) {
335
      $where['message_owner'] = $player['id'];
336
      // Mallformed $where
337
      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...
338
    }
339
  }
340
341
  /**
342
   * @param array $player
343
   * @param int   $current_class
344
   *
345
   * @return template
346
   */
347
  public static function messageShow(&$player, $current_class) {
348
    if ($current_class == MSG_TYPE_OUTBOX) {
349
      $message_query = static::db_message_list_outbox_by_user_id($player['id']);
350
    } else {
351
      if ($current_class == MSG_TYPE_NEW) {
352
        $SubUpdateQry = array();
353
        foreach (static::$snMessageClassList as $message_class_id => $message_class) {
354
          if ($message_class_id != MSG_TYPE_OUTBOX) {
355
            $SubUpdateQry[] = "`{$message_class['name']}` = '0'";
356
            $player[$message_class['name']] = 0;
357
          }
358
        }
359
        $SubUpdateQry = implode(',', $SubUpdateQry);
360
      } else {
361
        $classFieldNameCurrent = static::$snMessageClassList[$current_class]['name'];
362
        $classFieldNameNew = static::$snMessageClassList[MSG_TYPE_NEW]['name'];
363
        $SubUpdateQry = "`{$classFieldNameCurrent}` = '0', `{$classFieldNameNew}` = `{$classFieldNameNew}` - '{$player[$classFieldNameCurrent]}'";
364
        $SubSelectQry = "AND `message_type` = '{$current_class}'";
365
366
        $player[static::$snMessageClassList[MSG_TYPE_NEW]['name']] -= $player[static::$snMessageClassList[$current_class]['name']];
367
        $player[static::$snMessageClassList[$current_class]['name']] = 0;
368
      }
369
370
      DBStaticUser::db_user_set_by_id($player['id'], $SubUpdateQry);
371
      $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...
372
    }
373
374
    if (sys_get_param_int('return')) {
375
      header('Location: messages.php');
376
      die();
377
    }
378
379
    $template = gettemplate('msg_message_list', true);
380
    static::messageRenderList($current_class, $template, $message_query);
381
382
    $current_class_text = classLocale::$lang['msg_class'][$current_class];
383
384
    $template->assign_vars(array(
385
      "MESSAGE_CLASS"      => $current_class,
386
      "MESSAGE_CLASS_TEXT" => $current_class_text,
387
    ));
388
389
    return $template;
390
  }
391
392
393
  /**
394
   * @param int      $current_class
395
   * @param template $template
396
   * @param          $message_query
397
   */
398
  public function messageRenderList($current_class, $template, $message_query) {
399
    while ($message_row = db_fetch($message_query)) {
400
      $template->assign_block_vars('messages', array(
401
        'ID'   => $message_row['message_id'],
402
        'DATE' => date(FMT_DATE_TIME, $message_row['message_time'] + SN_CLIENT_TIME_DIFF),
403
        'FROM' => htmlspecialchars($message_row['message_from']),
404
        'SUBJ' => htmlspecialchars($message_row['message_subject']),
405
        'TEXT' => in_array($message_row['message_type'], array(MSG_TYPE_PLAYER, MSG_TYPE_ALLIANCE)) && $message_row['message_sender']
406
          ? nl2br(htmlspecialchars($message_row['message_text']))
407
          : nl2br($message_row['message_text']),
408
409
        'FROM_ID'        => $message_row['message_sender'],
410
        'SUBJ_SANITIZED' => htmlspecialchars($message_row['message_subject']),
411
        'STYLE'          => $current_class == MSG_TYPE_OUTBOX
412
          ? static::$snMessageClassList[MSG_TYPE_OUTBOX]['name']
413
          : static::$snMessageClassList[$message_row['message_type']]['name'],
414
      ));
415
    }
416
  }
417
418
419
// Messages *************************************************************************************************************
420
  public static function db_message_list_get_last_20($user, $recipient_id) {
421
    return classSupernova::$db->doSelect(
422
      "SELECT * FROM {{messages}}
423
        WHERE
424
          `message_type` = '" . MSG_TYPE_PLAYER . "' AND
425
          ((`message_owner` = '{$user['id']}' AND `message_sender` = '{$recipient_id}')
426
          OR
427
          (`message_sender` = '{$user['id']}' AND `message_owner` = '{$recipient_id}')) ORDER BY `message_time` DESC LIMIT 20;");
428
  }
429
430
  public static function db_message_list_outbox_by_user_id($user_id) {
431
    $user_id = idval($user_id);
432
    if (empty($user_id)) {
433
      return false;
434
    }
435
436
    return classSupernova::$db->doSelect("SELECT {{messages}}.message_id, {{messages}}.message_owner, {{users}}.id AS message_sender, {{messages}}.message_time,
437
          {{messages}}.message_type, {{users}}.username AS message_from, {{messages}}.message_subject, {{messages}}.message_text
438
       FROM
439
         {{messages}} LEFT JOIN {{users}} ON {{users}}.id = {{messages}}.message_owner WHERE `message_sender` = '{$user_id}' AND `message_type` = 1
440
       ORDER BY `message_time` DESC;");
441
  }
442
443
  public static function db_message_list_by_owner_and_string($user, $SubSelectQry) {
444
    return classSupernova::$db->doSelect("SELECT * FROM {{messages}} WHERE `message_owner` = '{$user['id']}' {$SubSelectQry} ORDER BY `message_time` DESC;");
445
  }
446
447
  public static function db_message_count_by_owner_and_type($user) {
448
    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;");
449
  }
450
451
  public static function db_message_count_outbox($user) {
452
    $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;");
453
454
    return intval($row['message_count']);
455
  }
456
457
  public static function db_message_list_admin_by_type($int_type_selected, $StartRec) {
458
    return classSupernova::$db->doSelect("SELECT
459
  message_id as `ID`,
460
  message_from as `FROM`,
461
  message_owner as `OWNER_ID`,
462
  u.username as `OWNER_NAME`,
463
  message_text as `TEXT`,
464
  FROM_UNIXTIME(message_time) as `TIME`
465
FROM
466
  {{messages}} AS m
467
  LEFT JOIN {{users}} AS u ON u.id = m.message_owner " .
468
      ($int_type_selected >= 0 ? "WHERE `message_type` = {$int_type_selected} " : '') .
469
      "ORDER BY
470
  `message_id` DESC
471
LIMIT
472
  {$StartRec}, 25;");
473
  }
474
475
  public static function db_message_insert_all($message_type, $from, $subject, $text) {
476
    return classSupernova::$db->doInsert('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}, '{$from}', '{$subject}', '{$text}' 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
   * @param $insert_values
518
   */
519
  public static function db_message_insert($insert_values) {
520
    classSupernova::$db->doInsert('INSERT INTO `{{messages}}` (`message_owner`, `message_sender`, `message_time`, `message_type`, `message_from`, `message_subject`, `message_text`) ' .
521
      'VALUES ' . implode(',', $insert_values));
522
  }
523
524
}
525