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

includes/template.php (1 issue)

1
<?php
0 ignored issues
show
Coding Style Compatibility introduced by
For compatibility and reusability of your code, PSR1 recommends that a file should introduce either new symbols (like classes, functions, etc.) or have side-effects (like outputting something, or including other files), but not both at the same time. The first symbol is defined on line 15 and the first side effect is on line 613.

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

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

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

Loading history...
2
3
use \Pages\PageTutorial;
4
use Planet\DBStaticPlanet;
5
6
// Wrappers for functions
7
8
/**
9
 * Get template name from path to skin
10
 *
11
 * @param $userSkinPath
12
 *
13
 * @return mixed
14
 */
15
function getSkinPathTemplate($userSkinPath) {
16
  static $template_names = array();
17
18
  if (!isset($template_names[$userSkinPath])) {
19
    $template_names[$userSkinPath] = file_exists(SN_ROOT_PHYSICAL . $userSkinPath . '_template.ini') ? sys_file_read(SN_ROOT_PHYSICAL . $userSkinPath . '_template.ini') : TEMPLATE_NAME;
20
  }
21
22
  return $template_names[$userSkinPath];
23
}
24
25
/**
26
 * @param string    $message
27
 * @param string    $title
28
 * @param string    $redirectTo
29
 * @param int       $timeout
30
 * @param bool|true $showHeader
31
 */
32
function messageBox($message, $title = '', $redirectTo = '', $timeout = 5, $showHeader = true) {
33
  global $lang, $template_result;
34
35
  if (empty($title)) {
36
    $title = $lang['sys_error'];
37
  }
38
39
  $template = gettemplate('message_body', true);
40
41
  $template_result['GLOBAL_DISPLAY_NAVBAR'] = $showHeader;
42
43
  $template->assign_vars(array(
44
//    'GLOBAL_DISPLAY_NAVBAR' => $showHeader,
45
46
    'TITLE'       => $title,
47
    'MESSAGE'     => $message,
48
    'REDIRECT_TO' => $redirectTo,
49
    'TIMEOUT'     => $timeout,
50
  ));
51
52
  display($template, $title);
53
}
54
55
/**
56
 * Admin message box
57
 *
58
 * @see messageBox()
59
 */
60
function messageBoxAdmin($message, $title = '', $redirectTo = '', $timeout = 5) {
61
  messageBox($message, $title, $redirectTo, $timeout, false);
62
}
63
64
function messageBoxAdminAccessDenied($level = AUTH_LEVEL_ADMINISTRATOR) {
65
  global $user, $lang;
66
67
  if ($user['authlevel'] < $level) {
68
    messageBoxAdmin($lang['adm_err_denied'], $lang['admin_title_access_denied'], SN_ROOT_VIRTUAL . 'overview.php');
69
  }
70
}
71
72
/**
73
 * @param $menu
74
 * @param $extra
75
 */
76
function tpl_menu_merge_extra(&$menu, &$extra) {
77
  if (empty($menu) || empty($extra)) {
78
    return;
79
  }
80
81
  foreach ($extra as $menu_item_id => $menu_item) {
82
    if (empty($menu_item['LOCATION'])) {
83
      $menu[$menu_item_id] = $menu_item;
84
      continue;
85
    }
86
87
    $item_location = $menu_item['LOCATION'];
88
    unset($menu_item['LOCATION']);
89
90
    $is_positioned = $item_location[0];
91
    if ($is_positioned == '+' || $is_positioned == '-') {
92
      $item_location = substr($item_location, 1);
93
    } else {
94
      $is_positioned = '';
95
    }
96
97
    if ($item_location) {
98
      $menu_keys = array_keys($menu);
99
      $insert_position = array_search($item_location, $menu_keys);
100
      if ($insert_position === false) {
101
        $insert_position = count($menu) - 1;
102
        $is_positioned = '+';
103
        $item_location = '';
104
      }
105
    } else {
106
      $insert_position = $is_positioned == '-' ? 0 : count($menu);
107
    }
108
109
    $insert_position += $is_positioned == '+' ? 1 : 0;
110
    $spliced = array_splice($menu, $insert_position, count($menu) - $insert_position);
111
    $menu[$menu_item_id] = $menu_item;
112
113
    if (!$is_positioned && $item_location) {
114
      unset($spliced[$item_location]);
115
    }
116
    $menu = array_merge($menu, $spliced);
117
  }
118
119
  $extra = array();
120
}
121
122
/**
123
 * @param array    $sn_menu
124
 * @param template $template
125
 */
126
function tpl_menu_assign_to_template(&$sn_menu, &$template) {
127
  global $lang;
128
129
  if (empty($sn_menu) || !is_array($sn_menu)) {
130
    return;
131
  }
132
133
  foreach ($sn_menu as $menu_item_id => $menu_item) {
134
    if (!$menu_item) {
135
      continue;
136
    }
137
138
    if (is_string($menu_item_id)) {
139
      $menu_item['ID'] = $menu_item_id;
140
    }
141
142
    if ($menu_item['TYPE'] == 'lang') {
143
      $lang_string = &$lang;
144
      if (preg_match('#(\w+)(?:\[(\w+)\])?(?:\[(\w+)\])?(?:\[(\w+)\])?(?:\[(\w+)\])?#', $menu_item['ITEM'], $matches) && count($matches) > 1) {
145
        for ($i = 1; $i < count($matches); $i++) {
146
          if (defined($matches[$i])) {
147
            $matches[$i] = constant($matches[$i]);
148
          }
149
          $lang_string = &$lang_string[$matches[$i]];
150
        }
151
      }
152
      $menu_item['ITEM'] = $lang_string && is_string($lang_string) ? $lang_string : "{L_{$menu_item['ITEM']}}";
153
    }
154
155
    $menu_item['ALT'] = htmlentities($menu_item['ALT']);
156
    $menu_item['TITLE'] = htmlentities($menu_item['TITLE']);
157
158
    if (!empty($menu_item['ICON'])) {
159
      if (is_string($menu_item['ICON'])) {
160
        $menu_item['ICON_PATH'] = $menu_item['ICON'];
161
      } else {
162
        $menu_item['ICON'] = $menu_item_id;
163
      }
164
    }
165
166
    $template->assign_block_vars('menu', $menu_item);
167
  }
168
}
169
170
/**
171
 * @param template $template
172
 *
173
 * @return template
174
 */
