Test Failed
Push — trunk ( 429ead...baf0d6 )
by SuperNova.WS
10:51
created

SnTemplate::sn_tpl_render_topnav()   F

Complexity

Conditions 20
Paths 18

Size

Total Lines 164
Code Lines 120

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 20
eloc 120
c 1
b 0
f 0
nc 18
nop 4
dl 0
loc 164
rs 3.3333

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
use Common\Traits\TSingleton;
4
use Core\GlobalContainer;
5
use Fleet\DbFleetStatic;
6
use Note\Note;
7
use \Pages\PageTutorial;
0 ignored issues
show
Bug introduced by
The type \Pages\PageTutorial was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
8
use Planet\DBStaticPlanet;
9
use Player\playerTimeDiff;
10
use Template\TemplateMeta;
11
12
/**
13
 * Template manager
14
 */
15
class SnTemplate {
16
17
  use TSingleton;
18
19
  const TPL_HTML = '.tpl.html';
20
  /**
21
   * Partial path to templates root
22
   */
23
  const SN_TEMPLATES_PARTIAL_PATH = 'design/templates/';
24
  const SN_TEMPLATE_NAME_DEFAULT = 'OpenGame';
25
  const P_CONTENT = '__RENDERED_CONTENT';
26
27
  /**
28
   * @param template|string $template
29
   */
30
  public static function displayP($template) {
31
    if (is_object($template)) {
32
      if (empty($template->parsed)) {
33
        self::parsetemplate($template);
34
      }
35
36
      foreach ($template->files as $section => $filename) {
37
        $template->display($section);
38
      }
39
    } else {
40
      print($template);
41
    }
42
  }
43
44
  /**
45
   * @param template|string $template
46
   * @param array|bool      $array
47
   *
48
   * @return mixed
49
   */
50
  public static function parsetemplate($template, $array = false) {
51
    if (is_object($template)) {
52
      return self::templateObjectParse($template, $array);
53
    } else {
54
      $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...
55
      $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...
56
57
      $search[]  = '#\{L_([a-z0-9\-_]*?)\}#Ssie';
58
      $replace[] = '((isset($lang[\'\1\'])) ? $lang[\'\1\'] : \'{L_\1}\');';
59
60
      $search[]  = '#\{([a-z0-9\-_]*?)\}#Ssie';
61
      $replace[] = '((isset($array[\'\1\'])) ? $array[\'\1\'] : \'{\1}\');';
62
63
      return preg_replace($search, $replace, $template);
64
    }
65
  }
66
67
  /**
68
   * @param template   $template
69
   * @param array|bool $array
70
   *
71
   * @return mixed
72
   */
73
  public static function templateObjectParse($template, $array = false) {
74
    global $user;
75
76
    if (!empty($array) && is_array($array)) {
77
      foreach ($array as $key => $data) {
78
        $template->assign_var($key, $data);
79
      }
80
    }
81
82
    $template->assign_vars(array(
83
      'SN_TIME_NOW'      => SN_TIME_NOW,
84
      'SN_TEMPLATE_NAME' => SnTemplate::getPlayerTemplateName(),
85
      'USER_AUTHLEVEL'   => isset($user['authlevel']) ? $user['authlevel'] : -1,
86
      'SN_GOOGLE'        => SN_GOOGLE,
87
    ));
88
89
    $template->parsed = true;
90
91
    return $template;
92
  }
93
94
  /**
95
   * @param array $menu
96
   * @param array $extra
97
   */
98
  public static function tpl_menu_merge_extra(&$menu, &$extra) {
99
    if (!is_array($extra) || !is_array($menu) || empty($menu)) {
0 ignored issues
show
introduced by
The condition is_array($menu) is always true.
Loading history...
introduced by
The condition is_array($extra) is always true.
Loading history...
100
      return;
101
    }
102
103
    foreach ($extra as $menu_item_id => $menu_item) {
104
      if (empty($menu_item['LOCATION'])) {
105
        $menu[$menu_item_id] = $menu_item;
106
        continue;
107
      }
108
109
      $item_location = $menu_item['LOCATION'];
110
      unset($menu_item['LOCATION']);
111
112
      $is_positioned = $item_location[0];
113
      if ($is_positioned == '+' || $is_positioned == '-') {
114
        $item_location = substr($item_location, 1);
115
      } else {
116
        $is_positioned = '';
117
      }
118
119
      if ($item_location) {
120
        $menu_keys       = array_keys($menu);
121
        $insert_position = array_search($item_location, $menu_keys);
122
        if ($insert_position === false) {
123
          $insert_position = count($menu) - 1;
124
          $is_positioned   = '+';
125
          $item_location   = '';
126
        }
127
      } else {
128
        $insert_position = $is_positioned == '-' ? 0 : count($menu);
129
      }
130
131
      $insert_position     += $is_positioned == '+' ? 1 : 0;
132
      $spliced             = array_splice($menu, $insert_position, count($menu) - $insert_position);
133
      $menu[$menu_item_id] = $menu_item;
134
135
      if (!$is_positioned && $item_location) {
136
        unset($spliced[$item_location]);
137
      }
138
      $menu = array_merge($menu, $spliced);
139
    }
140
141
    $extra = array();
142
  }
143
144
  /**
145
   * @param array $menu
146
   *
147
   * @return array
148
   */
149
  public static function tpl_menu_adminize($menu) {
150
    !is_array($menu) ? $menu = [] : false;
0 ignored issues
show
introduced by
The condition is_array($menu) is always true.
Loading history...
151
152
    foreach ($menu as &$menuItem) {
153
      if (!isset($menuItem[MENU_FIELD_AUTH_LEVEL])) {
154
        $menuItem[MENU_FIELD_AUTH_LEVEL] = AUTH_LEVEL_ADMINISTRATOR;
155
      }
156
    }
157
158
    return $menu;
159
  }
160
161
  /**
162
   * @param array    $sn_menu
163
   * @param template $template
164
   */
165
  public static function tpl_menu_assign_to_template(&$sn_menu, &$template) {
166
    global $lang;
167
168
    if (empty($sn_menu) || !is_array($sn_menu)) {
169
      return;
170
    }
171
172
    foreach ($sn_menu as $menu_item_id => $menu_item) {
173
      if (!$menu_item) {
174
        continue;
175
      }
176
177
      if (is_string($menu_item_id)) {
178
        $menu_item['ID'] = $menu_item_id;
179
      }
180
181
      if ($menu_item['TYPE'] == 'lang') {
182
        $lang_string = &$lang;
183
        if (preg_match('#(\w+)(?:\[(\w+)\])?(?:\[(\w+)\])?(?:\[(\w+)\])?(?:\[(\w+)\])?#', $menu_item['ITEM'], $matches) && count($matches) > 1) {
184
          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...
185
            if (defined($matches[$i])) {
186
              $matches[$i] = constant($matches[$i]);
187
            }
188
            $lang_string = &$lang_string[$matches[$i]];
189
          }
190
        }
191
        $menu_item['ITEM'] = $lang_string && is_string($lang_string) ? $lang_string : "{L_{$menu_item['ITEM']}}";
192
      }
193
194
      $menu_item['ALT']   = htmlentities($menu_item['ALT']);
195
      $menu_item['TITLE'] = htmlentities($menu_item['TITLE']);
196
197
      if (!empty($menu_item['ICON'])) {
198
        if (is_string($menu_item['ICON'])) {
199
          $menu_item['ICON_PATH'] = $menu_item['ICON'];
200
        } else {
201
          $menu_item['ICON'] = $menu_item_id;
202
        }
203
      }
204
205
      $template->assign_block_vars('menu', $menu_item);
206
    }
207
  }
208
209
  /**
210
   * @param template $template
211
   *
212
   * @return template
213
   */
