Test Failed
Push — master ( 247090...f61425 )
by SuperNova.WS
18:56 queued 11:23
created

SnTemplate   F

Complexity

Total Complexity 224

Size/Duplication

Total Lines 1226
Duplicated Lines 0 %

Importance

Changes 2
Bugs 0 Features 0
Metric Value
eloc 570
c 2
b 0
f 0
dl 0
loc 1226
rs 2
wmc 224

39 Methods

Rating   Name   Duplication   Size   Complexity  
C tpl_menu_merge_extra() 0 44 14
A displayP() 0 11 4
B tpl_render_menu() 0 36 9
A tpl_menu_adminize() 0 10 4
A templateObjectParse() 0 19 5
C tpl_menu_assign_to_template() 0 41 15
A parsetemplate() 0 14 2
A renderFooter() 0 12 1
A playerFontSize() 0 17 4
A renderJavaScript() 0 4 1
A messageBox() 0 21 2
A tpl_assign_select() 0 7 3
A cssAddFileName() 0 8 3
A tpl_navbar_render_news() 0 9 3
A tpl_navbar_extra_buttons() 0 3 3
A tpl_navbar_render_notes() 0 4 2
A tplPrettyPlus() 0 2 2
A render_button_block() 0 20 4
A renderCss() 0 19 3
B tpl_login_lang() 0 26 10
F renderHeader() 0 103 22
A messageBoxAdmin() 0 2 1
B tpl_topnav_event_build() 0 38 10
A messageBoxAdminAccessDenied() 0 5 2
A renderFileListInclude() 0 11 6
A templateRenderToHtml() 0 9 1
A tplAddPlus() 0 2 2
A tplAddResult() 0 12 2
A tpl_render_unit_bonus_data() 0 17 4
A tpl_topnav_event_build_helper() 0 12 1
A getPlayerTemplateName() 0 2 1
B gettemplate() 0 31 7
D sn_tpl_render_topnav() 0 160 17
A pathRelativeToCurrentTemplate() 0 2 1
F display() 0 155 46
A getCurrentTemplate() 0 5 1
A registerTemplate() 0 6 2
A __construct() 0 2 2
A getServerDefaultTemplateName() 0 2 2

How to fix   Complexity   

Complex Class

Complex classes like SnTemplate often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use SnTemplate, and based on these observations, apply Extract Interface, too.

1
<?php
2
3
use Common\Traits\TSingleton;
4
use Core\GlobalContainer;
5
use Fleet\DbFleetStatic;
6
use Note\Note;
7
use \Pages\PageTutorial;
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'        => defined('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']) || defined('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']) && !defined('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']);
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...
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
340
    $template->assign_vars(array(
341
      'GLOBAL_DISPLAY_MENU'   => $isDisplayMenu,
342
      'GLOBAL_DISPLAY_NAVBAR' => $isDisplayTopNav,
343
344
      'USER_AUTHLEVEL' => intval($user['authlevel']),
345
346
      'FONT_SIZE'                        => self::playerFontSize(),
347
      'FONT_SIZE_PERCENT_DEFAULT_STRING' => FONT_SIZE_PERCENT_DEFAULT_STRING,
348
349
      'SN_TIME_NOW'          => SN_TIME_NOW,
350
      'LOGIN_LOGOUT'         => $template_result['LOGIN_LOGOUT'],
351
      'GAME_MODE_CSS_PREFIX' => $config->game_mode == GAME_BLITZ ? 'blitz_' : '',
352
      'TIME_DIFF_MEASURE'    => playerTimeDiff::timeDiffTemplate(), // Проводить замер только если не выставлен флаг форсированного замера И (иссяк интервал замера ИЛИ замера еще не было)
353
354
      'title'              => ($title ? "{$title} - " : '') . "{$lang['sys_server']} {$config->game_name} - {$lang['sys_supernova']}",
355
      'ADV_SEO_JAVASCRIPT' => $config->adv_seo_javascript,
356
357
      'SOUND_ENABLED'                        => SN::$user_options[PLAYER_OPTION_SOUND_ENABLED],
358
      'PLAYER_OPTION_ANIMATION_DISABLED'     => SN::$user_options[PLAYER_OPTION_ANIMATION_DISABLED],
359
      'PLAYER_OPTION_PROGRESS_BARS_DISABLED' => SN::$user_options[PLAYER_OPTION_PROGRESS_BARS_DISABLED],
360
361
      'IMPERSONATING'                        => !empty($template_result[F_IMPERSONATE_STATUS]) ? sprintf($lang['sys_impersonated_as'], $user['username'], $template_result[F_IMPERSONATE_OPERATOR]) : '',
362
      'PLAYER_OPTION_DESIGN_DISABLE_BORDERS' => SN::$user_options[PLAYER_OPTION_DESIGN_DISABLE_BORDERS],
363
364
      'WEBP_SUPPORT_NEED_CHECK' => ($webpSupported = SN::$gc->theUser->isWebpSupported()) === null ? 1 : 0,
365
      'WEBP_SUPPORTED'          => $webpSupported ? 1 : 0,
366
    ));