175
function tpl_render_menu($template) {
176
  global $user, $lang, $template_result, $sn_menu_admin_extra, $sn_menu_admin, $sn_menu, $sn_menu_extra;
177
178
  lng_include('admin');
179
180
//  $template = gettemplate('menu', true);
181
//  $template->assign_recursive($template_result);
182
183
  $template->assign_vars(array(
184
    'USER_AUTHLEVEL'      => $user['authlevel'],
185
    'USER_AUTHLEVEL_NAME' => $lang['user_level'][$user['authlevel']],
186
//    'USER_IMPERSONATOR'   => $template_result[F_IMPERSONATE_STATUS] != LOGIN_UNDEFINED,
187
    'PAYMENT'             => SN::$gc->modules->countModulesInGroup('payment'),
188
    'MENU_START_HIDE'     => !empty($_COOKIE[SN_COOKIE . '_menu_hidden']) || defined('SN_GOOGLE'),
189
  ));
190
191
  if (isset($template_result['MENU_CUSTOMIZE'])) {
192
    $template->assign_vars(array(
193
      'PLAYER_OPTION_MENU_SHOW_ON_BUTTON'   => SN::$user_options[PLAYER_OPTION_MENU_SHOW_ON_BUTTON],
194
      'PLAYER_OPTION_MENU_HIDE_ON_BUTTON'   => SN::$user_options[PLAYER_OPTION_MENU_HIDE_ON_BUTTON],
195
      'PLAYER_OPTION_MENU_HIDE_ON_LEAVE'    => SN::$user_options[PLAYER_OPTION_MENU_HIDE_ON_LEAVE],
196
      'PLAYER_OPTION_MENU_UNPIN_ABSOLUTE'   => SN::$user_options[PLAYER_OPTION_MENU_UNPIN_ABSOLUTE],
197
      'PLAYER_OPTION_MENU_ITEMS_AS_BUTTONS' => SN::$user_options[PLAYER_OPTION_MENU_ITEMS_AS_BUTTONS],
198
      'PLAYER_OPTION_MENU_WHITE_TEXT'       => SN::$user_options[PLAYER_OPTION_MENU_WHITE_TEXT],
199
      'PLAYER_OPTION_MENU_OLD'              => SN::$user_options[PLAYER_OPTION_MENU_OLD],
200
      'PLAYER_OPTION_MENU_HIDE_SHOW_BUTTON' => empty($_COOKIE[SN_COOKIE . '_menu_hidden']) && !defined('SN_GOOGLE')
201
        ? SN::$user_options[PLAYER_OPTION_MENU_HIDE_SHOW_BUTTON] : 1,
202
    ));
203
  }
204
205
  if (defined('IN_ADMIN') && IN_ADMIN === true && !empty($user['authlevel']) && $user['authlevel'] > 0) {
206
    tpl_menu_merge_extra($sn_menu_admin, $sn_menu_admin_extra);
207
    tpl_menu_assign_to_template($sn_menu_admin, $template);
208
  } else {
209
    tpl_menu_merge_extra($sn_menu, $sn_menu_extra);
210
    tpl_menu_assign_to_template($sn_menu, $template);
211
  }
212
213
  return $template;
214
}
215
216
/**
217
 * @param template|string $page
218
 * @param string          $title
219
 * @param bool|true       $isDisplayTopNav
220
 * @param string          $metatags
221
 * @param bool|false      $AdminPage
222
 * @param bool|true       $isDisplayMenu
223
 *
224
 * @return mixed
225
 */
226
function display($page, $title = '') {
227
  if (!defined('SN_TIME_RENDER_START')) {
228
    define('SN_TIME_RENDER_START', microtime(true));
229
  }
230
231
  return sn_function_call('display', array($page, $title));
232
}
233
234
/**
235
 * @param template|string $page
236
 * @param string          $title
237
 * @param bool|true       $isDisplayTopNav
238
 * @param string          $metatags
239
 * @param bool|false      $AdminPage
240
 * @param bool|true       $isDisplayMenu
241
 * @param bool|int|string $exitStatus - Код или сообщение выхода
242
 */
243
function sn_display($page, $title = '') {
244
  global $debug, $user, $planetrow, $config, $lang, $template_result, $sn_mvc, $sn_page_name;
245
246
  !empty($sn_mvc['view']['']) and execute_hooks($sn_mvc['view'][''], $page, 'view', '');
247
248
  $exitStatus = true;
249
  $template_result['LOGIN_LOGOUT'] = $inLoginLogout = defined('LOGIN_LOGOUT') && LOGIN_LOGOUT === true;
250
251
  if (is_object($page)) {
252
    isset($page->_rootref['PAGE_TITLE']) && empty($title) ? $title = $page->_rootref['PAGE_TITLE'] : false;
253
    !$title && !empty($page->_rootref['PAGE_HEADER']) ? $title = $page->_rootref['PAGE_HEADER'] : false;
254
    !isset($page->_rootref['PAGE_HEADER']) && $title ? $page->assign_var('PAGE_HEADER', $title) : false;
255
  }
256
257
  $isRenderGlobal = is_object($page) && isset($template_result['GLOBAL_DISPLAY_HEADER']) ? $template_result['GLOBAL_DISPLAY_HEADER'] : true;
258
259
  // Global header
260
  if ($isRenderGlobal) {
261
    renderHeader($page, $title, $template_result, $inLoginLogout, $user, $config, $lang, $planetrow);
262
  }
263
264
  // Page content
265
  !is_array($page) ? $page = array($page) : false;
266
  $result_added = false;
267
  foreach ($page as $page_item) {
268
    /**
269
     * @var template $page_item
270
     */
271
    if (!$result_added && is_object($page_item) && isset($page_item->_tpldata['result'])) {
272
      $resultTemplate = gettemplate('_result_message');
273
      $resultTemplate->_tpldata = $page_item->_tpldata;
274
      displayP($resultTemplate);
275
//      $page_item = gettemplate('_result_message', $page_item);
276
//      $temp = $page_item->files['_result_message'];
277
//      unset($page_item->files['_result_message']);
278
//      $page_item->files = array_reverse($page_item->files);
279
//      $page_item->files['_result_message'] = $temp;
280
//      $page_item->files = array_reverse($page_item->files);
281
      $result_added = true;
282
    }
283
//    $page_item->assign_recursive($template_result);
284
    displayP($page_item);
285
  }
286
287
  if(is_array($template_result[TEMPLATE_EXTRA_ARRAY]) && !empty($template_result[TEMPLATE_EXTRA_ARRAY])) {
288
    foreach($template_result[TEMPLATE_EXTRA_ARRAY] as $extraName => $extraTemplate) {
289
      /**
290
       * @var template $extraTemplate
291
       */
292
      displayP($extraTemplate);
293
    }
294
  }
295
296
  // Global footer
297
  if ($isRenderGlobal) {
298
    renderFooter();
299
  }
300
301
  $user['authlevel'] >= 3 && $config->debug ? $debug->echo_log() : false;;
302
303
  sn_db_disconnect();
304
305
  $exitStatus and die($exitStatus === true ? 0 : $exitStatus);
306
}
307
308
/**
309
 * @param $page
310
 * @param $title
311
 * @param $template_result
312
 * @param $inLoginLogout
313
 * @param $user
314
 * @param $config
315
 * @param $lang
316
 * @param $planetrow
317
 */
