Advertisement
Guest User

SSI_SAMP

a guest
Jan 2nd, 2017
305
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
PHP 74.66 KB | None | 0 0
  1. <?php
  2.  
  3. /**
  4.  * Simple Machines Forum (SMF)
  5.  *
  6.  * @package SMF
  7.  * @author Simple Machines http://www.simplemachines.org
  8.  * @copyright 2011 Simple Machines
  9.  * @license http://www.simplemachines.org/about/smf/license.php BSD
  10.  *
  11.  * @version 2.0.10
  12.  */
  13.  
  14. // Don't do anything if SMF is already loaded.
  15. if (defined('SMF'))
  16.     return true;
  17.  
  18. define('SMF', 'SSI');
  19.  
  20. // We're going to want a few globals... these are all set later.
  21. global $time_start, $maintenance, $msubject, $mmessage, $mbname, $language;
  22. global $boardurl, $boarddir, $sourcedir, $webmaster_email, $cookiename;
  23. global $db_server, $db_name, $db_user, $db_prefix, $db_persist, $db_error_send, $db_last_error;
  24. global $db_connection, $modSettings, $context, $sc, $user_info, $topic, $board, $txt;
  25. global $smcFunc, $ssi_db_user, $scripturl, $ssi_db_passwd, $db_passwd, $cachedir;
  26.  
  27. // Remember the current configuration so it can be set back.
  28. $ssi_magic_quotes_runtime = function_exists('get_magic_quotes_gpc') && get_magic_quotes_runtime();
  29. if (function_exists('set_magic_quotes_runtime'))
  30.     @set_magic_quotes_runtime(0);
  31. $time_start = microtime();
  32.  
  33. // Just being safe...
  34. foreach (array('db_character_set', 'cachedir') as $variable)
  35.     if (isset($GLOBALS[$variable]))
  36.         unset($GLOBALS[$variable]);
  37.  
  38. // Get the forum's settings for database and file paths.
  39. require_once(dirname(__FILE__) . '/Settings.php');
  40.  
  41. // Make absolutely sure the cache directory is defined.
  42. if ((empty($cachedir) || !file_exists($cachedir)) && file_exists($boarddir . '/cache'))
  43.     $cachedir = $boarddir . '/cache';
  44.  
  45. $ssi_error_reporting = error_reporting(defined('E_STRICT') ? E_ALL | E_STRICT : E_ALL);
  46. /* Set this to one of three values depending on what you want to happen in the case of a fatal error.
  47.     false:  Default, will just load the error sub template and die - not putting any theme layers around it.
  48.     true:   Will load the error sub template AND put the SMF layers around it (Not useful if on total custom pages).
  49.     string: Name of a callback function to call in the event of an error to allow you to define your own methods. Will die after function returns.
  50. */
  51. $ssi_on_error_method = false;
  52.  
  53. // Don't do john didley if the forum's been shut down competely.
  54. if ($maintenance == 2 && (!isset($ssi_maintenance_off) || $ssi_maintenance_off !== true))
  55.     die($mmessage);
  56.  
  57. // Fix for using the current directory as a path.
  58. if (substr($sourcedir, 0, 1) == '.' && substr($sourcedir, 1, 1) != '.')
  59.     $sourcedir = dirname(__FILE__) . substr($sourcedir, 1);
  60.  
  61. // Load the important includes.
  62. require_once($sourcedir . '/QueryString.php');
  63. require_once($sourcedir . '/Subs.php');
  64. require_once($sourcedir . '/Errors.php');
  65. require_once($sourcedir . '/Load.php');
  66. require_once($sourcedir . '/Security.php');
  67.  
  68. // Using an pre-PHP 5.1 version?
  69. if (@version_compare(PHP_VERSION, '5.1') == -1)
  70.     require_once($sourcedir . '/Subs-Compat.php');
  71.  
  72. // Create a variable to store some SMF specific functions in.
  73. $smcFunc = array();
  74.  
  75. // Initate the database connection and define some database functions to use.
  76. loadDatabase();
  77.  
  78. // Load installed 'Mods' settings.
  79. reloadSettings();
  80. // Clean the request variables.
  81. cleanRequest();
  82.  
  83. // Seed the random generator?
  84. if (empty($modSettings['rand_seed']) || mt_rand(1, 250) == 69)
  85.     smf_seed_generator();
  86.  
  87. // Check on any hacking attempts.
  88. if (isset($_REQUEST['GLOBALS']) || isset($_COOKIE['GLOBALS']))
  89.     die('Hacking attempt...');
  90. elseif (isset($_REQUEST['ssi_theme']) && (int) $_REQUEST['ssi_theme'] == (int) $ssi_theme)
  91.     die('Hacking attempt...');
  92. elseif (isset($_COOKIE['ssi_theme']) && (int) $_COOKIE['ssi_theme'] == (int) $ssi_theme)
  93.     die('Hacking attempt...');
  94. elseif (isset($_REQUEST['ssi_layers'], $ssi_layers) && (@get_magic_quotes_gpc() ? stripslashes($_REQUEST['ssi_layers']) : $_REQUEST['ssi_layers']) == $ssi_layers)
  95.     die('Hacking attempt...');
  96. if (isset($_REQUEST['context']))
  97.     die('Hacking attempt...');
  98.  
  99. // Make sure wireless is always off.
  100. define('WIRELESS', false);
  101.  
  102. // Gzip output? (because it must be boolean and true, this can't be hacked.)
  103. if (isset($ssi_gzip) && $ssi_gzip === true && @ini_get('zlib.output_compression') != '1' && @ini_get('output_handler') != 'ob_gzhandler' && @version_compare(PHP_VERSION, '4.2.0') != -1)
  104.     ob_start('ob_gzhandler');
  105. else
  106.     $modSettings['enableCompressedOutput'] = '0';
  107.  
  108. // Primarily, this is to fix the URLs...
  109. ob_start('ob_sessrewrite');
  110.  
  111. // Start the session... known to scramble SSI includes in cases...
  112. if (!headers_sent())
  113.     loadSession();
  114. else
  115. {
  116.     if (isset($_COOKIE[session_name()]) || isset($_REQUEST[session_name()]))
  117.     {
  118.         // Make a stab at it, but ignore the E_WARNINGs generated because we can't send headers.
  119.         $temp = error_reporting(error_reporting() & !E_WARNING);
  120.         loadSession();
  121.         error_reporting($temp);
  122.     }
  123.  
  124.     if (!isset($_SESSION['session_value']))
  125.     {
  126.         $_SESSION['session_var'] = substr(md5(mt_rand() . session_id() . mt_rand()), 0, rand(7, 12));
  127.         $_SESSION['session_value'] = md5(session_id() . mt_rand());
  128.     }
  129.     $sc = $_SESSION['session_value'];
  130. }
  131.  
  132. // Get rid of $board and $topic... do stuff loadBoard would do.
  133. unset($board, $topic);
  134. $user_info['is_mod'] = false;
  135. $context['user']['is_mod'] = &$user_info['is_mod'];
  136. $context['linktree'] = array();
  137.  
  138. // Load the user and their cookie, as well as their settings.
  139. loadUserSettings();
  140.  
  141. // Load the current user's permissions....
  142. loadPermissions();
  143.  
  144. // Load the current or SSI theme. (just use $ssi_theme = id_theme;)
  145. loadTheme(isset($ssi_theme) ? (int) $ssi_theme : 0);
  146.  
  147. // Take care of any banning that needs to be done.
  148. if (isset($_REQUEST['ssi_ban']) || (isset($ssi_ban) && $ssi_ban === true))
  149.     is_not_banned();
  150.  
  151. // Do we allow guests in here?
  152. if (empty($ssi_guest_access) && empty($modSettings['allow_guestAccess']) && $user_info['is_guest'] && basename($_SERVER['PHP_SELF']) != 'SSI.php')
  153. {
  154.     require_once($sourcedir . '/Subs-Auth.php');
  155.     KickGuest();
  156.     obExit(null, true);
  157. }
  158.  
  159. // Load the stuff like the menu bar, etc.
  160. if (isset($ssi_layers))
  161. {
  162.     $context['template_layers'] = $ssi_layers;
  163.     template_header();
  164. }
  165. else
  166.     setupThemeContext();
  167.  
  168. // Make sure they didn't muss around with the settings... but only if it's not cli.
  169. if (isset($_SERVER['REMOTE_ADDR']) && !isset($_SERVER['is_cli']) && session_id() == '')
  170.     trigger_error($txt['ssi_session_broken'], E_USER_NOTICE);
  171.  
  172. // Without visiting the forum this session variable might not be set on submit.
  173. if (!isset($_SESSION['USER_AGENT']) && (!isset($_GET['ssi_function']) || $_GET['ssi_function'] !== 'pollVote'))
  174.     $_SESSION['USER_AGENT'] = $_SERVER['HTTP_USER_AGENT'];
  175.  
  176. // Call a function passed by GET.
  177. if (isset($_GET['ssi_function']) && function_exists('ssi_' . $_GET['ssi_function']) && (!empty($modSettings['allow_guestAccess']) || !$user_info['is_guest']))
  178. {
  179.     call_user_func('ssi_' . $_GET['ssi_function']);
  180.     exit;
  181. }
  182. if (isset($_GET['ssi_function']))
  183.     exit;
  184. // You shouldn't just access SSI.php directly by URL!!
  185. elseif (basename($_SERVER['PHP_SELF']) == 'SSI.php')
  186.     die(sprintf($txt['ssi_not_direct'], $user_info['is_admin'] ? '\'' . addslashes(__FILE__) . '\'' : '\'SSI.php\''));
  187.  
  188. error_reporting($ssi_error_reporting);
  189. if (function_exists('set_magic_quotes_runtime'))
  190.     @set_magic_quotes_runtime($ssi_magic_quotes_runtime);
  191.  
  192. return true;
  193.  
  194. // This shuts down the SSI and shows the footer.
  195. function ssi_shutdown()
  196. {
  197.     if (!isset($_GET['ssi_function']) || $_GET['ssi_function'] != 'shutdown')
  198.         template_footer();
  199. }
  200.  
  201. // Display a welcome message, like:  Hey, User, you have 0 messages, 0 are new.
  202. function ssi_welcome($output_method = 'echo')
  203. {
  204.     global $context, $txt, $scripturl;
  205.  
  206.     if ($output_method == 'echo')
  207.     {
  208.         if ($context['user']['is_guest'])
  209.             echo sprintf($txt['welcome_guest'], $txt['guest_title']);
  210.         else
  211.             echo $txt['hello_member'], ' <strong>', $context['user']['name'], '</strong>', allowedTo('pm_read') ? ', ' . $txt['msg_alert_you_have'] . ' <a href="' . $scripturl . '?action=pm">' . $context['user']['messages'] . ' ' . ($context['user']['messages'] == '1' ? $txt['message_lowercase'] : $txt['msg_alert_messages']) . '</a>' . $txt['newmessages4'] . ' ' . $context['user']['unread_messages'] . ' ' . ($context['user']['unread_messages'] == '1' ? $txt['newmessages0'] : $txt['newmessages1']) : '', '.';
  212.     }
  213.     // Don't echo... then do what?!
  214.     else
  215.         return $context['user'];
  216. }
  217.  
  218. // Display a menu bar, like is displayed at the top of the forum.
  219. function ssi_menubar($output_method = 'echo')
  220. {
  221.     global $context;
  222.  
  223.     if ($output_method == 'echo')
  224.         template_menu();
  225.     // What else could this do?
  226.     else
  227.         return $context['menu_buttons'];
  228. }
  229.  
  230. // Show a logout link.
  231. function ssi_logout($redirect_to = '', $output_method = 'echo')
  232. {
  233.     global $context, $txt, $scripturl;
  234.  
  235.     if ($redirect_to != '')
  236.         $_SESSION['logout_url'] = $redirect_to;
  237.  
  238.     // Guests can't log out.
  239.     if ($context['user']['is_guest'])
  240.         return false;
  241.  
  242.     $link = '<a href="' . $scripturl . '?action=logout;' . $context['session_var'] . '=' . $context['session_id'] . '">' . $txt['logout'] . '</a>';
  243.  
  244.     if ($output_method == 'echo')
  245.         echo $link;
  246.     else
  247.         return $link;
  248. }
  249.  
  250. // Recent post list:   [board] Subject by Poster    Date
  251. function ssi_recentPosts($num_recent = 8, $exclude_boards = null, $include_boards = null, $output_method = 'echo', $limit_body = true)
  252. {
  253.     global $context, $settings, $scripturl, $txt, $db_prefix, $user_info;
  254.     global $modSettings, $smcFunc;
  255.  
  256.     // Excluding certain boards...
  257.     if ($exclude_boards === null && !empty($modSettings['recycle_enable']) && $modSettings['recycle_board'] > 0)
  258.         $exclude_boards = array($modSettings['recycle_board']);
  259.     else
  260.         $exclude_boards = empty($exclude_boards) ? array() : (is_array($exclude_boards) ? $exclude_boards : array($exclude_boards));
  261.  
  262.     // What about including certain boards - note we do some protection here as pre-2.0 didn't have this parameter.
  263.     if (is_array($include_boards) || (int) $include_boards === $include_boards)
  264.     {
  265.         $include_boards = is_array($include_boards) ? $include_boards : array($include_boards);
  266.     }
  267.     elseif ($include_boards != null)
  268.     {
  269.         $include_boards = array();
  270.     }
  271.  
  272.     // Let's restrict the query boys (and girls)
  273.     $query_where = '
  274.         m.id_msg >= {int:min_message_id}
  275.         ' . (empty($exclude_boards) ? '' : '
  276.         AND b.id_board NOT IN ({array_int:exclude_boards})') . '
  277.         ' . ($include_boards === null ? '' : '
  278.         AND b.id_board IN ({array_int:include_boards})') . '
  279.         AND {query_wanna_see_board}' . ($modSettings['postmod_active'] ? '
  280.         AND m.approved = {int:is_approved}' : '');
  281.  
  282.     $query_where_params = array(
  283.         'is_approved' => 1,
  284.         'include_boards' => $include_boards === null ? '' : $include_boards,
  285.         'exclude_boards' => empty($exclude_boards) ? '' : $exclude_boards,
  286.         'min_message_id' => $modSettings['maxMsgID'] - 25 * min($num_recent, 5),
  287.     );
  288.  
  289.     // Past to this simpleton of a function...
  290.     return ssi_queryPosts($query_where, $query_where_params, $num_recent, 'm.id_msg DESC', $output_method, $limit_body);
  291. }
  292.  
  293. // Fetch a post with a particular ID. By default will only show if you have permission to the see the board in question - this can be overriden.
  294. function ssi_fetchPosts($post_ids = array(), $override_permissions = false, $output_method = 'echo')
  295. {
  296.     global $user_info, $modSettings;
  297.  
  298.     if (empty($post_ids))
  299.         return;
  300.  
  301.     // Allow the user to request more than one - why not?
  302.     $post_ids = is_array($post_ids) ? $post_ids : array($post_ids);
  303.  
  304.     // Restrict the posts required...
  305.     $query_where = '
  306.         m.id_msg IN ({array_int:message_list})' . ($override_permissions ? '' : '
  307.             AND {query_wanna_see_board}') . ($modSettings['postmod_active'] ? '
  308.             AND m.approved = {int:is_approved}' : '');
  309.     $query_where_params = array(
  310.         'message_list' => $post_ids,
  311.         'is_approved' => 1,
  312.     );
  313.  
  314.     // Then make the query and dump the data.
  315.     return ssi_queryPosts($query_where, $query_where_params, '', 'm.id_msg DESC', $output_method);
  316. }
  317.  
  318. // This removes code duplication in other queries - don't call it direct unless you really know what you're up to.
  319. function ssi_queryPosts($query_where = '', $query_where_params = array(), $query_limit = 10, $query_order = 'm.id_msg DESC', $output_method = 'echo', $limit_body = false, $override_permissions = false)
  320. {
  321.     global $context, $settings, $scripturl, $txt, $db_prefix, $user_info;
  322.     global $modSettings, $smcFunc;
  323.  
  324.     // Find all the posts. Newer ones will have higher IDs.
  325.     $request = $smcFunc['db_query']('substring', '
  326.         SELECT
  327.             m.poster_time, m.subject, m.id_topic, m.id_member, m.id_msg, m.id_board, b.name AS board_name,
  328.             IFNULL(mem.real_name, m.poster_name) AS poster_name, ' . ($user_info['is_guest'] ? '1 AS is_read, 0 AS new_from' : '
  329.             IFNULL(lt.id_msg, IFNULL(lmr.id_msg, 0)) >= m.id_msg_modified AS is_read,
  330.             IFNULL(lt.id_msg, IFNULL(lmr.id_msg, -1)) + 1 AS new_from') . ', ' . ($limit_body ? 'SUBSTRING(m.body, 1, 384) AS body' : 'm.body') . ', m.smileys_enabled
  331.         FROM {db_prefix}messages AS m
  332.             INNER JOIN {db_prefix}boards AS b ON (b.id_board = m.id_board)
  333.             LEFT JOIN {db_prefix}members AS mem ON (mem.id_member = m.id_member)' . (!$user_info['is_guest'] ? '
  334.             LEFT JOIN {db_prefix}log_topics AS lt ON (lt.id_topic = m.id_topic AND lt.id_member = {int:current_member})
  335.             LEFT JOIN {db_prefix}log_mark_read AS lmr ON (lmr.id_board = m.id_board AND lmr.id_member = {int:current_member})' : '') . '
  336.         WHERE 1=1 ' . ($override_permissions ? '' : '
  337.             AND {query_wanna_see_board}') . ($modSettings['postmod_active'] ? '
  338.             AND m.approved = {int:is_approved}' : '') . '
  339.             ' . (empty($query_where) ? '' : 'AND ' . $query_where) . '
  340.         ORDER BY ' . $query_order . '
  341.         ' . ($query_limit == '' ? '' : 'LIMIT ' . $query_limit),
  342.         array_merge($query_where_params, array(
  343.             'current_member' => $user_info['id'],
  344.             'is_approved' => 1,
  345.         ))
  346.     );
  347.     $posts = array();
  348.     while ($row = $smcFunc['db_fetch_assoc']($request))
  349.     {
  350.         $row['body'] = parse_bbc($row['body'], $row['smileys_enabled'], $row['id_msg']);
  351.  
  352.         // Censor it!
  353.         censorText($row['subject']);
  354.         censorText($row['body']);
  355.  
  356.         $preview = strip_tags(strtr($row['body'], array('<br />' => '&#10;')));
  357.  
  358.         // Build the array.
  359.         $posts[] = array(
  360.             'id' => $row['id_msg'],
  361.             'board' => array(
  362.                 'id' => $row['id_board'],
  363.                 'name' => $row['board_name'],
  364.                 'href' => $scripturl . '?board=' . $row['id_board'] . '.0',
  365.                 'link' => '<a href="' . $scripturl . '?board=' . $row['id_board'] . '.0">' . $row['board_name'] . '</a>'
  366.             ),
  367.             'topic' => $row['id_topic'],
  368.             'poster' => array(
  369.                 'id' => $row['id_member'],
  370.                 'name' => $row['poster_name'],
  371.                 'href' => empty($row['id_member']) ? '' : $scripturl . '?action=profile;u=' . $row['id_member'],
  372.                 'link' => empty($row['id_member']) ? $row['poster_name'] : '<a href="' . $scripturl . '?action=profile;u=' . $row['id_member'] . '">' . $row['poster_name'] . '</a>'
  373.             ),
  374.             'subject' => $row['subject'],
  375.             'short_subject' => shorten_subject($row['subject'], 25),
  376.             'preview' => $smcFunc['strlen']($preview) > 128 ? $smcFunc['substr']($preview, 0, 128) . '...' : $preview,
  377.             'body' => $row['body'],
  378.             'time' => timeformat($row['poster_time']),
  379.             'timestamp' => forum_time(true, $row['poster_time']),
  380.             'href' => $scripturl . '?topic=' . $row['id_topic'] . '.msg' . $row['id_msg'] . ';topicseen#new',
  381.             'link' => '<a href="' . $scripturl . '?topic=' . $row['id_topic'] . '.msg' . $row['id_msg'] . '#msg' . $row['id_msg'] . '" rel="nofollow">' . $row['subject'] . '</a>',
  382.             'new' => !empty($row['is_read']),
  383.             'is_new' => empty($row['is_read']),
  384.             'new_from' => $row['new_from'],
  385.         );
  386.     }
  387.     $smcFunc['db_free_result']($request);
  388.  
  389.     // Just return it.
  390.     if ($output_method != 'echo' || empty($posts))
  391.         return $posts;
  392.  
  393.     echo '
  394.         <table border="0" class="ssi_table">';
  395.     foreach ($posts as $post)
  396.         echo '
  397.             <tr>
  398.                 <td align="right" valign="top" nowrap="nowrap">
  399.                     [', $post['board']['link'], ']
  400.                 </td>
  401.                 <td valign="top">
  402.                     <a href="', $post['href'], '">', $post['subject'], '</a>
  403.                     ', $txt['by'], ' ', $post['poster']['link'], '
  404.                     ', $post['is_new'] ? '<a href="' . $scripturl . '?topic=' . $post['topic'] . '.msg' . $post['new_from'] . ';topicseen#new" rel="nofollow"><img src="' . $settings['lang_images_url'] . '/new.gif" alt="' . $txt['new'] . '" /></a>' : '', '
  405.                 </td>
  406.                 <td align="right" nowrap="nowrap">
  407.                     ', $post['time'], '
  408.                 </td>
  409.             </tr>';
  410.     echo '
  411.         </table>';
  412. }
  413.  
  414. // Recent topic list:   [board] Subject by Poster   Date
  415. function ssi_recentTopics($num_recent = 8, $exclude_boards = null, $include_boards = null, $output_method = 'echo')
  416. {
  417.     global $context, $settings, $scripturl, $txt, $db_prefix, $user_info;
  418.     global $modSettings, $smcFunc;
  419.  
  420.     if ($exclude_boards === null && !empty($modSettings['recycle_enable']) && $modSettings['recycle_board'] > 0)
  421.         $exclude_boards = array($modSettings['recycle_board']);
  422.     else
  423.         $exclude_boards = empty($exclude_boards) ? array() : (is_array($exclude_boards) ? $exclude_boards : array($exclude_boards));
  424.  
  425.     // Only some boards?.
  426.     if (is_array($include_boards) || (int) $include_boards === $include_boards)
  427.     {
  428.         $include_boards = is_array($include_boards) ? $include_boards : array($include_boards);
  429.     }
  430.     elseif ($include_boards != null)
  431.     {
  432.         $output_method = $include_boards;
  433.         $include_boards = array();
  434.     }
  435.  
  436.     $stable_icons = array('xx', 'thumbup', 'thumbdown', 'exclamation', 'question', 'lamp', 'smiley', 'angry', 'cheesy', 'grin', 'sad', 'wink', 'moved', 'recycled', 'wireless');
  437.     $icon_sources = array();
  438.     foreach ($stable_icons as $icon)
  439.         $icon_sources[$icon] = 'images_url';
  440.  
  441.     // Find all the posts in distinct topics.  Newer ones will have higher IDs.
  442.     $request = $smcFunc['db_query']('substring', '
  443.         SELECT
  444.             m.poster_time, ms.subject, m.id_topic, m.id_member, m.id_msg, b.id_board, b.name AS board_name, t.num_replies, t.num_views,
  445.             IFNULL(mem.real_name, m.poster_name) AS poster_name, ' . ($user_info['is_guest'] ? '1 AS is_read, 0 AS new_from' : '
  446.             IFNULL(lt.id_msg, IFNULL(lmr.id_msg, 0)) >= m.id_msg_modified AS is_read,
  447.             IFNULL(lt.id_msg, IFNULL(lmr.id_msg, -1)) + 1 AS new_from') . ', SUBSTRING(m.body, 1, 384) AS body, m.smileys_enabled, m.icon
  448.         FROM {db_prefix}topics AS t
  449.             INNER JOIN {db_prefix}messages AS m ON (m.id_msg = t.id_last_msg)
  450.             INNER JOIN {db_prefix}boards AS b ON (b.id_board = t.id_board)
  451.             INNER JOIN {db_prefix}messages AS ms ON (ms.id_msg = t.id_first_msg)
  452.             LEFT JOIN {db_prefix}members AS mem ON (mem.id_member = m.id_member)' . (!$user_info['is_guest'] ? '
  453.             LEFT JOIN {db_prefix}log_topics AS lt ON (lt.id_topic = t.id_topic AND lt.id_member = {int:current_member})
  454.             LEFT JOIN {db_prefix}log_mark_read AS lmr ON (lmr.id_board = b.id_board AND lmr.id_member = {int:current_member})' : '') . '
  455.         WHERE t.id_last_msg >= {int:min_message_id}
  456.             ' . (empty($exclude_boards) ? '' : '
  457.             AND b.id_board NOT IN ({array_int:exclude_boards})') . '
  458.             ' . (empty($include_boards) ? '' : '
  459.             AND b.id_board IN ({array_int:include_boards})') . '
  460.             AND {query_wanna_see_board}' . ($modSettings['postmod_active'] ? '
  461.             AND t.approved = {int:is_approved}
  462.             AND m.approved = {int:is_approved}' : '') . '
  463.         ORDER BY t.id_last_msg DESC
  464.         LIMIT ' . $num_recent,
  465.         array(
  466.             'current_member' => $user_info['id'],
  467.             'include_boards' => empty($include_boards) ? '' : $include_boards,
  468.             'exclude_boards' => empty($exclude_boards) ? '' : $exclude_boards,
  469.             'min_message_id' => $modSettings['maxMsgID'] - 35 * min($num_recent, 5),
  470.             'is_approved' => 1,
  471.         )
  472.     );
  473.     $posts = array();
  474.     while ($row = $smcFunc['db_fetch_assoc']($request))
  475.     {
  476.         $row['body'] = strip_tags(strtr(parse_bbc($row['body'], $row['smileys_enabled'], $row['id_msg']), array('<br />' => '&#10;')));
  477.         if ($smcFunc['strlen']($row['body']) > 128)
  478.             $row['body'] = $smcFunc['substr']($row['body'], 0, 128) . '...';
  479.  
  480.         // Censor the subject.
  481.         censorText($row['subject']);
  482.         censorText($row['body']);
  483.  
  484.         if (empty($modSettings['messageIconChecks_disable']) && !isset($icon_sources[$row['icon']]))
  485.             $icon_sources[$row['icon']] = file_exists($settings['theme_dir'] . '/images/post/' . $row['icon'] . '.gif') ? 'images_url' : 'default_images_url';
  486.  
  487.         // Build the array.
  488.         $posts[] = array(
  489.             'board' => array(
  490.                 'id' => $row['id_board'],
  491.                 'name' => $row['board_name'],
  492.                 'href' => $scripturl . '?board=' . $row['id_board'] . '.0',
  493.                 'link' => '<a href="' . $scripturl . '?board=' . $row['id_board'] . '.0">' . $row['board_name'] . '</a>'
  494.             ),
  495.             'topic' => $row['id_topic'],
  496.             'poster' => array(
  497.                 'id' => $row['id_member'],
  498.                 'name' => $row['poster_name'],
  499.                 'href' => empty($row['id_member']) ? '' : $scripturl . '?action=profile;u=' . $row['id_member'],
  500.                 'link' => empty($row['id_member']) ? $row['poster_name'] : '<a href="' . $scripturl . '?action=profile;u=' . $row['id_member'] . '">' . $row['poster_name'] . '</a>'
  501.             ),
  502.             'subject' => $row['subject'],
  503.             'replies' => $row['num_replies'],
  504.             'views' => $row['num_views'],
  505.             'short_subject' => shorten_subject($row['subject'], 25),
  506.             'preview' => $row['body'],
  507.             'time' => timeformat($row['poster_time']),
  508.             'timestamp' => forum_time(true, $row['poster_time']),
  509.             'href' => $scripturl . '?topic=' . $row['id_topic'] . '.msg' . $row['id_msg'] . ';topicseen#new',
  510.             'link' => '<a href="' . $scripturl . '?topic=' . $row['id_topic'] . '.msg' . $row['id_msg'] . '#new" rel="nofollow">' . $row['subject'] . '</a>',
  511.             // Retained for compatibility - is technically incorrect!
  512.             'new' => !empty($row['is_read']),
  513.             'is_new' => empty($row['is_read']),
  514.             'new_from' => $row['new_from'],
  515.             'icon' => '<img src="' . $settings[$icon_sources[$row['icon']]] . '/post/' . $row['icon'] . '.gif" align="middle" alt="' . $row['icon'] . '" />',
  516.         );
  517.     }
  518.     $smcFunc['db_free_result']($request);
  519.  
  520.     // Just return it.
  521.     if ($output_method != 'echo' || empty($posts))
  522.         return $posts;
  523.  
  524.     echo '
  525.         <table border="0" class="ssi_table">';
  526.     foreach ($posts as $post)
  527.         echo '
  528.             <tr>
  529.                 <td align="right" valign="top" nowrap="nowrap">
  530.                     [', $post['board']['link'], ']
  531.                 </td>
  532.                 <td valign="top">
  533.                     <a href="', $post['href'], '">', $post['subject'], '</a>
  534.                     ', $txt['by'], ' ', $post['poster']['link'], '
  535.                     ', !$post['is_new'] ? '' : '<a href="' . $scripturl . '?topic=' . $post['topic'] . '.msg' . $post['new_from'] . ';topicseen#new" rel="nofollow"><img src="' . $settings['lang_images_url'] . '/new.gif" alt="' . $txt['new'] . '" /></a>', '
  536.                 </td>
  537.                 <td align="right" nowrap="nowrap">
  538.                     ', $post['time'], '
  539.                 </td>
  540.             </tr>';
  541.     echo '
  542.         </table>';
  543. }
  544.  
  545. // Show the top poster's name and profile link.
  546. function ssi_topPoster($topNumber = 1, $output_method = 'echo')
  547. {
  548.     global $db_prefix, $scripturl, $smcFunc;
  549.  
  550.     // Find the latest poster.
  551.     $request = $smcFunc['db_query']('', '
  552.         SELECT id_member, real_name, posts
  553.         FROM {db_prefix}members
  554.         ORDER BY posts DESC
  555.         LIMIT ' . $topNumber,
  556.         array(
  557.         )
  558.     );
  559.     $return = array();
  560.     while ($row = $smcFunc['db_fetch_assoc']($request))
  561.         $return[] = array(
  562.             'id' => $row['id_member'],
  563.             'name' => $row['real_name'],
  564.             'href' => $scripturl . '?action=profile;u=' . $row['id_member'],
  565.             'link' => '<a href="' . $scripturl . '?action=profile;u=' . $row['id_member'] . '">' . $row['real_name'] . '</a>',
  566.             'posts' => $row['posts']
  567.         );
  568.     $smcFunc['db_free_result']($request);
  569.  
  570.     // Just return all the top posters.
  571.     if ($output_method != 'echo')
  572.         return $return;
  573.  
  574.     // Make a quick array to list the links in.
  575.     $temp_array = array();
  576.     foreach ($return as $member)
  577.         $temp_array[] = $member['link'];
  578.  
  579.     echo implode(', ', $temp_array);
  580. }
  581.  
  582. // Show boards by activity.
  583. function ssi_topBoards($num_top = 10, $output_method = 'echo')
  584. {
  585.     global $context, $settings, $db_prefix, $txt, $scripturl, $user_info, $modSettings, $smcFunc;
  586.  
  587.     // Find boards with lots of posts.
  588.     $request = $smcFunc['db_query']('', '
  589.         SELECT
  590.             b.name, b.num_topics, b.num_posts, b.id_board,' . (!$user_info['is_guest'] ? ' 1 AS is_read' : '
  591.             (IFNULL(lb.id_msg, 0) >= b.id_last_msg) AS is_read') . '
  592.         FROM {db_prefix}boards AS b
  593.             LEFT JOIN {db_prefix}log_boards AS lb ON (lb.id_board = b.id_board AND lb.id_member = {int:current_member})
  594.         WHERE {query_wanna_see_board}' . (!empty($modSettings['recycle_enable']) && $modSettings['recycle_board'] > 0 ? '
  595.             AND b.id_board != {int:recycle_board}' : '') . '
  596.         ORDER BY b.num_posts DESC
  597.         LIMIT ' . $num_top,
  598.         array(
  599.             'current_member' => $user_info['id'],
  600.             'recycle_board' => (int) $modSettings['recycle_board'],
  601.         )
  602.     );
  603.     $boards = array();
  604.     while ($row = $smcFunc['db_fetch_assoc']($request))
  605.         $boards[] = array(
  606.             'id' => $row['id_board'],
  607.             'num_posts' => $row['num_posts'],
  608.             'num_topics' => $row['num_topics'],
  609.             'name' => $row['name'],
  610.             'new' => empty($row['is_read']),
  611.             'href' => $scripturl . '?board=' . $row['id_board'] . '.0',
  612.             'link' => '<a href="' . $scripturl . '?board=' . $row['id_board'] . '.0">' . $row['name'] . '</a>'
  613.         );
  614.     $smcFunc['db_free_result']($request);
  615.  
  616.     // If we shouldn't output or have nothing to output, just jump out.
  617.     if ($output_method != 'echo' || empty($boards))
  618.         return $boards;
  619.  
  620.     echo '
  621.         <table class="ssi_table">
  622.             <tr>
  623.                 <th align="left">', $txt['board'], '</th>
  624.                 <th align="left">', $txt['board_topics'], '</th>
  625.                 <th align="left">', $txt['posts'], '</th>
  626.             </tr>';
  627.     foreach ($boards as $board)
  628.         echo '
  629.             <tr>
  630.                 <td>', $board['link'], $board['new'] ? ' <a href="' . $board['href'] . '"><img src="' . $settings['lang_images_url'] . '/new.gif" alt="' . $txt['new'] . '" /></a>' : '', '</td>
  631.                 <td align="right">', comma_format($board['num_topics']), '</td>
  632.                 <td align="right">', comma_format($board['num_posts']), '</td>
  633.             </tr>';
  634.     echo '
  635.         </table>';
  636. }
  637.  
  638. // Shows the top topics.
  639. function ssi_topTopics($type = 'replies', $num_topics = 10, $output_method = 'echo')
  640. {
  641.     global $db_prefix, $txt, $scripturl, $user_info, $modSettings, $smcFunc, $context;
  642.  
  643.     if ($modSettings['totalMessages'] > 100000)
  644.     {
  645.         // !!! Why don't we use {query(_wanna)_see_board}?
  646.         $request = $smcFunc['db_query']('', '
  647.             SELECT id_topic
  648.             FROM {db_prefix}topics
  649.             WHERE num_' . ($type != 'replies' ? 'views' : 'replies') . ' != 0' . ($modSettings['postmod_active'] ? '
  650.                 AND approved = {int:is_approved}' : '') . '
  651.             ORDER BY num_' . ($type != 'replies' ? 'views' : 'replies') . ' DESC
  652.             LIMIT {int:limit}',
  653.             array(
  654.                 'is_approved' => 1,
  655.                 'limit' => $num_topics > 100 ? ($num_topics + ($num_topics / 2)) : 100,
  656.             )
  657.         );
  658.         $topic_ids = array();
  659.         while ($row = $smcFunc['db_fetch_assoc']($request))
  660.             $topic_ids[] = $row['id_topic'];
  661.         $smcFunc['db_free_result']($request);
  662.     }
  663.     else
  664.         $topic_ids = array();
  665.  
  666.     $request = $smcFunc['db_query']('', '
  667.         SELECT m.subject, m.id_topic, t.num_views, t.num_replies
  668.         FROM {db_prefix}topics AS t
  669.             INNER JOIN {db_prefix}messages AS m ON (m.id_msg = t.id_first_msg)
  670.             INNER JOIN {db_prefix}boards AS b ON (b.id_board = t.id_board)
  671.         WHERE {query_wanna_see_board}' . ($modSettings['postmod_active'] ? '
  672.             AND t.approved = {int:is_approved}' : '') . (!empty($topic_ids) ? '
  673.             AND t.id_topic IN ({array_int:topic_list})' : '') . (!empty($modSettings['recycle_enable']) && $modSettings['recycle_board'] > 0 ? '
  674.             AND b.id_board != {int:recycle_enable}' : '') . '
  675.         ORDER BY t.num_' . ($type != 'replies' ? 'views' : 'replies') . ' DESC
  676.         LIMIT {int:limit}',
  677.         array(
  678.             'topic_list' => $topic_ids,
  679.             'is_approved' => 1,
  680.             'recycle_enable' => $modSettings['recycle_board'],
  681.             'limit' => $num_topics,
  682.         )
  683.     );
  684.     $topics = array();
  685.     while ($row = $smcFunc['db_fetch_assoc']($request))
  686.     {
  687.         censorText($row['subject']);
  688.  
  689.         $topics[] = array(
  690.             'id' => $row['id_topic'],
  691.             'subject' => $row['subject'],
  692.             'num_replies' => $row['num_replies'],
  693.             'num_views' => $row['num_views'],
  694.             'href' => $scripturl . '?topic=' . $row['id_topic'] . '.0',
  695.             'link' => '<a href="' . $scripturl . '?topic=' . $row['id_topic'] . '.0">' . $row['subject'] . '</a>',
  696.         );
  697.     }
  698.     $smcFunc['db_free_result']($request);
  699.  
  700.     if ($output_method != 'echo' || empty($topics))
  701.         return $topics;
  702.  
  703.     echo '
  704.         <table class="ssi_table">
  705.             <tr>
  706.                 <th align="left"></th>
  707.                 <th align="left">', $txt['views'], '</th>
  708.                 <th align="left">', $txt['replies'], '</th>
  709.             </tr>';
  710.     foreach ($topics as $topic)
  711.         echo '
  712.             <tr>
  713.                 <td align="left">
  714.                     ', $topic['link'], '
  715.                 </td>
  716.                 <td align="right">', comma_format($topic['num_views']), '</td>
  717.                 <td align="right">', comma_format($topic['num_replies']), '</td>
  718.             </tr>';
  719.     echo '
  720.         </table>';
  721. }
  722.  
  723. // Shows the top topics, by replies.
  724. function ssi_topTopicsReplies($num_topics = 10, $output_method = 'echo')
  725. {
  726.     return ssi_topTopics('replies', $num_topics, $output_method);
  727. }
  728.  
  729. // Shows the top topics, by views.
  730. function ssi_topTopicsViews($num_topics = 10, $output_method = 'echo')
  731. {
  732.     return ssi_topTopics('views', $num_topics, $output_method);
  733. }
  734.  
  735. // Show a link to the latest member:  Please welcome, Someone, out latest member.
  736. function ssi_latestMember($output_method = 'echo')
  737. {
  738.     global $db_prefix, $txt, $scripturl, $context;
  739.  
  740.     if ($output_method == 'echo')
  741.         echo '
  742.     ', $txt['welcome_member'], ' ', $context['common_stats']['latest_member']['link'], '', $txt['newest_member'], '<br />';
  743.     else
  744.         return $context['common_stats']['latest_member'];
  745. }
  746.  
  747. // Fetch a random member - if type set to 'day' will only change once a day!
  748. function ssi_randomMember($random_type = '', $output_method = 'echo')
  749. {
  750.     global $modSettings;
  751.  
  752.     // If we're looking for something to stay the same each day then seed the generator.
  753.     if ($random_type == 'day')
  754.     {
  755.         // Set the seed to change only once per day.
  756.         mt_srand(floor(time() / 86400));
  757.     }
  758.  
  759.     // Get the lowest ID we're interested in.
  760.     $member_id = mt_rand(1, $modSettings['latestMember']);
  761.  
  762.     $where_query = '
  763.         id_member >= {int:selected_member}
  764.         AND is_activated = {int:is_activated}';
  765.  
  766.     $query_where_params = array(
  767.         'selected_member' => $member_id,
  768.         'is_activated' => 1,
  769.     );
  770.  
  771.     $result = ssi_queryMembers($where_query, $query_where_params, 1, 'id_member ASC', $output_method);
  772.  
  773.     // If we got nothing do the reverse - in case of unactivated members.
  774.     if (empty($result))
  775.     {
  776.         $where_query = '
  777.             id_member <= {int:selected_member}
  778.             AND is_activated = {int:is_activated}';
  779.  
  780.         $query_where_params = array(
  781.             'selected_member' => $member_id,
  782.             'is_activated' => 1,
  783.         );
  784.  
  785.         $result = ssi_queryMembers($where_query, $query_where_params, 1, 'id_member DESC', $output_method);
  786.     }
  787.  
  788.     // Just to be sure put the random generator back to something... random.
  789.     if ($random_type != '')
  790.         mt_srand(time());
  791.  
  792.     return $result;
  793. }
  794.  
  795. // Fetch a specific member.
  796. function ssi_fetchMember($member_ids = array(), $output_method = 'echo')
  797. {
  798.     if (empty($member_ids))
  799.         return;
  800.  
  801.     // Can have more than one member if you really want...
  802.     $member_ids = is_array($member_ids) ? $member_ids : array($member_ids);
  803.  
  804.     // Restrict it right!
  805.     $query_where = '
  806.         id_member IN ({array_int:member_list})';
  807.  
  808.     $query_where_params = array(
  809.         'member_list' => $member_ids,
  810.     );
  811.  
  812.     // Then make the query and dump the data.
  813.     return ssi_queryMembers($query_where, $query_where_params, '', 'id_member', $output_method);
  814. }
  815.  
  816. // Get all members of a group.
  817. function ssi_fetchGroupMembers($group_id = null, $output_method = 'echo')
  818. {
  819.     if ($group_id === null)
  820.         return;
  821.  
  822.     $query_where = '
  823.         id_group = {int:id_group}
  824.         OR id_post_group = {int:id_group}
  825.         OR FIND_IN_SET({int:id_group}, additional_groups) != 0';
  826.  
  827.     $query_where_params = array(
  828.         'id_group' => $group_id,
  829.     );
  830.  
  831.     return ssi_queryMembers($query_where, $query_where_params, '', 'real_name', $output_method);
  832. }
  833.  
  834. // Fetch some member data!
  835. function ssi_queryMembers($query_where = null, $query_where_params = array(), $query_limit = '', $query_order = 'id_member DESC', $output_method = 'echo')
  836. {
  837.     global $context, $settings, $scripturl, $txt, $db_prefix, $user_info;
  838.     global $modSettings, $smcFunc, $memberContext;
  839.  
  840.     if ($query_where === null)
  841.         return;
  842.  
  843.     // Fetch the members in question.
  844.     $request = $smcFunc['db_query']('', '
  845.         SELECT id_member
  846.         FROM {db_prefix}members
  847.         WHERE ' . $query_where . '
  848.         ORDER BY ' . $query_order . '
  849.         ' . ($query_limit == '' ? '' : 'LIMIT ' . $query_limit),
  850.         array_merge($query_where_params, array(
  851.         ))
  852.     );
  853.     $members = array();
  854.     while ($row = $smcFunc['db_fetch_assoc']($request))
  855.         $members[] = $row['id_member'];
  856.     $smcFunc['db_free_result']($request);
  857.  
  858.     if (empty($members))
  859.         return array();
  860.  
  861.     // Load the members.
  862.     loadMemberData($members);
  863.  
  864.     // Draw the table!
  865.     if ($output_method == 'echo')
  866.         echo '
  867.         <table border="0" class="ssi_table">';
  868.  
  869.     $query_members = array();
  870.     foreach ($members as $member)
  871.     {
  872.         // Load their context data.
  873.         if (!loadMemberContext($member))
  874.             continue;
  875.  
  876.         // Store this member's information.
  877.         $query_members[$member] = $memberContext[$member];
  878.  
  879.         // Only do something if we're echo'ing.
  880.         if ($output_method == 'echo')
  881.             echo '
  882.             <tr>
  883.                 <td align="right" valign="top" nowrap="nowrap">
  884.                     ', $query_members[$member]['link'], '
  885.                     <br />', $query_members[$member]['blurb'], '
  886.                     <br />', $query_members[$member]['avatar']['image'], '
  887.                 </td>
  888.             </tr>';
  889.     }
  890.  
  891.     // End the table if appropriate.
  892.     if ($output_method == 'echo')
  893.         echo '
  894.         </table>';
  895.  
  896.     // Send back the data.
  897.     return $query_members;
  898. }
  899.  
  900. // Show some basic stats:  Total This: XXXX, etc.
  901. function ssi_boardStats($output_method = 'echo')
  902. {
  903.     global $db_prefix, $txt, $scripturl, $modSettings, $smcFunc;
  904.  
  905.     $totals = array(
  906.         'members' => $modSettings['totalMembers'],
  907.         'posts' => $modSettings['totalMessages'],
  908.         'topics' => $modSettings['totalTopics']
  909.     );
  910.  
  911.     $result = $smcFunc['db_query']('', '
  912.         SELECT COUNT(*)
  913.         FROM {db_prefix}boards',
  914.         array(
  915.         )
  916.     );
  917.     list ($totals['boards']) = $smcFunc['db_fetch_row']($result);
  918.     $smcFunc['db_free_result']($result);
  919.  
  920.     $result = $smcFunc['db_query']('', '
  921.         SELECT COUNT(*)
  922.         FROM {db_prefix}categories',
  923.         array(
  924.         )
  925.     );
  926.     list ($totals['categories']) = $smcFunc['db_fetch_row']($result);
  927.     $smcFunc['db_free_result']($result);
  928.  
  929.     if ($output_method != 'echo')
  930.         return $totals;
  931.  
  932.     echo '
  933.         ', $txt['total_members'], ': <a href="', $scripturl . '?action=mlist">', comma_format($totals['members']), '</a><br />
  934.         ', $txt['total_posts'], ': ', comma_format($totals['posts']), '<br />
  935.         ', $txt['total_topics'], ': ', comma_format($totals['topics']), ' <br />
  936.         ', $txt['total_cats'], ': ', comma_format($totals['categories']), '<br />
  937.         ', $txt['total_boards'], ': ', comma_format($totals['boards']);
  938. }
  939.  
  940. // Shows a list of online users:  YY Guests, ZZ Users and then a list...
  941. function ssi_whosOnline($output_method = 'echo')
  942. {
  943.     global $user_info, $txt, $sourcedir, $settings, $modSettings;
  944.  
  945.     require_once($sourcedir . '/Subs-MembersOnline.php');
  946.     $membersOnlineOptions = array(
  947.         'show_hidden' => allowedTo('moderate_forum'),
  948.         'sort' => 'log_time',
  949.         'reverse_sort' => true,
  950.     );
  951.     $return = getMembersOnlineStats($membersOnlineOptions);
  952.  
  953.     // Add some redundancy for backwards compatibility reasons.
  954.     if ($output_method != 'echo')
  955.         return $return + array(
  956.             'users' => $return['users_online'],
  957.             'guests' => $return['num_guests'],
  958.             'hidden' => $return['num_users_hidden'],
  959.             'buddies' => $return['num_buddies'],
  960.             'num_users' => $return['num_users_online'],
  961.             'total_users' => $return['num_users_online'] + $return['num_guests'] + $return['num_spiders'],
  962.         );
  963.  
  964.     echo '
  965.         ', comma_format($return['num_guests']), ' ', $return['num_guests'] == 1 ? $txt['guest'] : $txt['guests'], ', ', comma_format($return['num_users_online']), ' ', $return['num_users_online'] == 1 ? $txt['user'] : $txt['users'];
  966.  
  967.     $bracketList = array();
  968.     if (!empty($user_info['buddies']))
  969.         $bracketList[] = comma_format($return['num_buddies']) . ' ' . ($return['num_buddies'] == 1 ? $txt['buddy'] : $txt['buddies']);
  970.     if (!empty($return['num_spiders']))
  971.         $bracketList[] = comma_format($return['num_spiders']) . ' ' . ($return['num_spiders'] == 1 ? $txt['spider'] : $txt['spiders']);
  972.     if (!empty($return['num_users_hidden']))
  973.         $bracketList[] = comma_format($return['num_users_hidden']) . ' ' . $txt['hidden'];
  974.  
  975.     if (!empty($bracketList))
  976.         echo ' (' . implode(', ', $bracketList) . ')';
  977.  
  978.     echo '<br />
  979.             ', implode(', ', $return['list_users_online']);
  980.  
  981.     // Showing membergroups?
  982.     if (!empty($settings['show_group_key']) && !empty($return['membergroups']))
  983.         echo '<br />
  984.             [' . implode(']&nbsp;&nbsp;[', $return['membergroups']) . ']';
  985. }
  986.  
  987. // Just like whosOnline except it also logs the online presence.
  988. function ssi_logOnline($output_method = 'echo')
  989. {
  990.     writeLog();
  991.  
  992.     if ($output_method != 'echo')
  993.         return ssi_whosOnline($output_method);
  994.     else
  995.         ssi_whosOnline($output_method);
  996. }
  997.  
  998. // Shows a login box.
  999. function ssi_login($redirect_to = '', $output_method = 'echo')
  1000. {
  1001.     global $scripturl, $txt, $user_info, $context, $modSettings;
  1002.  
  1003.     if ($redirect_to != '')
  1004.         $_SESSION['login_url'] = $redirect_to;
  1005.  
  1006.     if ($output_method != 'echo' || !$user_info['is_guest'])
  1007.         return $user_info['is_guest'];
  1008.  
  1009.     echo '
  1010.         <form action="', $scripturl, '?action=login2" method="post" accept-charset="', $context['character_set'], '">
  1011.             <table border="0" cellspacing="1" cellpadding="0" class="ssi_table">
  1012.                 <tr>
  1013.                     <td align="right"><label for="user">', $txt['username'], ':</label>&nbsp;</td>
  1014.                     <td><input type="text" id="user" name="user" size="9" value="', $user_info['username'], '" class="input_text" /></td>
  1015.                 </tr><tr>
  1016.                     <td align="right"><label for="passwrd">', $txt['password'], ':</label>&nbsp;</td>
  1017.                     <td><input type="password" name="passwrd" id="passwrd" size="9" class="input_password" /></td>
  1018.                 </tr>';
  1019.  
  1020.     // Open ID?
  1021.     if (!empty($modSettings['enableOpenID']))
  1022.         echo '<tr>
  1023.                     <td colspan="2" align="center"><strong>&mdash;', $txt['or'], '&mdash;</strong></td>
  1024.                 </tr><tr>
  1025.                     <td align="right"><label for="openid_url">', $txt['openid'], ':</label>&nbsp;</td>
  1026.                     <td><input type="text" name="openid_identifier" id="openid_url" class="input_text openid_login" size="17" /></td>
  1027.                 </tr>';
  1028.  
  1029.     echo '<tr>
  1030.                     <td><input type="hidden" name="cookielength" value="-1" /></td>
  1031.                     <td><input type="submit" value="', $txt['login'], '" class="button_submit" /></td>
  1032.                 </tr>
  1033.             </table>
  1034.         </form>';
  1035.  
  1036. }
  1037.  
  1038. // Show the most-voted-in poll.
  1039. function ssi_topPoll($output_method = 'echo')
  1040. {
  1041.     // Just use recentPoll, no need to duplicate code...
  1042.     return ssi_recentPoll(true, $output_method);
  1043. }
  1044.  
  1045. // Show the most recently posted poll.
  1046. function ssi_recentPoll($topPollInstead = false, $output_method = 'echo')
  1047. {
  1048.     global $db_prefix, $txt, $settings, $boardurl, $user_info, $context, $smcFunc, $modSettings;
  1049.  
  1050.     $boardsAllowed = array_intersect(boardsAllowedTo('poll_view'), boardsAllowedTo('poll_vote'));
  1051.  
  1052.     if (empty($boardsAllowed))
  1053.         return array();
  1054.  
  1055.     $request = $smcFunc['db_query']('', '
  1056.         SELECT p.id_poll, p.question, t.id_topic, p.max_votes, p.guest_vote, p.hide_results, p.expire_time
  1057.         FROM {db_prefix}polls AS p
  1058.             INNER JOIN {db_prefix}topics AS t ON (t.id_poll = p.id_poll' . ($modSettings['postmod_active'] ? ' AND t.approved = {int:is_approved}' : '') . ')
  1059.             INNER JOIN {db_prefix}boards AS b ON (b.id_board = t.id_board)' . ($topPollInstead ? '
  1060.             INNER JOIN {db_prefix}poll_choices AS pc ON (pc.id_poll = p.id_poll)' : '') . '
  1061.             LEFT JOIN {db_prefix}log_polls AS lp ON (lp.id_poll = p.id_poll AND lp.id_member > {int:no_member} AND lp.id_member = {int:current_member})
  1062.         WHERE p.voting_locked = {int:voting_opened}
  1063.             AND (p.expire_time = {int:no_expiration} OR {int:current_time} < p.expire_time)
  1064.             AND ' . ($user_info['is_guest'] ? 'p.guest_vote = {int:guest_vote_allowed}' : 'lp.id_choice IS NULL') . '
  1065.             AND {query_wanna_see_board}' . (!in_array(0, $boardsAllowed) ? '
  1066.             AND b.id_board IN ({array_int:boards_allowed_list})' : '') . (!empty($modSettings['recycle_enable']) && $modSettings['recycle_board'] > 0 ? '
  1067.             AND b.id_board != {int:recycle_enable}' : '') . '
  1068.         ORDER BY ' . ($topPollInstead ? 'pc.votes' : 'p.id_poll') . ' DESC
  1069.         LIMIT 1',
  1070.         array(
  1071.             'current_member' => $user_info['id'],
  1072.             'boards_allowed_list' => $boardsAllowed,
  1073.             'is_approved' => 1,
  1074.             'guest_vote_allowed' => 1,
  1075.             'no_member' => 0,
  1076.             'voting_opened' => 0,
  1077.             'no_expiration' => 0,
  1078.             'current_time' => time(),
  1079.             'recycle_enable' => $modSettings['recycle_board'],
  1080.         )
  1081.     );
  1082.     $row = $smcFunc['db_fetch_assoc']($request);
  1083.     $smcFunc['db_free_result']($request);
  1084.  
  1085.     // This user has voted on all the polls.
  1086.     if ($row === false)
  1087.         return array();
  1088.  
  1089.     // If this is a guest who's voted we'll through ourselves to show poll to show the results.
  1090.     if ($user_info['is_guest'] && (!$row['guest_vote'] || (isset($_COOKIE['guest_poll_vote']) && in_array($row['id_poll'], explode(',', $_COOKIE['guest_poll_vote'])))))
  1091.         return ssi_showPoll($row['id_topic'], $output_method);
  1092.  
  1093.     $request = $smcFunc['db_query']('', '
  1094.         SELECT COUNT(DISTINCT id_member)
  1095.         FROM {db_prefix}log_polls
  1096.         WHERE id_poll = {int:current_poll}',
  1097.         array(
  1098.             'current_poll' => $row['id_poll'],
  1099.         )
  1100.     );
  1101.     list ($total) = $smcFunc['db_fetch_row']($request);
  1102.     $smcFunc['db_free_result']($request);
  1103.  
  1104.     $request = $smcFunc['db_query']('', '
  1105.         SELECT id_choice, label, votes
  1106.         FROM {db_prefix}poll_choices
  1107.         WHERE id_poll = {int:current_poll}',
  1108.         array(
  1109.             'current_poll' => $row['id_poll'],
  1110.         )
  1111.     );
  1112.     $options = array();
  1113.     while ($rowChoice = $smcFunc['db_fetch_assoc']($request))
  1114.     {
  1115.         censorText($rowChoice['label']);
  1116.  
  1117.         $options[$rowChoice['id_choice']] = array($rowChoice['label'], $rowChoice['votes']);
  1118.     }
  1119.     $smcFunc['db_free_result']($request);
  1120.  
  1121.     // Can they view it?
  1122.     $is_expired = !empty($row['expire_time']) && $row['expire_time'] < time();
  1123.     $allow_view_results = allowedTo('moderate_board') || $row['hide_results'] == 0 || $is_expired;
  1124.  
  1125.     $return = array(
  1126.         'id' => $row['id_poll'],
  1127.         'image' => 'poll',
  1128.         'question' => $row['question'],
  1129.         'total_votes' => $total,
  1130.         'is_locked' => false,
  1131.         'topic' => $row['id_topic'],
  1132.         'allow_view_results' => $allow_view_results,
  1133.         'options' => array()
  1134.     );
  1135.  
  1136.     // Calculate the percentages and bar lengths...
  1137.     $divisor = $return['total_votes'] == 0 ? 1 : $return['total_votes'];
  1138.     foreach ($options as $i => $option)
  1139.     {
  1140.         $bar = floor(($option[1] * 100) / $divisor);
  1141.         $barWide = $bar == 0 ? 1 : floor(($bar * 5) / 3);
  1142.         $return['options'][$i] = array(
  1143.             'id' => 'options-' . ($topPollInstead ? 'top-' : 'recent-') . $i,
  1144.             'percent' => $bar,
  1145.             'votes' => $option[1],
  1146.             'bar' => '<span style="white-space: nowrap;"><img src="' . $settings['images_url'] . '/poll_' . ($context['right_to_left'] ? 'right' : 'left') . '.gif" alt="" /><img src="' . $settings['images_url'] . '/poll_middle.gif" width="' . $barWide . '" height="12" alt="-" /><img src="' . $settings['images_url'] . '/poll_' . ($context['right_to_left'] ? 'left' : 'right') . '.gif" alt="" /></span>',
  1147.             'option' => parse_bbc($option[0]),
  1148.             'vote_button' => '<input type="' . ($row['max_votes'] > 1 ? 'checkbox' : 'radio') . '" name="options[]" id="options-' . ($topPollInstead ? 'top-' : 'recent-') . $i . '" value="' . $i . '" class="input_' . ($row['max_votes'] > 1 ? 'check' : 'radio') . '" />'
  1149.         );
  1150.     }
  1151.  
  1152.     $return['allowed_warning'] = $row['max_votes'] > 1 ? sprintf($txt['poll_options6'], min(count($options), $row['max_votes'])) : '';
  1153.  
  1154.     if ($output_method != 'echo')
  1155.         return $return;
  1156.  
  1157.     if ($allow_view_results)
  1158.     {
  1159.         echo '
  1160.         <form class="ssi_poll" action="', $boardurl, '/SSI.php?ssi_function=pollVote" method="post" accept-charset="', $context['character_set'], '">
  1161.             <strong>', $return['question'], '</strong><br />
  1162.             ', !empty($return['allowed_warning']) ? $return['allowed_warning'] . '<br />' : '';
  1163.  
  1164.         foreach ($return['options'] as $option)
  1165.             echo '
  1166.             <label for="', $option['id'], '">', $option['vote_button'], ' ', $option['option'], '</label><br />';
  1167.  
  1168.         echo '
  1169.             <input type="submit" value="', $txt['poll_vote'], '" class="button_submit" />
  1170.             <input type="hidden" name="poll" value="', $return['id'], '" />
  1171.             <input type="hidden" name="', $context['session_var'], '" value="', $context['session_id'], '" />
  1172.         </form>';
  1173.     }
  1174.     else
  1175.         echo $txt['poll_cannot_see'];
  1176. }
  1177.  
  1178. function ssi_showPoll($topic = null, $output_method = 'echo')
  1179. {
  1180.     global $db_prefix, $txt, $settings, $boardurl, $user_info, $context, $smcFunc, $modSettings;
  1181.  
  1182.     $boardsAllowed = boardsAllowedTo('poll_view');
  1183.  
  1184.     if (empty($boardsAllowed))
  1185.         return array();
  1186.  
  1187.     if ($topic === null && isset($_REQUEST['ssi_topic']))
  1188.         $topic = (int) $_REQUEST['ssi_topic'];
  1189.     else
  1190.         $topic = (int) $topic;
  1191.  
  1192.     $request = $smcFunc['db_query']('', '
  1193.         SELECT
  1194.             p.id_poll, p.question, p.voting_locked, p.hide_results, p.expire_time, p.max_votes, p.guest_vote, b.id_board
  1195.         FROM {db_prefix}topics AS t
  1196.             INNER JOIN {db_prefix}polls AS p ON (p.id_poll = t.id_poll)
  1197.             INNER JOIN {db_prefix}boards AS b ON (b.id_board = t.id_board)
  1198.         WHERE t.id_topic = {int:current_topic}
  1199.             AND {query_see_board}' . (!in_array(0, $boardsAllowed) ? '
  1200.             AND b.id_board IN ({array_int:boards_allowed_see})' : '') . ($modSettings['postmod_active'] ? '
  1201.             AND t.approved = {int:is_approved}' : '') . '
  1202.         LIMIT 1',
  1203.         array(
  1204.             'current_topic' => $topic,
  1205.             'boards_allowed_see' => $boardsAllowed,
  1206.             'is_approved' => 1,
  1207.         )
  1208.     );
  1209.  
  1210.     // Either this topic has no poll, or the user cannot view it.
  1211.     if ($smcFunc['db_num_rows']($request) == 0)
  1212.         return array();
  1213.  
  1214.     $row = $smcFunc['db_fetch_assoc']($request);
  1215.     $smcFunc['db_free_result']($request);
  1216.  
  1217.     // Check if they can vote.
  1218.     $already_voted = false;
  1219.     if (!empty($row['expire_time']) && $row['expire_time'] < time())
  1220.         $allow_vote = false;
  1221.     elseif ($user_info['is_guest'])
  1222.     {
  1223.         // There's a difference between "allowed to vote" and "already voted"...
  1224.         $allow_vote = $row['guest_vote'];
  1225.  
  1226.         // Did you already vote?
  1227.         if (isset($_COOKIE['guest_poll_vote']) && in_array($row['id_poll'], explode(',', $_COOKIE['guest_poll_vote'])))
  1228.         {
  1229.             $already_voted = true;
  1230.         }
  1231.     }
  1232.     elseif (!empty($row['voting_locked']) || !allowedTo('poll_vote', $row['id_board']))
  1233.         $allow_vote = false;
  1234.     else
  1235.     {
  1236.         $request = $smcFunc['db_query']('', '
  1237.             SELECT id_member
  1238.             FROM {db_prefix}log_polls
  1239.             WHERE id_poll = {int:current_poll}
  1240.                 AND id_member = {int:current_member}
  1241.             LIMIT 1',
  1242.             array(
  1243.                 'current_member' => $user_info['id'],
  1244.                 'current_poll' => $row['id_poll'],
  1245.             )
  1246.         );
  1247.         $allow_vote = $smcFunc['db_num_rows']($request) == 0;
  1248.         $already_voted = $allow_vote;
  1249.         $smcFunc['db_free_result']($request);
  1250.     }
  1251.  
  1252.     // Can they view?
  1253.     $is_expired = !empty($row['expire_time']) && $row['expire_time'] < time();
  1254.     $allow_view_results = allowedTo('moderate_board') || $row['hide_results'] == 0 || ($row['hide_results'] == 1 && $already_voted) || $is_expired;
  1255.  
  1256.     $request = $smcFunc['db_query']('', '
  1257.         SELECT COUNT(DISTINCT id_member)
  1258.         FROM {db_prefix}log_polls
  1259.         WHERE id_poll = {int:current_poll}',
  1260.         array(
  1261.             'current_poll' => $row['id_poll'],
  1262.         )
  1263.     );
  1264.     list ($total) = $smcFunc['db_fetch_row']($request);
  1265.     $smcFunc['db_free_result']($request);
  1266.  
  1267.     $request = $smcFunc['db_query']('', '
  1268.         SELECT id_choice, label, votes
  1269.         FROM {db_prefix}poll_choices
  1270.         WHERE id_poll = {int:current_poll}',
  1271.         array(
  1272.             'current_poll' => $row['id_poll'],
  1273.         )
  1274.     );
  1275.     $options = array();
  1276.     $total_votes = 0;
  1277.     while ($rowChoice = $smcFunc['db_fetch_assoc']($request))
  1278.     {
  1279.         censorText($rowChoice['label']);
  1280.  
  1281.         $options[$rowChoice['id_choice']] = array($rowChoice['label'], $rowChoice['votes']);
  1282.         $total_votes += $rowChoice['votes'];
  1283.     }
  1284.     $smcFunc['db_free_result']($request);
  1285.  
  1286.     $return = array(
  1287.         'id' => $row['id_poll'],
  1288.         'image' => empty($pollinfo['voting_locked']) ? 'poll' : 'locked_poll',
  1289.         'question' => $row['question'],
  1290.         'total_votes' => $total,
  1291.         'is_locked' => !empty($pollinfo['voting_locked']),
  1292.         'allow_vote' => $allow_vote,
  1293.         'allow_view_results' => $allow_view_results,
  1294.         'topic' => $topic
  1295.     );
  1296.  
  1297.     // Calculate the percentages and bar lengths...
  1298.     $divisor = $total_votes == 0 ? 1 : $total_votes;
  1299.     foreach ($options as $i => $option)
  1300.     {
  1301.         $bar = floor(($option[1] * 100) / $divisor);
  1302.         $barWide = $bar == 0 ? 1 : floor(($bar * 5) / 3);
  1303.         $return['options'][$i] = array(
  1304.             'id' => 'options-' . $i,
  1305.             'percent' => $bar,
  1306.             'votes' => $option[1],
  1307.             'bar' => '<span style="white-space: nowrap;"><img src="' . $settings['images_url'] . '/poll_' . ($context['right_to_left'] ? 'right' : 'left') . '.gif" alt="" /><img src="' . $settings['images_url'] . '/poll_middle.gif" width="' . $barWide . '" height="12" alt="-" /><img src="' . $settings['images_url'] . '/poll_' . ($context['right_to_left'] ? 'left' : 'right') . '.gif" alt="" /></span>',
  1308.             'option' => parse_bbc($option[0]),
  1309.             'vote_button' => '<input type="' . ($row['max_votes'] > 1 ? 'checkbox' : 'radio') . '" name="options[]" id="options-' . $i . '" value="' . $i . '" class="input_' . ($row['max_votes'] > 1 ? 'check' : 'radio') . '" />'
  1310.         );
  1311.     }
  1312.  
  1313.     $return['allowed_warning'] = $row['max_votes'] > 1 ? sprintf($txt['poll_options6'], min(count($options), $row['max_votes'])) : '';
  1314.  
  1315.     if ($output_method != 'echo')
  1316.         return $return;
  1317.  
  1318.     if ($return['allow_vote'])
  1319.     {
  1320.         echo '
  1321.             <form class="ssi_poll" action="', $boardurl, '/SSI.php?ssi_function=pollVote" method="post" accept-charset="', $context['character_set'], '">
  1322.                 <strong>', $return['question'], '</strong><br />
  1323.                 ', !empty($return['allowed_warning']) ? $return['allowed_warning'] . '<br />' : '';
  1324.  
  1325.         foreach ($return['options'] as $option)
  1326.             echo '
  1327.                 <label for="', $option['id'], '">', $option['vote_button'], ' ', $option['option'], '</label><br />';
  1328.  
  1329.         echo '
  1330.                 <input type="submit" value="', $txt['poll_vote'], '" class="button_submit" />
  1331.                 <input type="hidden" name="poll" value="', $return['id'], '" />
  1332.                 <input type="hidden" name="', $context['session_var'], '" value="', $context['session_id'], '" />
  1333.             </form>';
  1334.     }
  1335.     else
  1336.     {
  1337.         echo '
  1338.             <div class="ssi_poll">
  1339.                 <strong>', $return['question'], '</strong>
  1340.                 <dl>';
  1341.  
  1342.         foreach ($return['options'] as $option)
  1343.         {
  1344.             echo '
  1345.                     <dt>', $option['option'], '</dt>
  1346.                     <dd>';
  1347.  
  1348.             if ($return['allow_view_results'])
  1349.             {
  1350.                 echo '
  1351.                         <div class="ssi_poll_bar" style="border: 1px solid #666; height: 1em">
  1352.                             <div class="ssi_poll_bar_fill" style="background: #ccf; height: 1em; width: ', $option['percent'], '%;">
  1353.                             </div>
  1354.                         </div>
  1355.                         ', $option['votes'], ' (', $option['percent'], '%)';
  1356.             }
  1357.  
  1358.             echo '
  1359.                     </dd>';
  1360.         }
  1361.  
  1362.         echo '
  1363.                 </dl>', ($return['allow_view_results'] ? '
  1364.                 <strong>'. $txt['poll_total_voters'] .': '. $return['total_votes'] .'</strong>' : ''), '
  1365.             </div>';
  1366.     }
  1367. }
  1368.  
  1369. // Takes care of voting - don't worry, this is done automatically.
  1370. function ssi_pollVote()
  1371. {
  1372.     global $context, $db_prefix, $user_info, $sc, $smcFunc, $sourcedir, $modSettings;
  1373.  
  1374.     if (!isset($_POST[$context['session_var']]) || $_POST[$context['session_var']] != $sc || empty($_POST['options']) || !isset($_POST['poll']))
  1375.     {
  1376.         echo '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
  1377. <html>
  1378. <head>
  1379.     <script type="text/javascript"><!-- // --><![CDATA[
  1380.         history.go(-1);
  1381.     // ]]></script>
  1382. </head>
  1383. <body>&laquo;</body>
  1384. </html>';
  1385.         return;
  1386.     }
  1387.  
  1388.     // This can cause weird errors! (ie. copyright missing.)
  1389.     checkSession();
  1390.  
  1391.     $_POST['poll'] = (int) $_POST['poll'];
  1392.  
  1393.     // Check if they have already voted, or voting is locked.
  1394.     $request = $smcFunc['db_query']('', '
  1395.         SELECT
  1396.             p.id_poll, p.voting_locked, p.expire_time, p.max_votes, p.guest_vote,
  1397.             t.id_topic,
  1398.             IFNULL(lp.id_choice, -1) AS selected
  1399.         FROM {db_prefix}polls AS p
  1400.             INNER JOIN {db_prefix}topics AS t ON (t.id_poll = {int:current_poll})
  1401.             INNER JOIN {db_prefix}boards AS b ON (b.id_board = t.id_board)
  1402.             LEFT JOIN {db_prefix}log_polls AS lp ON (lp.id_poll = p.id_poll AND lp.id_member = {int:current_member})
  1403.         WHERE p.id_poll = {int:current_poll}
  1404.             AND {query_see_board}' . ($modSettings['postmod_active'] ? '
  1405.             AND t.approved = {int:is_approved}' : '') . '
  1406.         LIMIT 1',
  1407.         array(
  1408.             'current_member' => $user_info['id'],
  1409.             'current_poll' => $_POST['poll'],
  1410.             'is_approved' => 1,
  1411.         )
  1412.     );
  1413.     if ($smcFunc['db_num_rows']($request) == 0)
  1414.         die;
  1415.     $row = $smcFunc['db_fetch_assoc']($request);
  1416.     $smcFunc['db_free_result']($request);
  1417.  
  1418.     if (!empty($row['voting_locked']) || ($row['selected'] != -1 && !$user_info['is_guest']) || (!empty($row['expire_time']) && time() > $row['expire_time']))
  1419.         redirectexit('topic=' . $row['id_topic'] . '.0');
  1420.  
  1421.     // Too many options checked?
  1422.     if (count($_REQUEST['options']) > $row['max_votes'])
  1423.         redirectexit('topic=' . $row['id_topic'] . '.0');
  1424.  
  1425.     // It's a guest who has already voted?
  1426.     if ($user_info['is_guest'])
  1427.     {
  1428.         // Guest voting disabled?
  1429.         if (!$row['guest_vote'])
  1430.             redirectexit('topic=' . $row['id_topic'] . '.0');
  1431.         // Already voted?
  1432.         elseif (isset($_COOKIE['guest_poll_vote']) && in_array($row['id_poll'], explode(',', $_COOKIE['guest_poll_vote'])))
  1433.             redirectexit('topic=' . $row['id_topic'] . '.0');
  1434.     }
  1435.  
  1436.     $options = array();
  1437.     $inserts = array();
  1438.     foreach ($_REQUEST['options'] as $id)
  1439.     {
  1440.         $id = (int) $id;
  1441.  
  1442.         $options[] = $id;
  1443.         $inserts[] = array($_POST['poll'], $user_info['id'], $id);
  1444.     }
  1445.  
  1446.     // Add their vote in to the tally.
  1447.     $smcFunc['db_insert']('insert',
  1448.         $db_prefix . 'log_polls',
  1449.         array('id_poll' => 'int', 'id_member' => 'int', 'id_choice' => 'int'),
  1450.         $inserts,
  1451.         array('id_poll', 'id_member', 'id_choice')
  1452.     );
  1453.     $smcFunc['db_query']('', '
  1454.         UPDATE {db_prefix}poll_choices
  1455.         SET votes = votes + 1
  1456.         WHERE id_poll = {int:current_poll}
  1457.             AND id_choice IN ({array_int:option_list})',
  1458.         array(
  1459.             'option_list' => $options,
  1460.             'current_poll' => $_POST['poll'],
  1461.         )
  1462.     );
  1463.  
  1464.     // Track the vote if a guest.
  1465.     if ($user_info['is_guest'])
  1466.     {
  1467.         $_COOKIE['guest_poll_vote'] = !empty($_COOKIE['guest_poll_vote']) ? ($_COOKIE['guest_poll_vote'] . ',' . $row['id_poll']) : $row['id_poll'];
  1468.  
  1469.         require_once($sourcedir . '/Subs-Auth.php');
  1470.         $cookie_url = url_parts(!empty($modSettings['localCookies']), !empty($modSettings['globalCookies']));
  1471.         setcookie('guest_poll_vote', $_COOKIE['guest_poll_vote'], time() + 2500000, $cookie_url[1], $cookie_url[0], 0);
  1472.     }
  1473.  
  1474.     redirectexit('topic=' . $row['id_topic'] . '.0');
  1475. }
  1476.  
  1477. // Show a search box.
  1478. function ssi_quickSearch($output_method = 'echo')
  1479. {
  1480.     global $scripturl, $txt, $context;
  1481.  
  1482.     if ($output_method != 'echo')
  1483.         return $scripturl . '?action=search';
  1484.  
  1485.     echo '
  1486.         <form action="', $scripturl, '?action=search2" method="post" accept-charset="', $context['character_set'], '">
  1487.             <input type="hidden" name="advanced" value="0" /><input type="text" name="search" size="30" class="input_text" /> <input type="submit" name="submit" value="', $txt['search'], '" class="button_submit" />
  1488.         </form>';
  1489. }
  1490.  
  1491. // Show what would be the forum news.
  1492. function ssi_news($output_method = 'echo')
  1493. {
  1494.     global $context;
  1495.  
  1496.     if ($output_method != 'echo')
  1497.         return $context['random_news_line'];
  1498.  
  1499.     echo $context['random_news_line'];
  1500. }
  1501.  
  1502. // Show today's birthdays.
  1503. function ssi_todaysBirthdays($output_method = 'echo')
  1504. {
  1505.     global $scripturl, $modSettings, $user_info;
  1506.  
  1507.     if (empty($modSettings['cal_enabled']) || !allowedTo('calendar_view') || !allowedTo('profile_view_any'))
  1508.         return;
  1509.  
  1510.     $eventOptions = array(
  1511.         'include_birthdays' => true,
  1512.         'num_days_shown' => empty($modSettings['cal_days_for_index']) || $modSettings['cal_days_for_index'] < 1 ? 1 : $modSettings['cal_days_for_index'],
  1513.     );
  1514.     $return = cache_quick_get('calendar_index_offset_' . ($user_info['time_offset'] + $modSettings['time_offset']), 'Subs-Calendar.php', 'cache_getRecentEvents', array($eventOptions));
  1515.  
  1516.     if ($output_method != 'echo')
  1517.         return $return['calendar_birthdays'];
  1518.  
  1519.     foreach ($return['calendar_birthdays'] as $member)
  1520.         echo '
  1521.             <a href="', $scripturl, '?action=profile;u=', $member['id'], '">' . $member['name'] . (isset($member['age']) ? ' (' . $member['age'] . ')' : '') . '</a>' . (!$member['is_last'] ? ', ' : '');
  1522. }
  1523.  
  1524. // Show today's holidays.
  1525. function ssi_todaysHolidays($output_method = 'echo')
  1526. {
  1527.     global $modSettings, $user_info;
  1528.  
  1529.     if (empty($modSettings['cal_enabled']) || !allowedTo('calendar_view'))
  1530.         return;
  1531.  
  1532.     $eventOptions = array(
  1533.         'include_holidays' => true,
  1534.         'num_days_shown' => empty($modSettings['cal_days_for_index']) || $modSettings['cal_days_for_index'] < 1 ? 1 : $modSettings['cal_days_for_index'],
  1535.     );
  1536.     $return = cache_quick_get('calendar_index_offset_' . ($user_info['time_offset'] + $modSettings['time_offset']), 'Subs-Calendar.php', 'cache_getRecentEvents', array($eventOptions));
  1537.  
  1538.     if ($output_method != 'echo')
  1539.         return $return['calendar_holidays'];
  1540.  
  1541.     echo '
  1542.         ', implode(', ', $return['calendar_holidays']);
  1543. }
  1544.  
  1545. // Show today's events.
  1546. function ssi_todaysEvents($output_method = 'echo')
  1547. {
  1548.     global $modSettings, $user_info;
  1549.  
  1550.     if (empty($modSettings['cal_enabled']) || !allowedTo('calendar_view'))
  1551.         return;
  1552.  
  1553.     $eventOptions = array(
  1554.         'include_events' => true,
  1555.         'num_days_shown' => empty($modSettings['cal_days_for_index']) || $modSettings['cal_days_for_index'] < 1 ? 1 : $modSettings['cal_days_for_index'],
  1556.     );
  1557.     $return = cache_quick_get('calendar_index_offset_' . ($user_info['time_offset'] + $modSettings['time_offset']), 'Subs-Calendar.php', 'cache_getRecentEvents', array($eventOptions));
  1558.  
  1559.     if ($output_method != 'echo')
  1560.         return $return['calendar_events'];
  1561.  
  1562.     foreach ($return['calendar_events'] as $event)
  1563.     {
  1564.         if ($event['can_edit'])
  1565.             echo '
  1566.     <a href="' . $event['modify_href'] . '" style="color: #ff0000;">*</a> ';
  1567.         echo '
  1568.     ' . $event['link'] . (!$event['is_last'] ? ', ' : '');
  1569.     }
  1570. }
  1571.  
  1572. // Show all calendar entires for today. (birthdays, holodays, and events.)
  1573. function ssi_todaysCalendar($output_method = 'echo')
  1574. {
  1575.     global $modSettings, $txt, $scripturl, $user_info;
  1576.  
  1577.     $eventOptions = array(
  1578.         'include_birthdays' => allowedTo('profile_view_any'),
  1579.         'include_holidays' => true,
  1580.         'include_events' => true,
  1581.         'num_days_shown' => empty($modSettings['cal_days_for_index']) || $modSettings['cal_days_for_index'] < 1 ? 1 : $modSettings['cal_days_for_index'],
  1582.     );
  1583.     $return = cache_quick_get('calendar_index_offset_' . ($user_info['time_offset'] + $modSettings['time_offset']), 'Subs-Calendar.php', 'cache_getRecentEvents', array($eventOptions));
  1584.  
  1585.     if ($output_method != 'echo')
  1586.         return $return;
  1587.  
  1588.     if (!empty($return['calendar_holidays']))
  1589.         echo '
  1590.             <span class="holiday">' . $txt['calendar_prompt'] . ' ' . implode(', ', $return['calendar_holidays']) . '<br /></span>';
  1591.     if (!empty($return['calendar_birthdays']))
  1592.     {
  1593.         echo '
  1594.             <span class="birthday">' . $txt['birthdays_upcoming'] . '</span> ';
  1595.         foreach ($return['calendar_birthdays'] as $member)
  1596.             echo '
  1597.             <a href="', $scripturl, '?action=profile;u=', $member['id'], '">', $member['name'], isset($member['age']) ? ' (' . $member['age'] . ')' : '', '</a>', !$member['is_last'] ? ', ' : '';
  1598.         echo '
  1599.             <br />';
  1600.     }
  1601.     if (!empty($return['calendar_events']))
  1602.     {
  1603.         echo '
  1604.             <span class="event">' . $txt['events_upcoming'] . '</span> ';
  1605.         foreach ($return['calendar_events'] as $event)
  1606.         {
  1607.             if ($event['can_edit'])
  1608.                 echo '
  1609.             <a href="' . $event['modify_href'] . '" style="color: #ff0000;">*</a> ';
  1610.             echo '
  1611.             ' . $event['link'] . (!$event['is_last'] ? ', ' : '');
  1612.         }
  1613.     }
  1614. }
  1615.  
  1616. // Show the latest news, with a template... by board.
  1617. function ssi_boardNews($board = null, $limit = null, $start = null, $length = null, $output_method = 'echo')
  1618. {
  1619.     global $scripturl, $db_prefix, $txt, $settings, $modSettings, $context;
  1620.     global $smcFunc;
  1621.  
  1622.     loadLanguage('Stats');
  1623.  
  1624.     // Must be integers....
  1625.     if ($limit === null)
  1626.         $limit = isset($_GET['limit']) ? (int) $_GET['limit'] : 5;
  1627.     else
  1628.         $limit = (int) $limit;
  1629.  
  1630.     if ($start === null)
  1631.         $start = isset($_GET['start']) ? (int) $_GET['start'] : 0;
  1632.     else
  1633.         $start = (int) $start;
  1634.  
  1635.     if ($board !== null)
  1636.         $board = (int) $board;
  1637.     elseif (isset($_GET['board']))
  1638.         $board = (int) $_GET['board'];
  1639.  
  1640.     if ($length === null)
  1641.         $length = isset($_GET['length']) ? (int) $_GET['length'] : 0;
  1642.     else
  1643.         $length = (int) $length;
  1644.  
  1645.     $limit = max(0, $limit);
  1646.     $start = max(0, $start);
  1647.  
  1648.     // Make sure guests can see this board.
  1649.     $request = $smcFunc['db_query']('', '
  1650.         SELECT id_board
  1651.         FROM {db_prefix}boards
  1652.         WHERE ' . ($board === null ? '' : 'id_board = {int:current_board}
  1653.             AND ') . 'FIND_IN_SET(-1, member_groups) != 0
  1654.         LIMIT 1',
  1655.         array(
  1656.             'current_board' => $board,
  1657.         )
  1658.     );
  1659.     if ($smcFunc['db_num_rows']($request) == 0)
  1660.     {
  1661.         if ($output_method == 'echo')
  1662.             die($txt['ssi_no_guests']);
  1663.         else
  1664.             return array();
  1665.     }
  1666.     list ($board) = $smcFunc['db_fetch_row']($request);
  1667.     $smcFunc['db_free_result']($request);
  1668.  
  1669.     // Load the message icons - the usual suspects.
  1670.     $stable_icons = array('xx', 'thumbup', 'thumbdown', 'exclamation', 'question', 'lamp', 'smiley', 'angry', 'cheesy', 'grin', 'sad', 'wink', 'moved', 'recycled', 'wireless');
  1671.     $icon_sources = array();
  1672.     foreach ($stable_icons as $icon)
  1673.         $icon_sources[$icon] = 'images_url';
  1674.  
  1675.     // Find the post ids.
  1676.     $request = $smcFunc['db_query']('', '
  1677.         SELECT t.id_first_msg
  1678.         FROM {db_prefix}topics as t
  1679.         LEFT JOIN {db_prefix}boards as b ON (b.id_board = t.id_board)
  1680.         WHERE t.id_board = {int:current_board}' . ($modSettings['postmod_active'] ? '
  1681.             AND t.approved = {int:is_approved}' : '') . '
  1682.             AND {query_see_board}
  1683.         ORDER BY t.id_first_msg DESC
  1684.         LIMIT ' . $start . ', ' . $limit,
  1685.         array(
  1686.             'current_board' => $board,
  1687.             'is_approved' => 1,
  1688.         )
  1689.     );
  1690.     $posts = array();
  1691.     while ($row = $smcFunc['db_fetch_assoc']($request))
  1692.         $posts[] = $row['id_first_msg'];
  1693.     $smcFunc['db_free_result']($request);
  1694.  
  1695.     if (empty($posts))
  1696.         return array();
  1697.  
  1698.     // Find the posts.
  1699.     $request = $smcFunc['db_query']('', '
  1700.         SELECT
  1701.             m.icon, m.subject, m.body, IFNULL(mem.real_name, m.poster_name) AS poster_name, m.poster_time,
  1702.             t.num_replies, t.id_topic, m.id_member, m.smileys_enabled, m.id_msg, t.locked, t.id_last_msg
  1703.         FROM {db_prefix}topics AS t
  1704.             INNER JOIN {db_prefix}messages AS m ON (m.id_msg = t.id_first_msg)
  1705.             LEFT JOIN {db_prefix}members AS mem ON (mem.id_member = m.id_member)
  1706.         WHERE t.id_first_msg IN ({array_int:post_list})
  1707.         ORDER BY t.id_first_msg DESC
  1708.         LIMIT ' . count($posts),
  1709.         array(
  1710.             'post_list' => $posts,
  1711.         )
  1712.     );
  1713.     $return = array();
  1714.     while ($row = $smcFunc['db_fetch_assoc']($request))
  1715.     {
  1716.         // If we want to limit the length of the post.
  1717.         if (!empty($length) && $smcFunc['strlen']($row['body']) > $length)
  1718.         {
  1719.             $row['body'] = $smcFunc['substr']($row['body'], 0, $length);
  1720.  
  1721.             // The first space or line break. (<br />, etc.)
  1722.             $cutoff = max(strrpos($row['body'], ' '), strrpos($row['body'], '<'));
  1723.  
  1724.             if ($cutoff !== false)
  1725.                 $row['body'] = $smcFunc['substr']($row['body'], 0, $cutoff);
  1726.             $row['body'] .= '... [Leer más]';
  1727.         }
  1728.  
  1729.         $row['body'] = parse_bbc($row['body'], $row['smileys_enabled'], $row['id_msg']);
  1730.  
  1731.         // Check that this message icon is there...
  1732.         if (empty($modSettings['messageIconChecks_disable']) && !isset($icon_sources[$row['icon']]))
  1733.             $icon_sources[$row['icon']] = file_exists($settings['theme_dir'] . '/images/post/' . $row['icon'] . '.gif') ? 'images_url' : 'default_images_url';
  1734.  
  1735.         censorText($row['subject']);
  1736.         censorText($row['body']);
  1737.  
  1738.         $return[] = array(
  1739.             'id' => $row['id_topic'],
  1740.             'message_id' => $row['id_msg'],
  1741.             'icon' => '<img src="' . $settings[$icon_sources[$row['icon']]] . '/post/' . $row['icon'] . '.gif" alt="' . $row['icon'] . '" />',
  1742.             'subject' => $row['subject'],
  1743.             'time' => timeformat($row['poster_time']),
  1744.             'timestamp' => forum_time(true, $row['poster_time']),
  1745.             'body' => $row['body'],
  1746.             'href' => $scripturl . '?topic=' . $row['id_topic'] . '.0',
  1747.             'link' => '<a href="' . $scripturl . '?topic=' . $row['id_topic'] . '.0">' . $row['num_replies'] . ' ' . ($row['num_replies'] == 1 ? $txt['ssi_comment'] : $txt['ssi_comments']) . '</a>',
  1748.             'replies' => $row['num_replies'],
  1749.             'comment_href' => !empty($row['locked']) ? '' : $scripturl . '?action=post;topic=' . $row['id_topic'] . '.' . $row['num_replies'] . ';last_msg=' . $row['id_last_msg'],
  1750.             'comment_link' => !empty($row['locked']) ? '' : '<a href="' . $scripturl . '?action=post;topic=' . $row['id_topic'] . '.' . $row['num_replies'] . ';last_msg=' . $row['id_last_msg'] . '">' . $txt['ssi_write_comment'] . '</a>',
  1751.             'new_comment' => !empty($row['locked']) ? '' : '<a href="' . $scripturl . '?action=post;topic=' . $row['id_topic'] . '.' . $row['num_replies'] . '">' . $txt['ssi_write_comment'] . '</a>',
  1752.             'poster' => array(
  1753.                 'id' => $row['id_member'],
  1754.                 'name' => $row['poster_name'],
  1755.                 'href' => !empty($row['id_member']) ? $scripturl . '?action=profile;u=' . $row['id_member'] : '',
  1756.                 'link' => !empty($row['id_member']) ? '<a href="' . $scripturl . '?action=profile;u=' . $row['id_member'] . '">' . $row['poster_name'] . '</a>' : $row['poster_name']
  1757.             ),
  1758.             'locked' => !empty($row['locked']),
  1759.             'is_last' => false
  1760.         );
  1761.     }
  1762.     $smcFunc['db_free_result']($request);
  1763.  
  1764.     if (empty($return))
  1765.         return $return;
  1766.  
  1767.     $return[count($return) - 1]['is_last'] = true;
  1768.  
  1769.     if ($output_method != 'echo')
  1770.         return $return;
  1771.  
  1772.     foreach ($return as $news)
  1773.     {
  1774.         echo '
  1775.         <div class="td-gr">
  1776.         <div class="icono-td"><img src="./imagenes/nuevo.png"/></div>
  1777.             <div style="height:22px;font-weight:bold; font-size:14px;text-shadow:0 1px 0 #FFFFFF;color:#305B79;padding-top:8px; margin-left:10px; margin-left:34px">
  1778.                 <a href="', $news['href'], '">', $news['subject'], '</a>
  1779.             </div>
  1780.             <div class="news_body" style="padding: 10px;">', $news['body'], '<div class="hr"></div>
  1781.                 <div><a href="', $news['href'], '">', $news['replies'] ,' comentarios</a> | <a href="', $news['comment_href'] ,'">Escribir comentario</a> | Fecha: ', $news['time'], ' por ', $news['poster']['link'] ,'</div>
  1782.             </div>
  1783.         </div>';
  1784.     }
  1785. }
  1786.  
  1787. // Show the most recent events.
  1788. function ssi_recentEvents($max_events = 7, $output_method = 'echo')
  1789. {
  1790.     global $db_prefix, $user_info, $scripturl, $modSettings, $txt, $context, $smcFunc;
  1791.  
  1792.     if (empty($modSettings['cal_enabled']) || !allowedTo('calendar_view'))
  1793.         return;
  1794.  
  1795.     // Find all events which are happening in the near future that the member can see.
  1796.     $request = $smcFunc['db_query']('', '
  1797.         SELECT
  1798.             cal.id_event, cal.start_date, cal.end_date, cal.title, cal.id_member, cal.id_topic,
  1799.             cal.id_board, t.id_first_msg, t.approved
  1800.         FROM {db_prefix}calendar AS cal
  1801.             LEFT JOIN {db_prefix}boards AS b ON (b.id_board = cal.id_board)
  1802.             LEFT JOIN {db_prefix}topics AS t ON (t.id_topic = cal.id_topic)
  1803.         WHERE cal.start_date <= {date:current_date}
  1804.             AND cal.end_date >= {date:current_date}
  1805.             AND (cal.id_board = {int:no_board} OR {query_wanna_see_board})
  1806.         ORDER BY cal.start_date DESC
  1807.         LIMIT ' . $max_events,
  1808.         array(
  1809.             'current_date' => strftime('%Y-%m-%d', forum_time(false)),
  1810.             'no_board' => 0,
  1811.         )
  1812.     );
  1813.     $return = array();
  1814.     $duplicates = array();
  1815.     while ($row = $smcFunc['db_fetch_assoc']($request))
  1816.     {
  1817.         // Check if we've already come by an event linked to this same topic with the same title... and don't display it if we have.
  1818.         if (!empty($duplicates[$row['title'] . $row['id_topic']]))
  1819.             continue;
  1820.  
  1821.         // Censor the title.
  1822.         censorText($row['title']);
  1823.  
  1824.         if ($row['start_date'] < strftime('%Y-%m-%d', forum_time(false)))
  1825.             $date = strftime('%Y-%m-%d', forum_time(false));
  1826.         else
  1827.             $date = $row['start_date'];
  1828.  
  1829.         // If the topic it is attached to is not approved then don't link it.
  1830.         if (!empty($row['id_first_msg']) && !$row['approved'])
  1831.             $row['id_board'] = $row['id_topic'] = $row['id_first_msg'] = 0;
  1832.  
  1833.         $return[$date][] = array(
  1834.             'id' => $row['id_event'],
  1835.             'title' => $row['title'],
  1836.             'can_edit' => allowedTo('calendar_edit_any') || ($row['id_member'] == $user_info['id'] && allowedTo('calendar_edit_own')),
  1837.             'modify_href' => $scripturl . '?action=' . ($row['id_board'] == 0 ? 'calendar;sa=post;' : 'post;msg=' . $row['id_first_msg'] . ';topic=' . $row['id_topic'] . '.0;calendar;') . 'eventid=' . $row['id_event'] . ';' . $context['session_var'] . '=' . $context['session_id'],
  1838.             'href' => $row['id_board'] == 0 ? '' : $scripturl . '?topic=' . $row['id_topic'] . '.0',
  1839.             'link' => $row['id_board'] == 0 ? $row['title'] : '<a href="' . $scripturl . '?topic=' . $row['id_topic'] . '.0">' . $row['title'] . '</a>',
  1840.             'start_date' => $row['start_date'],
  1841.             'end_date' => $row['end_date'],
  1842.             'is_last' => false
  1843.         );
  1844.  
  1845.         // Let's not show this one again, huh?
  1846.         $duplicates[$row['title'] . $row['id_topic']] = true;
  1847.     }
  1848.     $smcFunc['db_free_result']($request);
  1849.  
  1850.     foreach ($return as $mday => $array)
  1851.         $return[$mday][count($array) - 1]['is_last'] = true;
  1852.  
  1853.     if ($output_method != 'echo' || empty($return))
  1854.         return $return;
  1855.  
  1856.     // Well the output method is echo.
  1857.     echo '
  1858.             <span class="event">' . $txt['events'] . '</span> ';
  1859.     foreach ($return as $mday => $array)
  1860.         foreach ($array as $event)
  1861.         {
  1862.             if ($event['can_edit'])
  1863.                 echo '
  1864.                 <a href="' . $event['modify_href'] . '" style="color: #ff0000;">*</a> ';
  1865.  
  1866.             echo '
  1867.                 ' . $event['link'] . (!$event['is_last'] ? ', ' : '');
  1868.         }
  1869. }
  1870.  
  1871. // Check the passed id_member/password.  If $is_username is true, treats $id as a username.
  1872. function ssi_checkPassword($id = null, $password = null, $is_username = false)
  1873. {
  1874.     global $db_prefix, $sourcedir, $smcFunc;
  1875.  
  1876.     // If $id is null, this was most likely called from a query string and should do nothing.
  1877.     if ($id === null)
  1878.         return;
  1879.  
  1880.     $request = $smcFunc['db_query']('', '
  1881.         SELECT passwd, member_name, is_activated
  1882.         FROM {db_prefix}members
  1883.         WHERE ' . ($is_username ? 'member_name' : 'id_member') . ' = {string:id}
  1884.         LIMIT 1',
  1885.         array(
  1886.             'id' => $id,
  1887.         )
  1888.     );
  1889.     list ($pass, $user, $active) = $smcFunc['db_fetch_row']($request);
  1890.     $smcFunc['db_free_result']($request);
  1891.  
  1892.     return sha1(strtolower($user) . $password) == $pass && $active == 1;
  1893. }
  1894.  
  1895. // We want to show the recent attachments outside of the forum.
  1896. function ssi_recentAttachments($num_attachments = 10, $attachment_ext = array(), $output_method = 'echo')
  1897. {
  1898.     global $smcFunc, $context, $modSettings, $scripturl, $txt, $settings;
  1899.  
  1900.     // We want to make sure that we only get attachments for boards that we can see *if* any.
  1901.     $attachments_boards = boardsAllowedTo('view_attachments');
  1902.  
  1903.     // No boards?  Adios amigo.
  1904.     if (empty($attachments_boards))
  1905.         return array();
  1906.  
  1907.     // Is it an array?
  1908.     if (!is_array($attachment_ext))
  1909.         $attachment_ext = array($attachment_ext);
  1910.  
  1911.     // Lets build the query.
  1912.     $request = $smcFunc['db_query']('', '
  1913.         SELECT
  1914.             att.id_attach, att.id_msg, att.filename, IFNULL(att.size, 0) AS filesize, att.downloads, mem.id_member,
  1915.             IFNULL(mem.real_name, m.poster_name) AS poster_name, m.id_topic, m.subject, t.id_board, m.poster_time,
  1916.             att.width, att.height' . (empty($modSettings['attachmentShowImages']) || empty($modSettings['attachmentThumbnails']) ? '' : ', IFNULL(thumb.id_attach, 0) AS id_thumb, thumb.width AS thumb_width, thumb.height AS thumb_height') . '
  1917.         FROM {db_prefix}attachments AS att
  1918.             INNER JOIN {db_prefix}messages AS m ON (m.id_msg = att.id_msg)
  1919.             INNER JOIN {db_prefix}topics AS t ON (t.id_topic = m.id_topic)
  1920.             LEFT JOIN {db_prefix}members AS mem ON (mem.id_member = m.id_member)' . (empty($modSettings['attachmentShowImages']) || empty($modSettings['attachmentThumbnails']) ? '' : '
  1921.             LEFT JOIN {db_prefix}attachments AS thumb ON (thumb.id_attach = att.id_thumb)') . '
  1922.         WHERE att.attachment_type = 0' . ($attachments_boards === array(0) ? '' : '
  1923.             AND m.id_board IN ({array_int:boards_can_see})') . (!empty($attachment_ext) ? '
  1924.             AND att.fileext IN ({array_string:attachment_ext})' : '') .
  1925.             (!$modSettings['postmod_active'] || allowedTo('approve_posts') ? '' : '
  1926.             AND t.approved = {int:is_approved}
  1927.             AND m.approved = {int:is_approved}
  1928.             AND att.approved = {int:is_approved}') . '
  1929.         ORDER BY att.id_attach DESC
  1930.         LIMIT {int:num_attachments}',
  1931.         array(
  1932.             'boards_can_see' => $attachments_boards,
  1933.             'attachment_ext' => $attachment_ext,
  1934.             'num_attachments' => $num_attachments,
  1935.             'is_approved' => 1,
  1936.         )
  1937.     );
  1938.  
  1939.     // We have something.
  1940.     $attachments = array();
  1941.     while ($row = $smcFunc['db_fetch_assoc']($request))
  1942.     {
  1943.         $filename = preg_replace('~&amp;#(\\d{1,7}|x[0-9a-fA-F]{1,6});~', '&#\\1;', htmlspecialchars($row['filename']));
  1944.  
  1945.         // Is it an image?
  1946.         $attachments[$row['id_attach']] = array(
  1947.             'member' => array(
  1948.                 'id' => $row['id_member'],
  1949.                 'name' => $row['poster_name'],
  1950.                 'link' => empty($row['id_member']) ? $row['poster_name'] : '<a href="' . $scripturl . '?action=profile;u=' . $row['id_member'] . '">' . $row['poster_name'] . '</a>',
  1951.             ),
  1952.             'file' => array(
  1953.                 'filename' => $filename,
  1954.                 'filesize' => round($row['filesize'] /1024, 2) . $txt['kilobyte'],
  1955.                 'downloads' => $row['downloads'],
  1956.                 'href' => $scripturl . '?action=dlattach;topic=' . $row['id_topic'] . '.0;attach=' . $row['id_attach'],
  1957.                 'link' => '<img src="' . $settings['images_url'] . '/icons/clip.gif" alt="" /> <a href="' . $scripturl . '?action=dlattach;topic=' . $row['id_topic'] . '.0;attach=' . $row['id_attach'] . '">' . $filename . '</a>',
  1958.                 'is_image' => !empty($row['width']) && !empty($row['height']) && !empty($modSettings['attachmentShowImages']),
  1959.             ),
  1960.             'topic' => array(
  1961.                 'id' => $row['id_topic'],
  1962.                 'subject' => $row['subject'],
  1963.                 'href' => $scripturl . '?topic=' . $row['id_topic'] . '.msg' . $row['id_msg'] . '#msg' . $row['id_msg'],
  1964.                 'link' => '<a href="' . $scripturl . '?topic=' . $row['id_topic'] . '.msg' . $row['id_msg'] . '#msg' . $row['id_msg'] . '">' . $row['subject'] . '</a>',
  1965.                 'time' => timeformat($row['poster_time']),
  1966.             ),
  1967.         );
  1968.  
  1969.         // Images.
  1970.         if ($attachments[$row['id_attach']]['file']['is_image'])
  1971.         {
  1972.             $id_thumb = empty($row['id_thumb']) ? $row['id_attach'] : $row['id_thumb'];
  1973.             $attachments[$row['id_attach']]['file']['image'] = array(
  1974.                 'id' => $id_thumb,
  1975.                 'width' => $row['width'],
  1976.                 'height' => $row['height'],
  1977.                 'img' => '<img src="' . $scripturl . '?action=dlattach;topic=' . $row['id_topic'] . '.0;attach=' . $row['id_attach'] . ';image" alt="' . $filename . '" />',
  1978.                 'thumb' => '<img src="' . $scripturl . '?action=dlattach;topic=' . $row['id_topic'] . '.0;attach=' . $id_thumb . ';image" alt="' . $filename . '" />',
  1979.                 'href' => $scripturl . '?action=dlattach;topic=' . $row['id_topic'] . '.0;attach=' . $id_thumb . ';image',
  1980.                 'link' => '<a href="' . $scripturl . '?action=dlattach;topic=' . $row['id_topic'] . '.0;attach=' . $row['id_attach'] . ';image"><img src="' . $scripturl . '?action=dlattach;topic=' . $row['id_topic'] . '.0;attach=' . $id_thumb . ';image" alt="' . $filename . '" /></a>',
  1981.             );
  1982.         }
  1983.     }
  1984.     $smcFunc['db_free_result']($request);
  1985.  
  1986.     // So you just want an array?  Here you can have it.
  1987.     if ($output_method == 'array' || empty($attachments))
  1988.         return $attachments;
  1989.  
  1990.     // Give them the default.
  1991.     echo '
  1992.         <table class="ssi_downloads" cellpadding="2">
  1993.             <tr>
  1994.                 <th align="left">', $txt['file'], '</th>
  1995.                 <th align="left">', $txt['posted_by'], '</th>
  1996.                 <th align="left">', $txt['downloads'], '</th>
  1997.                 <th align="left">', $txt['filesize'], '</th>
  1998.             </tr>';
  1999.     foreach ($attachments as $attach)
  2000.         echo '
  2001.             <tr>
  2002.                 <td>', $attach['file']['link'], '</td>
  2003.                 <td>', $attach['member']['link'], '</td>
  2004.                 <td align="center">', $attach['file']['downloads'], '</td>
  2005.                 <td>', $attach['file']['filesize'], '</td>
  2006.             </tr>';
  2007.     echo '
  2008.         </table>';
  2009. }
  2010.  
  2011. ?>
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement