tags. */ public $extra_header = ""; /** * @var string Any additional messages to add after the flash messages are shown. */ public $extra_messages = array(); /** * @var string Show a post verify error */ public $show_post_verify_error = ''; /** * @var string */ public $_menu; /** * Output the page header. * * @param string $title The title of the page. */ function output_header($title="") { global $mybb, $admin_session, $lang, $plugins; $args = array( 'this' => &$this, 'title' => &$title, ); $plugins->run_hooks("admin_page_output_header", $args); if(!$title) { $title = $lang->mybb_admin_panel; } $rtl = ""; if($lang->settings['rtl'] == 1) { $rtl = " dir=\"rtl\""; } echo "\n"; echo "\n"; echo "\n"; echo " ".$title."\n"; echo " \n"; echo " \n"; echo " style."/main.css?ver=1813\" type=\"text/css\" />\n"; echo " style."/modal.css?ver=1813\" type=\"text/css\" />\n"; // Load stylesheet for this module if it has one if(file_exists(MYBB_ADMIN_DIR."styles/{$this->style}/{$this->active_module}.css")) { echo " style}/{$this->active_module}.css\" type=\"text/css\" />\n"; } echo " \n"; echo " \n"; echo " \n"; echo " \n"; echo " \n"; echo " \n"; echo " \n"; echo " \n"; echo " \n"; // Stop JS elements showing while page is loading (JS supported browsers only) echo " \n"; echo " \n"; echo " \n"; echo $this->extra_header; echo "\n"; echo "\n"; echo "
\n"; echo "

{$lang->mybb_admin_cp}

\n"; $username = htmlspecialchars_uni($mybb->user['username']); echo "
{$lang->logged_in_as} user['uid']}\" class=\"username\">{$username} | settings['bburl']}\" target=\"_blank\" class=\"forum\">{$lang->view_board} | post_code}\" class=\"logout\">{$lang->logout}
\n"; echo $this->_build_menu(); echo "
\n"; echo "
\n"; echo $this->submenu; echo $this->sidebar; echo "
\n"; echo "
\n"; echo "
\n"; echo $this->_generate_breadcrumb(); echo "
\n"; echo "
\n"; if(isset($admin_session['data']['flash_message']) && $admin_session['data']['flash_message']) { $message = $admin_session['data']['flash_message']['message']; $type = $admin_session['data']['flash_message']['type']; echo "
\n"; echo "{$message}\n"; echo "
\n"; update_admin_session('flash_message', ''); } if(!empty($this->extra_messages) && is_array($this->extra_messages)) { foreach($this->extra_messages as $message) { switch($message['type']) { case 'success': case 'error': echo "
\n"; echo "{$message['message']}\n"; echo "
\n"; break; default: $this->output_error($message['message']); break; } } } if($this->show_post_verify_error == true) { $this->output_error($lang->invalid_post_verify_key); } } /** * Output the page footer. * * @param bool $quit */ function output_footer($quit=true) { global $mybb, $maintimer, $db, $lang, $plugins; $args = array( 'this' => &$this, 'quit' => &$quit, ); $plugins->run_hooks("admin_page_output_footer", $args); $memory_usage = get_friendly_size(get_memory_usage()); $totaltime = format_time_duration($maintimer->stop()); $querycount = $db->query_count; if(my_strpos(getenv("REQUEST_URI"), "?")) { $debuglink = htmlspecialchars_uni(getenv("REQUEST_URI")) . "&debug=1#footer"; } else { $debuglink = htmlspecialchars_uni(getenv("REQUEST_URI")) . "?debug=1#footer"; } echo "
\n"; echo "
\n"; echo "
"; echo "
"; echo "
\n"; echo "

".$lang->sprintf($lang->generated_in, $totaltime, $debuglink, $querycount, $memory_usage)."

Powered By MyBB, © 2002-".COPY_YEAR." MyBB Group.