214
  public static function tpl_render_menu($template) {
215
    global $user, $lang, $template_result, $sn_menu_admin_extra, $sn_menu_admin, $sn_menu, $sn_menu_extra;
216
217
    lng_include('admin');
218
219
    $template->assign_vars(array(
220
      'USER_AUTHLEVEL'      => $user['authlevel'],
221
      'USER_AUTHLEVEL_NAME' => $lang['user_level'][$user['authlevel']],
222
      'PAYMENT'             => SN::$gc->modules->countModulesInGroup('payment'),
223
      'MENU_START_HIDE'     => !empty($_COOKIE[SN_COOKIE . '_menu_hidden']) || SN_GOOGLE,
224
    ));
225
226
    if (isset($template_result['MENU_CUSTOMIZE'])) {
227
      $template->assign_vars(array(
228
        'PLAYER_OPTION_MENU_SHOW_ON_BUTTON'   => SN::$user_options[PLAYER_OPTION_MENU_SHOW_ON_BUTTON],
229
        'PLAYER_OPTION_MENU_HIDE_ON_BUTTON'   => SN::$user_options[PLAYER_OPTION_MENU_HIDE_ON_BUTTON],
230
        'PLAYER_OPTION_MENU_HIDE_ON_LEAVE'    => SN::$user_options[PLAYER_OPTION_MENU_HIDE_ON_LEAVE],
231
        'PLAYER_OPTION_MENU_UNPIN_ABSOLUTE'   => SN::$user_options[PLAYER_OPTION_MENU_UNPIN_ABSOLUTE],
232
        'PLAYER_OPTION_MENU_ITEMS_AS_BUTTONS' => SN::$user_options[PLAYER_OPTION_MENU_ITEMS_AS_BUTTONS],
233
        'PLAYER_OPTION_MENU_WHITE_TEXT'       => SN::$user_options[PLAYER_OPTION_MENU_WHITE_TEXT],
234
        'PLAYER_OPTION_MENU_OLD'              => SN::$user_options[PLAYER_OPTION_MENU_OLD],
235
        'PLAYER_OPTION_MENU_HIDE_SHOW_BUTTON' => empty($_COOKIE[SN_COOKIE . '_menu_hidden']) && !SN_GOOGLE
236
          ? SN::$user_options[PLAYER_OPTION_MENU_HIDE_SHOW_BUTTON] : 1,
237
      ));
238
    }
239
240
    if (defined('IN_ADMIN') && IN_ADMIN === true && !empty($user['authlevel']) && $user['authlevel'] > 0) {
241
      SnTemplate::tpl_menu_merge_extra($sn_menu_admin, $sn_menu_admin_extra);
242
      $sn_menu_admin = SnTemplate::tpl_menu_adminize($sn_menu_admin);
243
      SnTemplate::tpl_menu_assign_to_template($sn_menu_admin, $template);
244
    } else {
245
      SnTemplate::tpl_menu_merge_extra($sn_menu, $sn_menu_extra);
246
      SnTemplate::tpl_menu_assign_to_template($sn_menu, $template);
247
    }
248
249
    return $template;
250
  }
251
252
  /**
253
   * @param template[] $page
254
   * @param array      $template_result
255
   */