318
function renderHeader($page, $title, &$template_result, $inLoginLogout, &$user, $config, $lang, $planetrow) {
319
  if (SN::$headerRendered) {
320
    return;
321
  }
322
323
  ob_end_flush();
324
325
  ob_start();
326
//  pdump(microtime(true) - SN_TIME_MICRO, 'Header render started');
327
  $isDisplayTopNav = true;
328
  $isDisplayMenu = true;
329
330
  isset($template_result['GLOBAL_DISPLAY_MENU']) ? $isDisplayMenu = $template_result['GLOBAL_DISPLAY_MENU'] : false;
331
  isset($template_result['GLOBAL_DISPLAY_NAVBAR']) ? $isDisplayTopNav = $template_result['GLOBAL_DISPLAY_NAVBAR'] : false;
332
333
  // TODO: DEPRECATED! Use $template_result to turn menu and navbar or ond off!
334
  if (is_object($page)) {
335
    isset($page->_rootref['MENU']) ? $isDisplayMenu = $page->_rootref['MENU'] : false;
336
    isset($page->_rootref['NAVBAR']) ? $isDisplayTopNav = $page->_rootref['NAVBAR'] : false;
337
  }
338
339
  $inAdmin = defined('IN_ADMIN') && IN_ADMIN === true;
340
  $isDisplayMenu = ($isDisplayMenu || $inAdmin) && !isset($_COOKIE['menu_disable']);
341
  $isDisplayTopNav = $isDisplayTopNav && !$inAdmin;
342
343
  if ($inLoginLogout || empty($user['id']) || !is_numeric($user['id'])) {
344
    $isDisplayMenu = false;
345
    $isDisplayTopNav = false;
346
  }
347
348
  $user_time_diff = playerTimeDiff::user_time_diff_get();
349
  $user_time_measured_unix = intval(isset($user_time_diff[PLAYER_OPTION_TIME_DIFF_MEASURE_TIME]) ? strtotime($user_time_diff[PLAYER_OPTION_TIME_DIFF_MEASURE_TIME]) : 0);
350
  $measureTimeDiff = intval(
351
    empty($user_time_diff[PLAYER_OPTION_TIME_DIFF_FORCED])
352
    &&
353
    (SN_TIME_NOW - $user_time_measured_unix > PERIOD_HOUR || $user_time_diff[PLAYER_OPTION_TIME_DIFF] == '')
354
  );
355
356
  $template = gettemplate('_page_20_header', true);
357
358
  renderJavaScript();
359
360
  renderCss($inLoginLogout);
361
362
  $template->assign_vars(array(
363
    'LANG_LANGUAGE'  => $lang['LANG_INFO']['LANG_NAME_ISO2'],
364
    'LANG_ENCODING'  => 'utf-8',
365
    'LANG_DIRECTION' => $lang['LANG_INFO']['LANG_DIRECTION'],
366
367
    'SN_ROOT_VIRTUAL' => SN_ROOT_VIRTUAL,
368
369
    'ADV_SEO_META_DESCRIPTION' => $config->adv_seo_meta_description,
370
    'ADV_SEO_META_KEYWORDS'    => $config->adv_seo_meta_keywords,
371
372
    // WARNING! This can be set by page!
373
    // CHANGE CODE TO MAKE IT IMPOSSIBLE!
374
    'GLOBAL_META_TAGS'         => isset($page->_rootref['GLOBAL_META_TAGS']) ? $page->_rootref['GLOBAL_META_TAGS'] : '',
375
  ));
376
377
  $template->assign_vars(array(
378
    'GLOBAL_DISPLAY_MENU'   => $isDisplayMenu,
379
    'GLOBAL_DISPLAY_NAVBAR' => $isDisplayTopNav,
380
381
    'USER_AUTHLEVEL' => intval($user['authlevel']),
382
383
    'FONT_SIZE'                        => playerFontSize(),
384
    'FONT_SIZE_PERCENT_DEFAULT_STRING' => FONT_SIZE_PERCENT_DEFAULT_STRING,
385
386
    'SN_TIME_NOW'          => SN_TIME_NOW,
387
    'LOGIN_LOGOUT'         => $template_result['LOGIN_LOGOUT'],
388
    'GAME_MODE_CSS_PREFIX' => $config->game_mode == GAME_BLITZ ? 'blitz_' : '',
389
    'TIME_DIFF_MEASURE'    => $measureTimeDiff, // Проводить замер только если не выставлен флаг форсированного замера И (иссяк интервал замера ИЛИ замера еще не было)
390
391
    'title'              => ($title ? "{$title} - " : '') . "{$lang['sys_server']} {$config->game_name} - {$lang['sys_supernova']}",
392
    'ADV_SEO_JAVASCRIPT' => $config->adv_seo_javascript,
393
394
    'SOUND_ENABLED'                        => SN::$user_options[PLAYER_OPTION_SOUND_ENABLED],
395
    'PLAYER_OPTION_ANIMATION_DISABLED'     => SN::$user_options[PLAYER_OPTION_ANIMATION_DISABLED],
396
    'PLAYER_OPTION_PROGRESS_BARS_DISABLED' => SN::$user_options[PLAYER_OPTION_PROGRESS_BARS_DISABLED],
397
398
    'IMPERSONATING'                        => !empty($template_result[F_IMPERSONATE_STATUS]) ? sprintf($lang['sys_impersonated_as'], $user['username'], $template_result[F_IMPERSONATE_OPERATOR]) : '',
399
    'PLAYER_OPTION_DESIGN_DISABLE_BORDERS' => SN::$user_options[PLAYER_OPTION_DESIGN_DISABLE_BORDERS],
400
  ));
401
  $template->assign_recursive($template_result);
402
403
  if ($isDisplayMenu) {
404
    tpl_render_menu($template);
405
  }
406
407
  if ($isDisplayTopNav) {
408
    SN::$gc->pimp->tpl_render_topnav($user, $planetrow, $template);
409
  }
410
411
  displayP($template);
412
  ob_end_flush();
413
414
  SN::$headerRendered = true;
415
416
  ob_start();
417
}
418
419
/**
420
 */
