Completed
Push — trunk ( c7e339...34029c )
by SuperNova.WS
04:10
created

tpl_render_topnav()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 1
Code Lines 0

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 1
eloc 0
c 1
b 0
f 0
nc 1
nop 3
dl 0
loc 1
rs 10
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 14 and the first side effect is on line 612.

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

38
  $template = gettemplate('message_body', /** @scrutinizer ignore-type */ true);
Loading history...
39
40
  $template_result['GLOBAL_DISPLAY_NAVBAR'] = $showHeader;
41
42
  $template->assign_vars(array(
43
//    '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...
44
45
    'TITLE'       => $title,
46
    'MESSAGE'     => $message,
47
    'REDIRECT_TO' => $redirectTo,
48
    'TIMEOUT'     => $timeout,
49
  ));
50
51
  display($template, $title);
52
}
53
54
/**
55
 * Admin message box
56
 *
57
 * @see messageBox()
58
 */
59
function messageBoxAdmin($message, $title = '', $redirectTo = '', $timeout = 5) {
60
  messageBox($message, $title, $redirectTo, $timeout, false);
61
}
62
63
function messageBoxAdminAccessDenied($level = AUTH_LEVEL_ADMINISTRATOR) {
64
  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...
65
66
  if ($user['authlevel'] < $level) {
67
    messageBoxAdmin($lang['adm_err_denied'], $lang['admin_title_access_denied'], SN_ROOT_VIRTUAL . 'overview.php');
68
  }
69
}
70
71
/**
72
 * @param $menu
73
 * @param $extra
74
 */
75
function tpl_menu_merge_extra(&$menu, &$extra) {
76
  if (empty($menu) || empty($extra)) {
77
    return;
78
  }
79
80
  foreach ($extra as $menu_item_id => $menu_item) {
81
    if (empty($menu_item['LOCATION'])) {
82
      $menu[$menu_item_id] = $menu_item;
83
      continue;
84
    }
85
86
    $item_location = $menu_item['LOCATION'];
87
    unset($menu_item['LOCATION']);
88
89
    $is_positioned = $item_location[0];
90
    if ($is_positioned == '+' || $is_positioned == '-') {
91
      $item_location = substr($item_location, 1);
92
    } else {
93
      $is_positioned = '';
94
    }
95
96
    if ($item_location) {
97
      $menu_keys = array_keys($menu);
98
      $insert_position = array_search($item_location, $menu_keys);
99
      if ($insert_position === false) {
100
        $insert_position = count($menu) - 1;
101
        $is_positioned = '+';
102
        $item_location = '';
103
      }
104
    } else {
105
      $insert_position = $is_positioned == '-' ? 0 : count($menu);
106
    }
107
108
    $insert_position += $is_positioned == '+' ? 1 : 0;
109
    $spliced = array_splice($menu, $insert_position, count($menu) - $insert_position);
110
    $menu[$menu_item_id] = $menu_item;
111
112
    if (!$is_positioned && $item_location) {
113
      unset($spliced[$item_location]);
114
    }
115
    $menu = array_merge($menu, $spliced);
116
  }
117
118
  $extra = array();
119
}
120
121
/**
122
 * @param array    $sn_menu
123
 * @param template $template
124
 */
