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

render_button_block()   A

Complexity

Conditions 4
Paths 2

Size

Total Lines 20
Code Lines 11

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 4
eloc 11
nc 2
nop 2
dl 0
loc 20
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 15 and the first side effect is on line 613.

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

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

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

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

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

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

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

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