367
    $template->assign_recursive($template_result);
368
369
    if ($isDisplayMenu) {
370
      SnTemplate::tpl_render_menu($template);
371
    }
372
373
    if ($isDisplayTopNav) {
374
      SN::$gc->pimp->tpl_render_topnav($user, $planetrow, $template);
375
    }
376
377
    SnTemplate::displayP($template);
378
    ob_end_flush();
379
380
    SN::$headerRendered = true;
381
382
    ob_start();
383
  }
384
385
  /**
386
   * @param $is_login
387
   */
388
  public static function renderCss($is_login) {
389
    global $sn_mvc, $sn_page_name, $template_result;
390
391
    empty($sn_mvc['css']) ? $sn_mvc['css'] = ['' => []] : false;
392
393
    $standard_css = [];
394
    $standard_css = self::cssAddFileName('design/css/jquery-ui', $standard_css);
395
    $standard_css = self::cssAddFileName('design/css/global', $standard_css);
396
    $is_login ? $standard_css = self::cssAddFileName('design/css/login', $standard_css) : false;
397
398
    $standard_css = self::getCurrentTemplate()->cssAddFileName('_template', $standard_css);
399
400
    $standard_css = self::cssAddFileName(SN::$gc->theUser->getSkinPath() . 'skin', $standard_css);
401
    $standard_css = self::cssAddFileName('design/css/global_override', $standard_css);
402
403
    // Prepending standard CSS files
404
    $sn_mvc['css'][''] = array_merge($standard_css, $sn_mvc['css']['']);
405
406
    self::renderFileListInclude($template_result, $sn_mvc, $sn_page_name, 'css');
407
  }
408
409
  /**
410
   */
411
  public static function renderJavaScript() {
412
    global $sn_mvc, $sn_page_name, $template_result;
413
414
    self::renderFileListInclude($template_result, $sn_mvc, $sn_page_name, 'javascript');
415
  }
416
417
  /**
418
   * @param $time
419
   * @param $event
420
   * @param $msg
421
   * @param $prefix
422
   * @param $is_decrease
423
   * @param $fleet_flying_row
424
   * @param $fleet_flying_sorter
425
   * @param $fleet_flying_events
426
   * @param $fleet_event_count
427
   */
428
  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) {
429
    $fleet_flying_sorter[$fleet_event_count] = $time;
430
    $fleet_flying_events[$fleet_event_count] = array(
431
      'ROW'              => $fleet_flying_row,
432
      'FLEET_ID'         => $fleet_flying_row['fleet_id'],
433
      'EVENT'            => $event,
434
      'COORDINATES'      => uni_render_coordinates($fleet_flying_row, $prefix),
435
      'COORDINATES_TYPE' => $fleet_flying_row["{$prefix}type"],
436
      'TEXT'             => "{$msg}",
437
      'DECREASE'         => $is_decrease,
438
    );
439
    $fleet_event_count++;
440
  }
441
442
  /**
443
   * @param template $template
444
   * @param array    $fleet_flying_list
445
   * @param string   $type
446
   */