421
function renderFooter() {
422
  $templateFooter = gettemplate('_page_90_footer', true);
423
424
  $templateFooter->assign_vars([
425
    'SN_TIME_NOW'      => SN_TIME_NOW,
426
    'SN_VERSION'       => SN_VERSION,
427
    'ADMIN_EMAIL'      => SN::$config->game_adminEmail,
428
    'CURRENT_YEAR'     => date('Y', SN_TIME_NOW),
429
    'DB_PATCH_VERSION' => dbPatchGetCurrent(),
430
  ]);
431
432
  displayP($templateFooter);
433
}
434
435
/**
436
 * @return mixed|string
437
 */
438
function playerFontSize() {
439
  $font_size = !empty($_COOKIE[SN_COOKIE_F]) ? $_COOKIE[SN_COOKIE_F] : SN::$user_options[PLAYER_OPTION_BASE_FONT_SIZE];
440
  if (strpos($font_size, '%') !== false) {
441
    // Размер шрифта в процентах
442
    $font_size = min(max(floatval($font_size), FONT_SIZE_PERCENT_MIN), FONT_SIZE_PERCENT_MAX) . '%';
443
444
    return $font_size;
445
  } elseif (strpos($font_size, 'px') !== false) {
446
    // Размер шрифта в пикселях
447
    $font_size = min(max(floatval($font_size), FONT_SIZE_PIXELS_MIN), FONT_SIZE_PIXELS_MAX) . 'px';
448
449
    return $font_size;
450
  } else {
451
    // Не мышонка, не лягушка...
452
    $font_size = FONT_SIZE_PERCENT_DEFAULT_STRING;
453
454
    return $font_size;
455
  }
456
}
457
458
/**
459
 * @param $template_result
460
 * @param $is_login
461
 */
462
function tpl_global_header(&$template_result, $is_login) {
463
  renderJavaScript();
464
465
  renderCss($is_login);
466
}
467
468
/**
469
 * Checks if minified/full-size CSS file exists - and adds it if any
470
 *
471
 * @param $cssFileName
472
 * @param &$cssArray
473
 *
474
 * @return bool
475
 */
476
function cssAddFileName($cssFileName, &$cssArray) {
477
  $result = false;
478
  if (file_exists(SN_ROOT_PHYSICAL . $cssFileName . '.min.css')) {
479
    $cssArray[$cssFileName . '.min.css'] = '';
480
    $result = true;
481
  } elseif (file_exists(SN_ROOT_PHYSICAL . $cssFileName . '.css')) {
482
    $cssArray[$cssFileName . '.css'] = '';
483
    $result = true;
484
  }
485
486
  return $result;
487
}
488
489
/**
490
 * @param $is_login
491
 */
492
function renderCss($is_login) {
493
  global $sn_mvc, $sn_page_name, $template_result;
494
495
  empty($sn_mvc['css']) ? $sn_mvc['css'] = array('' => array()) : false;
496
497
  $standard_css = array();
498
  cssAddFileName('design/css/jquery-ui', $standard_css);
499
  cssAddFileName('design/css/global', $standard_css);
500
  $is_login ? cssAddFileName('design/css/login', $standard_css) : false;
501
  cssAddFileName(TEMPLATE_PATH . '/_template', $standard_css);
502
  cssAddFileName(SN::$gc->theUser->getSkinPath() . 'skin', $standard_css);
503
  cssAddFileName('design/css/global_override', $standard_css);
504
505
  // Prepending standard CSS files
506
  $sn_mvc['css'][''] = array_merge($standard_css, $sn_mvc['css']['']);
507
508
  renderFileListInclude($template_result, $sn_mvc, $sn_page_name, 'css');
509
}
510
511
/**
512
 */
513
function renderJavaScript() {
514
  global $sn_mvc, $sn_page_name, $template_result;
515
516
  renderFileListInclude($template_result, $sn_mvc, $sn_page_name, 'javascript');
517
}
518
519
/**
520
 * @param array   $template_result
521
 * @param array[] $sn_mvc
522
 * @param string  $sn_page_name
523
 * @param string  $fileType - 'css' or 'javascript'
524
 */
525
function renderFileListInclude(&$template_result, &$sn_mvc, $sn_page_name, $fileType) {
526
  if (empty($sn_mvc[$fileType])) {
527
    return;
528
  }
529
530
  foreach ($sn_mvc[$fileType] as $page_name => $script_list) {
531
    if (empty($page_name) || $page_name == $sn_page_name) {
532
      foreach ($script_list as $filename => $content) {
533
        $template_result['.'][$fileType][] = array(
534
          'FILE'    => $filename,
535
          'CONTENT' => $content,
536
        );
537
      }
538
    }
539
  }
540
}
541
542
/**
543
 * @param $time
544
 * @param $event
545
 * @param $msg
546
 * @param $prefix
547
 * @param $is_decrease
548
 * @param $fleet_flying_row
549
 * @param $fleet_flying_sorter
550
 * @param $fleet_flying_events
551
 * @param $fleet_event_count
552
 */
553
function tpl_topnav_event_build_helper($time, $event, $msg, $prefix, $is_decrease, $fleet_flying_row, &$fleet_flying_sorter, &$fleet_flying_events, &$fleet_event_count) {
554
  $fleet_flying_sorter[$fleet_event_count] = $time;
555
  $fleet_flying_events[$fleet_event_count] = array(
556
    'ROW'              => $fleet_flying_row,
557
    'FLEET_ID'         => $fleet_flying_row['fleet_id'],
558
    'EVENT'            => $event,
559
    'COORDINATES'      => uni_render_coordinates($fleet_flying_row, $prefix),
560
    'COORDINATES_TYPE' => $fleet_flying_row["{$prefix}type"],
561
    'TEXT'             => "{$msg}",
562
    'DECREASE'         => $is_decrease,
563
  );
564
  $fleet_event_count++;
565
}
566
567
/**
568
 * @param template $template
569
 * @param array    $fleet_flying_list
570
 * @param string   $type
571
 */