\n"; if($mybb->debug_mode) { echo $db->explain; } echo "
\n"; echo "\n"; echo "\n"; if($quit != false) { exit; } } /** * Add an item to the page breadcrumb trail. * * @param string $name The name of the item to add. * @param string $url The URL to the item we're adding (if there is one) */ function add_breadcrumb_item($name, $url="") { $this->_breadcrumb_trail[] = array("name" => $name, "url" => $url); } /** * Generate a breadcrumb trail. * * @return bool|string */ function _generate_breadcrumb() { if(!is_array($this->_breadcrumb_trail)) { return false; } $trail = ""; foreach($this->_breadcrumb_trail as $key => $crumb) { if(isset($this->_breadcrumb_trail[$key+1])) { $trail .= "".$crumb['name'].""; if(isset($this->_breadcrumb_trail[$key+2])) { $trail .= " » "; } } else { $trail .= "".$crumb['name'].""; } } return $trail; } /** * Output a success message. * * @param string $message The message to output. */ function output_success($message) { echo "
{$message}
\n"; } /** * Output an alert/warning message. * * @param string $message The message to output. * @param string $id The ID of the alert/warning (optional) */ function output_alert($message, $id="") { if($id) { $id = " id=\"{$id}\""; } echo "
{$message}
\n"; } /** * Output an inline message. * * @param string $message The message to output. */ function output_inline_message($message) { echo "
{$message}
\n"; } /** * Output a single error message. * * @param string $error The message to output. */ function output_error($error) { echo "
\n"; echo "{$error}\n"; echo "
\n"; } /** * Output one or more inline error messages. * * @param array $errors Array of error messages to output. */ function output_inline_error($errors) { global $lang; if(!is_array($errors)) { $errors = array($errors); } echo "
\n"; echo "

{$lang->encountered_errors}

\n"; echo "\n"; echo "
\n"; } /** * Generate the login page. * * @param string $message The any message to output on the page if there is one. * @param string $class The class name of the message (defaults to success) */ function show_login($message="", $class="success") { global $plugins, $lang, $cp_style, $mybb; $args = array( 'this' => &$this, 'message' => &$message, 'class' => &$class ); $plugins->run_hooks('admin_page_show_login_start', $args); $copy_year = COPY_YEAR; $login_container_width = ""; $login_label_width = ""; // If the language string for "Username" is too cramped then use this to define how much larger you want the gap to be (in px) if(isset($lang->login_field_width)) { $login_label_width = " style=\"width: ".((int)$lang->login_field_width+100)."px;\""; $login_container_width = " style=\"width: ".(410+((int)$lang->login_field_width))."px;\""; } $login_page = << {$lang->mybb_admin_login}

{$lang->please_login}