125
function tpl_menu_assign_to_template(&$sn_menu, &$template) {
126
  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...
127
128
  if (empty($sn_menu) || !is_array($sn_menu)) {
129
    return;
130
  }
131
132
  foreach ($sn_menu as $menu_item_id => $menu_item) {
133
    if (!$menu_item) {
134
      continue;
135
    }
136
137
    if (is_string($menu_item_id)) {
138
      $menu_item['ID'] = $menu_item_id;
139
    }
140
141
    if ($menu_item['TYPE'] == 'lang') {
142
      $lang_string = &$lang;
143
      if (preg_match('#(\w+)(?:\[(\w+)\])?(?:\[(\w+)\])?(?:\[(\w+)\])?(?:\[(\w+)\])?#', $menu_item['ITEM'], $matches) && count($matches) > 1) {
144
        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...
145
          if (defined($matches[$i])) {
146
            $matches[$i] = constant($matches[$i]);
147
          }
148
          $lang_string = &$lang_string[$matches[$i]];
149
        }
150
      }
151
      $menu_item['ITEM'] = $lang_string && is_string($lang_string) ? $lang_string : "{L_{$menu_item['ITEM']}}";
152
    }
153
154
    $menu_item['ALT'] = htmlentities($menu_item['ALT']);
155
    $menu_item['TITLE'] = htmlentities($menu_item['TITLE']);
156
157
    if (!empty($menu_item['ICON'])) {
158
      if (is_string($menu_item['ICON'])) {
159
        $menu_item['ICON_PATH'] = $menu_item['ICON'];
160
      } else {
161
        $menu_item['ICON'] = $menu_item_id;
162
      }
163
    }
164
165
    $template->assign_block_vars('menu', $menu_item);
166
  }
167
}
168
169
/**
170
 * @param template $template
171
 *
172
 * @return template
173
 */
174
function tpl_render_menu($template) {
175
  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...
176
177
  lng_include('admin');
178
179
//  $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...
180
//  $template->assign_recursive($template_result);
181
182
  $template->assign_vars(array(
183
    'USER_AUTHLEVEL'      => $user['authlevel'],
184
    'USER_AUTHLEVEL_NAME' => $lang['user_level'][$user['authlevel']],
185
//    '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...
186
    'PAYMENT'             => sn_module::sn_module_get_active_count('payment'),
187
    'MENU_START_HIDE'     => !empty($_COOKIE[SN_COOKIE . '_menu_hidden']) || defined('SN_GOOGLE'),
188
  ));
189
190
  if (isset($template_result['MENU_CUSTOMIZE'])) {
191
    $template->assign_vars(array(
192
      'PLAYER_OPTION_MENU_SHOW_ON_BUTTON'   => SN::$user_options[PLAYER_OPTION_MENU_SHOW_ON_BUTTON],
193
      'PLAYER_OPTION_MENU_HIDE_ON_BUTTON'   => SN::$user_options[PLAYER_OPTION_MENU_HIDE_ON_BUTTON],
194
      'PLAYER_OPTION_MENU_HIDE_ON_LEAVE'    => SN::$user_options[PLAYER_OPTION_MENU_HIDE_ON_LEAVE],
195
      'PLAYER_OPTION_MENU_UNPIN_ABSOLUTE'   => SN::$user_options[PLAYER_OPTION_MENU_UNPIN_ABSOLUTE],
196
      'PLAYER_OPTION_MENU_ITEMS_AS_BUTTONS' => SN::$user_options[PLAYER_OPTION_MENU_ITEMS_AS_BUTTONS],
197
      'PLAYER_OPTION_MENU_WHITE_TEXT'       => SN::$user_options[PLAYER_OPTION_MENU_WHITE_TEXT],
198
      'PLAYER_OPTION_MENU_OLD'              => SN::$user_options[PLAYER_OPTION_MENU_OLD],
199
      'PLAYER_OPTION_MENU_HIDE_SHOW_BUTTON' => empty($_COOKIE[SN_COOKIE . '_menu_hidden']) && !defined('SN_GOOGLE')
200
        ? SN::$user_options[PLAYER_OPTION_MENU_HIDE_SHOW_BUTTON] : 1,
201
    ));
202
  }
203
204
  if (defined('IN_ADMIN') && IN_ADMIN === true && !empty($user['authlevel']) && $user['authlevel'] > 0) {
205
    tpl_menu_merge_extra($sn_menu_admin, $sn_menu_admin_extra);
206
    tpl_menu_assign_to_template($sn_menu_admin, $template);
207
  } else {
208
    tpl_menu_merge_extra($sn_menu, $sn_menu_extra);
209
    tpl_menu_assign_to_template($sn_menu, $template);
210
  }
211
212
  return $template;
213
}
214
215
/**
216
 * @param template|string $page
217
 * @param string          $title
218
 * @param bool|true       $isDisplayTopNav
219
 * @param string          $metatags
220
 * @param bool|false      $AdminPage
221
 * @param bool|true       $isDisplayMenu
222
 *
223
 * @return mixed
224
 */
