Completed
Push — trunk ( 91a948...0e7a2e )
by SuperNova.WS
05:44
created

qst_get_quests()   C

Complexity

Conditions 7
Paths 10

Size

Total Lines 30
Code Lines 19

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 7
eloc 19
c 1
b 0
f 0
nc 10
nop 2
dl 0
loc 30
rs 6.7272
1
<?php
2
3
use \DBAL\DbQuery;
4
use DBAL\OldDbChangeSet;
5
6
function roughQuestRenderWrapper() {
7
  global $lang, $user;
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...
8
  lng_include('quest');
9
10
  $template = gettemplate('quest', true);
0 ignored issues
show
Bug introduced by
true of type true is incompatible with the type null|template expected by parameter $template of gettemplate(). ( Ignorable by Annotation )

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

10
  $template = gettemplate('quest', /** @scrutinizer ignore-type */ true);
Loading history...
11
  qst_render_page($lang, $user, $template);
12
13
  display($template, $lang['qst_quests']);
14
}
15
16
/**
17
 * @param classLocale $lang
18
 * @param array       $user
19
 * @param template    $template
20
 */
21
function qst_render_page(classLocale $lang, array $user, template $template) {
22
  $questCurrentManaged = null;
23
  $in_admin = defined('IN_ADMIN') && IN_ADMIN === true;
24
25
  $user_id = sys_get_param_id('user_id', false);
0 ignored issues
show
Bug introduced by
false of type false is incompatible with the type integer|string|double expected by parameter $default of sys_get_param_id(). ( Ignorable by Annotation )

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

25
  $user_id = sys_get_param_id('user_id', /** @scrutinizer ignore-type */ false);
Loading history...
26
  $currentMode = sys_get_param_str('mode');
27
28
  if ($in_admin) {
29
    $questCurrentManaged = questPageModelManage($lang, $template, $currentMode);
30
  } elseif (!$user_id) {
31
    $user_id = $user['id'];
32
  }
33
34
  $quest_list = qst_get_quests($user_id, SN::$user_options[PLAYER_OPTION_QUEST_LIST_FILTER]);
35
  $template->assign_vars(array(
36
    'AUTHLEVEL' => $user['authlevel'],
37
    'TOTAL'     => count($quest_list),
38
    'mode'      => $currentMode,
39
    'USER_ID'   => $user_id,
40
    'IN_ADMIN'  => $in_admin,
41
42
    'QUEST_STATUS_NOT_STARTED' => QUEST_STATUS_NOT_STARTED,
43
    'QUEST_STATUS_STARTED'     => QUEST_STATUS_STARTED,
44
    'QUEST_STATUS_COMPLETE'    => QUEST_STATUS_COMPLETE,
45
46
    'PLAYER_OPTION_QUEST_LIST_FILTER' => SN::$user_options[PLAYER_OPTION_QUEST_LIST_FILTER],
47
  ));
48
49
  foreach ($lang['qst_status_list'] as $statusId => $statusName) {
50
    $template->assign_block_vars('status', array(
51
      'ID'   => $statusId,
52
      'NAME' => $statusName,
53
    ));
54
  }
55
56
  if (!empty($questCurrentManaged)) {
57
    $quest_templatized = qst_templatize(qst_quest_parse($questCurrentManaged));
58
  } else {
59
    $quest_templatized['quest_rewards_list'] = [];
0 ignored issues
show
Comprehensibility Best Practice introduced by
$quest_templatized was never initialized. Although not strictly required by PHP, it is generally a good practice to add $quest_templatized = array(); before regardless.
Loading history...
60
  }
61
62
  questTemplatizeReward($quest_templatized, $lang);
63
64
  qst_assign_to_template($template, $quest_templatized);
65
66
  foreach ($quest_list as $quest_data) {
67
    qst_assign_to_template($template, qst_templatize($quest_data, true), 'quest');
68
  }
69
70
  foreach (questUnitsAllowed() as $unit_id) {
71
    $template->assign_block_vars('allowed_unit', array(
72
      'ID'   => $unit_id,
73
      'NAME' => $lang['tech'][$unit_id],
74
    ));
75
  }
76
}
77
78
/**
79
 * @param classLocale $lang
80
 * @param template    $template
81
 * @param string      $mode
82
 */