447
  public static function tpl_topnav_event_build(&$template, $fleet_flying_list, $type = 'fleet') {
448
    if (empty($fleet_flying_list)) {
449
      return;
450
    }
451
452
    global $lang;
453
454
    $fleet_event_count   = 0;
455
    $fleet_flying_sorter = array();
456
    $fleet_flying_events = array();
457
    foreach ($fleet_flying_list as &$fleet_flying_row) {
458
      $will_return = true;
459
      if ($fleet_flying_row['fleet_mess'] == 0) {
460
        // cut fleets on Hold and Expedition
461
        if ($fleet_flying_row['fleet_start_time'] >= SN_TIME_NOW) {
462
          $fleet_flying_row['fleet_mission'] == MT_RELOCATE ? $will_return = false : false;
463
          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);
464
        }
465
        if ($fleet_flying_row['fleet_end_stay']) {
466
          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);
467
        }
468
      }
469
      if ($will_return) {
470
        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);
471
      }
472
    }
473
474
    asort($fleet_flying_sorter);
475
476
    $fleet_flying_count = count($fleet_flying_list);
477
    foreach ($fleet_flying_sorter as $fleet_event_id => $fleet_time) {
478
      $fleet_event = &$fleet_flying_events[$fleet_event_id];
479
      $template->assign_block_vars("flying_{$type}s", array(
480
        'TIME' => max(0, $fleet_time - SN_TIME_NOW),
481
        'TEXT' => $fleet_flying_count,
482
        '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']]}",
483
      ));
484
      $fleet_event['DECREASE'] ? $fleet_flying_count-- : false;
485
    }
486
  }
487
488
  /**
489
   * @return mixed|string
490
   */
491
  public static function playerFontSize() {
492
    $font_size = !empty($_COOKIE[SN_COOKIE_F]) ? $_COOKIE[SN_COOKIE_F] : SN::$user_options[PLAYER_OPTION_BASE_FONT_SIZE];
493
    if (strpos($font_size, '%') !== false) {
494
      // Размер шрифта в процентах
495
      $font_size = min(max(floatval($font_size), FONT_SIZE_PERCENT_MIN), FONT_SIZE_PERCENT_MAX) . '%';
496
497
      return $font_size;
498
    } elseif (strpos($font_size, 'px') !== false) {
499
      // Размер шрифта в пикселях
500
      $font_size = min(max(floatval($font_size), FONT_SIZE_PIXELS_MIN), FONT_SIZE_PIXELS_MAX) . 'px';
501
502
      return $font_size;
503
    } else {
504
      // Не мышонка, не лягушка...
505
      $font_size = FONT_SIZE_PERCENT_DEFAULT_STRING;
506
507
      return $font_size;
508
    }
509
  }
510
511
  /**
512
   * Checks if minified/full-size CSS file exists - and adds it if any
513
   *
514
   * @param string $cssFileName
515
   * @param array  $cssArray
516
   *
517
   * @return array
518
   */
519
  public static function cssAddFileName($cssFileName, $cssArray) {
520
    if (file_exists(SN_ROOT_PHYSICAL . $cssFileName . '.min.css')) {
521
      $cssArray[$cssFileName . '.min.css'] = '';
522
    } elseif (file_exists(SN_ROOT_PHYSICAL . $cssFileName . '.css')) {
523
      $cssArray[$cssFileName . '.css'] = '';
524
    }
525
526
    return $cssArray;
527
  }
528
529
  /**
530
   * @param array   $template_result
531
   * @param array[] $sn_mvc
532
   * @param string  $sn_page_name
533
   * @param string  $fileType - 'css' or 'javascript'
534
   */
535
  public static function renderFileListInclude(&$template_result, &$sn_mvc, $sn_page_name, $fileType) {
536
    if (empty($sn_mvc[$fileType])) {
537
      return;
538
    }
539
540
    foreach ($sn_mvc[$fileType] as $page_name => $script_list) {
541
      if (empty($page_name) || $page_name == $sn_page_name) {
542
        foreach ($script_list as $filename => $content) {
543
          $template_result['.'][$fileType][] = array(
544
            'FILE'    => $filename,
545
            'CONTENT' => $content,
546
          );
547
        }
548
      }
549
    }
550
  }
551
552
  /**
553
   * @param $template
554
   * @param $user
555
   */