EOF; if($message) { $login_page .= "

{$message}

"; } // Make query string nice and pretty so that user can go to his/her preferred destination $query_string = ''; if($_SERVER['QUERY_STRING']) { $query_string = '?'.preg_replace('#adminsid=(.{32})#i', '', $_SERVER['QUERY_STRING']); $query_string = preg_replace('#my_post_key=(.{32})#i', '', $query_string); $query_string = str_replace('action=logout', '', $query_string); $query_string = preg_replace('#&+#', '&', $query_string); $query_string = str_replace('?&', '?', $query_string); $query_string = htmlspecialchars_uni($query_string); } switch($mybb->settings['username_method']) { case 0: $lang_username = $lang->username; break; case 1: $lang_username = $lang->username1; break; case 2: $lang_username = $lang->username2; break; default: $lang_username = $lang->username; break; } // Secret PIN global $config; if(isset($config['secret_pin']) && $config['secret_pin'] != '') { $secret_pin = "
"; } else { $secret_pin = ''; } $login_lang_string = $lang->enter_username_and_password; switch($mybb->settings['username_method']) { case 0: // Username only $login_lang_string = $lang->sprintf($login_lang_string, $lang->login_username); break; case 1: // Email only $login_lang_string = $lang->sprintf($login_lang_string, $lang->login_email); break; case 2: // Username and email default: $login_lang_string = $lang->sprintf($login_lang_string, $lang->login_username_and_password); break; } $this_file = htmlspecialchars_uni($_SERVER['SCRIPT_NAME']); $login_page .= <<{$login_lang_string}

{$secret_pin}

{$lang->lost_password}

EOF; $args = array( 'this' => &$this, 'login_page' => &$login_page ); $plugins->run_hooks('admin_page_show_login_end', $args); echo $login_page; exit; } function show_2fa() { global $lang, $cp_style, $mybb; $copy_year = COPY_YEAR; $mybb2fa_page = << {$lang->my2fa}

{$lang->my2fa}

EOF; // Make query string nice and pretty so that user can go to his/her preferred destination $query_string = ''; if($_SERVER['QUERY_STRING']) { $query_string = '?'.preg_replace('#adminsid=(.{32})#i', '', $_SERVER['QUERY_STRING']); $query_string = preg_replace('#my_post_key=(.{32})#i', '', $query_string); $query_string = str_replace('action=logout', '', $query_string); $query_string = preg_replace('#&+#', '&', $query_string); $query_string = str_replace('?&', '?', $query_string); $query_string = htmlspecialchars_uni($query_string); } $mybb2fa_page .= <<{$lang->my2fa_code}

EOF; echo $mybb2fa_page; exit; } /** * Generate the lockout page * */ function show_lockedout() { global $lang, $mybb, $cp_style; $copy_year = COPY_YEAR; $allowed_attempts = (int)$mybb->settings['maxloginattempts']; $lockedout_message = $lang->sprintf($lang->error_mybb_admin_lockedout_message, $allowed_attempts); print << {$lang->mybb_admin_cp} - {$lang->error_mybb_admin_lockedout}

{$lang->error_mybb_admin_lockedout}

{$lockedout_message}
EOF; exit; } /** * Generate the lockout unlock page * * @param string $message The any message to output on the page if there is one. * @param string $class The class name of the message (defaults to success) */ function show_lockout_unlock($message="", $class="success") { global $lang, $mybb, $cp_style; $copy_year = COPY_YEAR; $login_label_width = ""; // If the language string for "Username" is too cramped then use this to define how much larger you want the gap to be (in px) if(isset($lang->login_field_width)) { $login_label_width = " style=\"width: ".((int)$lang->login_field_width+100)."px;\""; } switch($mybb->settings['username_method']) { case 0: $lang_username = $lang->username; break; case 1: $lang_username = $lang->username1; break; case 2: $lang_username = $lang->username2; break; default: $lang_username = $lang->username; break; } if($message) { $message = "

{$message}

"; } print << {$lang->mybb_admin_cp} - {$lang->lockout_unlock}

{$lang->lockout_unlock}

{$message}

{$lang->enter_username_and_token}

{$lang->lost_password}

EOF; exit; } /** * Add an item to the primary navigation menu. * * @param string $title The title of the menu item. * @param string $id The ID of the menu item. This should correspond with the module the menu will run. * @param string $link The link to follow when the menu item is clicked. * @param int $order The display order of the menu item. Lower display order means closer to start of the menu. * @param array $submenu Array of sub menu items if there are any. */ function add_menu_item($title, $id, $link, $order=10, $submenu=array()) { $this->_menu[$order][] = array( "title" => $title, "id" => $id, "link" => $link, "submenu" => $submenu ); } /** * Build the actual navigation menu. * * @return bool|string */ function _build_menu() { if(!is_array($this->_menu)) { return false; } $build_menu = "
\n
    \n"; ksort($this->_menu); foreach($this->_menu as $items) { foreach($items as $menu_item) { $menu_item['link'] = htmlspecialchars_uni($menu_item['link']); if($menu_item['id'] == $this->active_module) { $sub_menu = $menu_item['submenu']; $sub_menu_title = $menu_item['title']; $build_menu .= "
  • {$menu_item['title']}
  • \n"; } else { $build_menu .= "
  • {$menu_item['title']}
  • \n"; } } } $build_menu .= "
\n
"; if(!empty($sub_menu)) { $this->_build_submenu($sub_menu_title, $sub_menu); } return $build_menu; } /** * Build a navigation sub menu if we have one. * * @param string $title A title for the sub menu. * @param array $items Array of items for the sub menu. */ function _build_submenu($title, $items) { if(is_array($items)) { $sidebar = new sideBarItem($title); $sidebar->add_menu_items($items, $this->active_action); $this->submenu .= $sidebar->get_markup(); } } /** * Output a Javascript based tab control on to the page. * * @param array $tabs Array of tabs in name => title format. Name should correspond to the name of a DIV containing the tab content. * @param boolean $observe_onload Whether or not to run the event onload or instantly * @param string $id The ID to use for the tabs for if you run multiple instances of the tabbing control in one html page */ function output_tab_control($tabs=array(), $observe_onload=true, $id="tabs") { global $plugins; $tabs = $plugins->run_hooks("admin_page_output_tab_control_start", $tabs); echo "
    \n"; $tab_count = count($tabs); $done = 1; foreach($tabs as $anchor => $title) { $class = ""; if($tab_count == $done) { $class .= " last"; } if($done == 1) { $class .= " first"; } ++$done; echo "
  • {$title}
  • \n"; } echo "
\n"; $plugins->run_hooks("admin_page_output_tab_control_end", $tabs); } /** * Output a series of primary navigation tabs for swithcing between items within a particular module/action. * * @param array $tabs Nested array of tabs containing possible keys of align, link_target, link_rel, link, title. * @param string $active The name of the active tab. Corresponds with the key of each tab item. */ function output_nav_tabs($tabs=array(), $active='') { global $plugins; $tabs = $plugins->run_hooks("admin_page_output_nav_tabs_start", $tabs); echo "
"; echo "\t
    \n"; foreach($tabs as $id => $tab) { $class = ''; if($id == $active) { $class = ' active'; } if(isset($tab['align']) == "right") { $class .= " right"; } $target = ''; if(isset($tab['link_target'])) { $target = " target=\"{$tab['link_target']}\""; } $rel = ''; if(isset($tab['link_rel'])) { $rel = " rel=\"{$tab['link_rel']}\""; } if(!isset($tab['link'])) { $tab['link'] = ''; } echo "\t\t
  • {$tab['title']}
  • \n"; $target = ''; } echo "\t