83
function questPageModelManage(classLocale $lang, template $template, &$mode) {
84
  $questManaged = null;
85
86
  $quest_id = sys_get_param_id('id');
87
  $quest_name = sys_get_param_str_unsafe('QUEST_NAME');
88
  if (!empty($quest_name)) {
89
    try {
90
      // TODO: Change quest type
91
      $quest_type = 0;
92
      $theQuery = DbQuery::build()
93
        ->setTable('quest')
94
        ->setValues([
95
          'quest_type'        => $quest_type,
96
          'quest_name'        => $quest_name,
97
          'quest_description' => sys_get_param_str_unsafe('QUEST_DESCRIPTION'),
98
          'quest_conditions'  => questGetConditionFromParams($lang),
99
          'quest_rewards'     => questGetRewardsStringFromParams($lang),
100
        ]);
101
102
      if ($mode == 'edit') {
103
        $theQuery
104
          ->setWhereArray(['quest_id' => $quest_id])
105
          ->setOneRow()
106
          ->doUpdate();
107
      } else {
108
        $theQuery->doInsert();
109
      }
110
111
      // TODO: Add mass mail for new quests
112
      /*
0 ignored issues
show
Unused Code Comprehensibility introduced by
70% 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...
113
      if(sys_get_param_int('news_mass_mail')) {
114
        msg_send_simple_message('*', 0, 0, MSG_TYPE_PLAYER, $lang['sys_administration'], $lang['news_title'], $text);
115
      }
116
      */
117
    } catch (Exception $e) {
118
      messageBox($e->getMessage(), $lang['sys_error']);
119
    }
120
121
    $mode = '';
122
  }
123
124
  switch ($mode) {
125
    case 'del':
126
      doquery("DELETE FROM `{{quest}}` WHERE `quest_id` = {$quest_id} LIMIT 1;");
127
      $mode = '';
128
    break;
129
130
    /** @noinspection PhpMissingBreakStatementInspection */
131
    case 'edit':
0 ignored issues
show
Coding Style introduced by
There must be a comment when fall-through is intentional in a non-empty case body
Loading history...
132
      $template->assign_var('QUEST_ID', $quest_id);
0 ignored issues
show
Coding Style Comprehensibility introduced by
Consider adding a comment if this fall-through is intended.
Loading history...
133
134
    case 'copy':
135
      $questManaged = doquery("SELECT * FROM `{{quest}}` WHERE `quest_id` = {$quest_id} LIMIT 1;", '', true);
136
    break;
137
  }
138
139
  $query = doquery("SELECT count(*) AS count FROM `{{quest}}`;", '', true);
140
  SN::$config->pass()->quest_total = $query['count'];
141
142
  return $questManaged;
143
}
144
145
/**
146
 * @param array       $quest_templatized
147
 * @param classLocale $lang
148
 */
149
function questTemplatizeReward(&$quest_templatized, $lang) {
150
  foreach (questAllowedRewardsList() as $unit_id) {
151
    $found = false;
152
    foreach ($quest_templatized['quest_rewards_list'] as $quest_templatized_reward) {
153
      if ($quest_templatized_reward['ID'] == $unit_id) {
154
        $found = true;
155
        break;
156
      }
157
    }
158
159
    if (!$found) {
160
      $quest_templatized['quest_rewards_list'][$unit_id] = array(
161
        'ID'     => $unit_id,
162
        'NAME'   => $lang['tech'][$unit_id],
163
        'AMOUNT' => 0,
164
      );
165
    }
166
  }
167
}
168
169
/**
170
 * @param $lang
171
 *
172
 * @return string
173
 * @throws Exception
174
 */
175
function questGetRewardsStringFromParams($lang) {
176
  $quest_reward_allowed = questAllowedRewardsList();
177
  $quest_rewards = [];
178
  foreach (sys_get_param('QUEST_REWARDS_LIST') as $quest_rewards_id => $quest_rewards_amount) {
179
    if (!in_array($quest_rewards_id, $quest_reward_allowed)) {
180
      throw new Exception($lang['qst_adm_err_reward_type']);
181
    }
182
183
    $quest_rewards_amount = round($quest_rewards_amount);
184
    if ($quest_rewards_amount < 0) {
185
      throw new Exception($lang['qst_adm_err_reward_amount']);
186
    } elseif ($quest_rewards_amount > 0) {
187
      $quest_rewards[intval($quest_rewards_id)] = $quest_rewards_amount;
188
    }
189
  }
190
  if (empty($quest_rewards)) {
191
    throw new Exception($lang['qst_adm_err_reward_empty']);
192
  }
193
  $quest_rewards_string = sys_unit_arr2str($quest_rewards);
194
195
  return $quest_rewards_string;
196
}
197
198
/**
199
 * @param $lang
200
 *
201
 * @return string
202
 * @throws Exception
203
 */