225
function display($page, $title = '') {
226
  if (!defined('SN_TIME_RENDER_START')) {
227
    define('SN_TIME_RENDER_START', microtime(true));
228
  }
229
230
  return sn_function_call('display', array($page, $title));
231
}
232
233
/**
234
 * @param template|string $page
235
 * @param string          $title
236
 * @param bool|true       $isDisplayTopNav
237
 * @param string          $metatags
238
 * @param bool|false      $AdminPage
239
 * @param bool|true       $isDisplayMenu
240
 * @param bool|int|string $exitStatus - Код или сообщение выхода
241
 */
242
function sn_display($page, $title = '') {
243
  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...
244
245
  !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...
246
247
  $exitStatus = true;
248
  $template_result['LOGIN_LOGOUT'] = $inLoginLogout = defined('LOGIN_LOGOUT') && LOGIN_LOGOUT === true;
249
250
  if (is_object($page)) {
251
    isset($page->_rootref['PAGE_TITLE']) && empty($title) ? $title = $page->_rootref['PAGE_TITLE'] : false;
252
    !$title && !empty($page->_rootref['PAGE_HEADER']) ? $title = $page->_rootref['PAGE_HEADER'] : false;
253
    !isset($page->_rootref['PAGE_HEADER']) && $title ? $page->assign_var('PAGE_HEADER', $title) : false;
254
  }
255
256
  $isRenderGlobal = is_object($page) && isset($template_result['GLOBAL_DISPLAY_HEADER']) ? $template_result['GLOBAL_DISPLAY_HEADER'] : true;
257
258
  // Global header
259
  if ($isRenderGlobal) {
260
    renderHeader($page, $title, $template_result, $inLoginLogout, $user, $config, $lang, $planetrow);
261
  }
262
263
  // Page content
264
  !is_array($page) ? $page = array($page) : false;
0 ignored issues
show
introduced by
The condition is_array($page) is always false.
Loading history...
265
  $result_added = false;
266
  foreach ($page as $page_item) {
267
    /**
268
     * @var template $page_item
269
     */
270
    if (!$result_added && is_object($page_item) && isset($page_item->_tpldata['result'])) {
271
      $resultTemplate = gettemplate('_result_message');
272
      $resultTemplate->_tpldata = $page_item->_tpldata;
273
      displayP($resultTemplate);
274
//      $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...
275
//      $temp = $page_item->files['_result_message'];
276
//      unset($page_item->files['_result_message']);
277
//      $page_item->files = array_reverse($page_item->files);
278
//      $page_item->files['_result_message'] = $temp;
279
//      $page_item->files = array_reverse($page_item->files);
280
      $result_added = true;
281
    }
282
//    $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...
283
    displayP($page_item);
284
  }
285
286
  if(is_array($template_result[TEMPLATE_EXTRA_ARRAY]) && !empty($template_result[TEMPLATE_EXTRA_ARRAY])) {
287
    foreach($template_result[TEMPLATE_EXTRA_ARRAY] as $extraName => $extraTemplate) {
288
      /**
289
       * @var template $extraTemplate
290
       */
291
      displayP($extraTemplate);
292
    }
293
  }
294
295
  // Global footer
296
  if ($isRenderGlobal) {
297
    renderFooter();
298
  }
299
300
  $user['authlevel'] >= 3 && $config->debug ? $debug->echo_log() : false;;
301
302
  sn_db_disconnect();
303
304
  $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...
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...
introduced by
The condition $exitStatus === true is always true.
Loading history...
305
}
306
307
/**
308
 * @param $page
309
 * @param $title
310
 * @param $template_result
311
 * @param $inLoginLogout
312
 * @param $user
313
 * @param $config
314
 * @param $lang
315
 * @param $planetrow
316
 */