572
function tpl_topnav_event_build(&$template, $fleet_flying_list, $type = 'fleet') {
573
  if (empty($fleet_flying_list)) {
574
    return;
575
  }
576
577
  global $lang;
578
579
  $fleet_event_count = 0;
580
  $fleet_flying_sorter = array();
581
  $fleet_flying_events = array();
582
  foreach ($fleet_flying_list as &$fleet_flying_row) {
583
    $will_return = true;
584
    if ($fleet_flying_row['fleet_mess'] == 0) {
585
      // cut fleets on Hold and Expedition
586
      if ($fleet_flying_row['fleet_start_time'] >= SN_TIME_NOW) {
587
        $fleet_flying_row['fleet_mission'] == MT_RELOCATE ? $will_return = false : false;
588
        tpl_topnav_event_build_helper($fleet_flying_row['fleet_start_time'], EVENT_FLEET_ARRIVE, $lang['sys_event_arrive'], 'fleet_end_', !$will_return, $fleet_flying_row, $fleet_flying_sorter, $fleet_flying_events, $fleet_event_count);
589
      }
590
      if ($fleet_flying_row['fleet_end_stay']) {
591
        tpl_topnav_event_build_helper($fleet_flying_row['fleet_end_stay'], EVENT_FLEET_STAY, $lang['sys_event_stay'], 'fleet_end_', false, $fleet_flying_row, $fleet_flying_sorter, $fleet_flying_events, $fleet_event_count);
592
      }
593
    }
594
    if ($will_return) {
595
      tpl_topnav_event_build_helper($fleet_flying_row['fleet_end_time'], EVENT_FLEET_RETURN, $lang['sys_event_return'], 'fleet_start_', true, $fleet_flying_row, $fleet_flying_sorter, $fleet_flying_events, $fleet_event_count);
596
    }
597
  }
598
599
  asort($fleet_flying_sorter);
600
601
  $fleet_flying_count = count($fleet_flying_list);
602
  foreach ($fleet_flying_sorter as $fleet_event_id => $fleet_time) {
603
    $fleet_event = &$fleet_flying_events[$fleet_event_id];
604
    $template->assign_block_vars("flying_{$type}s", array(
605
      'TIME' => max(0, $fleet_time - SN_TIME_NOW),
606
      'TEXT' => $fleet_flying_count,
607
      'HINT' => date(FMT_DATE_TIME, $fleet_time + SN_CLIENT_TIME_DIFF) . " - {$lang['sys_fleet']} {$fleet_event['TEXT']} {$fleet_event['COORDINATES']} {$lang['sys_planet_type_sh'][$fleet_event['COORDINATES_TYPE']]} {$lang['type_mission'][$fleet_event['ROW']['fleet_mission']]}",
608
    ));
609
    $fleet_event['DECREASE'] ? $fleet_flying_count-- : false;
610
  }
611
}
612
613
SN::$afterInit[] = function () {
614
  SN::$gc->pimp->add()->tpl_render_topnav($t = 'sn_tpl_render_topnav', [], null);
615
};
616
617
/**
618
 * @param array    $user
619
 * @param array    $planetrow
620
 * @param template $template
621
 *
622
 * @return array
623
 */