\n"; if(!empty($tabs[$active]['description'])) { echo "\t
{$tabs[$active]['description']}
\n"; } echo "
"; $arguments = array('tabs' => $tabs, 'active' => $active); $plugins->run_hooks("admin_page_output_nav_tabs_end", $arguments); } /** * Output a page asking if a user wishes to continue performing a specific action. * * @param string $url The URL to be forwarded to. * @param string $message The confirmation message to output. * @param string $title The title to use in the output header */ function output_confirm_action($url, $message="", $title="") { global $lang, $plugins; $args = array( 'this' => &$this, 'url' => &$url, 'message' => &$message, 'title' => &$title, ); $plugins->run_hooks('admin_page_output_confirm_action', $args); if(!$message) { $message = $lang->confirm_action; } $this->output_header($title); $form = new Form($url, 'post'); echo "
\n"; echo "

{$message}

\n"; echo "
\n"; echo "

\n"; echo $form->generate_submit_button($lang->yes, array('class' => 'button_yes')); echo $form->generate_submit_button($lang->no, array("name" => "no", 'class' => 'button_no')); echo "

\n"; echo "
\n"; $form->end(); $this->output_footer(); } /** * Build a clickable MyCode editor for the Admin CP. * * @param string $bind The ID of the textarea to bind the editor to. * @param string $editor_language The language string for the editor. * @param bool $smilies Whether or not smilies should be included * @return string The build MyCode editor Javascript. */ function build_codebuttons_editor($bind, $editor_language, $smilies) { global $lang, $mybb, $smiliecache, $smiliecount, $cache; // Smilies $emoticon = ""; $emoticons_enabled = "false"; if($smilies) { if($mybb->settings['smilieinserter'] && $mybb->settings['smilieinsertercols'] && $mybb->settings['smilieinsertertot']) { $emoticon = ",emoticon"; } $emoticons_enabled = "true"; if(!$smiliecount) { $smilie_cache = $cache->read("smilies"); if(!is_array($smilie_cache)) { $smilie_cache = array(); } $smiliecount = count($smilie_cache); } if(!$smiliecache) { if(!is_array($smilie_cache)) { $smilie_cache = $cache->read("smilies"); } foreach($smilie_cache as $smilie) { $smilie['image'] = str_replace("{theme}", "images", $smilie['image']); $smiliecache[$smilie['sid']] = $smilie; } } unset($smilie); if(is_array($smiliecache)) { reset($smiliecache); $dropdownsmilies = $moresmilies = $hiddensmilies = ""; $i = 0; foreach($smiliecache as $smilie) { $finds = explode("\n", $smilie['find']); $finds_count = count($finds); // Only show the first text to replace in the box $find = str_replace(array('\\', '"'), array('\\\\', '\"'), htmlspecialchars_uni($finds[0])); $image = str_replace(array('\\', '"'), array('\\\\', '\"'), htmlspecialchars_uni($smilie['image'])); if(substr($image, 0, 4) != "http") { $image = $mybb->settings['bburl']."/".$image; } if(!$mybb->settings['smilieinserter'] || !$mybb->settings['smilieinsertercols'] || !$mybb->settings['smilieinsertertot'] || !$smilie['showclickable']) { $hiddensmilies .= '"'.$find.'": "'.$image.'",'; } elseif($i < $mybb->settings['smilieinsertertot']) { $dropdownsmilies .= '"'.$find.'": "'.$image.'",'; ++$i; } else { $moresmilies .= '"'.$find.'": "'.$image.'",'; } for($j = 1; $j < $finds_count; ++$j) { $find = str_replace(array('\\', '"'), array('\\\\', '\"'), htmlspecialchars_uni($finds[$j])); $hiddensmilies .= '"'.$find.'": "'.$image.'",'; } } } } $basic1 = $basic2 = $align = $font = $size = $color = $removeformat = $email = $link = $list = $code = $sourcemode = ""; if($mybb->settings['allowbasicmycode'] == 1) { $basic1 = "bold,italic,underline,strike|"; $basic2 = "horizontalrule,"; } if($mybb->settings['allowalignmycode'] == 1) { $align = "left,center,right,justify|"; } if($mybb->settings['allowfontmycode'] == 1) { $font = "font,"; } if($mybb->settings['allowsizemycode'] == 1) { $size = "size,"; } if($mybb->settings['allowcolormycode'] == 1) { $color = "color,"; } if($mybb->settings['allowfontmycode'] == 1 || $mybb->settings['allowsizemycode'] == 1 || $mybb->settings['allowcolormycode'] == 1) { $removeformat = "removeformat|"; } if($mybb->settings['allowemailmycode'] == 1) { $email = "email,"; } if($mybb->settings['allowlinkmycode'] == 1) { $link = "link,unlink"; } if($mybb->settings['allowlistmycode'] == 1) { $list = "bulletlist,orderedlist|"; } if($mybb->settings['allowcodemycode'] == 1) { $code = "code,php,"; } if($mybb->user['sourceeditor'] == 1) { $sourcemode = "MyBBEditor.sourceMode(true);"; } return << var partialmode = {$mybb->settings['partialmode']}, opt_editor = { plugins: "undo", format: "bbcode", bbcodeTrim: true, style: "../jscripts/sceditor/styles/jquery.sceditor.mybb.css", rtl: {$lang->settings['rtl']}, locale: "mybblang", enablePasteFiltering: true, autoUpdate: true, emoticonsEnabled: {$emoticons_enabled}, emoticons: { // Emoticons to be included in the dropdown dropdown: { {$dropdownsmilies} }, // Emoticons to be included in the more section more: { {$moresmilies} }, // Emoticons that are not shown in the dropdown but will still be converted. Can be used for things like aliases hidden: { {$hiddensmilies} } }, emoticonsCompat: true, toolbar: "{$basic1}{$align}{$font}{$size}{$color}{$removeformat}{$basic2}image,{$email}{$link}|video{$emoticon}|{$list}{$code}quote|maximize,source", }; {$editor_language} $(function() { $("#{$bind}").sceditor(opt_editor); MyBBEditor = $("#{$bind}").sceditor("instance"); {$sourcemode} }); EOF; } } /** * A class for generating side bar blocks. */ class DefaultSidebarItem { /** * @var string The title of the side bar block. */ private $_title; /** * @var string The contents of the side bar block. */ private $_contents; /** * Constructor. Set the title of the side bar block. * * @param string $title The title of the side bar block. */ function __construct($title="") { $this->_title = $title; } /** * Add menus item to the side bar block. * * @param array $items Array of menu items to add. Each menu item should be a nested array of id, link and title. * @param string $active The ID of the active menu item if there is one. */ function add_menu_items($items, $active) { global $run_module; $this->_contents = "
    "; foreach($items as $item) { if(!check_admin_permissions(array("module" => $run_module, "action" => $item['id']), false)) { continue; } $class = ""; if($item['id'] == $active) { $class = "active"; } $item['link'] = htmlspecialchars_uni($item['link']); $this->_contents .= "
  • {$item['title']}
  • \n"; } $this->_contents .= "