317
function renderHeader($page, $title, &$template_result, $inLoginLogout, &$user, $config, $lang, $planetrow) {
318
  if (SN::$headerRendered) {
319
    return;
320
  }
321
322
  ob_end_flush();
323
324
  ob_start();
325
//  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...
326
  $isDisplayTopNav = true;
327
  $isDisplayMenu = true;
328
329
  isset($template_result['GLOBAL_DISPLAY_MENU']) ? $isDisplayMenu = $template_result['GLOBAL_DISPLAY_MENU'] : false;
330
  isset($template_result['GLOBAL_DISPLAY_NAVBAR']) ? $isDisplayTopNav = $template_result['GLOBAL_DISPLAY_NAVBAR'] : false;
331
332
  // TODO: DEPRECATED! Use $template_result to turn menu and navbar or ond off!
333
  if (is_object($page)) {
334
    isset($page->_rootref['MENU']) ? $isDisplayMenu = $page->_rootref['MENU'] : false;
335
    isset($page->_rootref['NAVBAR']) ? $isDisplayTopNav = $page->_rootref['NAVBAR'] : false;
336
  }
337
338
  $inAdmin = defined('IN_ADMIN') && IN_ADMIN === true;
339
  $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...
340
  $isDisplayTopNav = $isDisplayTopNav && !$inAdmin;
341
342
  if ($inLoginLogout || empty($user['id']) || !is_numeric($user['id'])) {
343
    $isDisplayMenu = false;
344
    $isDisplayTopNav = false;
345
  }
346
347
  $user_time_diff = playerTimeDiff::user_time_diff_get();
348
  $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);
349
  $measureTimeDiff = intval(
350
    empty($user_time_diff[PLAYER_OPTION_TIME_DIFF_FORCED])
351
    &&
352
    (SN_TIME_NOW - $user_time_measured_unix > PERIOD_HOUR || $user_time_diff[PLAYER_OPTION_TIME_DIFF] == '')
353
  );
354
355
  $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

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

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

673
  $premium_lvl = mrc_get_level($user, /** @scrutinizer ignore-type */ false, UNIT_PREMIUM, true, true);
Loading history...
674
675
  $str_date_format = "%3$02d %2$0s %1$04d {$lang['top_of_year']} %4$02d:%5$02d:%6$02d";
676
  $time_now_parsed = getdate(SN_TIME_NOW);
677
  $time_local_parsed = getdate(defined('SN_CLIENT_TIME_LOCAL') ? SN_CLIENT_TIME_LOCAL : SN_TIME_NOW);