556
  public static function tpl_navbar_render_notes(&$template, &$user) {
557
    $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

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

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

770
    $template = self::gettemplate('message_body', /** @scrutinizer ignore-type */ true);
Loading history...
771
772
    $template_result['GLOBAL_DISPLAY_NAVBAR'] = $showHeader;
773
774
    $template->assign_vars(array(
775
//    'GLOBAL_DISPLAY_NAVBAR' => $showHeader,
776
777
      'TITLE'       => $title,
778
      'MESSAGE'     => $message,
779
      'REDIRECT_TO' => $redirectTo,
780
      'TIMEOUT'     => $timeout,
781
    ));
782
783
    self::display($template, $title);
784
  }
785
786
  /**
787
   * Admin message box
788
   *
789
   * @param        $message
790
   * @param string $title
791
   * @param string $redirectTo
792
   * @param int    $timeout
793
   *
794
   * @see SnTemplate::messageBox()
795
   */
796
  public static function messageBoxAdmin($message, $title = '', $redirectTo = '', $timeout = 5) {
797
    SnTemplate::messageBox($message, $title, $redirectTo, $timeout, false);
798
  }
799
800
  public static function messageBoxAdminAccessDenied($level = AUTH_LEVEL_ADMINISTRATOR) {
801
    global $user, $lang;
802
803
    if ($user['authlevel'] < $level) {
804
      SnTemplate::messageBoxAdmin($lang['adm_err_denied'], $lang['admin_title_access_denied'], SN_ROOT_VIRTUAL . 'overview.php');
805
    }
806
  }
807
808
  /**
809
   * @param          $prevUser
810
   * @param array    $user
811
   * @param array    $planetrow
812
   * @param template $template
813
   *
814
   * @return array
815
   */