"; } /** * Sets custom html to the contents variable * * @param string $html The custom html to set */ function set_contents($html) { $this->_contents = $html; } /** * Fetch the HTML markup for the side bar box. * * @return string */ function get_markup() { $markup = "
\n"; $markup .= "
{$this->_title}
\n"; if($this->_contents) { $markup .= $this->_contents; } $markup .= "
\n"; return $markup; } } /** * Generate a Javascript based popup menu. */ class DefaultPopupMenu { /** * @var string The title of the popup menu to be shown on the button. */ private $_title; /** * @var string The ID of this popup menu. Must be unique. */ private $_id; /** * @var string Built HTML for the items in the popup menu. */ private $_items; /** * Initialise a new popup menu. * * @var string $id The ID of the popup menu. * @var string $title The title of the popup menu. */ function __construct($id, $title='') { $this->_id = $id; $this->_title = $title; } /** * Add an item to the popup menu. * * @param string $text The title of this item. * @param string $link The page this item should link to. * @param string $onclick The onclick event handler if we have one. */ function add_item($text, $link, $onclick='') { if($onclick) { $onclick = " onclick=\"{$onclick}\""; } $this->_items .= "\n"; } /** * Fetch the contents of the popup menu. * * @return string The popup menu. */ function fetch() { $popup = "
_id}_popup\">\n{$this->_items}
\n"; if($this->_title) { $popup .= "_id}\" class=\"popup_button\">{$this->_title}\n"; } $popup .= "\n"; return $popup; } /** * Outputs a popup menu to the browser. */ function output() { echo $this->fetch(); } }