256
  public static function renderFooter($page, $template_result) {
0 ignored issues
show
Unused Code introduced by
The parameter $template_result is not used and could be removed. ( Ignorable by Annotation )

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

256
  public static function renderFooter($page, /** @scrutinizer ignore-unused */ $template_result) {

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
Unused Code introduced by
The parameter $page is not used and could be removed. ( Ignorable by Annotation )

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

256
  public static function renderFooter(/** @scrutinizer ignore-unused */ $page, $template_result) {

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
257
    $templateFooter = self::gettemplate('_page/_99_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 SnTemplate::gettemplate(). ( Ignorable by Annotation )

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

257
    $templateFooter = self::gettemplate('_page/_99_footer', /** @scrutinizer ignore-type */ true);
Loading history...
258
259
    $templateFooter->assign_vars([
260
      'SN_TIME_NOW'      => SN_TIME_NOW,
261
      'SN_VERSION'       => SN_VERSION,
262
      'ADMIN_EMAIL'      => SN::$config->game_adminEmail,
263
      'CURRENT_YEAR'     => date('Y', SN_TIME_NOW),
264
      'DB_PATCH_VERSION' => dbPatchGetCurrent(),
265
    ]);
266
267
    SnTemplate::displayP($templateFooter);
268
  }
269
270
  /**
271
   * @param $page
272
   * @param $title
273
   * @param $template_result
274
   * @param $inLoginLogout
275
   * @param $user
276
   * @param $config
277
   * @param $lang
278
   * @param $planetrow
279
   */
280
  public static function renderHeader($page, $title, &$template_result, $inLoginLogout, &$user, $config, $lang, $planetrow, $renderedContent) {
281
    if (SN::$headerRendered) {
282
      return;
283
    }
284
285
    ob_end_flush();
286
287
    ob_start();
288
//  pdump(microtime(true) - SN_TIME_MICRO, 'Header render started');
289
    $isDisplayTopNav = true;
290
    $isDisplayMenu   = true;
291
292
    isset($template_result['GLOBAL_DISPLAY_MENU']) ? $isDisplayMenu = $template_result['GLOBAL_DISPLAY_MENU'] : false;
293
    isset($template_result['GLOBAL_DISPLAY_NAVBAR']) ? $isDisplayTopNav = $template_result['GLOBAL_DISPLAY_NAVBAR'] : false;
294
295
    // TODO: DEPRECATED! Use $template_result to turn menu and navbar or ond off!
296
    if (is_object($page)) {
297
      isset($page->_rootref['MENU']) ? $isDisplayMenu = $page->_rootref['MENU'] : false;
298
      isset($page->_rootref['NAVBAR']) ? $isDisplayTopNav = $page->_rootref['NAVBAR'] : false;
299
    }
300
301
    $inAdmin         = defined('IN_ADMIN') && IN_ADMIN === true;
302
    $isDisplayMenu   = ($isDisplayMenu || $inAdmin) && !isset($_COOKIE['menu_disable']);
303
    $isDisplayTopNav = $isDisplayTopNav && !$inAdmin;
304
305
    if ($inLoginLogout || empty($user['id']) || !is_numeric($user['id'])) {
306
      $isDisplayMenu   = false;
307
      $isDisplayTopNav = false;
308
    }
309
310
    $template = self::gettemplate('_page/_00_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 SnTemplate::gettemplate(). ( Ignorable by Annotation )

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

310
    $template = self::gettemplate('_page/_00_header', /** @scrutinizer ignore-type */ true);
Loading history...
311
    $template->assign_vars([
312
      'SN_TIME_NOW'      => SN_TIME_NOW,
313
      'SN_VERSION'       => SN_VERSION,
314
      'ADMIN_EMAIL'      => SN::$config->game_adminEmail,
315
      'CURRENT_YEAR'     => date('Y', SN_TIME_NOW),
316
      'DB_PATCH_VERSION' => dbPatchGetCurrent(),
317
    ]);
318
319
    self::renderJavaScript();
320
321
    self::renderCss($inLoginLogout);
322
323
    $template->assign_vars(array(
324
      self::P_CONTENT => $renderedContent,
325
326
      'LANG_LANGUAGE'  => $lang['LANG_INFO']['LANG_NAME_ISO2'],
327
      'LANG_ENCODING'  => 'utf-8',
328
      'LANG_DIRECTION' => $lang['LANG_INFO']['LANG_DIRECTION'],
329
330
      'SN_ROOT_VIRTUAL' => SN_ROOT_VIRTUAL,
331
332
      'ADV_SEO_META_DESCRIPTION' => $config->adv_seo_meta_description,
333
      'ADV_SEO_META_KEYWORDS'    => $config->adv_seo_meta_keywords,
334
335
      // WARNING! This can be set by page!
336
      // CHANGE CODE TO MAKE IT IMPOSSIBLE!
337
      'GLOBAL_META_TAGS'         => isset($page->_rootref['GLOBAL_META_TAGS']) ? $page->_rootref['GLOBAL_META_TAGS'] : '',
338
339
      'IN_ADMIN' => $inAdmin ? 1 : '',
340
    ));
341
342
    $template->assign_vars(array(
343
      'GLOBAL_DISPLAY_MENU'   => $isDisplayMenu,
344
      'GLOBAL_DISPLAY_NAVBAR' => $isDisplayTopNav,
345
346
      'USER_AUTHLEVEL' => intval($user['authlevel']),
347
348
      'FONT_SIZE'                        => self::playerFontSize(),
349
      'FONT_SIZE_PERCENT_DEFAULT_STRING' => FONT_SIZE_PERCENT_DEFAULT_STRING,
350
351
      'SN_TIME_NOW'          => SN_TIME_NOW,
352
      'LOGIN_LOGOUT'         => $template_result['LOGIN_LOGOUT'],
353
      'GAME_MODE_CSS_PREFIX' => $config->game_mode == GAME_BLITZ ? 'blitz_' : '',
354
      'TIME_DIFF_MEASURE'    => playerTimeDiff::timeDiffTemplate(), // Проводить замер только если не выставлен флаг форсированного замера И (иссяк интервал замера ИЛИ замера еще не было)
355
356
      'title'              => ($title ? "{$title} - " : '') . "{$lang['sys_server']} {$config->game_name} - {$lang['sys_supernova']}",
357
      'ADV_SEO_JAVASCRIPT' => $config->adv_seo_javascript,
358
359
      'SOUND_ENABLED'                        => SN::$user_options[PLAYER_OPTION_SOUND_ENABLED],
360
      'PLAYER_OPTION_ANIMATION_DISABLED'     => SN::$user_options[PLAYER_OPTION_ANIMATION_DISABLED],
361
      'PLAYER_OPTION_PROGRESS_BARS_DISABLED' => SN::$user_options[PLAYER_OPTION_PROGRESS_BARS_DISABLED],
362
363
      'IMPERSONATING'                        => !empty($template_result[F_IMPERSONATE_STATUS]) ? sprintf($lang['sys_impersonated_as'], $user['username'], $template_result[F_IMPERSONATE_OPERATOR]) : '',
364
      'PLAYER_OPTION_DESIGN_DISABLE_BORDERS' => SN::$user_options[PLAYER_OPTION_DESIGN_DISABLE_BORDERS],
365
366
      'WEBP_SUPPORT_NEED_CHECK' => ($webpSupported = SN::$gc->theUser->isWebpSupported()) === null ? 1 : 0,
367
      'WEBP_SUPPORTED'          => $webpSupported ? 1 : 0,
368
    ));
369
    $template->assign_recursive($template_result);
370
371
    if ($isDisplayMenu) {
372
      SnTemplate::tpl_render_menu($template);
373
    }
374
375
    if ($isDisplayTopNav) {
376
      SN::$gc->pimp->tpl_render_topnav($user, $planetrow, $template);
377
    }
378
379
    SnTemplate::displayP($template);
380
    ob_end_flush();
381
382
    SN::$headerRendered = true;
383
384
    ob_start();
385
  }
386
387
  /**
388
   */
389
  public static function renderJavaScript() {
390
    global $sn_mvc, $sn_page_name, $template_result;
391
392
    empty($sn_mvc['javascript']) ? $sn_mvc['javascript'] = ['' => []] : false;
393
394
    $standard_js = self::addFileName([
395
      'js/lib/jquery',
396
      'js/lib/js.cookie',
397
      'js/lib/jquery-ui',
398
      'js/lib/jquery.ui.touch-punch',
399
      'js/lib/ion.sound',
400
      'js/sn_global',
401
      'js/sn_sound',
402
      'js/sn_timer',
403
    ], [], '.js');
404
405
    $standard_js = self::addFileName(!empty($sn_mvc['javascript_filenames']) ? $sn_mvc['javascript_filenames'] : [], $standard_js, '.js');
406
407
    $standard_js = self::cacheFiles($standard_js, '.js');
408
409
    // Prepending standard CSS files
410
    $sn_mvc['javascript'][''] = array_merge($standard_js, $sn_mvc['javascript']['']);
411
412
    self::renderFileListInclude($template_result, $sn_mvc, $sn_page_name, 'javascript');
413
  }
414
415
  /**
416
   * @param $is_login
417
   */
418
  public static function renderCss($is_login) {
419
    global $sn_mvc, $sn_page_name, $template_result;
420
421
    empty($sn_mvc['css']) ? $sn_mvc['css'] = ['' => []] : false;
422
423
    $standard_css = [];
424
    $standard_css = self::addFileName('design/css/jquery-ui', $standard_css);
425
    $standard_css = self::addFileName('design/css/global', $standard_css);
426
    $is_login ? $standard_css = self::addFileName('design/css/login', $standard_css) : false;
427
    $standard_css = self::addFileName('design/css/menu_icons', $standard_css);
428
429
    $standard_css = self::getCurrentTemplate()->cssAddFileName('_template', $standard_css);
430
431
    $standard_css = self::addFileName(SN::$gc->theUser->getSkinPath() . 'skin', $standard_css);
432
    $standard_css = self::addFileName('design/css/global_override', $standard_css);
433
434
    // Trying to cache CSS files
435
    $standard_css = self::cacheFiles($standard_css);
436
437
    // Prepending standard CSS files
438
    $sn_mvc['css'][''] = array_merge($standard_css, $sn_mvc['css']['']);
439
440
    self::renderFileListInclude($template_result, $sn_mvc, $sn_page_name, 'css');
441
  }
442
443
  /**
444
   * @param $time
445
   * @param $event
446
   * @param $msg
447
   * @param $prefix
448
   * @param $is_decrease
449
   * @param $fleet_flying_row
450
   * @param $fleet_flying_sorter
451
   * @param $fleet_flying_events
452
   * @param $fleet_event_count
453
   */
454
  public static function tpl_topnav_event_build_helper($time, $event, $msg, $prefix, $is_decrease, $fleet_flying_row, &$fleet_flying_sorter, &$fleet_flying_events, &$fleet_event_count) {
455
    $fleet_flying_sorter[$fleet_event_count] = $time;
456
    $fleet_flying_events[$fleet_event_count] = array(
457
      'ROW'              => $fleet_flying_row,
458
      'FLEET_ID'         => $fleet_flying_row['fleet_id'],
459
      'EVENT'            => $event,
460
      'COORDINATES'      => uni_render_coordinates($fleet_flying_row, $prefix),
461
      'COORDINATES_TYPE' => $fleet_flying_row["{$prefix}type"],
462
      'TEXT'             => "{$msg}",
463
      'DECREASE'         => $is_decrease,
464
    );
465
    $fleet_event_count++;
466
  }
467
468
  /**
469
   * @param template $template
470
   * @param array    $fleet_flying_list
471
   * @param string   $type
472
   */
473
  public static function tpl_topnav_event_build(&$template, $fleet_flying_list, $type = 'fleet') {
474
    if (empty($fleet_flying_list)) {
475
      return;
476
    }
477
478
    global $lang;
479
480
    $fleet_event_count   = 0;
481
    $fleet_flying_sorter = array();
482
    $fleet_flying_events = array();
483
    foreach ($fleet_flying_list as &$fleet_flying_row) {
484
      $will_return = true;
485
      if ($fleet_flying_row['fleet_mess'] == 0) {
486
        // cut fleets on Hold and Expedition
487
        if ($fleet_flying_row['fleet_start_time'] >= SN_TIME_NOW) {
488
          $fleet_flying_row['fleet_mission'] == MT_RELOCATE ? $will_return = false : false;
489
          SnTemplate::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);
490
        }
491
        if ($fleet_flying_row['fleet_end_stay']) {
492
          SnTemplate::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);
493
        }
494
      }
495
      if ($will_return) {
496
        SnTemplate::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);
497
      }
498
    }
499
500
    asort($fleet_flying_sorter);
501
502
    $fleet_flying_count = count($fleet_flying_list);
503
    foreach ($fleet_flying_sorter as $fleet_event_id => $fleet_time) {
504
      $fleet_event = &$fleet_flying_events[$fleet_event_id];
505
      $template->assign_block_vars("flying_{$type}s", array(
506
        'TIME' => max(0, $fleet_time - SN_TIME_NOW),
507
        'TEXT' => $fleet_flying_count,
508
        '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']]}",
509
      ));