816
  public static function sn_tpl_render_topnav(&$prevUser, $user, $planetrow, $template) {
817
    global $lang, $config, $sn_mvc;
818
819
    // This call was not first one... Using results from previous call
820
    if (!empty($prevUser['username'])) {
821
      $user = $prevUser;
822
    }
823
824
    if (!is_array($user)) {
825
      return $user;
826
    }
827
828
    $GET_mode = sys_get_param_str('mode');
829
830
    $ThisUsersPlanets = DBStaticPlanet::db_planet_list_sorted($user);
831
    foreach ($ThisUsersPlanets as $CurPlanet) {
0 ignored issues
show
Bug introduced by
The expression $ThisUsersPlanets of type false is not traversable.
Loading history...
832
      if ($CurPlanet['destruyed']) {
833
        continue;
834
      }
835
836
      $fleet_listx = flt_get_fleets_to_planet($CurPlanet);
837
      if($CurPlanet['planet_type'] == PT_MOON) {
838
        $parentPlanet = DBStaticPlanet::db_planet_by_id($CurPlanet['parent_planet']);
839
      } else {
840
        $parentPlanet = $CurPlanet;
841
      }
842
843
      $template->assign_block_vars('topnav_planets', [
844
        'ID'          => $CurPlanet['id'],
845
        'NAME'        => $CurPlanet['name'],
846
        'TYPE'        => $CurPlanet['planet_type'],
847
        'TYPE_TEXT'   => $lang['sys_planet_type_sh'][$CurPlanet['planet_type']],
848
        'IS_CAPITAL'  => $parentPlanet['id'] == $user['id_planet'],
849
        'IS_MOON'     => $CurPlanet['planet_type'] == PT_MOON,
850
        'PLIMAGE'     => $CurPlanet['image'],
851
        'FLEET_ENEMY' => $fleet_listx['enemy']['count'],
852
        'COORDS'      => uni_render_coordinates($CurPlanet),
853
        'SELECTED'    => $CurPlanet['id'] == $user['current_planet'] ? ' selected' : '',
854
      ]);
855
    }
856
857
    $fleet_flying_list = DbFleetStatic::tpl_get_fleets_flying($user);
858
    SnTemplate::tpl_topnav_event_build($template, $fleet_flying_list[0]);
859
    SnTemplate::tpl_topnav_event_build($template, $fleet_flying_list[MT_EXPLORE], 'expedition');
860
861
    que_tpl_parse($template, QUE_STRUCTURES, $user, $planetrow, null, true);
862
    que_tpl_parse($template, QUE_RESEARCH, $user, array(), null, !SN::$user_options[PLAYER_OPTION_NAVBAR_RESEARCH_WIDE]);
863
    que_tpl_parse($template, SUBQUE_FLEET, $user, $planetrow, null, true);
864
    que_tpl_parse($template, SUBQUE_DEFENSE, $user, $planetrow, null, true);
865
866
    SnTemplate::tpl_navbar_extra_buttons($sn_mvc, $template);
867
    SnTemplate::tpl_navbar_render_news($template, $user, $config);
868
    SnTemplate::tpl_navbar_render_notes($template, $user);
869
    $tutorial_enabled = PageTutorial::renderNavBar($template);
870
871
872
    $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

872
    $premium_lvl = mrc_get_level($user, /** @scrutinizer ignore-type */ false, UNIT_PREMIUM, true, true);
Loading history...
873
874
    $str_date_format   = "%3$02d %2$0s %1$04d {$lang['top_of_year']} %4$02d:%5$02d:%6$02d";
875
    $time_now_parsed   = getdate(SN_TIME_NOW);
876
    $time_local_parsed = getdate(defined('SN_CLIENT_TIME_LOCAL') ? SN_CLIENT_TIME_LOCAL : SN_TIME_NOW);
877
878
    $template->assign_vars(array(
879
      'QUE_ID'   => QUE_RESEARCH,
880
      'QUE_HTML' => 'topnav',
881
882
      'RESEARCH_ONGOING' => (boolean)$user['que'],
883
884
      'TIME_TEXT'       => sprintf($str_date_format, $time_now_parsed['year'], $lang['months'][$time_now_parsed['mon']], $time_now_parsed['mday'],
885
        $time_now_parsed['hours'], $time_now_parsed['minutes'], $time_now_parsed['seconds']
886
      ),
887
      'TIME_TEXT_LOCAL' => sprintf($str_date_format, $time_local_parsed['year'], $lang['months'][$time_local_parsed['mon']], $time_local_parsed['mday'],
888
        $time_local_parsed['hours'], $time_local_parsed['minutes'], $time_local_parsed['seconds']
889
      ),
890
891
      'GAME_BLITZ_REGISTER'             => $config->game_blitz_register,
892
      'GAME_BLITZ_REGISTER_TEXT'        => $lang['sys_blitz_registration_mode_list'][$config->game_blitz_register],
893
      'BLITZ_REGISTER_OPEN'             => $config->game_blitz_register == BLITZ_REGISTER_OPEN,
894
      'BLITZ_REGISTER_CLOSED'           => $config->game_blitz_register == BLITZ_REGISTER_CLOSED,
895
      'BLITZ_REGISTER_SHOW_LOGIN'       => $config->game_blitz_register == BLITZ_REGISTER_SHOW_LOGIN,
896
      'BLITZ_REGISTER_DISCLOSURE_NAMES' => $config->game_blitz_register == BLITZ_REGISTER_DISCLOSURE_NAMES,
897
      'GAME_BLITZ'                      => $config->game_mode == GAME_BLITZ,
898
899
      'USERS_ONLINE'  => $config->var_online_user_count,
900
      'USERS_TOTAL'   => $config->users_amount,
901
      'USER_RANK'     => $user['total_rank'],
902
      'USER_NICK'     => $user['username'],
903
      'USER_AVATAR'   => $user['avatar'],
904
      'USER_AVATARID' => $user['id'],
905
      'USER_PREMIUM'  => $premium_lvl,
906
      'USER_RACE'     => $user['player_race'],
907
908
      'TOPNAV_CURRENT_PLANET'       => $user['current_planet'],
909
      'TOPNAV_CURRENT_PLANET_NAME'  => uni_render_planet_full($planetrow), // htmlspecialchars($planetrow['name']),
910
      'TOPNAV_CURRENT_PLANET_IMAGE' => $planetrow['image'],
911
      'TOPNAV_COLONIES_CURRENT'     => get_player_current_colonies($user),
912
      'TOPNAV_COLONIES_MAX'         => get_player_max_colonies($user),
913
      'NAVBAR_MODE'                 => $GET_mode,
914
915
      '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

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

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

1238
    $tMeta        = static::me()->/** @scrutinizer ignore-call */ registerTemplate($templateName);
Loading history...
1239
1240
    return $tMeta;
1241
  }
1242
1243
}
1244