204
function questGetConditionFromParams($lang) {
205
  $quest_unit_id = sys_get_param_int('QUEST_UNIT_ID');
206
  if (!in_array($quest_unit_id, questUnitsAllowed())) {
207
    throw new Exception($lang['qst_adm_err_unit_id']);
208
  }
209
  $quest_unit_amount = sys_get_param_float('QUEST_UNIT_AMOUNT');
210
  if ($quest_unit_amount <= 0) {
211
    throw new Exception($lang['qst_adm_err_unit_amount']);
212
  }
213
  $quest_conditions = "{$quest_unit_id},{$quest_unit_amount}";
214
215
  return $quest_conditions;
216
}
217
218
/**
219
 * @return array
220
 */
221
function questAllowedRewardsList() {
222
  return sn_get_groups('quest_rewards');
223
}
224
225
/**
226
 * @return array
227
 */
228
function questUnitsAllowed() {
229
  return sn_get_groups(['structures', 'tech', 'fleet', 'defense']);
230
}
231
232
function qst_get_quests($user_id = false, $status = QUEST_STATUS_ALL) {
233
  $quest_list = array();
234
235
  if ($user_id) {
236
    if ($status !== QUEST_STATUS_ALL) {
237
      $query_add_where = "";
238
      if ($status == null || $status == QUEST_STATUS_NOT_STARTED) {
239
        $query_add_where .= "AND qs.quest_status_status IS NULL";
240
      } elseif ($status == QUEST_STATUS_EXCEPT_COMPLETE) {
241
        $query_add_where .= "AND (qs.quest_status_status IS NULL OR qs.quest_status_status = " . QUEST_STATUS_STARTED . ")";
242
      } else {
243
        $query_add_where .= "AND qs.quest_status_status = {$status}";
244
      }
245
    }
246
    $query_add_select = ", qs.quest_status_progress, qs.quest_status_status";
247
    $query_add_from = "LEFT JOIN {{quest_status}} AS qs ON qs.quest_status_quest_id = q.quest_id AND qs.quest_status_user_id = {$user_id}";
248
  }
249
250
  $query = doquery(
251
    "SELECT q.* {$query_add_select}
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $query_add_select does not seem to be defined for all execution paths leading up to this point.
Loading history...
252
      FROM `{{quest}}` AS q {$query_add_from}
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $query_add_from does not seem to be defined for all execution paths leading up to this point.
Loading history...
253
      WHERE 1 {$query_add_where}
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $query_add_where does not seem to be defined for all execution paths leading up to this point.
Loading history...
254
    ;"
255
  );
256
257
  while ($quest = db_fetch($query)) {
258
    $quest_list[$quest['quest_id']] = qst_quest_parse($quest);
259
  }
260
261
  return $quest_list;
262
}
263
264
/**
265
 * @param template    $template
266
 * @param array       $quest_templatized
267
 * @param string|bool $block_name
268
 */