510
      $fleet_event['DECREASE'] ? $fleet_flying_count-- : false;
511
    }
512
  }
513
514
  /**
515
   * @return mixed|string
516
   */
517
  public static function playerFontSize() {
518
    $font_size = !empty($_COOKIE[SN_COOKIE_F]) ? $_COOKIE[SN_COOKIE_F] : SN::$user_options[PLAYER_OPTION_BASE_FONT_SIZE];
519
    if (strpos($font_size, '%') !== false) {
520
      // Размер шрифта в процентах
521
      $font_size = min(max(floatval($font_size), FONT_SIZE_PERCENT_MIN), FONT_SIZE_PERCENT_MAX) . '%';
522
523
      return $font_size;
524
    } elseif (strpos($font_size, 'px') !== false) {
525
      // Размер шрифта в пикселях
526
      $font_size = min(max(floatval($font_size), FONT_SIZE_PIXELS_MIN), FONT_SIZE_PIXELS_MAX) . 'px';
527
528
      return $font_size;
529
    } else {
530
      // Не мышонка, не лягушка...
531
      $font_size = FONT_SIZE_PERCENT_DEFAULT_STRING;
532
533
      return $font_size;
534
    }
535
  }
536
537
  /**
538
   * Checks if minified/full-size file variant exists - and adds it if any
539
   *
540
   * @param string|string[] $fileNames
541
   * @param array  $anArray
542
   *
543
   * @return array
544
   */
545
  public static function addFileName($fileNames, $anArray, $ext = '.css') {
546
    if(!is_array($fileNames)) {
547
      $fileNames = [$fileNames];
548
    }
549
550
    foreach($fileNames as $fileName) {
551
      if (file_exists(SN_ROOT_PHYSICAL . $fileName . '.min' . $ext)) {
552
        $anArray[$fileName . '.min' . $ext] = '';
553
      } elseif (file_exists(SN_ROOT_PHYSICAL . $fileName . '.css' . $ext)) {
554
        $anArray[$fileName . $ext] = '';
555
      }
556
    }
557
558
    return $anArray;
559
  }
560
561
  /**
562
   * @param array   $template_result
563
   * @param array[] $sn_mvc
564
   * @param string  $sn_page_name
565
   * @param string  $fileType - 'css' or 'javascript'
566
   */
567
  public static function renderFileListInclude(&$template_result, &$sn_mvc, $sn_page_name, $fileType) {
568
    if (empty($sn_mvc[$fileType])) {
569
      return;
570
    }
571
572
    foreach ($sn_mvc[$fileType] as $page_name => $script_list) {
573
      if (empty($page_name) || $page_name == $sn_page_name) {
574
        foreach ($script_list as $filename => $content) {
575
          $template_result['.'][$fileType][] = array(
576
            'FILE'    => $filename,
577
            'CONTENT' => $content,
578
          );
579
        }
580
      }
581
    }
582
  }
583
584
  /**
585
   * @param $template
586
   * @param $user
587
   */
588
  public static function tpl_navbar_render_notes(&$template, &$user) {
589
    $notes_query = doquery("SELECT * FROM {{notes}} WHERE `owner` = {$user['id']} AND `sticky` = 1 ORDER BY priority DESC, time DESC");
0 ignored issues
show
Deprecated Code introduced by
The function doquery() 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

589
    $notes_query = /** @scrutinizer ignore-deprecated */ doquery("SELECT * FROM {{notes}} WHERE `owner` = {$user['id']} AND `sticky` = 1 ORDER BY priority DESC, time DESC");
Loading history...
590
    while ($note_row = db_fetch($notes_query)) {
591
      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

591
      /** @scrutinizer ignore-deprecated */ Note::note_assign($template, $note_row);
Loading history...
592
    }
593
  }
594
595
  /**
596
   * @param             $template
597
   * @param             $user
598
   * @param classConfig $config
599
   */
600
  public static function tpl_navbar_render_news(&$template, &$user, $config) {
601
    if ($config->game_news_overview) {
602
      $user_last_read_safe     = intval($user['news_lastread']);
603
      $newsSql                 = "AND UNIX_TIMESTAMP(`tsTimeStamp`) >= {$user_last_read_safe} ";
604
      $newsOverviewShowSeconds = intval($config->game_news_overview_show);
605
      if ($newsOverviewShowSeconds) {
606
        $newsSql .= "AND `tsTimeStamp` >= DATE_SUB(NOW(), INTERVAL {$newsOverviewShowSeconds} SECOND) ";
607
      }
608
      nws_render($user, $template, $newsSql, $config->game_news_overview);
609
    }
610
  }
611
612
  /**
613
   * @param array  $sn_mvc
614
   * @param string $blockName
615
   *
616
   * @return array|false
617
   */
618
  public static function render_button_block(&$sn_mvc, $blockName) {
619
    $result = false;
620
621
    if (!empty($sn_mvc[$blockName]) && is_array($sn_mvc[$blockName])) {
622
      foreach ($sn_mvc[$blockName] as $navbar_button_image => $navbar_button_url) {
623
        $result[] = array(
624
          'IMAGE'        => $navbar_button_image,
625
          'URL_RELATIVE' => $navbar_button_url,
626
        );
627
      }
628
629
      $result = array(
630
        '.' => array(
631
          $blockName =>
632
            $result
633
        ),
634
      );
635
    }
636
637
    return $result;
638
  }
639
640
  /**
641
   * @param array    $sn_mvc
642
   * @param template $template
643
   */
644
  public static function tpl_navbar_extra_buttons(&$sn_mvc, $template) {
645
    ($block = SnTemplate::render_button_block($sn_mvc, 'navbar_prefix_button')) ? $template->assign_recursive($block) : false;
646
    ($block = SnTemplate::render_button_block($sn_mvc, 'navbar_main_button')) ? $template->assign_recursive($block) : false;
647
  }
648
649
  /**
650
   * @param template|string $template
651
   *
652
   * @return false|string|null
653
   */
654
  public static function templateRenderToHtml($template) {
655
    $output = null;
0 ignored issues
show
Unused Code introduced by
The assignment to $output is dead and can be removed.
Loading history...
656
657
    ob_start();
658
    SnTemplate::displayP($template);
659
    $output = ob_get_contents();
660
    ob_end_clean();
661
662
    return $output;
663
  }
664
665
  /**
666
   * @param template $template
667
   */
668
  public static function tpl_login_lang(&$template) {
669
    global $language;
670
671
    $url_params = array();
672
673
    $language ? $url_params[] = "lang={$language}" : false;
674
675
    ($id_ref = sys_get_param_id('id_ref')) ? $url_params[] = "id_ref={$id_ref}" : false;
676
677
    $template->assign_vars($q = array(
678
      'LANG'     => $language ? $language : '',
679
      'referral' => $id_ref ? '&id_ref=' . $id_ref : '',
680
681
      'REQUEST_PARAMS' => !empty($url_params) ? '?' . implode('&', $url_params) : '',// "?lang={$language}" . ($id_ref ? "&id_ref={$id_ref}" : ''),
682
      'FILENAME'       => basename($_SERVER['PHP_SELF']),
683
    ));
684
685
    foreach (lng_get_list() as $lng_id => $lng_data) {
686
      if (isset($lng_data['LANG_VARIANTS']) && is_array($lng_data['LANG_VARIANTS'])) {
687
        foreach ($lng_data['LANG_VARIANTS'] as $lang_variant) {
688
          $lng_data1 = $lng_data;
689
          $lng_data1 = array_merge($lng_data1, $lang_variant);
690
          $template->assign_block_vars('language', $lng_data1);
691
        }
692
      } else {
693
        $template->assign_block_vars('language', $lng_data);
694
      }
695
    }
696
  }
