| Total Complexity | 224 | 
| Total Lines | 1226 | 
| Duplicated Lines | 0 % | 
| Changes | 2 | ||
| Bugs | 0 | Features | 0 | 
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  | 
            ||
| 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'; | 
            ||
| 
                                                                                                    
                        
                         | 
                |||
| 55 |       $replace[] = '((isset($lang[\'\1\'][\'\2\'])) ? $lang[\'\1\'][\'\2\'] : \'{L_\1[\2]}\');'; | 
            ||
| 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) { | 
            ||
| 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;  | 
            ||
| 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++) { | 
            ||
| 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) { | 
            ||
| 250 | }  | 
            ||
| 251 | |||
| 252 | /**  | 
            ||
| 253 | * @param template[] $page  | 
            ||
| 254 | * @param array $template_result  | 
            ||
| 255 | */  | 
            ||
| 256 |   public static function renderFooter($page, $template_result) { | 
            ||
| 268 | }  | 
            ||
| 269 | |||
| 270 | /**  | 
            ||
| 271 | * @param $page  | 
            ||
| 272 | * @param $title  | 
            ||
| 273 | * @param $template_result  | 
            ||
| 274 | * @param $inLoginLogout  | 
            ||
| 275 | * @param $user  | 
            ||
| 276 | * @param $config  | 
            ||
| 277 | * @param $lang  | 
            ||
| 278 | * @param $planetrow  | 
            ||
| 279 | */  | 
            ||
| 280 |   public static function renderHeader($page, $title, &$template_result, $inLoginLogout, &$user, $config, $lang, $planetrow, $renderedContent) { | 
            ||
| 281 |     if (SN::$headerRendered) { | 
            ||
| 282 | return;  | 
            ||
| 283 | }  | 
            ||
| 284 | |||
| 285 | ob_end_flush();  | 
            ||
| 286 | |||
| 287 | ob_start();  | 
            ||
| 288 | // pdump(microtime(true) - SN_TIME_MICRO, 'Header render started');  | 
            ||
| 289 | $isDisplayTopNav = true;  | 
            ||
| 290 | $isDisplayMenu = true;  | 
            ||
| 291 | |||
| 292 | isset($template_result['GLOBAL_DISPLAY_MENU']) ? $isDisplayMenu = $template_result['GLOBAL_DISPLAY_MENU'] : false;  | 
            ||
| 293 | isset($template_result['GLOBAL_DISPLAY_NAVBAR']) ? $isDisplayTopNav = $template_result['GLOBAL_DISPLAY_NAVBAR'] : false;  | 
            ||
| 294 | |||
| 295 | // TODO: DEPRECATED! Use $template_result to turn menu and navbar or ond off!  | 
            ||
| 296 |     if (is_object($page)) { | 
            ||
| 297 | isset($page->_rootref['MENU']) ? $isDisplayMenu = $page->_rootref['MENU'] : false;  | 
            ||
| 298 | isset($page->_rootref['NAVBAR']) ? $isDisplayTopNav = $page->_rootref['NAVBAR'] : false;  | 
            ||
| 299 | }  | 
            ||
| 300 | |||
| 301 |     $inAdmin         = defined('IN_ADMIN') && IN_ADMIN === true; | 
            ||
| 302 | $isDisplayMenu = ($isDisplayMenu || $inAdmin) && !isset($_COOKIE['menu_disable']);  | 
            ||
| 303 | $isDisplayTopNav = $isDisplayTopNav && !$inAdmin;  | 
            ||
| 304 | |||
| 305 |     if ($inLoginLogout || empty($user['id']) || !is_numeric($user['id'])) { | 
            ||
| 306 | $isDisplayMenu = false;  | 
            ||
| 307 | $isDisplayTopNav = false;  | 
            ||
| 308 | }  | 
            ||
| 309 | |||
| 310 |     $template = self::gettemplate('_page/_00_header', true); | 
            ||
| 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() { | 
            ||
| 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"); | 
            ||
| 558 |     while ($note_row = db_fetch($notes_query)) { | 
            ||
| 559 | Note::note_assign($template, $note_row);  | 
            ||
| 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;  | 
            ||
| 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  | 
            ||
| 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) { | 
            ||
| 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) { | 
            ||
| 798 | }  | 
            ||
| 799 | |||
| 800 |   public static function messageBoxAdminAccessDenied($level = AUTH_LEVEL_ADMINISTRATOR) { | 
            ||
| 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) { | 
            ||
| 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);  | 
            ||
| 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),  | 
            ||
| 916 | 'TOPNAV_DARK_MATTER_TEXT' => HelperString::numberFloorAndFormat(mrc_get_level($user, '', RES_DARK_MATTER)),  | 
            ||
| 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, | 
            ||
| 941 |       'GAME_DEFENSE_DISABLED'    => defined('GAME_DEFENSE_DISABLED') && GAME_DEFENSE_DISABLED, | 
            ||
| 942 |       'GAME_STRUCTURES_DISABLED' => defined('GAME_STRUCTURES_DISABLED') && GAME_STRUCTURES_DISABLED, | 
            ||
| 943 |       'GAME_HANGAR_DISABLED'     => defined('GAME_HANGAR_DISABLED') && GAME_HANGAR_DISABLED, | 
            ||
| 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)) { | 
            ||
| 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);  | 
            ||
| 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() { | 
            ||
| 1220 | }  | 
            ||
| 1221 | |||
| 1222 | /**  | 
            ||
| 1223 | * Относительный путь к сконфигурированному темплейту  | 
            ||
| 1224 | * 'design/templates/(имя_темплейта)  | 
            ||
| 1225 | *  | 
            ||
| 1226 | * @return string  | 
            ||
| 1227 | * @deprecated  | 
            ||
| 1228 | */  | 
            ||
| 1229 |   public static function pathRelativeToCurrentTemplate() { | 
            ||
| 1231 | }  | 
            ||
| 1232 | |||
| 1233 | /**  | 
            ||
| 1234 | * @return TemplateMeta  | 
            ||
| 1235 | */  | 
            ||
| 1236 |   protected static function getCurrentTemplate() { | 
            ||
| 1241 | }  | 
            ||
| 1242 | |||
| 1243 | }  | 
            ||
| 1244 |