624
function sn_tpl_render_topnav($prevUser, $user, $planetrow, $template) {
625
  global $lang, $config, $sn_mvc;
626
627
  // This call was not first one... Using results from previous call
628
  if(!empty($prevUser['username'])) {
629
    $user = $prevUser;
630
  }
631
632
  if (!is_array($user)) {
633
    return $user;
634
  }
635
636
  $GET_mode = sys_get_param_str('mode');
637
638
  $ThisUsersPlanets = DBStaticPlanet::db_planet_list_sorted($user);
639
  foreach ($ThisUsersPlanets as $CurPlanet) {
640
    if ($CurPlanet['destruyed']) {
641
      continue;
642
    }
643
644
    $fleet_listx = flt_get_fleets_to_planet($CurPlanet);
645
646
    $template->assign_block_vars('topnav_planets', [
647
      'ID'          => $CurPlanet['id'],
648
      'NAME'        => $CurPlanet['name'],
649
      'TYPE'        => $CurPlanet['planet_type'],
650
      'TYPE_TEXT'   => $lang['sys_planet_type_sh'][$CurPlanet['planet_type']],
651
      'IS_CAPITAL'  => $CurPlanet['planet_type'] == PT_PLANET && $CurPlanet['id'] == $user['id_planet'],
652
      'IS_MOON'     => $CurPlanet['planet_type'] == PT_MOON,
653
      'PLIMAGE'     => $CurPlanet['image'],
654
      'FLEET_ENEMY' => $fleet_listx['enemy']['count'],
655
      'COORDS'      => uni_render_coordinates($CurPlanet),
656
      'SELECTED'    => $CurPlanet['id'] == $user['current_planet'] ? ' selected' : '',
657
    ]);
658
  }
659
660
  $fleet_flying_list = tpl_get_fleets_flying($user);
661
  tpl_topnav_event_build($template, $fleet_flying_list[0]);
662
  tpl_topnav_event_build($template, $fleet_flying_list[MT_EXPLORE], 'expedition');
663
664
  que_tpl_parse($template, QUE_STRUCTURES, $user, $planetrow, null, true);
665
  que_tpl_parse($template, QUE_RESEARCH, $user, array(), null, !SN::$user_options[PLAYER_OPTION_NAVBAR_RESEARCH_WIDE]);
666
  que_tpl_parse($template, SUBQUE_FLEET, $user, $planetrow, null, true);
667
668
  tpl_navbar_extra_buttons($sn_mvc, $template);
669
  tpl_navbar_render_news($template, $user, $config);
670
  tpl_navbar_render_notes($template, $user);
671
  $tutorial_enabled = PageTutorial::renderNavBar($template);
672
673
674
  $premium_lvl = mrc_get_level($user, false, UNIT_PREMIUM, true, true);
675
676
  $str_date_format = "%3$02d %2$0s %1$04d {$lang['top_of_year']} %4$02d:%5$02d:%6$02d";
677
  $time_now_parsed = getdate(SN_TIME_NOW);
678
  $time_local_parsed = getdate(defined('SN_CLIENT_TIME_LOCAL') ? SN_CLIENT_TIME_LOCAL : SN_TIME_NOW);
679
680
  $template->assign_vars(array(
681
    'QUE_ID'   => QUE_RESEARCH,
682
    'QUE_HTML' => 'topnav',
683
684
    'RESEARCH_ONGOING' => (boolean)$user['que'],
685
686
    'TIME_TEXT'       => sprintf($str_date_format, $time_now_parsed['year'], $lang['months'][$time_now_parsed['mon']], $time_now_parsed['mday'],
687
      $time_now_parsed['hours'], $time_now_parsed['minutes'], $time_now_parsed['seconds']
688
    ),
689
    'TIME_TEXT_LOCAL' => sprintf($str_date_format, $time_local_parsed['year'], $lang['months'][$time_local_parsed['mon']], $time_local_parsed['mday'],
690
      $time_local_parsed['hours'], $time_local_parsed['minutes'], $time_local_parsed['seconds']
691
    ),
692
693
    'GAME_BLITZ_REGISTER'             => $config->game_blitz_register,
694
    'GAME_BLITZ_REGISTER_TEXT'        => $lang['sys_blitz_registration_mode_list'][$config->game_blitz_register],
695
    'BLITZ_REGISTER_OPEN'             => $config->game_blitz_register == BLITZ_REGISTER_OPEN,
696
    'BLITZ_REGISTER_CLOSED'           => $config->game_blitz_register == BLITZ_REGISTER_CLOSED,
697
    'BLITZ_REGISTER_SHOW_LOGIN'       => $config->game_blitz_register == BLITZ_REGISTER_SHOW_LOGIN,
698
    'BLITZ_REGISTER_DISCLOSURE_NAMES' => $config->game_blitz_register == BLITZ_REGISTER_DISCLOSURE_NAMES,
699
    'GAME_BLITZ'                      => $config->game_mode == GAME_BLITZ,
700
701
    'USERS_ONLINE'  => $config->var_online_user_count,
702
    'USERS_TOTAL'   => $config->users_amount,
703
    'USER_RANK'     => $user['total_rank'],
704
    'USER_NICK'     => $user['username'],
705
    'USER_AVATAR'   => $user['avatar'],
706
    'USER_AVATARID' => $user['id'],
707
    'USER_PREMIUM'  => $premium_lvl,
708
    'USER_RACE'     => $user['player_race'],
709
710
    'TOPNAV_CURRENT_PLANET'       => $user['current_planet'],
711
    'TOPNAV_CURRENT_PLANET_NAME'  => uni_render_planet_full($planetrow), // htmlspecialchars($planetrow['name']),
712
    'TOPNAV_CURRENT_PLANET_IMAGE' => $planetrow['image'],
713
    'TOPNAV_COLONIES_CURRENT'     => get_player_current_colonies($user),
714
    'TOPNAV_COLONIES_MAX'         => get_player_max_colonies($user),
715
    'NAVBAR_MODE'                 => $GET_mode,
716
717
    'TOPNAV_DARK_MATTER'            => mrc_get_level($user, '', RES_DARK_MATTER),
718
    'TOPNAV_DARK_MATTER_TEXT'       => HelperString::numberFloorAndFormat(mrc_get_level($user, '', RES_DARK_MATTER)),
719
    'TOPNAV_DARK_MATTER_PLAIN'      => mrc_get_level($user, '', RES_DARK_MATTER, false, true),
720
    'TOPNAV_DARK_MATTER_PLAIN_TEXT' => HelperString::numberFloorAndFormat(mrc_get_level($user, '', RES_DARK_MATTER, false, true)),
721
    'TOPNAV_METAMATTER'             => mrc_get_level($user, '', RES_METAMATTER),
722
    'TOPNAV_METAMATTER_TEXT'        => HelperString::numberFloorAndFormat(mrc_get_level($user, '', RES_METAMATTER)),
723
724
    // TODO ГРЯЗНЫЙ ХАК!!!
725
    'TOPNAV_PAYMENT'                => SN::$gc->modules->countModulesInGroup('payment') && !defined('SN_GOOGLE'),
726
727
    'TOPNAV_MESSAGES_ADMIN'    => $user['msg_admin'],
728
    'TOPNAV_MESSAGES_PLAYER'   => $user['mnl_joueur'],
729
    'TOPNAV_MESSAGES_ALLIANCE' => $user['mnl_alliance'],
730
    'TOPNAV_MESSAGES_ATTACK'   => $user['mnl_attaque'],
731
    'TOPNAV_MESSAGES_ALL'      => $user['new_message'],
732
733
    'TOPNAV_FLEETS_FLYING'      => count($fleet_flying_list[0]),
734
    'TOPNAV_FLEETS_TOTAL'       => GetMaxFleets($user),
735
    'TOPNAV_EXPEDITIONS_FLYING' => count($fleet_flying_list[MT_EXPLORE]),
736
    'TOPNAV_EXPEDITIONS_TOTAL'  => get_player_max_expeditons($user),
737
738
    'TOPNAV_QUEST_COMPLETE'    => get_quest_amount_complete($user['id']),
739
    'TOPNAV_QUEST_IN_PROGRESS' => get_quest_amount_in_progress($user['id']),
740
741
    'GAME_NEWS_OVERVIEW'       => $config->game_news_overview,
742
    'GAME_RESEARCH_DISABLED'   => defined('GAME_RESEARCH_DISABLED') && GAME_RESEARCH_DISABLED,
743
    'GAME_DEFENSE_DISABLED'    => defined('GAME_DEFENSE_DISABLED') && GAME_DEFENSE_DISABLED,
744
    'GAME_STRUCTURES_DISABLED' => defined('GAME_STRUCTURES_DISABLED') && GAME_STRUCTURES_DISABLED,
745
    'GAME_HANGAR_DISABLED'     => defined('GAME_HANGAR_DISABLED') && GAME_HANGAR_DISABLED,
746
747
    'PLAYER_OPTION_NAVBAR_PLANET_VERTICAL'        => SN::$user_options[PLAYER_OPTION_NAVBAR_PLANET_VERTICAL],
748
    'PLAYER_OPTION_NAVBAR_PLANET_OLD'             => SN::$user_options[PLAYER_OPTION_NAVBAR_PLANET_OLD],
749
    'PLAYER_OPTION_NAVBAR_PLANET_DISABLE_STORAGE' => SN::$user_options[PLAYER_OPTION_NAVBAR_PLANET_DISABLE_STORAGE],
750
    'PLAYER_OPTION_NAVBAR_DISABLE_RESEARCH'       => SN::$user_options[PLAYER_OPTION_NAVBAR_DISABLE_RESEARCH],
751
    'PLAYER_OPTION_NAVBAR_DISABLE_PLANET'         => SN::$user_options[PLAYER_OPTION_NAVBAR_DISABLE_PLANET],
752
    'PLAYER_OPTION_NAVBAR_DISABLE_HANGAR'         => SN::$user_options[PLAYER_OPTION_NAVBAR_DISABLE_HANGAR],
753
    'PLAYER_OPTION_NAVBAR_DISABLE_FLYING_FLEETS'  => SN::$user_options[PLAYER_OPTION_NAVBAR_DISABLE_FLYING_FLEETS],
754
    'PLAYER_OPTION_NAVBAR_DISABLE_EXPEDITIONS'    => SN::$user_options[PLAYER_OPTION_NAVBAR_DISABLE_EXPEDITIONS],
755
    'PLAYER_OPTION_NAVBAR_DISABLE_QUESTS'         => SN::$user_options[PLAYER_OPTION_NAVBAR_DISABLE_QUESTS],
756
    'PLAYER_OPTION_NAVBAR_DISABLE_META_MATTER'    => SN::$user_options[PLAYER_OPTION_NAVBAR_DISABLE_META_MATTER],
757
    'PLAYER_OPTION_NAVBAR_RESEARCH_WIDE'          => SN::$user_options[PLAYER_OPTION_NAVBAR_RESEARCH_WIDE],
758
759
    'TUTORIAL_ENABLED' => $tutorial_enabled,
760
761
    'PT_MOON'        => PT_MOON,
762
    'SUBQUE_FLEET'   => SUBQUE_FLEET,
763
    'QUE_RESEARCH'   => QUE_RESEARCH,
764
    'QUE_STRUCTURES' => QUE_STRUCTURES,
765
  ));
766
767
  if ((defined('SN_RENDER_NAVBAR_PLANET') && SN_RENDER_NAVBAR_PLANET === true) || ($user['option_list'][OPT_INTERFACE]['opt_int_navbar_resource_force'] && SN_RENDER_NAVBAR_PLANET !== false)) {
768
    tpl_set_resource_info($template, $planetrow);
769
    $template->assign_vars(array(
770
      'SN_RENDER_NAVBAR_PLANET' => true,
771
      'SN_NAVBAR_HIDE_FLEETS'   => true,
772
    ));
773
  }
774
775
  return $user;
776
}
777
778
/**
779
 * @param $template
780
 * @param $user
781
 */