697
698
  /**
699
   * @param template $template
700
   * @param string   $blockName
701
   * @param mixed    $values
702
   * @param string   $keyName   - Name for key name
703
   * @param string   $valueName - Name for value name
704
   */
705
  public static function tpl_assign_select(&$template, $blockName, $values, $keyName = 'KEY', $valueName = 'VALUE') {
706
    !is_array($values) ? $values = array($values => $values) : false;
707
708
    foreach ($values as $key => $value) {
709
      $template->assign_block_vars($blockName, array(
710
        $keyName   => HelperString::htmlSafe($key),
711
        $valueName => HelperString::htmlSafe($value),
712
      ));
713
    }
714
  }
715
716
  /**
717
   * Renders unit bonus from unit data
718
   *
719
   * @param array $unitInfo
720
   *
721
   * @return string
722
   */
723
  public static function tpl_render_unit_bonus_data($unitInfo) {
724
    $strBonus = self::tplAddPlus($unitInfo[P_BONUS_VALUE]);
725
    switch ($unitInfo[P_BONUS_TYPE]) {
726
      case BONUS_PERCENT:
727
        $strBonus = "{$strBonus}% ";
728
      break;
729
730
      case BONUS_ABILITY:
731
        $strBonus = '';
732
      break;
733
734
      case BONUS_ADD:
735
      default:
736
      break;
737
    }
738
739
    return $strBonus;
740
  }
741
742
  /**
743
   * Converts number to string then adds "+" sign for positive AND ZERO numbers
744
   *
745
   * @param float $value
746
   *
747
   * @return string
748
   */
749
  public static function tplAddPlus($value) {
750
    return ($value >= 0 ? '+' : '') . $value;
751
  }
752
753
  /**
754
   * Convert number to prettified string then adds "+" sign for positive AND ZERO numbers
755
   *
756
   * @param float $value
757
   *
758
   * @return string
759
   */
760
  public static function tplPrettyPlus($value) {
761
    return ($value >= 0 ? '+' : '') . HelperString::numberFloorAndFormat($value);
762
  }
763
764
  /**
765
   * Add message to result box
766
   *
767
   * If $template specified - message would be added to template supplied. Otherwise - to $template_result
768
   *
769
   * @param string $message
770
   * @param int    $status
771
   * @param null   $template
0 ignored issues
show
Documentation Bug introduced by
Are you sure the doc-type for parameter $template is correct as it would always require null to be passed?
Loading history...
772
   */
773
  public static function tplAddResult($message, $status = ERR_NONE, $template = null) {
774
    global $template_result;
775
776
    $block = [
777
      'STATUS'  => $status,
778
      'MESSAGE' => $message,
779
    ];
780
781
    if ($template instanceof template) {
782
      $template->assign_block_vars('result', $block);
783
    } else {
784
      $template_result['.']['result'][] = $block;
785
    }
786
  }
787
788
  /**
789
   * @param string    $message
790
   * @param string    $title
791
   * @param string    $redirectTo
792
   * @param int       $timeout
793
   * @param bool|true $showHeader
794
   */
795
  public static function messageBox($message, $title = '', $redirectTo = '', $timeout = 5, $showHeader = true) {
796
    global $lang, $template_result;
797
798
    if (empty($title)) {
799
      $title = $lang['sys_error'];
800
    }
801
802
    $template = self::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 SnTemplate::gettemplate(). ( Ignorable by Annotation )

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

802
    $template = self::gettemplate('message_body', /** @scrutinizer ignore-type */ true);
Loading history...
803
804
    $template_result['GLOBAL_DISPLAY_NAVBAR'] = $showHeader;
805
806
    $template->assign_vars(array(
807
//    'GLOBAL_DISPLAY_NAVBAR' => $showHeader,
808
809
      'TITLE'       => $title,
810
      'MESSAGE'     => $message,
811
      'REDIRECT_TO' => $redirectTo,
812
      'TIMEOUT'     => $timeout,
813
    ));
814
815
    self::display($template, $title);
816
  }
817
818
  /**
819
   * Admin message box
820
   *
821
   * @param        $message
822
   * @param string $title
823
   * @param string $redirectTo
824
   * @param int    $timeout
825
   *
826
   * @see SnTemplate::messageBox()
827
   */
828
  public static function messageBoxAdmin($message, $title = '', $redirectTo = '', $timeout = 5) {
829
    SnTemplate::messageBox($message, $title, $redirectTo, $timeout, false);
830
  }
831
832
  public static function messageBoxAdminAccessDenied($level = AUTH_LEVEL_ADMINISTRATOR) {
833
    global $user, $lang;
834
835
    if ($user['authlevel'] < $level) {
836
      SnTemplate::messageBoxAdmin($lang['adm_err_denied'], $lang['admin_title_access_denied'], SN_ROOT_VIRTUAL . 'overview.php');
837
    }
838
  }
839
840
  /**
841
   * @param          $prevUser
842
   * @param array    $user
843
   * @param array    $planetrow
844
   * @param template $template
845
   *
846
   * @return array
847
   */
