Completed
Push — trunk ( d79498...d7aafa )
by SuperNova.WS
04:22
created

tpl_menu_adminize()   A

Complexity

Conditions 4
Paths 6

Size

Total Lines 10
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 4
eloc 5
nc 6
nop 1
dl 0
loc 10
rs 9.2
c 0
b 0
f 0
1
<?php
0 ignored issues
show
Coding Style Compatibility introduced by
For compatibility and reusability of your code, PSR1 recommends that a file should introduce either new symbols (like classes, functions, etc.) or have side-effects (like outputting something, or including other files), but not both at the same time. The first symbol is defined on line 16 and the first side effect is on line 632.

The PSR-1: Basic Coding Standard recommends that a file should either introduce new symbols, that is classes, functions, constants or similar, or have side effects. Side effects are anything that executes logic, like for example printing output, changing ini settings or writing to a file.

The idea behind this recommendation is that merely auto-loading a class should not change the state of an application. It also promotes a cleaner style of programming and makes your code less prone to errors, because the logic is not spread out all over the place.

To learn more about the PSR-1, please see the PHP-FIG site on the PSR-1.

Loading history...
2
3
use \Pages\PageTutorial;
4
use Planet\DBStaticPlanet;
5
use Player\playerTimeDiff;
6
7
// Wrappers for functions
8
9
/**
10
 * Get template name from path to skin
11
 *
12
 * @param $userSkinPath
13
 *
14
 * @return mixed
15
 */
16
function getSkinPathTemplate($userSkinPath) {
17
  static $template_names = array();
18
19
  if (!isset($template_names[$userSkinPath])) {
20
    $template_names[$userSkinPath] = file_exists(SN_ROOT_PHYSICAL . $userSkinPath . '_template.ini') ? sys_file_read(SN_ROOT_PHYSICAL . $userSkinPath . '_template.ini') : TEMPLATE_NAME;
21
  }
22
23
  return $template_names[$userSkinPath];
24
}
25
26
/**
27
 * @param string    $message
28
 * @param string    $title
29
 * @param string    $redirectTo
30
 * @param int       $timeout
31
 * @param bool|true $showHeader
32
 */