782
function tpl_navbar_render_notes(&$template, &$user) {
783
  $notes_query = doquery("SELECT * FROM {{notes}} WHERE `owner` = {$user['id']} AND `sticky` = 1 ORDER BY priority DESC, time DESC");
784
  while ($note_row = db_fetch($notes_query)) {
785
    \Note\Note::note_assign($template, $note_row);
786
  }
787
}
788
789
/**
790
 * @param $template
791
 * @param $user
792
 * @param $config
793
 */
794
function tpl_navbar_render_news(&$template, &$user, $config) {
795
  if ($config->game_news_overview) {
796
    $user_last_read_safe = intval($user['news_lastread']);
797
    $newsSql = "WHERE UNIX_TIMESTAMP(`tsTimeStamp`) >= {$user_last_read_safe}";
798
    $newsOverviewShowSeconds = intval($config->game_news_overview_show);
799
    if ($newsOverviewShowSeconds) {
800
      $newsSql .= " AND `tsTimeStamp` >= DATE_SUB(NOW(), INTERVAL {$newsOverviewShowSeconds} SECOND)";
801
    }
802
    nws_render($template, $newsSql, $config->game_news_overview);
803
  }
804
}
805
806
/**
807
 * @param array  $sn_mvc
808
 * @param string $blockName
809
 *
810
 * @return array|false
811
 */
812
function render_button_block(&$sn_mvc, $blockName) {
813
  $result = false;
814
815
  if (!empty($sn_mvc[$blockName]) && is_array($sn_mvc[$blockName])) {
816
    foreach ($sn_mvc[$blockName] as $navbar_button_image => $navbar_button_url) {
817
      $result[] = array(
818
        'IMAGE'        => $navbar_button_image,
819
        'URL_RELATIVE' => $navbar_button_url,
820
      );
821
    }
822
823
    $result = array(
824
      '.' => array(
825
        $blockName =>
826
          $result
827
      ),
828
    );
829
  }
830
831
  return $result;
832
}
833
834
/**
835
 * @param array    $sn_mvc
836
 * @param template $template
837
 */
838
function tpl_navbar_extra_buttons(&$sn_mvc, $template) {
839
  ($block = render_button_block($sn_mvc, 'navbar_prefix_button')) ? $template->assign_recursive($block) : false;
840
  ($block = render_button_block($sn_mvc, 'navbar_main_button')) ? $template->assign_recursive($block) : false;
841
}
842
843
/**
844
 * @param template|string $template
845
 */
846
function templateRenderToHtml($template) {
847
  $output = null;
848
849
  ob_start();
850
  displayP($template);
851
  $output = ob_get_contents();
852
  ob_end_clean();
853
854
  return $output;
855
}
856
857
858
/**
859
 * @param template|string $template
860
 */
861
function displayP($template) {
862
  if (is_object($template)) {
863
    if (empty($template->parsed)) {
864
      parsetemplate($template);
865
    }
866
867
    foreach ($template->files as $section => $filename) {
868
      $template->display($section);
869
    }
870
  } else {
871
    print($template);
872
  }
873
}
874
875
/**
876
 * @param template   $template
877
 * @param array|bool $array
878
 *
879
 * @return mixed
880
 */
881
function templateObjectParse($template, $array = false) {
882
  global $user;
883
884
  if (!empty($array) && is_array($array)) {
885
    foreach ($array as $key => $data) {
886
      $template->assign_var($key, $data);
887
    }
888
  }
889
890
  $template->assign_vars(array(
891
    'SN_TIME_NOW'    => SN_TIME_NOW,
892
    'USER_AUTHLEVEL' => isset($user['authlevel']) ? $user['authlevel'] : -1,
893
    'SN_GOOGLE'      => defined('SN_GOOGLE'),
894
  ));
895
896
  $template->parsed = true;
897
898
  return $template;
899
}
900
901
/**
902
 * @param template|string $template
903
 * @param array|bool      $array
904
 *
905
 * @return mixed
906
 */
907
function parsetemplate($template, $array = false) {
908
  if (is_object($template)) {
909
    return templateObjectParse($template, $array);
910
  } else {
911
    $search[] = '#\{L_([a-z0-9\-_]*?)\[([a-z0-9\-_]*?)\]\}#Ssie';
912
    $replace[] = '((isset($lang[\'\1\'][\'\2\'])) ? $lang[\'\1\'][\'\2\'] : \'{L_\1[\2]}\');';
913
914
    $search[] = '#\{L_([a-z0-9\-_]*?)\}#Ssie';
915
    $replace[] = '((isset($lang[\'\1\'])) ? $lang[\'\1\'] : \'{L_\1}\');';
916
917
    $search[] = '#\{([a-z0-9\-_]*?)\}#Ssie';
918
    $replace[] = '((isset($array[\'\1\'])) ? $array[\'\1\'] : \'{\1}\');';
919
920
    return preg_replace($search, $replace, $template);
921
  }
922
}
923
924
/**
925
 * @param array|string  $files
926
 * @param template|null $template
927
 * @param string|null   $template_path - path to template
928
 *
929
 * @return template
930
 */