848
  public static function sn_tpl_render_topnav(&$prevUser, $user, $planetrow, $template) {
849
    global $lang, $config, $sn_mvc;
850
851
    // This call was not first one... Using results from previous call
852
    if (!empty($prevUser['username'])) {
853
      $user = $prevUser;
854
    }
855
856
    if (!is_array($user)) {
857
      return $user;
858
    }
859
860
    $GET_mode = sys_get_param_str('mode');
861
862
    $ThisUsersPlanets = DBStaticPlanet::db_planet_list_sorted($user);
863
    foreach ($ThisUsersPlanets as $CurPlanet) {
0 ignored issues
show
Bug introduced by
The expression $ThisUsersPlanets of type false is not traversable.
Loading history...
864
      if ($CurPlanet['destruyed']) {
865
        continue;
866
      }
867
868
      $fleet_listx = flt_get_fleets_to_planet($CurPlanet);
869
      if ($CurPlanet['planet_type'] == PT_MOON) {
870
        $parentPlanet = DBStaticPlanet::db_planet_by_id($CurPlanet['parent_planet']);
871
      } else {
872
        $parentPlanet = $CurPlanet;
873
      }
874
875
      $template->assign_block_vars('topnav_planets', [
876
        'ID'          => $CurPlanet['id'],
877
        'NAME'        => $CurPlanet['name'],
878
        'TYPE'        => $CurPlanet['planet_type'],
879
        'TYPE_TEXT'   => $lang['sys_planet_type_sh'][$CurPlanet['planet_type']],
880
        'IS_CAPITAL'  => $parentPlanet['id'] == $user['id_planet'],
881
        'IS_MOON'     => $CurPlanet['planet_type'] == PT_MOON,
882
        'PLIMAGE'     => $CurPlanet['image'],
883
        'FLEET_ENEMY' => $fleet_listx['enemy']['count'],
884
        'COORDS'      => uni_render_coordinates($CurPlanet),
885
        'SELECTED'    => $CurPlanet['id'] == $user['current_planet'] ? ' selected' : '',
886
      ]);
887
    }
888
889
    $fleet_flying_list = DbFleetStatic::tpl_get_fleets_flying($user);
890
    SnTemplate::tpl_topnav_event_build($template, $fleet_flying_list[0]);
891
    SnTemplate::tpl_topnav_event_build($template, $fleet_flying_list[MT_EXPLORE], 'expedition');
892
893
    que_tpl_parse($template, QUE_STRUCTURES, $user, $planetrow, null, true);
894
    que_tpl_parse($template, QUE_RESEARCH, $user, array(), null, !SN::$user_options[PLAYER_OPTION_NAVBAR_RESEARCH_WIDE]);
895
    que_tpl_parse($template, SUBQUE_FLEET, $user, $planetrow, null, true);
896
    que_tpl_parse($template, SUBQUE_DEFENSE, $user, $planetrow, null, true);
897
898
    SnTemplate::tpl_navbar_extra_buttons($sn_mvc, $template);
899
    SnTemplate::tpl_navbar_render_news($template, $user, $config);
900
    SnTemplate::tpl_navbar_render_notes($template, $user);
901
    $tutorial_enabled = PageTutorial::renderNavBar($template);
902
903
904
    $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

904
    $premium_lvl = mrc_get_level($user, /** @scrutinizer ignore-type */ false, UNIT_PREMIUM, true, true);
Loading history...
905
906
    $str_date_format   = "%3$02d %2$0s %1$04d {$lang['top_of_year']} %4$02d:%5$02d:%6$02d";
907
    $time_now_parsed   = getdate(SN_TIME_NOW);
908
    $time_local_parsed = getdate(defined('SN_CLIENT_TIME_LOCAL') ? SN_CLIENT_TIME_LOCAL : SN_TIME_NOW);
909
910
    $template->assign_vars(array(
911
      'QUE_ID'   => QUE_RESEARCH,
912
      'QUE_HTML' => 'topnav',
913
914
      'RESEARCH_ONGOING' => (boolean)$user['que'],
915
916
      'TIME_TEXT'       => sprintf($str_date_format, $time_now_parsed['year'], $lang['months'][$time_now_parsed['mon']], $time_now_parsed['mday'],
917
        $time_now_parsed['hours'], $time_now_parsed['minutes'], $time_now_parsed['seconds']
918
      ),
919
      'TIME_TEXT_LOCAL' => sprintf($str_date_format, $time_local_parsed['year'], $lang['months'][$time_local_parsed['mon']], $time_local_parsed['mday'],
920
        $time_local_parsed['hours'], $time_local_parsed['minutes'], $time_local_parsed['seconds']
921
      ),
922
923
      'GAME_BLITZ_REGISTER'             => $config->game_blitz_register,
924
      'GAME_BLITZ_REGISTER_TEXT'        => $lang['sys_blitz_registration_mode_list'][$config->game_blitz_register],
925
      'BLITZ_REGISTER_OPEN'             => $config->game_blitz_register == BLITZ_REGISTER_OPEN,
926
      'BLITZ_REGISTER_CLOSED'           => $config->game_blitz_register == BLITZ_REGISTER_CLOSED,
927
      'BLITZ_REGISTER_SHOW_LOGIN'       => $config->game_blitz_register == BLITZ_REGISTER_SHOW_LOGIN,
928
      'BLITZ_REGISTER_DISCLOSURE_NAMES' => $config->game_blitz_register == BLITZ_REGISTER_DISCLOSURE_NAMES,
929
      'GAME_BLITZ'                      => $config->game_mode == GAME_BLITZ,
930
931
      'USERS_ONLINE'  => $config->var_online_user_count,
932
      'USERS_TOTAL'   => $config->users_amount,
933
      'USER_RANK'     => $user['total_rank'],
934
      'USER_NICK'     => $user['username'],
935
      'USER_AVATAR'   => $user['avatar'],
936
      'USER_AVATARID' => $user['id'],
937
      'USER_PREMIUM'  => $premium_lvl,
938
      'USER_RACE'     => $user['player_race'],
939
940
      'TOPNAV_CURRENT_PLANET'       => $user['current_planet'],
941
      'TOPNAV_CURRENT_PLANET_NAME'  => uni_render_planet_full($planetrow), // htmlspecialchars($planetrow['name']),
942
      'TOPNAV_CURRENT_PLANET_IMAGE' => $planetrow['image'],
943
      'TOPNAV_COLONIES_CURRENT'     => get_player_current_colonies($user),
944
      'TOPNAV_COLONIES_MAX'         => get_player_max_colonies($user),
945
      'NAVBAR_MODE'                 => $GET_mode,
946
947
      '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

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

948
      'TOPNAV_DARK_MATTER_TEXT'       => HelperString::numberFloorAndFormat(/** @scrutinizer ignore-type */ mrc_get_level($user, '', RES_DARK_MATTER)),
Loading history...
949
      'TOPNAV_DARK_MATTER_PLAIN'      => mrc_get_level($user, '', RES_DARK_MATTER, false, true),
950
      'TOPNAV_DARK_MATTER_PLAIN_TEXT' => HelperString::numberFloorAndFormat(mrc_get_level($user, '', RES_DARK_MATTER, false, true)),
951
      'TOPNAV_METAMATTER'             => mrc_get_level($user, '', RES_METAMATTER),
952
      'TOPNAV_METAMATTER_TEXT'        => HelperString::numberFloorAndFormat(mrc_get_level($user, '', RES_METAMATTER)),
953
954
      // TODO ГРЯЗНЫЙ ХАК!!!
955
      'TOPNAV_PAYMENT'                => SN::$gc->modules->countModulesInGroup('payment') && !SN_GOOGLE,
956
957
      'TOPNAV_MESSAGES_ADMIN'    => $user['msg_admin'],
958
      'TOPNAV_MESSAGES_PLAYER'   => $user['mnl_joueur'],
959
      'TOPNAV_MESSAGES_ALLIANCE' => $user['mnl_alliance'],
960
      'TOPNAV_MESSAGES_ATTACK'   => $user['mnl_attaque'],
961
      'TOPNAV_MESSAGES_ALL'      => $user['new_message'],
962
963
      'TOPNAV_FLEETS_FLYING'      => empty($fleet_flying_list[0]) ? 0 : count($fleet_flying_list[0]),
964
      'TOPNAV_FLEETS_TOTAL'       => GetMaxFleets($user),
965
      'TOPNAV_EXPEDITIONS_FLYING' => empty($fleet_flying_list[MT_EXPLORE]) ? 0 : count($fleet_flying_list[MT_EXPLORE]),
966
      'TOPNAV_EXPEDITIONS_TOTAL'  => get_player_max_expeditons($user),
967
968
      'TOPNAV_QUEST_COMPLETE'    => get_quest_amount_complete($user['id']),
969
      'TOPNAV_QUEST_IN_PROGRESS' => get_quest_amount_in_progress($user['id']),
970
971
      'GAME_NEWS_OVERVIEW'       => $config->game_news_overview,
972
      '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...
973
      '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...
974
      '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...
975
      '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...
976
977
      'PLAYER_OPTION_NAVBAR_PLANET_VERTICAL'        => SN::$user_options[PLAYER_OPTION_NAVBAR_PLANET_VERTICAL],
978
      'PLAYER_OPTION_NAVBAR_PLANET_OLD'             => SN::$user_options[PLAYER_OPTION_NAVBAR_PLANET_OLD],
979
      'PLAYER_OPTION_NAVBAR_PLANET_DISABLE_STORAGE' => SN::$user_options[PLAYER_OPTION_NAVBAR_PLANET_DISABLE_STORAGE],
980
      'PLAYER_OPTION_NAVBAR_DISABLE_RESEARCH'       => SN::$user_options[PLAYER_OPTION_NAVBAR_DISABLE_RESEARCH],
981
      'PLAYER_OPTION_NAVBAR_DISABLE_PLANET'         => SN::$user_options[PLAYER_OPTION_NAVBAR_DISABLE_PLANET],
982
      'PLAYER_OPTION_NAVBAR_DISABLE_HANGAR'         => SN::$user_options[PLAYER_OPTION_NAVBAR_DISABLE_HANGAR],
983
      'PLAYER_OPTION_NAVBAR_DISABLE_DEFENSE'        => SN::$user_options[PLAYER_OPTION_NAVBAR_DISABLE_DEFENSE],
984
      'PLAYER_OPTION_NAVBAR_DISABLE_FLYING_FLEETS'  => SN::$user_options[PLAYER_OPTION_NAVBAR_DISABLE_FLYING_FLEETS],
985
      'PLAYER_OPTION_NAVBAR_DISABLE_EXPEDITIONS'    => SN::$user_options[PLAYER_OPTION_NAVBAR_DISABLE_EXPEDITIONS],
986
      'PLAYER_OPTION_NAVBAR_DISABLE_QUESTS'         => SN::$user_options[PLAYER_OPTION_NAVBAR_DISABLE_QUESTS],
987
      'PLAYER_OPTION_NAVBAR_DISABLE_META_MATTER'    => SN::$user_options[PLAYER_OPTION_NAVBAR_DISABLE_META_MATTER],
988
      'PLAYER_OPTION_NAVBAR_RESEARCH_WIDE'          => SN::$user_options[PLAYER_OPTION_NAVBAR_RESEARCH_WIDE],
989
990
      'TUTORIAL_ENABLED' => $tutorial_enabled,
991
992
      'PT_MOON'        => PT_MOON,
993
      'SUBQUE_FLEET'   => SUBQUE_FLEET,
994
      'SUBQUE_DEFENSE' => SUBQUE_DEFENSE,
995
      'QUE_RESEARCH'   => QUE_RESEARCH,
996
      'QUE_STRUCTURES' => QUE_STRUCTURES,
997
    ));
998
999
    if (
1000
      (defined('SN_RENDER_NAVBAR_PLANET') && SN_RENDER_NAVBAR_PLANET === true)
1001
      ||
1002
      ($user['option_list'][OPT_INTERFACE]['opt_int_navbar_resource_force'] && (!defined('SN_RENDER_NAVBAR_PLANET') || SN_RENDER_NAVBAR_PLANET !== false))
1003
    ) {
1004
      tpl_set_resource_info($template, $planetrow);
1005
      $template->assign_vars(array(
1006
        'SN_RENDER_NAVBAR_PLANET' => true,
1007
        'SN_NAVBAR_HIDE_FLEETS'   => true,
1008
      ));
1009
    }
1010
1011
    return $user;
1012
  }