33
function messageBox($message, $title = '', $redirectTo = '', $timeout = 5, $showHeader = true) {
34
  global $lang, $template_result;
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...
35
36
  if (empty($title)) {
37
    $title = $lang['sys_error'];
38
  }
39
40
  $template = gettemplate('message_body', 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

40
  $template = gettemplate('message_body', /** @scrutinizer ignore-type */ true);
Loading history...
41
42
  $template_result['GLOBAL_DISPLAY_NAVBAR'] = $showHeader;
43
44
  $template->assign_vars(array(
45
//    'GLOBAL_DISPLAY_NAVBAR' => $showHeader,
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...
46
47
    'TITLE'       => $title,
48
    'MESSAGE'     => $message,
49
    'REDIRECT_TO' => $redirectTo,
50
    'TIMEOUT'     => $timeout,
51
  ));
52
53
  display($template, $title);
54
}
55
56
/**
57
 * Admin message box
58
 *
59
 * @see messageBox()
60
 */
61
function messageBoxAdmin($message, $title = '', $redirectTo = '', $timeout = 5) {
62
  messageBox($message, $title, $redirectTo, $timeout, false);
63
}
64
65
function messageBoxAdminAccessDenied($level = AUTH_LEVEL_ADMINISTRATOR) {
66
  global $user, $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...
67
68
  if ($user['authlevel'] < $level) {
69
    messageBoxAdmin($lang['adm_err_denied'], $lang['admin_title_access_denied'], SN_ROOT_VIRTUAL . 'overview.php');
70
  }
71
}
72
73
/**
74
 * @param array $menu
75
 *
76
 * @return array
77
 */
78
function tpl_menu_adminize($menu) {
79
  !is_array($menu) ? $menu = [] : false;
0 ignored issues
show
introduced by
The condition is_array($menu) is always true.
Loading history...
80
81
  foreach ($menu as &$menuItem) {
82
    if (!isset($menuItem[MENU_FIELD_AUTH_LEVEL])) {
83
      $menuItem[MENU_FIELD_AUTH_LEVEL] = AUTH_LEVEL_ADMINISTRATOR;
84
    }
85
  }
86
87
  return $menu;
88
}
89
90
/**
91
 * @param array $menu
92
 * @param array $extra
93
 */
94
function tpl_menu_merge_extra(&$menu, &$extra) {
95
  if (!is_array($extra) || !is_array($menu) || empty($menu)) {
0 ignored issues
show
introduced by
The condition is_array($extra) is always true.
Loading history...
introduced by
The condition is_array($menu) is always true.
Loading history...
96
    return;
97
  }
98
99
  foreach ($extra as $menu_item_id => $menu_item) {
100
    if (empty($menu_item['LOCATION'])) {
101
      $menu[$menu_item_id] = $menu_item;
102
      continue;
103
    }
104
105
    $item_location = $menu_item['LOCATION'];
106
    unset($menu_item['LOCATION']);
107
108
    $is_positioned = $item_location[0];
109
    if ($is_positioned == '+' || $is_positioned == '-') {
110
      $item_location = substr($item_location, 1);
111
    } else {
112
      $is_positioned = '';
113
    }
114
115
    if ($item_location) {
116
      $menu_keys = array_keys($menu);
117
      $insert_position = array_search($item_location, $menu_keys);
118
      if ($insert_position === false) {
119
        $insert_position = count($menu) - 1;
120
        $is_positioned = '+';
121
        $item_location = '';
122
      }
123
    } else {
124
      $insert_position = $is_positioned == '-' ? 0 : count($menu);
125
    }
126
127
    $insert_position += $is_positioned == '+' ? 1 : 0;
128
    $spliced = array_splice($menu, $insert_position, count($menu) - $insert_position);
129
    $menu[$menu_item_id] = $menu_item;
130
131
    if (!$is_positioned && $item_location) {
132
      unset($spliced[$item_location]);
133
    }
134
    $menu = array_merge($menu, $spliced);
135
  }
136
137
  $extra = array();
138
}
139
140
/**
141
 * @param array    $sn_menu
142
 * @param template $template
143
 */
144
function tpl_menu_assign_to_template(&$sn_menu, &$template) {
145
  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...
146
147
  if (empty($sn_menu) || !is_array($sn_menu)) {
148
    return;
149
  }
150
151
  foreach ($sn_menu as $menu_item_id => $menu_item) {
152
    if (!$menu_item) {
153
      continue;
154
    }
155
156
    if (is_string($menu_item_id)) {
157
      $menu_item['ID'] = $menu_item_id;
158
    }
159
160
    if ($menu_item['TYPE'] == 'lang') {
161
      $lang_string = &$lang;
162
      if (preg_match('#(\w+)(?:\[(\w+)\])?(?:\[(\w+)\])?(?:\[(\w+)\])?(?:\[(\w+)\])?#', $menu_item['ITEM'], $matches) && count($matches) > 1) {
163
        for ($i = 1; $i < count($matches); $i++) {
0 ignored issues
show
Performance Best Practice introduced by
It seems like you are calling the size function count() as part of the test condition. You might want to compute the size beforehand, and not on each iteration.

If the size of the collection does not change during the iteration, it is generally a good practice to compute it beforehand, and not on each iteration:

for ($i=0; $i<count($array); $i++) { // calls count() on each iteration
}

// Better
for ($i=0, $c=count($array); $i<$c; $i++) { // calls count() just once
}
Loading history...
164
          if (defined($matches[$i])) {
165
            $matches[$i] = constant($matches[$i]);
166
          }
167
          $lang_string = &$lang_string[$matches[$i]];
168
        }
169
      }
170
      $menu_item['ITEM'] = $lang_string && is_string($lang_string) ? $lang_string : "{L_{$menu_item['ITEM']}}";
171
    }
172
173
    $menu_item['ALT'] = htmlentities($menu_item['ALT']);
174
    $menu_item['TITLE'] = htmlentities($menu_item['TITLE']);
175
176
    if (!empty($menu_item['ICON'])) {
177
      if (is_string($menu_item['ICON'])) {
178
        $menu_item['ICON_PATH'] = $menu_item['ICON'];
179
      } else {
180
        $menu_item['ICON'] = $menu_item_id;
181
      }
182
    }
183
184
    $template->assign_block_vars('menu', $menu_item);
185
  }
186
}
187
188
/**
189
 * @param template $template
190
 *
191
 * @return template
192
 */
193
function tpl_render_menu($template) {
194
  global $user, $lang, $template_result, $sn_menu_admin_extra, $sn_menu_admin, $sn_menu, $sn_menu_extra;
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...
195
196
  lng_include('admin');
197
198
//  $template = gettemplate('menu', true);
0 ignored issues
show
Unused Code Comprehensibility introduced by
60% 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...
199
//  $template->assign_recursive($template_result);
200
201
  $template->assign_vars(array(
202
    'USER_AUTHLEVEL'      => $user['authlevel'],
203
    'USER_AUTHLEVEL_NAME' => $lang['user_level'][$user['authlevel']],
204
//    'USER_IMPERSONATOR'   => $template_result[F_IMPERSONATE_STATUS] != LOGIN_UNDEFINED,
0 ignored issues
show
Unused Code Comprehensibility introduced by
47% 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...
205
    'PAYMENT'             => SN::$gc->modules->countModulesInGroup('payment'),
206
    'MENU_START_HIDE'     => !empty($_COOKIE[SN_COOKIE . '_menu_hidden']) || defined('SN_GOOGLE'),
207
  ));
208
209
  if (isset($template_result['MENU_CUSTOMIZE'])) {
210
    $template->assign_vars(array(
211
      'PLAYER_OPTION_MENU_SHOW_ON_BUTTON'   => SN::$user_options[PLAYER_OPTION_MENU_SHOW_ON_BUTTON],
212
      'PLAYER_OPTION_MENU_HIDE_ON_BUTTON'   => SN::$user_options[PLAYER_OPTION_MENU_HIDE_ON_BUTTON],
213
      'PLAYER_OPTION_MENU_HIDE_ON_LEAVE'    => SN::$user_options[PLAYER_OPTION_MENU_HIDE_ON_LEAVE],
214
      'PLAYER_OPTION_MENU_UNPIN_ABSOLUTE'   => SN::$user_options[PLAYER_OPTION_MENU_UNPIN_ABSOLUTE],
215
      'PLAYER_OPTION_MENU_ITEMS_AS_BUTTONS' => SN::$user_options[PLAYER_OPTION_MENU_ITEMS_AS_BUTTONS],
216
      'PLAYER_OPTION_MENU_WHITE_TEXT'       => SN::$user_options[PLAYER_OPTION_MENU_WHITE_TEXT],
217
      'PLAYER_OPTION_MENU_OLD'              => SN::$user_options[PLAYER_OPTION_MENU_OLD],
218
      'PLAYER_OPTION_MENU_HIDE_SHOW_BUTTON' => empty($_COOKIE[SN_COOKIE . '_menu_hidden']) && !defined('SN_GOOGLE')
219
        ? SN::$user_options[PLAYER_OPTION_MENU_HIDE_SHOW_BUTTON] : 1,
220
    ));
221
  }
222
223
  if (defined('IN_ADMIN') && IN_ADMIN === true && !empty($user['authlevel']) && $user['authlevel'] > 0) {
224
    tpl_menu_merge_extra($sn_menu_admin, $sn_menu_admin_extra);
225
    $sn_menu_admin = tpl_menu_adminize($sn_menu_admin);
226
    tpl_menu_assign_to_template($sn_menu_admin, $template);
227
  } else {
228
    tpl_menu_merge_extra($sn_menu, $sn_menu_extra);
229
    tpl_menu_assign_to_template($sn_menu, $template);
230
  }
231
232
  return $template;
233
}
234
235
/**
236
 * @param template|string $page
237
 * @param string          $title
238
 * @param bool|true       $isDisplayTopNav
239
 * @param string          $metatags
240
 * @param bool|false      $AdminPage
241
 * @param bool|true       $isDisplayMenu
242
 *
243
 * @return mixed
244
 */
245
function display($page, $title = '') {
246
  if (!defined('SN_TIME_RENDER_START')) {
247
    define('SN_TIME_RENDER_START', microtime(true));
248
  }
249
250
  return sn_function_call('display', array($page, $title));
251
}
252
253
/**
254
 * @param template|string $page
255
 * @param string          $title
256
 * @param bool|true       $isDisplayTopNav
257
 * @param string          $metatags
258
 * @param bool|false      $AdminPage
259
 * @param bool|true       $isDisplayMenu
260
 * @param bool|int|string $exitStatus - Код или сообщение выхода
261
 */
262
function sn_display($page, $title = '') {
263
  global $debug, $user, $planetrow, $config, $lang, $template_result, $sn_mvc, $sn_page_name;
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...
264
265
  !empty($sn_mvc['view']['']) and execute_hooks($sn_mvc['view'][''], $page, 'view', '');
0 ignored issues
show
Comprehensibility Best Practice introduced by
Using logical operators such as and instead of && is generally not recommended.

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

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

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

Let’s take a look at a few examples:

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

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


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

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

Logical Operators are used for Control-Flow

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

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

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

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

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

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

Loading history...
266
267
  $exitStatus = true;
268
  $template_result['LOGIN_LOGOUT'] = $inLoginLogout = defined('LOGIN_LOGOUT') && LOGIN_LOGOUT === true;
269
270
  if (is_object($page)) {
271
    isset($page->_rootref['PAGE_TITLE']) && empty($title) ? $title = $page->_rootref['PAGE_TITLE'] : false;
272
    !$title && !empty($page->_rootref['PAGE_HEADER']) ? $title = $page->_rootref['PAGE_HEADER'] : false;
273
    !isset($page->_rootref['PAGE_HEADER']) && $title ? $page->assign_var('PAGE_HEADER', $title) : false;
274
  }
275
276
  $isRenderGlobal = is_object($page) && isset($template_result['GLOBAL_DISPLAY_HEADER']) ? $template_result['GLOBAL_DISPLAY_HEADER'] : true;
277
278
  // Global header
279
  if ($isRenderGlobal) {
280
    renderHeader($page, $title, $template_result, $inLoginLogout, $user, $config, $lang, $planetrow);
281
  }
282
283
  // Page content
284
  !is_array($page) ? $page = array($page) : false;
0 ignored issues
show
introduced by
The condition is_array($page) is always false.
Loading history...
285
  $result_added = false;
286
  foreach ($page as $page_item) {
287
    /**
288
     * @var template $page_item
289
     */
290
    if (!$result_added && is_object($page_item) && isset($page_item->_tpldata['result'])) {
291
      $resultTemplate = gettemplate('_result_message');
292
      $resultTemplate->_tpldata = $page_item->_tpldata;
293
      displayP($resultTemplate);
294
//      $page_item = gettemplate('_result_message', $page_item);
0 ignored issues
show
Unused Code Comprehensibility introduced by
55% 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...
295
//      $temp = $page_item->files['_result_message'];
296
//      unset($page_item->files['_result_message']);
297
//      $page_item->files = array_reverse($page_item->files);
298
//      $page_item->files['_result_message'] = $temp;
299
//      $page_item->files = array_reverse($page_item->files);
300
      $result_added = true;
301
    }
302
//    $page_item->assign_recursive($template_result);
0 ignored issues
show
Unused Code Comprehensibility introduced by
75% 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...
303
    displayP($page_item);
304
  }
305
306
  if (is_array($template_result[TEMPLATE_EXTRA_ARRAY]) && !empty($template_result[TEMPLATE_EXTRA_ARRAY])) {
307
    foreach ($template_result[TEMPLATE_EXTRA_ARRAY] as $extraName => $extraTemplate) {
308
      /**
309
       * @var template $extraTemplate
310
       */
311
      displayP($extraTemplate);
312
    }
313
  }
314
315
  // Global footer
316
  if ($isRenderGlobal) {
317
    renderFooter();
318
  }
319
320
  $user['authlevel'] >= 3 && $config->debug ? $debug->echo_log() : false;;
321
322
  sn_db_disconnect();
323
324
  $exitStatus and die($exitStatus === true ? 0 : $exitStatus);
0 ignored issues
show
Best Practice introduced by
Using exit here is not recommended.

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

Loading history...
introduced by
The condition $exitStatus === true is always true.
Loading history...
Comprehensibility Best Practice introduced by
Using logical operators such as and instead of && is generally not recommended.

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

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

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

Let’s take a look at a few examples:

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

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


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

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

Logical Operators are used for Control-Flow

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

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

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

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

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

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

Loading history...
325
}
326
327
/**
328
 * @param $page
329
 * @param $title
330
 * @param $template_result
331
 * @param $inLoginLogout
332
 * @param $user
333
 * @param $config
334
 * @param $lang
335
 * @param $planetrow
336
 */
337
function renderHeader($page, $title, &$template_result, $inLoginLogout, &$user, $config, $lang, $planetrow) {
338
  if (SN::$headerRendered) {
339
    return;
340
  }
341
342
  ob_end_flush();
343
344
  ob_start();
345
//  pdump(microtime(true) - SN_TIME_MICRO, 'Header render started');
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...
346
  $isDisplayTopNav = true;
347
  $isDisplayMenu = true;
348
349
  isset($template_result['GLOBAL_DISPLAY_MENU']) ? $isDisplayMenu = $template_result['GLOBAL_DISPLAY_MENU'] : false;
350
  isset($template_result['GLOBAL_DISPLAY_NAVBAR']) ? $isDisplayTopNav = $template_result['GLOBAL_DISPLAY_NAVBAR'] : false;
351
352
  // TODO: DEPRECATED! Use $template_result to turn menu and navbar or ond off!
353
  if (is_object($page)) {
354
    isset($page->_rootref['MENU']) ? $isDisplayMenu = $page->_rootref['MENU'] : false;
355
    isset($page->_rootref['NAVBAR']) ? $isDisplayTopNav = $page->_rootref['NAVBAR'] : false;
356
  }
357
358
  $inAdmin = defined('IN_ADMIN') && IN_ADMIN === true;
359
  $isDisplayMenu = ($isDisplayMenu || $inAdmin) && !isset($_COOKIE['menu_disable']);
0 ignored issues
show
introduced by
Consider adding parentheses for clarity. Current Interpretation: $isDisplayMenu = ($isDis...inAdmin && ! IssetNode), Probably Intended Meaning: $isDisplayMenu = $isDisp...inAdmin && ! IssetNode)
Loading history...
360
  $isDisplayTopNav = $isDisplayTopNav && !$inAdmin;
361
362
  if ($inLoginLogout || empty($user['id']) || !is_numeric($user['id'])) {
363
    $isDisplayMenu = false;
364
    $isDisplayTopNav = false;
365
  }
366
367
  $user_time_diff = playerTimeDiff::user_time_diff_get();
368
  $user_time_measured_unix = intval(isset($user_time_diff[PLAYER_OPTION_TIME_DIFF_MEASURE_TIME]) ? strtotime($user_time_diff[PLAYER_OPTION_TIME_DIFF_MEASURE_TIME]) : 0);
369
  $measureTimeDiff = intval(
370
    empty($user_time_diff[PLAYER_OPTION_TIME_DIFF_FORCED])
371
    &&
372
    (SN_TIME_NOW - $user_time_measured_unix > PERIOD_HOUR || $user_time_diff[PLAYER_OPTION_TIME_DIFF] == '')
373
  );
374
375
  $template = gettemplate('_page_20_header', 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

375
  $template = gettemplate('_page_20_header', /** @scrutinizer ignore-type */ true);
Loading history...
376
377
  renderJavaScript();
378
379
  renderCss($inLoginLogout);
380
381
  $template->assign_vars(array(
382
    'LANG_LANGUAGE'  => $lang['LANG_INFO']['LANG_NAME_ISO2'],
383
    'LANG_ENCODING'  => 'utf-8',
384
    'LANG_DIRECTION' => $lang['LANG_INFO']['LANG_DIRECTION'],
385
386
    'SN_ROOT_VIRTUAL' => SN_ROOT_VIRTUAL,
387
388
    'ADV_SEO_META_DESCRIPTION' => $config->adv_seo_meta_description,
389
    'ADV_SEO_META_KEYWORDS'    => $config->adv_seo_meta_keywords,
390
391
    // WARNING! This can be set by page!
392
    // CHANGE CODE TO MAKE IT IMPOSSIBLE!
393
    'GLOBAL_META_TAGS'         => isset($page->_rootref['GLOBAL_META_TAGS']) ? $page->_rootref['GLOBAL_META_TAGS'] : '',
394
  ));
395
396
  $template->assign_vars(array(
397
    'GLOBAL_DISPLAY_MENU'   => $isDisplayMenu,
398
    'GLOBAL_DISPLAY_NAVBAR' => $isDisplayTopNav,
399
400
    'USER_AUTHLEVEL' => intval($user['authlevel']),
401
402
    'FONT_SIZE'                        => playerFontSize(),
403
    'FONT_SIZE_PERCENT_DEFAULT_STRING' => FONT_SIZE_PERCENT_DEFAULT_STRING,
404
405
    'SN_TIME_NOW'          => SN_TIME_NOW,
406
    'LOGIN_LOGOUT'         => $template_result['LOGIN_LOGOUT'],
407
    'GAME_MODE_CSS_PREFIX' => $config->game_mode == GAME_BLITZ ? 'blitz_' : '',
408
    'TIME_DIFF_MEASURE'    => $measureTimeDiff, // Проводить замер только если не выставлен флаг форсированного замера И (иссяк интервал замера ИЛИ замера еще не было)
409
410
    'title'              => ($title ? "{$title} - " : '') . "{$lang['sys_server']} {$config->game_name} - {$lang['sys_supernova']}",
411
    'ADV_SEO_JAVASCRIPT' => $config->adv_seo_javascript,
412
413
    'SOUND_ENABLED'                        => SN::$user_options[PLAYER_OPTION_SOUND_ENABLED],
414
    'PLAYER_OPTION_ANIMATION_DISABLED'     => SN::$user_options[PLAYER_OPTION_ANIMATION_DISABLED],
415
    'PLAYER_OPTION_PROGRESS_BARS_DISABLED' => SN::$user_options[PLAYER_OPTION_PROGRESS_BARS_DISABLED],
416
417
    'IMPERSONATING'                        => !empty($template_result[F_IMPERSONATE_STATUS]) ? sprintf($lang['sys_impersonated_as'], $user['username'], $template_result[F_IMPERSONATE_OPERATOR]) : '',
418
    'PLAYER_OPTION_DESIGN_DISABLE_BORDERS' => SN::$user_options[PLAYER_OPTION_DESIGN_DISABLE_BORDERS],
419
  ));
420
  $template->assign_recursive($template_result);
421
422
  if ($isDisplayMenu) {
423
    tpl_render_menu($template);
424
  }
425
426
  if ($isDisplayTopNav) {
427
    SN::$gc->pimp->tpl_render_topnav($user, $planetrow, $template);
428
  }
429
430
  displayP($template);
431
  ob_end_flush();
432
433
  SN::$headerRendered = true;
434
435
  ob_start();
436
}
437
438
/**
439
 */
440
function renderFooter() {
441
  $templateFooter = gettemplate('_page_90_footer', 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

441
  $templateFooter = gettemplate('_page_90_footer', /** @scrutinizer ignore-type */ true);
Loading history...
442
443
  $templateFooter->assign_vars([
444
    'SN_TIME_NOW'      => SN_TIME_NOW,
445
    'SN_VERSION'       => SN_VERSION,
446
    'ADMIN_EMAIL'      => SN::$config->game_adminEmail,
447
    'CURRENT_YEAR'     => date('Y', SN_TIME_NOW),
448
    'DB_PATCH_VERSION' => dbPatchGetCurrent(),
449
  ]);
450
451
  displayP($templateFooter);
452
}
453
454
/**
455
 * @return mixed|string
456
 */
457
function playerFontSize() {
458
  $font_size = !empty($_COOKIE[SN_COOKIE_F]) ? $_COOKIE[SN_COOKIE_F] : SN::$user_options[PLAYER_OPTION_BASE_FONT_SIZE];
459
  if (strpos($font_size, '%') !== false) {
460
    // Размер шрифта в процентах
461
    $font_size = min(max(floatval($font_size), FONT_SIZE_PERCENT_MIN), FONT_SIZE_PERCENT_MAX) . '%';
462
463
    return $font_size;
464
  } elseif (strpos($font_size, 'px') !== false) {
465
    // Размер шрифта в пикселях
466
    $font_size = min(max(floatval($font_size), FONT_SIZE_PIXELS_MIN), FONT_SIZE_PIXELS_MAX) . 'px';
467
468
    return $font_size;
469
  } else {
470
    // Не мышонка, не лягушка...
471
    $font_size = FONT_SIZE_PERCENT_DEFAULT_STRING;
472
473
    return $font_size;
474
  }
475
}
476
477
/**
478
 * @param $template_result
479
 * @param $is_login
480
 */
481
function tpl_global_header(&$template_result, $is_login) {
482
  renderJavaScript();
483
484
  renderCss($is_login);
485
}
486
487
/**
488
 * Checks if minified/full-size CSS file exists - and adds it if any
489
 *
490
 * @param $cssFileName
491
 * @param &$cssArray
492
 *
493
 * @return bool
494
 */
495
function cssAddFileName($cssFileName, &$cssArray) {
496
  $result = false;
497
  if (file_exists(SN_ROOT_PHYSICAL . $cssFileName . '.min.css')) {
498
    $cssArray[$cssFileName . '.min.css'] = '';
499
    $result = true;
500
  } elseif (file_exists(SN_ROOT_PHYSICAL . $cssFileName . '.css')) {
501
    $cssArray[$cssFileName . '.css'] = '';
502
    $result = true;
503
  }
504
505
  return $result;
506
}
507
508
/**
509
 * @param $is_login
510
 */
511
function renderCss($is_login) {
512
  global $sn_mvc, $sn_page_name, $template_result;
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...
513
514
  empty($sn_mvc['css']) ? $sn_mvc['css'] = array('' => array()) : false;
515
516
  $standard_css = array();
517
  cssAddFileName('design/css/jquery-ui', $standard_css);
518
  cssAddFileName('design/css/global', $standard_css);
519
  $is_login ? cssAddFileName('design/css/login', $standard_css) : false;
520
  cssAddFileName(TEMPLATE_PATH . '/_template', $standard_css);
521
  cssAddFileName(SN::$gc->theUser->getSkinPath() . 'skin', $standard_css);
522
  cssAddFileName('design/css/global_override', $standard_css);
523
524
  // Prepending standard CSS files
525
  $sn_mvc['css'][''] = array_merge($standard_css, $sn_mvc['css']['']);
526
527
  renderFileListInclude($template_result, $sn_mvc, $sn_page_name, 'css');
528
}
529
530
/**
531
 */
532
function renderJavaScript() {
533
  global $sn_mvc, $sn_page_name, $template_result;
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...
534
535
  renderFileListInclude($template_result, $sn_mvc, $sn_page_name, 'javascript');
536
}
537
538
/**
539
 * @param array   $template_result
540
 * @param array[] $sn_mvc
541
 * @param string  $sn_page_name
542
 * @param string  $fileType - 'css' or 'javascript'
543
 */
544
function renderFileListInclude(&$template_result, &$sn_mvc, $sn_page_name, $fileType) {
545
  if (empty($sn_mvc[$fileType])) {
546
    return;
547
  }
548
549
  foreach ($sn_mvc[$fileType] as $page_name => $script_list) {
550
    if (empty($page_name) || $page_name == $sn_page_name) {
551
      foreach ($script_list as $filename => $content) {
552
        $template_result['.'][$fileType][] = array(
553
          'FILE'    => $filename,
554
          'CONTENT' => $content,
555
        );
556
      }
557
    }
558
  }
559
}
560
561
/**
562
 * @param $time
563
 * @param $event
564
 * @param $msg
565
 * @param $prefix
566
 * @param $is_decrease
567
 * @param $fleet_flying_row
568
 * @param $fleet_flying_sorter
569
 * @param $fleet_flying_events
570
 * @param $fleet_event_count
571
 */
572
function tpl_topnav_event_build_helper($time, $event, $msg, $prefix, $is_decrease, $fleet_flying_row, &$fleet_flying_sorter, &$fleet_flying_events, &$fleet_event_count) {
573
  $fleet_flying_sorter[$fleet_event_count] = $time;
574
  $fleet_flying_events[$fleet_event_count] = array(
575
    'ROW'              => $fleet_flying_row,
576
    'FLEET_ID'         => $fleet_flying_row['fleet_id'],
577
    'EVENT'            => $event,
578
    'COORDINATES'      => uni_render_coordinates($fleet_flying_row, $prefix),
579
    'COORDINATES_TYPE' => $fleet_flying_row["{$prefix}type"],
580
    'TEXT'             => "{$msg}",
581
    'DECREASE'         => $is_decrease,
582
  );
583
  $fleet_event_count++;
584
}
585
586
/**
587
 * @param template $template
588
 * @param array    $fleet_flying_list
589
 * @param string   $type
590
 */
591
function tpl_topnav_event_build(&$template, $fleet_flying_list, $type = 'fleet') {
592
  if (empty($fleet_flying_list)) {
593
    return;
594
  }
595
596
  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...
597
598
  $fleet_event_count = 0;
599
  $fleet_flying_sorter = array();
600
  $fleet_flying_events = array();
601
  foreach ($fleet_flying_list as &$fleet_flying_row) {
602
    $will_return = true;
603
    if ($fleet_flying_row['fleet_mess'] == 0) {
604
      // cut fleets on Hold and Expedition
605
      if ($fleet_flying_row['fleet_start_time'] >= SN_TIME_NOW) {
606
        $fleet_flying_row['fleet_mission'] == MT_RELOCATE ? $will_return = false : false;
607
        tpl_topnav_event_build_helper($fleet_flying_row['fleet_start_time'], EVENT_FLEET_ARRIVE, $lang['sys_event_arrive'], 'fleet_end_', !$will_return, $fleet_flying_row, $fleet_flying_sorter, $fleet_flying_events, $fleet_event_count);
608
      }
609
      if ($fleet_flying_row['fleet_end_stay']) {
610
        tpl_topnav_event_build_helper($fleet_flying_row['fleet_end_stay'], EVENT_FLEET_STAY, $lang['sys_event_stay'], 'fleet_end_', false, $fleet_flying_row, $fleet_flying_sorter, $fleet_flying_events, $fleet_event_count);
611
      }
612
    }
613
    if ($will_return) {
614
      tpl_topnav_event_build_helper($fleet_flying_row['fleet_end_time'], EVENT_FLEET_RETURN, $lang['sys_event_return'], 'fleet_start_', true, $fleet_flying_row, $fleet_flying_sorter, $fleet_flying_events, $fleet_event_count);
615
    }
616
  }
617
618
  asort($fleet_flying_sorter);
619
620
  $fleet_flying_count = count($fleet_flying_list);
621
  foreach ($fleet_flying_sorter as $fleet_event_id => $fleet_time) {
622
    $fleet_event = &$fleet_flying_events[$fleet_event_id];
623
    $template->assign_block_vars("flying_{$type}s", array(
624
      'TIME' => max(0, $fleet_time - SN_TIME_NOW),
625
      'TEXT' => $fleet_flying_count,
626
      'HINT' => date(FMT_DATE_TIME, $fleet_time + SN_CLIENT_TIME_DIFF) . " - {$lang['sys_fleet']} {$fleet_event['TEXT']} {$fleet_event['COORDINATES']} {$lang['sys_planet_type_sh'][$fleet_event['COORDINATES_TYPE']]} {$lang['type_mission'][$fleet_event['ROW']['fleet_mission']]}",
627
    ));
628
    $fleet_event['DECREASE'] ? $fleet_flying_count-- : false;
629
  }
630
}
631
632
SN::$afterInit[] = function () {
633
  SN::$gc->pimp->add()->tpl_render_topnav($t = 'sn_tpl_render_topnav', [], null);
634
};
635
636
/**
637
 * @param array    $user
638
 * @param array    $planetrow
639
 * @param template $template
640
 *
641
 * @return array
642
 */
643
function sn_tpl_render_topnav($prevUser, $user, $planetrow, $template) {
644
  global $lang, $config, $sn_mvc;
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...
645
646
  // This call was not first one... Using results from previous call
647
  if (!empty($prevUser['username'])) {
648
    $user = $prevUser;
649
  }
650
651
  if (!is_array($user)) {
652
    return $user;
653
  }
654
655
  $GET_mode = sys_get_param_str('mode');
656
657
  $ThisUsersPlanets = DBStaticPlanet::db_planet_list_sorted($user);
658
  foreach ($ThisUsersPlanets as $CurPlanet) {
0 ignored issues
show
Bug introduced by
The expression $ThisUsersPlanets of type false is not traversable.
Loading history...
659
    if ($CurPlanet['destruyed']) {
660
      continue;
661
    }
662
663
    $fleet_listx = flt_get_fleets_to_planet($CurPlanet);
664
665
    $template->assign_block_vars('topnav_planets', [
666
      'ID'          => $CurPlanet['id'],
667
      'NAME'        => $CurPlanet['name'],
668
      'TYPE'        => $CurPlanet['planet_type'],
669
      'TYPE_TEXT'   => $lang['sys_planet_type_sh'][$CurPlanet['planet_type']],
670
      'IS_CAPITAL'  => $CurPlanet['planet_type'] == PT_PLANET && $CurPlanet['id'] == $user['id_planet'],
671
      'IS_MOON'     => $CurPlanet['planet_type'] == PT_MOON,
672
      'PLIMAGE'     => $CurPlanet['image'],
673
      'FLEET_ENEMY' => $fleet_listx['enemy']['count'],
674
      'COORDS'      => uni_render_coordinates($CurPlanet),
675
      'SELECTED'    => $CurPlanet['id'] == $user['current_planet'] ? ' selected' : '',
676
    ]);
677
  }
678
679
  $fleet_flying_list = tpl_get_fleets_flying($user);
680
  tpl_topnav_event_build($template, $fleet_flying_list[0]);
681
  tpl_topnav_event_build($template, $fleet_flying_list[MT_EXPLORE], 'expedition');
682
683
  que_tpl_parse($template, QUE_STRUCTURES, $user, $planetrow, null, true);
684
  que_tpl_parse($template, QUE_RESEARCH, $user, array(), null, !SN::$user_options[PLAYER_OPTION_NAVBAR_RESEARCH_WIDE]);
685
  que_tpl_parse($template, SUBQUE_FLEET, $user, $planetrow, null, true);
686
687
  tpl_navbar_extra_buttons($sn_mvc, $template);
688
  tpl_navbar_render_news($template, $user, $config);
689
  tpl_navbar_render_notes($template, $user);
690
  $tutorial_enabled = PageTutorial::renderNavBar($template);
691
692
693
  $premium_lvl = mrc_get_level($user, false, UNIT_PREMIUM, true, true);
0 ignored issues
show
Bug introduced by
false of type false is incompatible with the type array expected by parameter $planet of mrc_get_level(). ( Ignorable by Annotation )

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

693
  $premium_lvl = mrc_get_level($user, /** @scrutinizer ignore-type */ false, UNIT_PREMIUM, true, true);
Loading history...
694
695
  $str_date_format = "%3$02d %2$0s %1$04d {$lang['top_of_year']} %4$02d:%5$02d:%6$02d";
696
  $time_now_parsed = getdate(SN_TIME_NOW);
697
  $time_local_parsed = getdate(defined('SN_CLIENT_TIME_LOCAL') ? SN_CLIENT_TIME_LOCAL : SN_TIME_NOW);
698
699
  $template->assign_vars(array(
700
    'QUE_ID'   => QUE_RESEARCH,
701
    'QUE_HTML' => 'topnav',
702
703
    'RESEARCH_ONGOING' => (boolean)$user['que'],
704
705
    'TIME_TEXT'       => sprintf($str_date_format, $time_now_parsed['year'], $lang['months'][$time_now_parsed['mon']], $time_now_parsed['mday'],
706
      $time_now_parsed['hours'], $time_now_parsed['minutes'], $time_now_parsed['seconds']
707
    ),
708
    'TIME_TEXT_LOCAL' => sprintf($str_date_format, $time_local_parsed['year'], $lang['months'][$time_local_parsed['mon']], $time_local_parsed['mday'],
709
      $time_local_parsed['hours'], $time_local_parsed['minutes'], $time_local_parsed['seconds']
710
    ),
711
712
    'GAME_BLITZ_REGISTER'             => $config->game_blitz_register,
713
    'GAME_BLITZ_REGISTER_TEXT'        => $lang['sys_blitz_registration_mode_list'][$config->game_blitz_register],
714
    'BLITZ_REGISTER_OPEN'             => $config->game_blitz_register == BLITZ_REGISTER_OPEN,
715
    'BLITZ_REGISTER_CLOSED'           => $config->game_blitz_register == BLITZ_REGISTER_CLOSED,
716
    'BLITZ_REGISTER_SHOW_LOGIN'       => $config->game_blitz_register == BLITZ_REGISTER_SHOW_LOGIN,
717
    'BLITZ_REGISTER_DISCLOSURE_NAMES' => $config->game_blitz_register == BLITZ_REGISTER_DISCLOSURE_NAMES,
718
    'GAME_BLITZ'                      => $config->game_mode == GAME_BLITZ,
719
720
    'USERS_ONLINE'  => $config->var_online_user_count,
721
    'USERS_TOTAL'   => $config->users_amount,
722
    'USER_RANK'     => $user['total_rank'],
723
    'USER_NICK'     => $user['username'],
724
    'USER_AVATAR'   => $user['avatar'],
725
    'USER_AVATARID' => $user['id'],
726
    'USER_PREMIUM'  => $premium_lvl,
727
    'USER_RACE'     => $user['player_race'],
728
729
    'TOPNAV_CURRENT_PLANET'       => $user['current_planet'],
730
    'TOPNAV_CURRENT_PLANET_NAME'  => uni_render_planet_full($planetrow), // htmlspecialchars($planetrow['name']),
0 ignored issues
show
Unused Code Comprehensibility introduced by
78% 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...
731
    'TOPNAV_CURRENT_PLANET_IMAGE' => $planetrow['image'],
732
    'TOPNAV_COLONIES_CURRENT'     => get_player_current_colonies($user),
733
    'TOPNAV_COLONIES_MAX'         => get_player_max_colonies($user),
734
    'NAVBAR_MODE'                 => $GET_mode,
735
736
    'TOPNAV_DARK_MATTER'            => mrc_get_level($user, '', RES_DARK_MATTER),
0 ignored issues
show
Bug introduced by
'' of type string is incompatible with the type array expected by parameter $planet of mrc_get_level(). ( Ignorable by Annotation )

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

736
    'TOPNAV_DARK_MATTER'            => mrc_get_level($user, /** @scrutinizer ignore-type */ '', RES_DARK_MATTER),
Loading history...
737
    'TOPNAV_DARK_MATTER_TEXT'       => HelperString::numberFloorAndFormat(mrc_get_level($user, '', RES_DARK_MATTER)),
0 ignored issues
show
Bug introduced by
It seems like mrc_get_level($user, '', RES_DARK_MATTER) can also be of type boolean; however, parameter $number of HelperString::numberFloorAndFormat() does only seem to accept integer|double, maybe add an additional type check? ( Ignorable by Annotation )

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

737
    'TOPNAV_DARK_MATTER_TEXT'       => HelperString::numberFloorAndFormat(/** @scrutinizer ignore-type */ mrc_get_level($user, '', RES_DARK_MATTER)),
Loading history...
738
    'TOPNAV_DARK_MATTER_PLAIN'      => mrc_get_level($user, '', RES_DARK_MATTER, false, true),
739
    'TOPNAV_DARK_MATTER_PLAIN_TEXT' => HelperString::numberFloorAndFormat(mrc_get_level($user, '', RES_DARK_MATTER, false, true)),
740
    'TOPNAV_METAMATTER'             => mrc_get_level($user, '', RES_METAMATTER),
741
    'TOPNAV_METAMATTER_TEXT'        => HelperString::numberFloorAndFormat(mrc_get_level($user, '', RES_METAMATTER)),
742
743
    // TODO ГРЯЗНЫЙ ХАК!!!
744
    'TOPNAV_PAYMENT'                => SN::$gc->modules->countModulesInGroup('payment') && !defined('SN_GOOGLE'),
745
746
    'TOPNAV_MESSAGES_ADMIN'    => $user['msg_admin'],
747
    'TOPNAV_MESSAGES_PLAYER'   => $user['mnl_joueur'],
748
    'TOPNAV_MESSAGES_ALLIANCE' => $user['mnl_alliance'],
749
    'TOPNAV_MESSAGES_ATTACK'   => $user['mnl_attaque'],
750
    'TOPNAV_MESSAGES_ALL'      => $user['new_message'],
751
752
    'TOPNAV_FLEETS_FLYING'      => count($fleet_flying_list[0]),
753
    'TOPNAV_FLEETS_TOTAL'       => GetMaxFleets($user),
754
    'TOPNAV_EXPEDITIONS_FLYING' => count($fleet_flying_list[MT_EXPLORE]),
755
    'TOPNAV_EXPEDITIONS_TOTAL'  => get_player_max_expeditons($user),
756
757
    'TOPNAV_QUEST_COMPLETE'    => get_quest_amount_complete($user['id']),
758
    'TOPNAV_QUEST_IN_PROGRESS' => get_quest_amount_in_progress($user['id']),
759
760
    'GAME_NEWS_OVERVIEW'       => $config->game_news_overview,
761
    'GAME_RESEARCH_DISABLED'   => defined('GAME_RESEARCH_DISABLED') && GAME_RESEARCH_DISABLED,
0 ignored issues
show
Bug introduced by
The constant GAME_RESEARCH_DISABLED was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
762
    'GAME_DEFENSE_DISABLED'    => defined('GAME_DEFENSE_DISABLED') && GAME_DEFENSE_DISABLED,
0 ignored issues
show
Bug introduced by
The constant GAME_DEFENSE_DISABLED was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
763
    'GAME_STRUCTURES_DISABLED' => defined('GAME_STRUCTURES_DISABLED') && GAME_STRUCTURES_DISABLED,
0 ignored issues
show
Bug introduced by
The constant GAME_STRUCTURES_DISABLED was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
764
    'GAME_HANGAR_DISABLED'     => defined('GAME_HANGAR_DISABLED') && GAME_HANGAR_DISABLED,
0 ignored issues
show
Bug introduced by
The constant GAME_HANGAR_DISABLED was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
765
766
    'PLAYER_OPTION_NAVBAR_PLANET_VERTICAL'        => SN::$user_options[PLAYER_OPTION_NAVBAR_PLANET_VERTICAL],
767
    'PLAYER_OPTION_NAVBAR_PLANET_OLD'             => SN::$user_options[PLAYER_OPTION_NAVBAR_PLANET_OLD],
768
    'PLAYER_OPTION_NAVBAR_PLANET_DISABLE_STORAGE' => SN::$user_options[PLAYER_OPTION_NAVBAR_PLANET_DISABLE_STORAGE],
769
    'PLAYER_OPTION_NAVBAR_DISABLE_RESEARCH'       => SN::$user_options[PLAYER_OPTION_NAVBAR_DISABLE_RESEARCH],
770
    'PLAYER_OPTION_NAVBAR_DISABLE_PLANET'         => SN::$user_options[PLAYER_OPTION_NAVBAR_DISABLE_PLANET],
771
    'PLAYER_OPTION_NAVBAR_DISABLE_HANGAR'         => SN::$user_options[PLAYER_OPTION_NAVBAR_DISABLE_HANGAR],
772
    'PLAYER_OPTION_NAVBAR_DISABLE_FLYING_FLEETS'  => SN::$user_options[PLAYER_OPTION_NAVBAR_DISABLE_FLYING_FLEETS],
773
    'PLAYER_OPTION_NAVBAR_DISABLE_EXPEDITIONS'    => SN::$user_options[PLAYER_OPTION_NAVBAR_DISABLE_EXPEDITIONS],
774
    'PLAYER_OPTION_NAVBAR_DISABLE_QUESTS'         => SN::$user_options[PLAYER_OPTION_NAVBAR_DISABLE_QUESTS],
775
    'PLAYER_OPTION_NAVBAR_DISABLE_META_MATTER'    => SN::$user_options[PLAYER_OPTION_NAVBAR_DISABLE_META_MATTER],
776
    'PLAYER_OPTION_NAVBAR_RESEARCH_WIDE'          => SN::$user_options[PLAYER_OPTION_NAVBAR_RESEARCH_WIDE],
777
778
    'TUTORIAL_ENABLED' => $tutorial_enabled,
779
780
    'PT_MOON'        => PT_MOON,
781
    'SUBQUE_FLEET'   => SUBQUE_FLEET,
782
    'QUE_RESEARCH'   => QUE_RESEARCH,
783
    'QUE_STRUCTURES' => QUE_STRUCTURES,
784
  ));
785
786
  if ((defined('SN_RENDER_NAVBAR_PLANET') && SN_RENDER_NAVBAR_PLANET === true) || ($user['option_list'][OPT_INTERFACE]['opt_int_navbar_resource_force'] && SN_RENDER_NAVBAR_PLANET !== false)) {
787
    tpl_set_resource_info($template, $planetrow);
788
    $template->assign_vars(array(
789
      'SN_RENDER_NAVBAR_PLANET' => true,
790
      'SN_NAVBAR_HIDE_FLEETS'   => true,
791
    ));
792
  }
793
794
  return $user;
795
}
796
797
/**
798
 * @param $template
799
 * @param $user
800
 */
801
function tpl_navbar_render_notes(&$template, &$user) {
802
  $notes_query = doquery("SELECT * FROM {{notes}} WHERE `owner` = {$user['id']} AND `sticky` = 1 ORDER BY priority DESC, time DESC");
803
  while ($note_row = db_fetch($notes_query)) {
804
    \Note\Note::note_assign($template, $note_row);
0 ignored issues
show
Deprecated Code introduced by
The function Note\Note::note_assign() 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

804
    /** @scrutinizer ignore-deprecated */ \Note\Note::note_assign($template, $note_row);
Loading history...
805
  }
806
}
807
808
/**
809
 * @param $template
810
 * @param $user
811
 * @param $config
812
 */
813
function tpl_navbar_render_news(&$template, &$user, $config) {
814
  if ($config->game_news_overview) {
815
    $user_last_read_safe = intval($user['news_lastread']);
816
    $newsSql = "WHERE UNIX_TIMESTAMP(`tsTimeStamp`) >= {$user_last_read_safe}";
817
    $newsOverviewShowSeconds = intval($config->game_news_overview_show);
818
    if ($newsOverviewShowSeconds) {
819
      $newsSql .= " AND `tsTimeStamp` >= DATE_SUB(NOW(), INTERVAL {$newsOverviewShowSeconds} SECOND)";
820
    }
821
    nws_render($template, $newsSql, $config->game_news_overview);
822
  }
823
}
824
825
/**
826
 * @param array  $sn_mvc
827
 * @param string $blockName
828
 *
829
 * @return array|false
830
 */
831
function render_button_block(&$sn_mvc, $blockName) {
832
  $result = false;
833
834
  if (!empty($sn_mvc[$blockName]) && is_array($sn_mvc[$blockName])) {
835
    foreach ($sn_mvc[$blockName] as $navbar_button_image => $navbar_button_url) {
836
      $result[] = array(
837
        'IMAGE'        => $navbar_button_image,
838
        'URL_RELATIVE' => $navbar_button_url,
839
      );
840
    }
841
842
    $result = array(
843
      '.' => array(
844
        $blockName =>
845
          $result
846
      ),
847
    );
848
  }
849
850
  return $result;
851
}
852
853
/**
854
 * @param array    $sn_mvc
855
 * @param template $template
856
 */
857
function tpl_navbar_extra_buttons(&$sn_mvc, $template) {
858
  ($block = render_button_block($sn_mvc, 'navbar_prefix_button')) ? $template->assign_recursive($block) : false;
859
  ($block = render_button_block($sn_mvc, 'navbar_main_button')) ? $template->assign_recursive($block) : false;
860
}
861
862
/**
863
 * @param template|string $template
864
 */
865
function templateRenderToHtml($template) {
866
  $output = null;
0 ignored issues
show
Unused Code introduced by
The assignment to $output is dead and can be removed.
Loading history...
867
868
  ob_start();
869
  displayP($template);
870
  $output = ob_get_contents();
871
  ob_end_clean();
872
873
  return $output;
874
}
875
876
877
/**
878
 * @param template|string $template
879
 */
880
function displayP($template) {
881
  if (is_object($template)) {
882
    if (empty($template->parsed)) {
883
      parsetemplate($template);
884
    }
885
886
    foreach ($template->files as $section => $filename) {
887
      $template->display($section);
888
    }
889
  } else {
890
    print($template);
891
  }
892
}
893
894
/**
895
 * @param template   $template
896
 * @param array|bool $array
897
 *
898
 * @return mixed
899
 */
900
function templateObjectParse($template, $array = false) {
901
  global $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...
902
903
  if (!empty($array) && is_array($array)) {
904
    foreach ($array as $key => $data) {
905
      $template->assign_var($key, $data);
906
    }
907
  }
908
909
  $template->assign_vars(array(
910
    'SN_TIME_NOW'    => SN_TIME_NOW,
911
    'USER_AUTHLEVEL' => isset($user['authlevel']) ? $user['authlevel'] : -1,
912
    'SN_GOOGLE'      => defined('SN_GOOGLE'),
913
  ));
914
915
  $template->parsed = true;
916
917
  return $template;
918
}
919
920
/**
921
 * @param template|string $template
922
 * @param array|bool      $array
923
 *
924
 * @return mixed
925
 */
926
function parsetemplate($template, $array = false) {
927
  if (is_object($template)) {
928
    return templateObjectParse($template, $array);
929
  } else {
930
    $search[] = '#\{L_([a-z0-9\-_]*?)\[([a-z0-9\-_]*?)\]\}#Ssie';
0 ignored issues
show
Comprehensibility Best Practice introduced by
$search was never initialized. Although not strictly required by PHP, it is generally a good practice to add $search = array(); before regardless.
Loading history...
931
    $replace[] = '((isset($lang[\'\1\'][\'\2\'])) ? $lang[\'\1\'][\'\2\'] : \'{L_\1[\2]}\');';
0 ignored issues
show
Comprehensibility Best Practice introduced by
$replace was never initialized. Although not strictly required by PHP, it is generally a good practice to add $replace = array(); before regardless.
Loading history...
932
933
    $search[] = '#\{L_([a-z0-9\-_]*?)\}#Ssie';
934
    $replace[] = '((isset($lang[\'\1\'])) ? $lang[\'\1\'] : \'{L_\1}\');';
935
936
    $search[] = '#\{([a-z0-9\-_]*?)\}#Ssie';
937
    $replace[] = '((isset($array[\'\1\'])) ? $array[\'\1\'] : \'{\1}\');';
938
939
    return preg_replace($search, $replace, $template);
940
  }
941
}
942
943
/**
944
 * @param array|string  $files
945
 * @param template|null $template
946
 * @param string|null   $template_path - path to template
947
 *
948
 * @return template
949
 */
950
function gettemplate($files, $template = null, $template_path = null) {
951
  global $sn_mvc, $sn_page_name;
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...
952
953
  $template_ex = '.tpl.html';
954
955
  is_string($files) ? $files = array(basename($files) => $files) : false;
956
957
  !is_object($template) ? $template = new template(SN_ROOT_PHYSICAL) : false;
958
  //$template->set_custom_template($template_path ? $template_path : TEMPLATE_DIR, TEMPLATE_NAME, TEMPLATE_DIR);
0 ignored issues
show
Unused Code Comprehensibility introduced by
53% 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...
959
960
  $templateName = getSkinPathTemplate(SN::$gc->theUser->getSkinPath());
961
  !$template_path || !is_string($template_path) ? $template_path = SN_ROOT_PHYSICAL . 'design/templates/' : false;
962
  $template->set_custom_template($template_path . $templateName . '/', $templateName, TEMPLATE_DIR);
963
964
  // TODO ГРЯЗНЫЙ ХАК! Это нужно, что бы по возможности перезаписать инфу из языковых пакетов модулей там, где она была перезаписана раньше инфой из основного пакета. Почему?
965
  //  - сначала грузятся модули и их языковые пакеты
966
  //  - затем по ходу дела ОСНОВНОЙ языковой пакет может перезаписать данные из МОДУЛЬНОГО языкового пакета
967
  // Поэтому и нужен этот грязный хак
968
  // В норме же - страницы заявляют сами, какие им пакеты нужны. Так что сначала всегда должны грузится основные языковые пакеты, а уже ПОВЕРХ них - пакеты модулей
969
  !empty($sn_mvc['i18n']['']) ? lng_load_i18n($sn_mvc['i18n']['']) : false;
970
  $sn_page_name ? lng_load_i18n($sn_mvc['i18n'][$sn_page_name]) : false;
971
972
  foreach ($files as &$filename) {
973
    $filename = $filename . $template_ex;
974
  }
975
976
  $template->set_filenames($files);
977
978
  return $template;
979
}
980
981
/**
982
 * @param template $template
983
 */
984
function tpl_login_lang(&$template) {
985
  global $language;
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...
986
987
  $url_params = array();
988
989
  $language ? $url_params[] = "lang={$language}" : false;
990
991
  ($id_ref = sys_get_param_id('id_ref')) ? $url_params[] = "id_ref={$id_ref}" : false;
992
993
  $template->assign_vars($q = array(
994
    'LANG'     => $language ? $language : '',
995
    'referral' => $id_ref ? '&id_ref=' . $id_ref : '',
996
997
    'REQUEST_PARAMS' => !empty($url_params) ? '?' . implode('&', $url_params) : '',// "?lang={$language}" . ($id_ref ? "&id_ref={$id_ref}" : ''),
0 ignored issues
show
Unused Code Comprehensibility introduced by
53% 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...
998
    'FILENAME'       => basename($_SERVER['PHP_SELF']),
999
  ));
1000
1001
  foreach (lng_get_list() as $lng_id => $lng_data) {
1002
    if (isset($lng_data['LANG_VARIANTS']) && is_array($lng_data['LANG_VARIANTS'])) {
1003
      foreach ($lng_data['LANG_VARIANTS'] as $lang_variant) {
1004
        $lng_data1 = $lng_data;
1005
        $lng_data1 = array_merge($lng_data1, $lang_variant);
1006
        $template->assign_block_vars('language', $lng_data1);
1007
      }
1008
    } else {
1009
      $template->assign_block_vars('language', $lng_data);
1010
    }
1011
  }
1012
}
1013
1014
/**
1015
 * @param array $user
1016
 *
1017
 * @return array
1018
 */
1019
function tpl_get_fleets_flying(&$user) {
1020
  $fleet_flying_list = array();
1021
1022
  $fleet_flying_list[0] = fleet_list_by_owner_id($user['id']);
1023
  foreach ($fleet_flying_list[0] as $fleet_id => $fleet_flying_row) {
1024
    $fleet_flying_list[$fleet_flying_row['fleet_mission']][$fleet_id] = &$fleet_flying_list[0][$fleet_id];
1025
  }
1026
1027
  return $fleet_flying_list;
1028
}
1029
1030
/**
1031
 * @param template $template
1032
 * @param string   $blockName
1033
 * @param mixed    $values
1034
 * @param string   $keyName   - Name for key name
1035
 * @param string   $valueName - Name for value name
1036
 */
1037
function tpl_assign_select(&$template, $blockName, $values, $keyName = 'KEY', $valueName = 'VALUE') {
1038
  !is_array($values) ? $values = array($values => $values) : false;
1039
1040
  foreach ($values as $key => $value) {
1041
    $template->assign_block_vars($blockName, array(
1042
      $keyName   => HelperString::htmlSafe($key),
1043
      $valueName => HelperString::htmlSafe($value),
1044
    ));
1045
  }
1046
}
1047
1048
/**
1049
 * Renders unit bonus from unit data
1050
 *
1051
 * @param array $unitInfo
1052
 *
1053
 * @return string
1054
 */
1055
function tpl_render_unit_bonus_data($unitInfo) {
1056
  $strBonus = tplAddPlus($unitInfo[P_BONUS_VALUE]);
1057
  switch ($unitInfo[P_BONUS_TYPE]) {
1058
    case BONUS_PERCENT:
1059
      $strBonus = "{$strBonus}% ";
1060
    break;
1061
1062
    case BONUS_ABILITY:
1063
      $strBonus = '';
1064
    break;
1065
1066
    case BONUS_ADD:
1067
    default:
1068
    break;
1069
  }
1070
1071
  return $strBonus;
1072
}
1073
1074
/**
1075
 * Converts number to string then adds "+" sign for positive AND ZERO numbers
1076
 *
1077
 * @param float $value
1078
 *
1079
 * @return string
1080
 */
1081
function tplAddPlus($value) {
1082
  return ($value >= 0 ? '+' : '') . $value;
1083
}
1084
1085
1086
/**
1087
 * Convert number to prettified string then adds "+" sign for positive AND ZERO numbers
1088
 *
1089
 * @param float $value
1090
 *
1091
 * @return string
1092
 */
1093
function tplPrettyPlus($value) {
1094
  return ($value >= 0 ? '+' : '') . HelperString::numberFloorAndFormat($value);
1095
}
1096