931
function gettemplate($files, $template = null, $template_path = null) {
932
  global $sn_mvc, $sn_page_name;
933
934
  $template_ex = '.tpl.html';
935
936
  is_string($files) ? $files = array(basename($files) => $files) : false;
937
938
  !is_object($template) ? $template = new template(SN_ROOT_PHYSICAL) : false;
939
  //$template->set_custom_template($template_path ? $template_path : TEMPLATE_DIR, TEMPLATE_NAME, TEMPLATE_DIR);
940
941
  $templateName = getSkinPathTemplate(SN::$gc->theUser->getSkinPath());
942
  !$template_path || !is_string($template_path) ? $template_path = SN_ROOT_PHYSICAL . 'design/templates/' : false;
943
  $template->set_custom_template($template_path . $templateName . '/', $templateName, TEMPLATE_DIR);
944
945
  // TODO ГРЯЗНЫЙ ХАК! Это нужно, что бы по возможности перезаписать инфу из языковых пакетов модулей там, где она была перезаписана раньше инфой из основного пакета. Почему?
946
  //  - сначала грузятся модули и их языковые пакеты
947
  //  - затем по ходу дела ОСНОВНОЙ языковой пакет может перезаписать данные из МОДУЛЬНОГО языкового пакета
948
  // Поэтому и нужен этот грязный хак
949
  // В норме же - страницы заявляют сами, какие им пакеты нужны. Так что сначала всегда должны грузится основные языковые пакеты, а уже ПОВЕРХ них - пакеты модулей
950
  !empty($sn_mvc['i18n']['']) ? lng_load_i18n($sn_mvc['i18n']['']) : false;
951
  $sn_page_name ? lng_load_i18n($sn_mvc['i18n'][$sn_page_name]) : false;
952
953
  foreach ($files as &$filename) {
954
    $filename = $filename . $template_ex;
955
  }
956
957
  $template->set_filenames($files);
958
959
  return $template;
960
}
961
962
/**
963
 * @param template $template
964
 */
965
function tpl_login_lang(&$template) {
966
  global $language;
967
968
  $url_params = array();
969
970
  $language ? $url_params[] = "lang={$language}" : false;
971
972
  ($id_ref = sys_get_param_id('id_ref')) ? $url_params[] = "id_ref={$id_ref}" : false;
973
974
  $template->assign_vars($q = array(
975
    'LANG'     => $language ? $language : '',
976
    'referral' => $id_ref ? '&id_ref=' . $id_ref : '',
977
978
    'REQUEST_PARAMS' => !empty($url_params) ? '?' . implode('&', $url_params) : '',// "?lang={$language}" . ($id_ref ? "&id_ref={$id_ref}" : ''),
979
    'FILENAME'       => basename($_SERVER['PHP_SELF']),
980
  ));
981
982
  foreach (lng_get_list() as $lng_id => $lng_data) {
983
    if (isset($lng_data['LANG_VARIANTS']) && is_array($lng_data['LANG_VARIANTS'])) {
984
      foreach ($lng_data['LANG_VARIANTS'] as $lang_variant) {
985
        $lng_data1 = $lng_data;
986
        $lng_data1 = array_merge($lng_data1, $lang_variant);
987
        $template->assign_block_vars('language', $lng_data1);
988
      }
989
    } else {
990
      $template->assign_block_vars('language', $lng_data);
991
    }
992
  }
993
}
994
995
/**
996
 * @param array $user
997
 *
998
 * @return array
999
 */
1000
function tpl_get_fleets_flying(&$user) {
1001
  $fleet_flying_list = array();
1002
1003
  $fleet_flying_list[0] = fleet_list_by_owner_id($user['id']);
1004
  foreach ($fleet_flying_list[0] as $fleet_id => $fleet_flying_row) {
1005
    $fleet_flying_list[$fleet_flying_row['fleet_mission']][$fleet_id] = &$fleet_flying_list[0][$fleet_id];
1006
  }
1007
1008
  return $fleet_flying_list;
1009
}
1010
1011
/**
1012
 * @param template $template
1013
 * @param string   $blockName
1014
 * @param mixed    $values
1015
 * @param string   $keyName   - Name for key name
1016
 * @param string   $valueName - Name for value name
1017
 */
1018
function tpl_assign_select(&$template, $blockName, $values, $keyName = 'KEY', $valueName = 'VALUE') {
1019
  !is_array($values) ? $values = array($values => $values) : false;
1020
1021
  foreach ($values as $key => $value) {
1022
    $template->assign_block_vars($blockName, array(
1023
      $keyName   => HelperString::htmlSafe($key),
1024
      $valueName => HelperString::htmlSafe($value),
1025
    ));
1026
  }
1027
}
1028
1029
/**
1030
 * Renders unit bonus from unit data
1031
 *
1032
 * @param array $unitInfo
1033
 *
1034
 * @return string
1035
 */
1036
function tpl_render_unit_bonus_data($unitInfo) {
1037
  $strBonus = tplAddPlus($unitInfo[P_BONUS_VALUE]);
1038
  switch ($unitInfo[P_BONUS_TYPE]) {
1039
    case BONUS_PERCENT:
1040
      $strBonus = "{$strBonus}% ";
1041
    break;
1042
1043
    case BONUS_ABILITY:
1044
      $strBonus = '';
1045
    break;
1046
1047
    case BONUS_ADD:
1048
    default:
1049
    break;
1050
  }
1051
1052
  return $strBonus;
1053
}
1054
1055
/**
1056
 * Converts number to string then adds "+" sign for positive AND ZERO numbers
1057
 *
1058
 * @param float $value
1059
 *
1060
 * @return string
1061
 */
1062
function tplAddPlus($value) {
1063
  return ($value >= 0 ? '+' : '') . $value;
1064
}
1065
1066
1067
/**
1068
 * Convert number to prettified string then adds "+" sign for positive AND ZERO numbers
1069
 *
1070
 * @param float $value
1071
 *
1072
 * @return string
1073
 */
1074
function tplPrettyPlus($value) {
1075
  return ($value >= 0 ? '+' : '') . HelperString::numberFloorAndFormat($value);
1076
}
1077