269
function qst_assign_to_template(&$template, $quest_templatized, $block_name = false) {
270
  if ($block_name) {
271
    $template->assign_block_vars($block_name, $quest_templatized);
272
  } else {
273
    $template->assign_vars($quest_templatized);
274
    if (!empty($quest_templatized['quest_rewards_list'])) {
275
      foreach ($quest_templatized['quest_rewards_list'] as $quest_reward) {
276
        $template->assign_block_vars(($block_name ? $block_name . '.' : '') . 'quest_rewards_list', $quest_reward);
0 ignored issues
show
Bug introduced by
Are you sure $block_name of type string|true can be used in concatenation? ( Ignorable by Annotation )

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

276
        $template->assign_block_vars(($block_name ? /** @scrutinizer ignore-type */ $block_name . '.' : '') . 'quest_rewards_list', $quest_reward);
Loading history...
277
      }
278
    }
279
  }
280
}
281
282
function qst_quest_parse($quest) {
283
  list($quest['quest_unit_id'], $quest['quest_unit_amount']) = explode(',', $quest['quest_conditions']);
284
285
  $quest['quest_rewards_list'] = sys_unit_str2arr($quest['quest_rewards']);
286
287
  return $quest;
288
}
289
290
function qst_templatize($quest, $for_display = true) {
291
  global $lang;
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...
292
293
  $tmp = array();
294
  foreach ($quest['quest_rewards_list'] as $quest_reward_id => $quest_reward_amount) {
295
    $tmp[] = array(
296
      'ID'     => $quest_reward_id,
297
      'NAME'   => $for_display ? str_replace(' ', '&nbsp;', $lang['tech'][$quest_reward_id]) : $lang['tech'][$quest_reward_id],
298
      'AMOUNT' => $quest_reward_amount,
299
    );
300
  }
301
302
  return array(
303
    'QUEST_ID'           => $quest['quest_id'],
304
    'QUEST_NAME'         => $quest['quest_name'],
305
    'QUEST_TYPE'         => $quest['quest_type'],
306
    'QUEST_DESCRIPTION'  => $for_display ? HelperString::nl2br($quest['quest_description']) : $quest['quest_description'],
307
    'QUEST_CONDITIONS'   => $quest['quest_condition'],
308
    'QUEST_UNIT_ID'      => $quest['quest_unit_id'],
309
    'QUEST_UNIT_NAME'    => $lang['tech'][$quest['quest_unit_id']],
310
    'QUEST_UNIT_AMOUNT'  => $quest['quest_unit_amount'],
311
    'QUEST_STATUS'       => intval($quest['quest_status_status']),
312
    'QUEST_STATUS_NAME'  => $lang['qst_status_list'][intval($quest['quest_status_status'])],
313
    'quest_rewards_list' => $tmp,
314
  );
315
}
316
317
function qst_active_triggers($quest_list) {
318
  $quest_triggers = array();
319
  foreach ($quest_list as $quest_id => $quest) {
320
    if ($quest['quest_status_status'] != QUEST_STATUS_COMPLETE) {
321
      list($quest_unit_id, $quest_unit_amount) = explode(',', $quest['quest_conditions']);
322
      $quest_triggers[$quest_id] = $quest_unit_id;
323
    }
324
  }
325
326
  return $quest_triggers;
327
}
328
329
/**
330
 * @param           $user
331
 * @param           $rewards
332
 * @param           $quest_list
333
 * @param integer[] $quest_statuses
334
 */