1013
1014
  /**
1015
   * @param array|string  $files
1016
   * @param template|null $template
1017
   * @param string|null   $template_path - path to templates root
1018
   *
1019
   * @return template
1020
   */
1021
  public static function gettemplate($files, $template = null, $template_path = null, $fallBackPath = '') {
1022
    global $sn_mvc, $sn_page_name;
1023
1024
    $template = self::getCurrentTemplate()->getTemplate($template, $template_path, $fallBackPath);
1025
1026
    // TODO ГРЯЗНЫЙ ХАК! Это нужно, что бы по возможности перезаписать инфу из языковых пакетов модулей там, где она была перезаписана раньше инфой из основного пакета. Почему?
1027
    //  - сначала грузятся модули и их языковые пакеты
1028
    //  - затем по ходу дела ОСНОВНОЙ языковой пакет может перезаписать данные из МОДУЛЬНОГО языкового пакета
1029
    // Поэтому и нужен этот грязный хак
1030
    // В норме же - страницы заявляют сами, какие им пакеты нужны. Так что сначала всегда должны грузится основные языковые пакеты, а уже ПОВЕРХ них - пакеты модулей
1031
    !empty($sn_mvc['i18n']['']) ? lng_load_i18n($sn_mvc['i18n']['']) : false;
1032
    $sn_page_name ? lng_load_i18n($sn_mvc['i18n'][$sn_page_name]) : false;
1033
1034
    if (empty($files)) {
1035
      // Make sure that all empty files will translate to empty array
1036
      $files = [];
1037
    } elseif (is_string($files)) {
1038
      // If we have single filename - making array from it
1039
      $files = [basename($files) => $files];
1040
    } elseif (!is_array($files)) {
0 ignored issues
show
introduced by
The condition is_array($files) is always true.
Loading history...
1041
      // And final touch - all other non-string and non-array inputs converted to empty array
1042
      $files = [];
1043
    }
1044
1045
    foreach ($files as &$filename) {
1046
      $filename = $filename . self::TPL_HTML;
1047
    }
1048
1049
    $template->set_filenames($files);
1050
1051
    return $template;
1052
  }
1053
1054
  /**
1055
   * @param template|string $page
1056
   * @param string          $title
1057
   *
1058
   * @return mixed
1059
   */
1060
  public static function display($page, $title = '') {
1061
    SN::$gSomethingWasRendered = true;
1062
1063
    if (!defined('SN_TIME_RENDER_START')) {
1064
      define('SN_TIME_RENDER_START', microtime(true));
1065
    }
1066
1067
//  return sn_function_call('display', array($page, $title));
1068
//}
1069
//
1070
///**
1071
// * @param template|string $page
1072
// * @param string          $title
1073
// */
1074
//function sn_display($page, $title = '') {
1075
    global $debug, $user, $planetrow, $config, $lang, $template_result, $sn_mvc;
1076
1077
    !empty($sn_mvc['view']['']) and execute_hooks($sn_mvc['view'][''], $page, 'view', '');
1078
1079
    $exitStatus                      = true;
1080
    $template_result['LOGIN_LOGOUT'] = $inLoginLogout = defined('LOGIN_LOGOUT') && LOGIN_LOGOUT === true;
1081
1082
    if (is_object($page)) {
1083
      isset($page->_rootref['PAGE_TITLE']) && empty($title) ? $title = $page->_rootref['PAGE_TITLE'] : false;
1084
      !$title && !empty($page->_rootref['PAGE_HEADER']) ? $title = $page->_rootref['PAGE_HEADER'] : false;
1085
      !isset($page->_rootref['PAGE_HEADER']) && $title ? $page->assign_var('PAGE_HEADER', $title) : false;
1086
    }
1087
1088
    $isRenderGlobal = is_object($page) && isset($template_result['GLOBAL_DISPLAY_HEADER']) ? $template_result['GLOBAL_DISPLAY_HEADER'] : true;
1089
1090
    if (self::getCurrentTemplate()->isRenderWhole()) {
1091
      ob_start();
1092
    } else {
1093
      // Global header
1094
      if ($isRenderGlobal) {
1095
        SnTemplate::renderHeader($page, $title, $template_result, $inLoginLogout, $user, $config, $lang, $planetrow, null);
1096
      }
1097
    }
1098
1099
    // Page content
1100
    !is_array($page) ? $page = array($page) : false;
1101
    $result_added = false;
1102
    foreach ($page as $page_item) {
1103
      /**
1104
       * @var template $page_item
1105
       */
1106
      if (
1107
        !$result_added
1108
        && is_object($page_item)
1109
        && (
1110
          isset($page_item->_tpldata['result'])
1111
          ||
1112
          !empty($template_result['.']['result'])
1113
        )
1114
      ) {
1115
        $resultTemplate = SnTemplate::gettemplate('_result_message');
1116
1117
        $resultTemplate->_tpldata = $page_item->_tpldata;
1118
1119
        // Checking that no duplicates would be merged from template_result to template itself
1120
        $filtered = [];
1121
        if (!empty($template_result['.']['result']) && is_array($template_result['.']['result'])) {
1122
          foreach ($template_result['.']['result'] as $message) {
1123
            if (empty($message['MESSAGE'])) {
1124
              continue;
1125
            }
1126
1127
            foreach ($resultTemplate->_tpldata['result'] as $tplData) {
1128
              if (empty($tplData['MESSAGE'])) {
1129
                continue;
1130
              }
1131
1132
              if ($tplData['MESSAGE'] == $message['MESSAGE']) {
1133
                continue 2;
1134
              }
1135
            }
1136
1137
            $filtered['.']['result'][] = $message;
1138
          }
1139
        }
1140
        $resultTemplate->assign_recursive($filtered);
1141
1142
        SnTemplate::displayP($resultTemplate);
1143
        $result_added = true;
1144
      }
1145
1146
      SnTemplate::displayP($page_item);
1147
    }
1148
1149
    if (is_array($template_result[TEMPLATE_EXTRA_ARRAY]) && !empty($template_result[TEMPLATE_EXTRA_ARRAY])) {
1150
      foreach ($template_result[TEMPLATE_EXTRA_ARRAY] as $extraName => $extraTemplate) {
1151
        /**
1152
         * @var template $extraTemplate
1153
         */
1154
        SnTemplate::displayP($extraTemplate);
1155
      }
1156
    }
1157
1158
    if (
1159
      is_object($page[0])
1160
      &&
1161
      (
1162
        // Checking if hiding page hint flag is present
1163
        empty($template_result['PAGE_HINT_HIDE'])
1164
        &&
1165
        empty($page[0]->_rootref['PAGE_HINT_HIDE'])
1166
      )
1167
      &&
1168
      (
1169
        isset($page[0]->_tpldata['page_hint'])
1170
        ||
1171
        isset($page[0]->_rootref['PAGE_HINT'])
1172
        ||
1173
        !empty($template_result['.']['page_hint'])
1174
        ||
1175
        !empty($template_result['PAGE_HINT'])
1176
      )
1177
    ) {
1178
      $resultTemplate = self::gettemplate('page_hint');
1179
1180
      $resultTemplate->_tpldata = &$page[0]->_tpldata;
1181
      $resultTemplate->_rootref = &$page[0]->_rootref;
1182
      $resultTemplate->assign_recursive($template_result);
1183
1184
      SnTemplate::displayP($resultTemplate);
1185
    }
1186
1187
    if (self::getCurrentTemplate()->isRenderWhole()) {
1188
      $renderedContent = ob_get_clean();
1189
      // Global header
1190
      if ($isRenderGlobal) {
1191
        SnTemplate::renderHeader($page, $title, $template_result, $inLoginLogout, $user, $config, $lang, $planetrow, $renderedContent);
1192
      } else {
1193
        echo $renderedContent;
1194
      }
1195
    }
1196
1197
    // Flushing all opened buffers
1198
    while (@ob_end_flush()) {
1199
      ;
1200
    }
1201
1202
1203
    // Global footer
1204
    if ($isRenderGlobal) {
1205
      SnTemplate::renderFooter($page, $template_result);
1206
    }
1207
1208
    $user['authlevel'] >= 3 && $config->debug ? $debug->echo_log() : false;;
1209
1210
    SN::$db->db_disconnect();
1211
1212
    $exitStatus and die($exitStatus === true ? 0 : $exitStatus);
0 ignored issues
show
introduced by
The condition $exitStatus === true is always true.
Loading history...
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...
1213
1214
    return $exitStatus;
1215
  }