678
679
  $template->assign_vars(array(
680
    'HALLOWEEN' => !empty($sn_module_list['event']['event_halloween_2015']) && $sn_module_list['event']['event_halloween_2015']->manifest['active'],
681
682
    'QUE_ID'   => QUE_RESEARCH,
683
    'QUE_HTML' => 'topnav',
684
685
    'RESEARCH_ONGOING' => (boolean)$user['que'],
686
687
    'TIME_TEXT'       => sprintf($str_date_format, $time_now_parsed['year'], $lang['months'][$time_now_parsed['mon']], $time_now_parsed['mday'],
688
      $time_now_parsed['hours'], $time_now_parsed['minutes'], $time_now_parsed['seconds']
689
    ),
690
    'TIME_TEXT_LOCAL' => sprintf($str_date_format, $time_local_parsed['year'], $lang['months'][$time_local_parsed['mon']], $time_local_parsed['mday'],
691
      $time_local_parsed['hours'], $time_local_parsed['minutes'], $time_local_parsed['seconds']
692
    ),
693
694
    'GAME_BLITZ_REGISTER'             => $config->game_blitz_register,
695
    'GAME_BLITZ_REGISTER_TEXT'        => $lang['sys_blitz_registration_mode_list'][$config->game_blitz_register],
696
    'BLITZ_REGISTER_OPEN'             => $config->game_blitz_register == BLITZ_REGISTER_OPEN,
697
    'BLITZ_REGISTER_CLOSED'           => $config->game_blitz_register == BLITZ_REGISTER_CLOSED,
698
    'BLITZ_REGISTER_SHOW_LOGIN'       => $config->game_blitz_register == BLITZ_REGISTER_SHOW_LOGIN,
699
    'BLITZ_REGISTER_DISCLOSURE_NAMES' => $config->game_blitz_register == BLITZ_REGISTER_DISCLOSURE_NAMES,
700
    'GAME_BLITZ'                      => $config->game_mode == GAME_BLITZ,
701
702
    'USERS_ONLINE'  => $config->var_online_user_count,
703
    'USERS_TOTAL'   => $config->users_amount,
704
    'USER_RANK'     => $user['total_rank'],
705
    'USER_NICK'     => $user['username'],
706
    'USER_AVATAR'   => $user['avatar'],
707
    'USER_AVATARID' => $user['id'],
708
    'USER_PREMIUM'  => $premium_lvl,
709
    'USER_RACE'     => $user['player_race'],
710
711
    'TOPNAV_CURRENT_PLANET'       => $user['current_planet'],
712
    '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...
713
    'TOPNAV_CURRENT_PLANET_IMAGE' => $planetrow['image'],
714
    'TOPNAV_COLONIES_CURRENT'     => get_player_current_colonies($user),
715
    'TOPNAV_COLONIES_MAX'         => get_player_max_colonies($user),
716
    'NAVBAR_MODE'                 => $GET_mode,
717
718
    '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

718
    'TOPNAV_DARK_MATTER'            => mrc_get_level($user, /** @scrutinizer ignore-type */ '', RES_DARK_MATTER),
Loading history...
719
    '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

719
    'TOPNAV_DARK_MATTER_TEXT'       => HelperString::numberFloorAndFormat(/** @scrutinizer ignore-type */ mrc_get_level($user, '', RES_DARK_MATTER)),
Loading history...
720
    'TOPNAV_DARK_MATTER_PLAIN'      => mrc_get_level($user, '', RES_DARK_MATTER, false, true),
721
    'TOPNAV_DARK_MATTER_PLAIN_TEXT' => HelperString::numberFloorAndFormat(mrc_get_level($user, '', RES_DARK_MATTER, false, true)),
722
    'TOPNAV_METAMATTER'             => mrc_get_level($user, '', RES_METAMATTER),
723
    'TOPNAV_METAMATTER_TEXT'        => HelperString::numberFloorAndFormat(mrc_get_level($user, '', RES_METAMATTER)),
724
725
    // TODO ГРЯЗНЫЙ ХАК!!!
726
    'TOPNAV_PAYMENT'                => sn_module::sn_module_get_active_count('payment') && !defined('SN_GOOGLE'),
727
728
    'TOPNAV_MESSAGES_ADMIN'    => $user['msg_admin'],
729
    'TOPNAV_MESSAGES_PLAYER'   => $user['mnl_joueur'],
730
    'TOPNAV_MESSAGES_ALLIANCE' => $user['mnl_alliance'],
731
    'TOPNAV_MESSAGES_ATTACK'   => $user['mnl_attaque'],
732
    'TOPNAV_MESSAGES_ALL'      => $user['new_message'],
733
734
    'TOPNAV_FLEETS_FLYING'      => count($fleet_flying_list[0]),
735
    'TOPNAV_FLEETS_TOTAL'       => GetMaxFleets($user),
736
    'TOPNAV_EXPEDITIONS_FLYING' => count($fleet_flying_list[MT_EXPLORE]),
737
    'TOPNAV_EXPEDITIONS_TOTAL'  => get_player_max_expeditons($user),
738
739
    'TOPNAV_QUEST_COMPLETE'    => get_quest_amount_complete($user['id']),
740
    'TOPNAV_QUEST_IN_PROGRESS' => get_quest_amount_in_progress($user['id']),
741
742
    'GAME_NEWS_OVERVIEW'       => $config->game_news_overview,
743
    '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...
744
    '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...
745
    '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...
746
    '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...
747
748
    'PLAYER_OPTION_NAVBAR_PLANET_VERTICAL'        => SN::$user_options[PLAYER_OPTION_NAVBAR_PLANET_VERTICAL],
749
    'PLAYER_OPTION_NAVBAR_PLANET_OLD'             => SN::$user_options[PLAYER_OPTION_NAVBAR_PLANET_OLD],
750
    'PLAYER_OPTION_NAVBAR_PLANET_DISABLE_STORAGE' => SN::$user_options[PLAYER_OPTION_NAVBAR_PLANET_DISABLE_STORAGE],
751
    'PLAYER_OPTION_NAVBAR_DISABLE_RESEARCH'       => SN::$user_options[PLAYER_OPTION_NAVBAR_DISABLE_RESEARCH],
752
    'PLAYER_OPTION_NAVBAR_DISABLE_PLANET'         => SN::$user_options[PLAYER_OPTION_NAVBAR_DISABLE_PLANET],
753
    'PLAYER_OPTION_NAVBAR_DISABLE_HANGAR'         => SN::$user_options[PLAYER_OPTION_NAVBAR_DISABLE_HANGAR],
754
    'PLAYER_OPTION_NAVBAR_DISABLE_FLYING_FLEETS'  => SN::$user_options[PLAYER_OPTION_NAVBAR_DISABLE_FLYING_FLEETS],
755
    'PLAYER_OPTION_NAVBAR_DISABLE_EXPEDITIONS'    => SN::$user_options[PLAYER_OPTION_NAVBAR_DISABLE_EXPEDITIONS],
756
    'PLAYER_OPTION_NAVBAR_DISABLE_QUESTS'         => SN::$user_options[PLAYER_OPTION_NAVBAR_DISABLE_QUESTS],
757
    'PLAYER_OPTION_NAVBAR_DISABLE_META_MATTER'    => SN::$user_options[PLAYER_OPTION_NAVBAR_DISABLE_META_MATTER],
758
    'PLAYER_OPTION_NAVBAR_RESEARCH_WIDE'          => SN::$user_options[PLAYER_OPTION_NAVBAR_RESEARCH_WIDE],
759
760
    'TUTORIAL_ENABLED' => $tutorial_enabled,
761
762
    'PT_MOON'        => PT_MOON,
763
    'SUBQUE_FLEET'   => SUBQUE_FLEET,
764
    'QUE_RESEARCH'   => QUE_RESEARCH,
765
    'QUE_STRUCTURES' => QUE_STRUCTURES,
766
  ));
767
768
  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)) {
769
    tpl_set_resource_info($template, $planetrow);
770
    $template->assign_vars(array(
771
      'SN_RENDER_NAVBAR_PLANET' => true,
772
      'SN_NAVBAR_HIDE_FLEETS'   => true,
773
    ));
774
  }
775
776
  return $user;
777
}
778
779
/**
780
 * @param $template
781
 * @param $user
782
 */
783
function tpl_navbar_render_notes(&$template, &$user) {
784
  $notes_query = doquery("SELECT * FROM {{notes}} WHERE `owner` = {$user['id']} AND `sticky` = 1 ORDER BY priority DESC, time DESC");
785
  while ($note_row = db_fetch($notes_query)) {
786
    \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

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