335
function qst_reward(&$user, &$rewards, &$quest_list, &$quest_statuses) {
336
  if (empty($quest_statuses)) {
337
    return;
338
  }
339
340
  global $lang;
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...
341
342
  foreach ($quest_statuses as $quest_id => $quest_status) {
343
    $quest_list[$quest_id]['quest_status_status'] = $quest_status;
344
345
    $questStatus = DbQuery::build()
346
      ->setTable('quest_status')
347
      ->setWhereArray(array(
348
        'quest_status_quest_id' => $quest_id,
349
        'quest_status_user_id'  => $user['id'],
350
      ))
351
      ->doSelectFetch();
352
353
    if (empty($questStatus)) {
354
      DbQuery::build()
355
        ->setTable('quest_status')
356
        ->setValues(array(
357
          'quest_status_quest_id' => $quest_id,
358
          'quest_status_user_id'  => $user['id'],
359
          'quest_status_status'   => $quest_status
360
        ))
361
        ->doInsert();
362
    } elseif ($questStatus['quest_status_status'] != $quest_status) {
363
      DbQuery::build()
364
        ->setTable('quest_status')
365
        ->setWhereArray(array(
366
          'quest_status_quest_id' => $quest_id,
367
          'quest_status_user_id'  => $user['id'],
368
        ))
369
        ->setValues(array(
370
          'quest_status_status' => $quest_status
371
        ))
372
        ->doUpdate();
373
    }
374
  }
375
376
  if (empty($rewards)) {
377
    return;
378
  }
379
380
  $db_changeset = array();
381
  $total_rewards = array();
382
  $comment_dm = '';
383
384
  foreach ($rewards as $quest_id => $user_data) {
385
    foreach ($user_data as $user_id => $planet_data) {
386
      foreach ($planet_data as $planet_id => $reward_list) {
387
        $comment = sprintf($lang['qst_msg_complete_body'], $quest_list[$quest_id]['quest_name']);
388
        $comment_dm .= isset($reward_list[RES_DARK_MATTER]) ? $comment : '';
389
390
        $comment_reward = array();
391
        foreach ($reward_list as $unit_id => $unit_amount) {
392
          $comment_reward[] = $unit_amount . ' ' . $lang['tech'][$unit_id];
393
          $total_rewards[$user_id][$planet_id][$unit_id] += $unit_amount;
394
        }
395
        $comment .= " {$lang['qst_msg_your_reward']} " . implode(',', $comment_reward);
396
397
        msg_send_simple_message($user['id'], 0, SN_TIME_NOW, MSG_TYPE_ADMIN, $lang['msg_from_admin'], $lang['qst_msg_complete_subject'], $comment);
398
399
        DbQuery::build()
400
          ->setTable('quest_status')
401
          ->setValues(array(
402
            'quest_status_quest_id' => $quest_id,
403
            'quest_status_user_id'  => $user_id,
404
            'quest_status_status'   => QUEST_STATUS_COMPLETE
405
          ))
406
          ->doInsert();
407
      }
408
    }
409
  }
410
411
  $group_resources = sn_get_groups('resources_loot');
412
  $quest_rewards_allowed = questAllowedRewardsList();
413
  if (!empty($total_rewards)) {
414
    foreach ($total_rewards as $user_id => $planet_data) {
415
      $user_row = db_user_by_id($user_id);
0 ignored issues
show
Deprecated Code introduced by
The function db_user_by_id() has been deprecated. ( Ignorable by Annotation )

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

415
      $user_row = /** @scrutinizer ignore-deprecated */ db_user_by_id($user_id);
Loading history...
416
      foreach ($planet_data as $planet_id => $unit_data) {
417
        $local_changeset = array();
418
        foreach ($unit_data as $unit_id => $unit_amount) {
419
          if (!isset($quest_rewards_allowed[$unit_id])) {
420
            continue;
421
          }
422
423
          if ($unit_id == RES_DARK_MATTER) {
424
            rpg_points_change($user['id'], RPG_QUEST, $unit_amount, $comment_dm);
425
          } elseif (isset($group_resources[$unit_id])) {
426
            $local_changeset[pname_resource_name($unit_id)] = array('delta' => $unit_amount);
427
          } else // Проверим на юниты
428
          {
429
            $db_changeset['unit'][] = OldDbChangeSet::db_changeset_prepare_unit($unit_id, $unit_amount, $user_row, $planet_id);
0 ignored issues
show
Deprecated Code introduced by
The function DBAL\OldDbChangeSet::db_changeset_prepare_unit() has been deprecated. ( Ignorable by Annotation )

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

429
            $db_changeset['unit'][] = /** @scrutinizer ignore-deprecated */ OldDbChangeSet::db_changeset_prepare_unit($unit_id, $unit_amount, $user_row, $planet_id);
Loading history...
430
          }
431
        }
432
433
        if (!empty($local_changeset)) {
434
          $planet_id = $planet_id == 0 && isset($user_row['id_planet']) ? $user_row['id_planet'] : $planet_id;
435
          $db_changeset[$planet_id ? 'planets' : 'users'][] = array(
436
            'action'  => SQL_OP_UPDATE,
437
            P_VERSION => 1,
438
            'where'   => array(
439
              "id" => $planet_id ? $planet_id : $user_id,
440
            ),
441
            'fields'  => $local_changeset,
442
          );
443
        }
444
      }
445
    }
446
447
    OldDbChangeSet::db_changeset_apply($db_changeset);
0 ignored issues
show
Deprecated Code introduced by
The function DBAL\OldDbChangeSet::db_changeset_apply() has been deprecated. ( Ignorable by Annotation )

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

447
    /** @scrutinizer ignore-deprecated */ OldDbChangeSet::db_changeset_apply($db_changeset);
Loading history...
448
  }
449
}
450
451
function get_quest_amount_complete($user_id) {
452
  return count(qst_get_quests($user_id, QUEST_STATUS_COMPLETE));
453
}
454
455
function get_quest_amount_in_progress($user_id) {
456
  return count(qst_get_quests($user_id, QUEST_STATUS_STARTED));
457
}
458