1216
1217
  /**
1218
   * @var GlobalContainer|null $gc
1219
   */
1220
  protected $gc = null;
1221
1222
  /**
1223
   * @var TemplateMeta[] $templates
1224
   */
1225
  protected $templates = [];
1226
1227
  public function __construct($gc = null) {
1228
    $this->gc = empty($gc) ? SN::$gc : $gc;
1229
  }
1230
1231
  public function registerTemplate($templateName) {
1232
    if (empty($this->templates[$templateName])) {
1233
      $this->templates[$templateName] = new TemplateMeta($this, $templateName);
1234
    }
1235
1236
    return $this->templates[$templateName];
1237
  }
1238
1239
1240
  /**
1241
   * Дефолтное имя темплейта на сервере
1242
   *
1243
   * @return string
1244
   */
1245
  public static function getServerDefaultTemplateName() {
1246
    return SN::$config->game_default_template ? SN::$config->game_default_template : self::SN_TEMPLATE_NAME_DEFAULT;
1247
  }
1248
1249
  /**
1250
   * Имя темплейта у игрока
1251
   *
1252
   * @return string
1253
   */
1254
  public static function getPlayerTemplateName() {
1255
    return SN::$gc->theUser->getTemplateName();
1256
  }
1257
1258
  /**
1259
   * Относительный путь к сконфигурированному темплейту
1260
   * 'design/templates/(имя_темплейта)
1261
   *
1262
   * @return string
1263
   * @deprecated
1264
   */
1265
  public static function pathRelativeToCurrentTemplate() {
1266
    return self::SN_TEMPLATES_PARTIAL_PATH . self::getPlayerTemplateName();
1267
  }
1268
1269
  /**
1270
   * @return TemplateMeta
1271
   */
1272
  public static function getCurrentTemplate() {
1273
    $templateName = SnTemplate::getPlayerTemplateName();
1274
    $tMeta        = static::me()->registerTemplate($templateName);
0 ignored issues
show
Bug introduced by
It seems like registerTemplate() must be provided by classes using this trait. How about adding it as abstract method to this trait? ( Ignorable by Annotation )

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

1274
    $tMeta        = static::me()->/** @scrutinizer ignore-call */ registerTemplate($templateName);
Loading history...
1275
1276
    return $tMeta;
1277
  }
1278
1279
  /**
1280
   * @param array  $fileList
1281
   * @param string $extension
1282
   *
1283
   * @return array|string[]
1284
   */
1285
  protected static function cacheFiles($fileList, $extension = '.css') {
1286
    // Calculating file key which include all used filenames and modification time for them
1287
    $key          = '';
1288
    $filesToMerge = [];
1289
    foreach ($fileList as $fileName => $aContent) {
1290
      // If content empty - index is a filename
1291
      if (empty($aContent)) {
1292
        // Checking file modification time. Also we will check if file exists
1293
        if ($fileMTime = filemtime(SN_ROOT_PHYSICAL . $fileName)) {
1294
          // Generating key
1295
          $key .= "$fileName:" . date(FMT_DATE_TIME_SQL, $fileMTime) . "\n";
1296
          // Adding filename to list of merge
1297
          $filesToMerge[$fileName] = "$fileName:" . date(FMT_DATE_TIME_SQL, $fileMTime);
1298
        }
1299
      }
1300
    }
1301
    // Name we will be using to address this file
1302
    $cacheFileName = 'design/cache/' . md5($key) . $extension;
1303
    // If no file exists - trying to create it
1304
    if (!file_exists($fullCacheFileName = SN_ROOT_PHYSICAL . $cacheFileName)) {
1305
      // Caching several files into one
1306
      $contentToCache = '';
1307
      foreach ($filesToMerge as $fileName => $temp) {
1308
        if (file_exists($fName = SN_ROOT_PHYSICAL . $fileName) && !empty($content = file_get_contents($fName))) {
1309
          // Adding content of cached file
1310
          $contentToCache .= $content . "\n";
1311
          // Marking that file was read OK - for future debug purposes if any
1312
          $filesToMerge[$fileName] .= " - OK\n";
1313
        }
1314
      }
1315
      // If we have something to cache...
1316
      if (!empty($contentToCache)) {
1317
        // /* */ works as comment for both JS and CSS
1318
        file_put_contents($fullCacheFileName, "/* Generated content. Safe to delete\n" . implode('', $filesToMerge) . "*/\n\n" . $contentToCache);
1319
      }
1320
    }
1321
1322
    // If CSS cache exists for current combination of files
1323
    if (file_exists($fullCacheFileName)) {
1324
      // Removing from list all CSS files that already in cache
1325
      foreach ($filesToMerge as $fileName => $temp) {
1326
        unset($fileList[$fileName]);
1327
      }
1328
      // Adding to list cache file
1329
      $fileList = [$cacheFileName => ''] + $fileList;
1330
    }
1331
1332
    return $fileList;
1333
  }
1334
1335
}
1336