/**
 * Get legacy karma value for member id
 * @param int $member_id
 * @return array|bool
 */
function getLegacyKarmaByMemberID($member_id = 0)
{
    global $smcFunc;
    if (!$member_id) {
        return false;
    }
    // Check cache
    $legacyKarma = cache_get_data('legacyKarma_' . $member_id);
    if (empty($legacyKarma)) {
        $request = $smcFunc['db_query']('', '
			SELECT karma_good, karma_bad
			FROM {db_prefix}members
			WHERE id_member = {int:member_id}
			LIMIT 1', array('member_id' => $member_id));
        $legacyKarma = array();
        list($legacyKarma['good'], $legacyKarma['bad']) = $smcFunc['db_fetch_row']($request);
        $smcFunc['db_free_result']($request);
        cache_put_data('legacyKarma_' . $member_id, $legacyKarma);
    }
    if (!empty($legacyKarma['good']) || !empty($legacyKarma['bad'])) {
        return (!empty($legacyKarma['good']) ? '+' . $legacyKarma['good'] : '') . (!empty($legacyKarma['good']) && !empty($legacyKarma['bad']) ? '/' : '') . (!empty($legacyKarma['bad']) ? '-' . $legacyKarma['bad'] : '');
    } else {
        return false;
    }
}
 public static function load_theme()
 {
     global $context, $modSettings, $txt, $settings, $user_info;
     if (($themes = cache_get_data('TS_themes_list', 3600)) === null) {
         loadLanguage('ManageThemes');
         require_once SUBSDIR . '/Themes.subs.php';
         $themes = availableThemes($user_info['theme'], $user_info['id']);
         cache_put_data('TS_themes_list', $themes, 3600);
     }
     foreach ($themes[0] as $theme_id => $theme) {
         $name = $theme['name'];
         $selected = !empty($user_info['theme']) && $user_info['theme'] == $theme_id;
         $context['ThemeSelector'][$theme_id] = array('name' => $name, 'selected' => $selected, 'variants' => array());
         if (isset($theme['variants'])) {
             foreach ($theme['variants'] as $key => $variant) {
                 $context['ThemeSelector'][$theme_id]['variants'][$key] = array('name' => $variant['label'], 'selected' => $context['theme_variant'] == '_' . $key);
             }
         }
     }
     if (!isset($context['theme_header_callbacks'])) {
         $context['theme_header_callbacks'] = array();
     }
     $context['theme_header_callbacks'][] = 'themeselector';
     loadTemplate('ThemeSelector');
     loadJavascriptFile('ThemeSelector.js');
     loadCSSFile('ThemeSelector.css');
 }
Beispiel #3
0
/**
 * Try to retrieve a cache entry. On failure, call the appropriate function.
 * This callback is sent as $file to include, and $function to call, with
 * $params parameters.
 *
 * @param string $key cache entry key
 * @param string $file file to include
 * @param string $function function to call
 * @param mixed[] $params parameters sent to the function
 * @param int $level = 1
 * @return string
 */
function cache_quick_get($key, $file, $function, $params, $level = 1)
{
    global $modSettings;
    // @todo Why are we doing this if caching is disabled?
    if (function_exists('call_integration_hook')) {
        call_integration_hook('pre_cache_quick_get', array(&$key, &$file, &$function, &$params, &$level));
    }
    /* Refresh the cache if either:
    		1. Caching is disabled.
    		2. The cache level isn't high enough.
    		3. The item has not been cached or the cached item expired.
    		4. The cached item has a custom expiration condition evaluating to true.
    		5. The expire time set in the cache item has passed (needed for Zend).
    	*/
    if (empty($modSettings['cache_enable']) || $modSettings['cache_enable'] < $level || !is_array($cache_block = cache_get_data($key, 3600)) || !empty($cache_block['refresh_eval']) && eval($cache_block['refresh_eval']) || !empty($cache_block['expires']) && $cache_block['expires'] < time()) {
        require_once SOURCEDIR . '/' . $file;
        $cache_block = call_user_func_array($function, $params);
        if (!empty($modSettings['cache_enable']) && $modSettings['cache_enable'] >= $level) {
            cache_put_data($key, $cache_block, $cache_block['expires'] - time());
        }
    }
    // Some cached data may need a freshening up after retrieval.
    if (!empty($cache_block['post_retri_eval'])) {
        eval($cache_block['post_retri_eval']);
    }
    if (function_exists('call_integration_hook')) {
        call_integration_hook('post_cache_quick_get', array($cache_block));
    }
    return $cache_block['data'];
}
Beispiel #4
0
function template_init()
{
    global $context, $settings, $options, $txt, $modSettings;
    $settings['use_default_images'] = 'never';
    $settings['doctype'] = 'html';
    $settings['theme_version'] = '2.0';
    $settings['use_tabs'] = true;
    $settings['use_buttons'] = true;
    $settings['separate_sticky_lock'] = true;
    $settings['strict_doctype'] = false;
    $settings['message_index_preview'] = true;
    $settings['require_theme_strings'] = true;
    $settings['alphathemes'] = true;
    if (($settings['tp_boardicons'] = cache_get_data('alpha_boardicons', 2)) == null) {
        $settings['tp_boardicons'] = my_readfolder($settings['theme_dir'] . '/images/boardicons', $settings['theme_url'] . '/images/boardicons', '.png');
        cache_put_data('alpha_boardicons', $settings['tp_boardicons'], 2);
    }
    $settings['extra_copyrights'] = array('<b>ShelfLife</b> theme &copy; 2015, BK');
    $settings['catch_action'] = array('layers' => array('wrapinit', 'html', 'body', 'wrap'));
    /* all modules possible
    	$settings['module_display'] = '';
    	$settings['module_boardindex'] = '';
    	$settings['module_messageindex'] = '';
    	$settings['module_profile'] = '';
    	$settings['module_pm'] = '';
    	*/
    // can be board-based.
}
/**
 * Loads all the shouts for a given shoutbox
 *
 * @param int $shoutbox id of the shoutbox to get data from
 * @param mixed[] $parameters
 *
 * @return type
 */
function sportal_get_shouts($shoutbox, $parameters)
{
    global $scripturl, $context, $user_info, $modSettings, $txt;
    $db = database();
    // Set defaults or used what was passed
    $shoutbox = !empty($shoutbox) ? (int) $shoutbox : 0;
    $start = !empty($parameters['start']) ? (int) $parameters['start'] : 0;
    $limit = !empty($parameters['limit']) ? (int) $parameters['limit'] : 20;
    $bbc = !empty($parameters['bbc']) ? $parameters['bbc'] : array();
    $reverse = !empty($parameters['reverse']);
    $cache = !empty($parameters['cache']);
    $can_delete = !empty($parameters['can_moderate']);
    // Cached, use it first
    if (!empty($start) || !$cache || ($shouts = cache_get_data('shoutbox_shouts-' . $shoutbox, 240)) === null) {
        $request = $db->query('', '
			SELECT
				sh.id_shout, sh.body, IFNULL(mem.id_member, 0) AS id_member,
				IFNULL(mem.real_name, sh.member_name) AS member_name, sh.log_time,
				mg.online_color AS member_group_color, pg.online_color AS post_group_color
			FROM {db_prefix}sp_shouts AS sh
				LEFT JOIN {db_prefix}members AS mem ON (mem.id_member = sh.id_member)
				LEFT JOIN {db_prefix}membergroups AS pg ON (pg.id_group = mem.id_post_group)
				LEFT JOIN {db_prefix}membergroups AS mg ON (mg.id_group = mem.id_group)
			WHERE sh.id_shoutbox = {int:id_shoutbox}
			ORDER BY sh.id_shout DESC
			LIMIT {int:start}, {int:limit}', array('id_shoutbox' => $shoutbox, 'start' => $start, 'limit' => $limit));
        $shouts = array();
        while ($row = $db->fetch_assoc($request)) {
            // Disable the aeva mod for the shoutbox.
            $context['aeva_disable'] = true;
            $online_color = !empty($row['member_group_color']) ? $row['member_group_color'] : $row['post_group_color'];
            $shouts[$row['id_shout']] = array('id' => $row['id_shout'], 'author' => array('id' => $row['id_member'], 'name' => $row['member_name'], 'link' => $row['id_member'] ? '<a href="' . $scripturl . '?action=profile;u=' . $row['id_member'] . '" title="' . $txt['on'] . ' ' . strip_tags(standardTime($row['log_time'])) . '"' . (!empty($online_color) ? ' style="color: ' . $online_color . ';"' : '') . '>' . $row['member_name'] . '</a>' : $row['member_name'], 'color' => $online_color), 'time' => $row['log_time'], 'text' => parse_bbc($row['body'], true, '', $bbc));
        }
        $db->free_result($request);
        if (empty($start) && $cache) {
            cache_put_data('shoutbox_shouts-' . $shoutbox, $shouts, 240);
        }
    }
    foreach ($shouts as $shout) {
        // Private shouts @username: only get shown to the shouter and shoutee, and the admin
        if (preg_match('~^@(.+?): ~u', $shout['text'], $target) && Util::strtolower($target[1]) !== Util::strtolower($user_info['name']) && $shout['author']['id'] != $user_info['id'] && !$user_info['is_admin']) {
            unset($shouts[$shout['id']]);
            continue;
        }
        $shouts[$shout['id']] += array('is_me' => preg_match('~^<div\\sclass="meaction">\\* ' . preg_quote($shout['author']['name'], '~') . '.+</div>$~', $shout['text']) != 0, 'delete_link' => $can_delete ? '<a class="dot dotdelete" href="' . $scripturl . '?action=shoutbox;shoutbox_id=' . $shoutbox . ';delete=' . $shout['id'] . ';' . $context['session_var'] . '=' . $context['session_id'] . '"></a> ' : '', 'delete_link_js' => $can_delete ? '<a class="dot dotdelete" href="' . $scripturl . '?action=shoutbox;shoutbox_id=' . $shoutbox . ';delete=' . $shout['id'] . ';' . $context['session_var'] . '=' . $context['session_id'] . '" onclick="sp_delete_shout(' . $shoutbox . ', ' . $shout['id'] . ', \'' . $context['session_var'] . '\', \'' . $context['session_id'] . '\'); return false;"></a> ' : '');
        // Prepare for display in the box
        $shouts[$shout['id']]['time'] = standardTime($shouts[$shout['id']]['time']);
        $shouts[$shout['id']]['text'] = preg_replace('~(</?)div([^<]*>)~', '$1span$2', $shouts[$shout['id']]['text']);
        $shouts[$shout['id']]['text'] = preg_replace('~<a([^>]+>)([^<]+)</a>~', '<a$1' . $txt['sp_link'] . '</a>', $shouts[$shout['id']]['text']);
        $shouts[$shout['id']]['text'] = censorText($shouts[$shout['id']]['text']);
        // Ignored user, hide the shout with option to show it
        if (!empty($modSettings['enable_buddylist']) && in_array($shout['author']['id'], $context['user']['ignoreusers'])) {
            $shouts[$shout['id']]['text'] = '<a href="#toggle" id="ignored_shout_link_' . $shout['id'] . '" onclick="sp_show_ignored_shout(' . $shout['id'] . '); return false;">[' . $txt['sp_shoutbox_show_ignored'] . ']</a><span id="ignored_shout_' . $shout['id'] . '" style="display: none;">' . $shouts[$shout['id']]['text'] . '</span>';
        }
    }
    if ($reverse) {
        $shouts = array_reverse($shouts);
    }
    return $shouts;
}
Beispiel #6
0
function akismet_load_theme()
{
    global $context, $topic;
    // Is this a topic being displayed?
    if (empty($_REQUEST['action']) && !empty($board) && !empty($topic)) {
        // Looking through the topic table can be slow, so try using the cache first.
        if (($spam = cache_get_data('akismet-spam-topic-' . $topic, 3600)) === NULL) {
            $request = $smcFunc['db_query']('', '
				SELECT id_topic
				FROM {db_prefix}topics
				WHERE id_topic = {int:id_topic}', array('id_topic' => $topic));
            // So did it find anything?
            if ($smcFunc['db_num_rows']($request)) {
                list($spam) = $smcFunc['db_fetch_row']($request);
                $smcFunc['db_free_result']($request);
                // Save save save.
                cache_put_data('akismet-spam-topic-' . $topic, $spam, 120);
            }
        }
        if (!empty($span)) {
            // So we now know this is a spam topic. Show a warning.
            loadLanguage('Akismet');
            loadTemplate('Akismet');
            $context['template_layers'][] = 'akismet_warn_topic';
        }
    }
}
/**
 * Parse smileys in the passed message.
 *
 * What it does:
 * - The smiley parsing function which makes pretty faces appear :).
 * - If custom smiley sets are turned off by smiley_enable, the default set of smileys will be used.
 * - These are specifically not parsed in code tags [url=mailto:Dad@blah.com]
 * - Caches the smileys from the database or array in memory.
 * - Doesn't return anything, but rather modifies message directly.
 *
 * @param string $message
 */
function parsesmileys(&$message)
{
    global $modSettings, $txt, $user_info;
    static $smileyPregSearch = null, $smileyPregReplacements = array();
    // No smiley set at all?!
    if ($user_info['smiley_set'] == 'none' || trim($message) == '') {
        return;
    }
    // If smileyPregSearch hasn't been set, do it now.
    if (empty($smileyPregSearch)) {
        // Use the default smileys if it is disabled. (better for "portability" of smileys.)
        if (empty($modSettings['smiley_enable'])) {
            $smileysfrom = array('>:D', ':D', '::)', '>:(', ':))', ':)', ';)', ';D', ':(', ':o', '8)', ':P', '???', ':-[', ':-X', ':-*', ':\'(', ':-\\', '^-^', 'O0', 'C:-)', 'O:)');
            $smileysto = array('evil.gif', 'cheesy.gif', 'rolleyes.gif', 'angry.gif', 'laugh.gif', 'smiley.gif', 'wink.gif', 'grin.gif', 'sad.gif', 'shocked.gif', 'cool.gif', 'tongue.gif', 'huh.gif', 'embarrassed.gif', 'lipsrsealed.gif', 'kiss.gif', 'cry.gif', 'undecided.gif', 'azn.gif', 'afro.gif', 'police.gif', 'angel.gif');
            $smileysdescs = array('', $txt['icon_cheesy'], $txt['icon_rolleyes'], $txt['icon_angry'], $txt['icon_laugh'], $txt['icon_smiley'], $txt['icon_wink'], $txt['icon_grin'], $txt['icon_sad'], $txt['icon_shocked'], $txt['icon_cool'], $txt['icon_tongue'], $txt['icon_huh'], $txt['icon_embarrassed'], $txt['icon_lips'], $txt['icon_kiss'], $txt['icon_cry'], $txt['icon_undecided'], '', '', '', $txt['icon_angel']);
        } else {
            // Load the smileys in reverse order by length so they don't get parsed wrong.
            if (($temp = cache_get_data('parsing_smileys', 480)) == null) {
                $smileysfrom = array();
                $smileysto = array();
                $smileysdescs = array();
                // @todo there is no reason $db should be used before this
                $db = database();
                $db->fetchQueryCallback('
					SELECT code, filename, description
					FROM {db_prefix}smileys
					ORDER BY LENGTH(code) DESC', array(), function ($row) use(&$smileysfrom, &$smileysto, &$smileysdescs) {
                    $smileysfrom[] = $row['code'];
                    $smileysto[] = htmlspecialchars($row['filename']);
                    $smileysdescs[] = $row['description'];
                });
                cache_put_data('parsing_smileys', array($smileysfrom, $smileysto, $smileysdescs), 480);
            } else {
                list($smileysfrom, $smileysto, $smileysdescs) = $temp;
            }
        }
        // The non-breaking-space is a complex thing...
        $non_breaking_space = '\\x{A0}';
        // This smiley regex makes sure it doesn't parse smileys within code tags (so [url=mailto:David@bla.com] doesn't parse the :D smiley)
        $smileyPregReplacements = array();
        $searchParts = array();
        $smileys_path = htmlspecialchars($modSettings['smileys_url'] . '/' . $user_info['smiley_set'] . '/');
        for ($i = 0, $n = count($smileysfrom); $i < $n; $i++) {
            $specialChars = htmlspecialchars($smileysfrom[$i], ENT_QUOTES);
            $smileyCode = '<img src="' . $smileys_path . $smileysto[$i] . '" alt="' . strtr($specialChars, array(':' => '&#58;', '(' => '&#40;', ')' => '&#41;', '$' => '&#36;', '[' => '&#091;')) . '" title="' . strtr(htmlspecialchars($smileysdescs[$i]), array(':' => '&#58;', '(' => '&#40;', ')' => '&#41;', '$' => '&#36;', '[' => '&#091;')) . '" class="smiley" />';
            $smileyPregReplacements[$smileysfrom[$i]] = $smileyCode;
            $searchParts[] = preg_quote($smileysfrom[$i], '~');
            if ($smileysfrom[$i] != $specialChars) {
                $smileyPregReplacements[$specialChars] = $smileyCode;
                $searchParts[] = preg_quote($specialChars, '~');
            }
        }
        $smileyPregSearch = '~(?<=[>:\\?\\.\\s' . $non_breaking_space . '[\\]()*\\\\;]|^)(' . implode('|', $searchParts) . ')(?=[^[:alpha:]0-9]|$)~';
    }
    // Replace away!
    $message = preg_replace_callback($smileyPregSearch, function ($matches) use($smileyPregReplacements) {
        return $smileyPregReplacements[$matches[0]];
    }, $message);
}
function parse_smileys(&$message)
{
    global $modSettings, $txt, $user_info, $context, $smcFunc;
    static $smileyarray = array();
    // No smiley set at all?!
    if ($user_info['smiley_set'] == 'none' || trim($message) == '') {
        return;
    }
    // If the smiley array hasn't been set, do it now.
    if (empty($smileyarray)) {
        // Small fix because entities are getting messed up
        $smileyarray = array('&quot;' => '&quot;', '&apos;' => '&apos;', '&#039;' => '&#039;', '&lt;' => '&lt;', '&gt;' => '&gt;', '&amp;' => '&amp;');
        // Use the default smileys if it is disabled. (better for "portability" of smileys.)
        if (empty($modSettings['smiley_enable'])) {
            $smileysfrom = array('>:D', ':D', '::)', '>:(', ':))', ':)', ';)', ';D', ':(', ':o', '8)', ':P', '???', ':-[', ':-X', ':-*', ':\'(', ':-\\', '^-^', 'O0', 'C:-)', '0:)');
            $smileysto = array('evil.gif', 'cheesy.gif', 'rolleyes.gif', 'angry.gif', 'laugh.gif', 'smiley.gif', 'wink.gif', 'grin.gif', 'sad.gif', 'shocked.gif', 'cool.gif', 'tongue.gif', 'huh.gif', 'embarrassed.gif', 'lipsrsealed.gif', 'kiss.gif', 'cry.gif', 'undecided.gif', 'azn.gif', 'afro.gif', 'police.gif', 'angel.gif');
            $smileysdescs = array('', $txt['icon_cheesy'], $txt['icon_rolleyes'], $txt['icon_angry'], '', $txt['icon_smiley'], $txt['icon_wink'], $txt['icon_grin'], $txt['icon_sad'], $txt['icon_shocked'], $txt['icon_cool'], $txt['icon_tongue'], $txt['icon_huh'], $txt['icon_embarrassed'], $txt['icon_lips'], $txt['icon_kiss'], $txt['icon_cry'], $txt['icon_undecided'], '', '', '', '');
        } else {
            // Load the smileys in reverse order by length so they don't get parsed wrong.
            if (($temp = cache_get_data('parsing_smileys', 480)) == null) {
                $result = $smcFunc['db_query']('', '
					SELECT code, filename, description
					FROM {db_prefix}smileys', array());
                $smileysfrom = array();
                $smileysto = array();
                $smileysdescs = array();
                while ($row = $smcFunc['db_fetch_assoc']($result)) {
                    $smileysfrom[] = $row['code'];
                    $smileysto[] = $row['filename'];
                    $smileysdescs[] = $row['description'];
                }
                $smcFunc['db_free_result']($result);
                cache_put_data('parsing_smileys', array($smileysfrom, $smileysto, $smileysdescs), 480);
            } else {
                list($smileysfrom, $smileysto, $smileysdescs) = $temp;
            }
        }
        foreach ($smileysfrom as $i => $from) {
            $smileyCode = '<img src="' . $modSettings['smileys_url'] . '/' . $user_info['smiley_set'] . '/' . $smileysto[$i] . '" alt="' . htmlentities($from) . '" title="' . htmlentities($smileysdescs[$i]) . '" class="smiley" />';
            $smileyarray[$from] = $smileyCode;
            if ($from != ($specialChars = htmlspecialchars($from, ENT_QUOTES))) {
                $smileyarray[$specialChars] = $smileyCode;
            }
        }
    }
    // Replace away!
    $message = strtr($message, $smileyarray);
}
/**
 * Loads information about the users personal message limit.
 *
 * @package PersonalMessage
 */
function loadMessageLimit()
{
    global $user_info, $context;
    $db = database();
    if ($user_info['is_admin']) {
        $context['message_limit'] = 0;
    } elseif (($context['message_limit'] = cache_get_data('msgLimit:' . $user_info['id'], 360)) === null) {
        $request = $db->query('', '
			SELECT
				MAX(max_messages) AS top_limit, MIN(max_messages) AS bottom_limit
			FROM {db_prefix}membergroups
			WHERE id_group IN ({array_int:users_groups})', array('users_groups' => $user_info['groups']));
        list($maxMessage, $minMessage) = $db->fetch_row($request);
        $db->free_result($request);
        $context['message_limit'] = $minMessage == 0 ? 0 : $maxMessage;
        // Save us doing it again!
        cache_put_data('msgLimit:' . $user_info['id'], $context['message_limit'], 360);
    }
}
Beispiel #10
0
function loadArcadeSettings()
{
    global $arcSettings, $modSettings, $smcFunc;
    if (($arcSettings = cache_get_data('arcSettings', 90)) == null) {
        $request = $smcFunc['db_query']('', '
			SELECT variable, value
			FROM {db_prefix}arcade_settings', array());
        $arcSettings = array();
        if (!$request) {
            db_fatal_error();
        }
        while ($row = $smcFunc['db_fetch_row']($request)) {
            $arcSettings[$row[0]] = $row[1];
        }
        $smcFunc['db_free_result']($request);
        if (!empty($modSettings['cache_enable'])) {
            cache_put_data('arcSettings', $arcSettings, 90);
        }
    }
}
Beispiel #11
0
function setupMenuContext()
{
    global $context, $modSettings, $user_info, $txt, $scripturl;
    // Set up the menu privileges.
    $context['allow_search'] = allowedTo('search_posts');
    $context['allow_admin'] = allowedTo(array('admin_forum', 'manage_boards', 'manage_permissions', 'moderate_forum', 'manage_membergroups', 'manage_bans', 'send_mail', 'edit_news', 'manage_attachments', 'manage_smileys'));
    $context['allow_edit_profile'] = !$user_info['is_guest'] && allowedTo(array('profile_view_own', 'profile_view_any', 'profile_identity_own', 'profile_identity_any', 'profile_extra_own', 'profile_extra_any', 'profile_remove_own', 'profile_remove_any', 'moderate_forum', 'manage_membergroups', 'profile_title_own', 'profile_title_any'));
    $context['allow_memberlist'] = allowedTo('view_mlist');
    $context['allow_calendar'] = allowedTo('calendar_view') && !empty($modSettings['cal_enabled']);
    $context['allow_moderation_center'] = $context['user']['can_mod'];
    $context['allow_pm'] = allowedTo('pm_read');
    $cacheTime = $modSettings['lastActive'] * 60;
    // All the buttons we can possible want and then some, try pulling the final list of buttons from cache first.
    if (($menu_buttons = cache_get_data('menu_buttons-' . implode('_', $user_info['groups']) . '-' . $user_info['language'], $cacheTime)) === null || time() - $cacheTime <= $modSettings['settings_updated']) {
        $buttons = array('home' => array('title' => $txt['home'], 'href' => $scripturl, 'show' => true, 'sub_buttons' => array(), 'is_last' => $context['right_to_left']), 'help' => array('title' => $txt['help'], 'href' => $scripturl . '?action=help', 'show' => true, 'sub_buttons' => array()), 'search' => array('title' => $txt['search'], 'href' => $scripturl . '?action=search', 'show' => $context['allow_search'], 'sub_buttons' => array()), 'admin' => array('title' => $txt['admin'], 'href' => $scripturl . '?action=admin', 'show' => $context['allow_admin'], 'sub_buttons' => array('featuresettings' => array('title' => $txt['modSettings_title'], 'href' => $scripturl . '?action=admin;area=featuresettings', 'show' => allowedTo('admin_forum')), 'packages' => array('title' => $txt['package'], 'href' => $scripturl . '?action=admin;area=packages', 'show' => allowedTo('admin_forum')), 'errorlog' => array('title' => $txt['errlog'], 'href' => $scripturl . '?action=admin;area=logs;sa=errorlog;desc', 'show' => allowedTo('admin_forum') && !empty($modSettings['enableErrorLogging'])), 'permissions' => array('title' => $txt['edit_permissions'], 'href' => $scripturl . '?action=admin;area=permissions', 'show' => allowedTo('manage_permissions'), 'is_last' => true))), 'moderate' => array('title' => $txt['moderate'], 'href' => $scripturl . '?action=moderate', 'show' => $context['allow_moderation_center'], 'sub_buttons' => array('modlog' => array('title' => $txt['modlog_view'], 'href' => $scripturl . '?action=moderate;area=modlog', 'show' => !empty($modSettings['modlog_enabled']) && !empty($user_info['mod_cache']) && $user_info['mod_cache']['bq'] != '0=1'), 'poststopics' => array('title' => $txt['mc_unapproved_poststopics'], 'href' => $scripturl . '?action=moderate;area=postmod;sa=posts', 'show' => $modSettings['postmod_active'] && !empty($user_info['mod_cache']['ap'])), 'attachments' => array('title' => $txt['mc_unapproved_attachments'], 'href' => $scripturl . '?action=moderate;area=attachmod;sa=attachments', 'show' => $modSettings['postmod_active'] && !empty($user_info['mod_cache']['ap'])), 'reports' => array('title' => $txt['mc_reported_posts'], 'href' => $scripturl . '?action=moderate;area=reports', 'show' => !empty($user_info['mod_cache']) && $user_info['mod_cache']['bq'] != '0=1', 'is_last' => true))), 'profile' => array('title' => $txt['profile'], 'href' => $scripturl . '?action=profile', 'show' => $context['allow_edit_profile'], 'sub_buttons' => array('summary' => array('title' => $txt['summary'], 'href' => $scripturl . '?action=profile', 'show' => true), 'account' => array('title' => $txt['account'], 'href' => $scripturl . '?action=profile;area=account', 'show' => allowedTo(array('profile_identity_any', 'profile_identity_own', 'manage_membergroups'))), 'profile' => array('title' => $txt['forumprofile'], 'href' => $scripturl . '?action=profile;area=forumprofile', 'show' => allowedTo(array('profile_extra_any', 'profile_extra_own')), 'is_last' => true))), 'pm' => array('title' => $txt['pm_short'], 'href' => $scripturl . '?action=pm', 'show' => $context['allow_pm'], 'sub_buttons' => array('pm_read' => array('title' => $txt['pm_menu_read'], 'href' => $scripturl . '?action=pm', 'show' => allowedTo('pm_read')), 'pm_send' => array('title' => $txt['pm_menu_send'], 'href' => $scripturl . '?action=pm;sa=send', 'show' => allowedTo('pm_send'), 'is_last' => true))), 'calendar' => array('title' => $txt['calendar'], 'href' => $scripturl . '?action=calendar', 'show' => $context['allow_calendar'], 'sub_buttons' => array('view' => array('title' => $txt['calendar_menu'], 'href' => $scripturl . '?action=calendar', 'show' => allowedTo('calendar_post')), 'post' => array('title' => $txt['calendar_post_event'], 'href' => $scripturl . '?action=calendar;sa=post', 'show' => allowedTo('calendar_post'), 'is_last' => true))), 'mlist' => array('title' => $txt['members_title'], 'href' => $scripturl . '?action=mlist', 'show' => $context['allow_memberlist'], 'sub_buttons' => array('mlist_view' => array('title' => $txt['mlist_menu_view'], 'href' => $scripturl . '?action=mlist', 'show' => true), 'mlist_search' => array('title' => $txt['mlist_search'], 'href' => $scripturl . '?action=mlist;sa=search', 'show' => true, 'is_last' => true))), 'login' => array('title' => $txt['login'], 'href' => $scripturl . '?action=login', 'show' => $user_info['is_guest'], 'sub_buttons' => array()), 'register' => array('title' => $txt['register'], 'href' => $scripturl . '?action=register', 'show' => $user_info['is_guest'], 'sub_buttons' => array(), 'is_last' => !$context['right_to_left']), 'logout' => array('title' => $txt['logout'], 'href' => $scripturl . '?action=logout;%1$s=%2$s', 'show' => !$user_info['is_guest'], 'sub_buttons' => array(), 'is_last' => !$context['right_to_left']));
        // Allow editing menu buttons easily.
        call_integration_hook('integrate_menu_buttons', array(&$buttons));
        // Now we put the buttons in the context so the theme can use them.
        $menu_buttons = array();
        foreach ($buttons as $act => $button) {
            if (!empty($button['show'])) {
                $button['active_button'] = false;
                // Make sure the last button truely is the last button.
                if (!empty($button['is_last'])) {
                    if (isset($last_button)) {
                        unset($menu_buttons[$last_button]['is_last']);
                    }
                    $last_button = $act;
                }
                // Go through the sub buttons if there are any.
                if (!empty($button['sub_buttons'])) {
                    foreach ($button['sub_buttons'] as $key => $subbutton) {
                        if (empty($subbutton['show'])) {
                            unset($button['sub_buttons'][$key]);
                        }
                        // 2nd level sub buttons next...
                        if (!empty($subbutton['sub_buttons'])) {
                            foreach ($subbutton['sub_buttons'] as $key2 => $sub_button2) {
                                if (empty($sub_button2['show'])) {
                                    unset($button['sub_buttons'][$key]['sub_buttons'][$key2]);
                                }
                            }
                        }
                    }
                }
                $menu_buttons[$act] = $button;
            }
        }
        if (!empty($modSettings['cache_enable']) && $modSettings['cache_enable'] >= 2) {
            cache_put_data('menu_buttons-' . implode('_', $user_info['groups']) . '-' . $user_info['language'], $menu_buttons, $cacheTime);
        }
    }
    $context['menu_buttons'] = $menu_buttons;
    // Logging out requires the session id in the url.
    if (isset($context['menu_buttons']['logout'])) {
        $context['menu_buttons']['logout']['href'] = sprintf($context['menu_buttons']['logout']['href'], $context['session_var'], $context['session_id']);
    }
    // Figure out which action we are doing so we can set the active tab.
    // Default to home.
    $current_action = 'home';
    if (isset($context['menu_buttons'][$context['current_action']])) {
        $current_action = $context['current_action'];
    } elseif ($context['current_action'] == 'search2') {
        $current_action = 'search';
    } elseif ($context['current_action'] == 'theme') {
        $current_action = isset($_REQUEST['sa']) && $_REQUEST['sa'] == 'pick' ? 'profile' : 'admin';
    } elseif ($context['current_action'] == 'register2') {
        $current_action = 'register';
    } elseif ($context['current_action'] == 'login2' || $user_info['is_guest'] && $context['current_action'] == 'reminder') {
        $current_action = 'login';
    } elseif ($context['current_action'] == 'groups' && $context['allow_moderation_center']) {
        $current_action = 'moderate';
    }
    $context['menu_buttons'][$current_action]['active_button'] = true;
    if (!$user_info['is_guest'] && $context['user']['unread_messages'] > 0 && isset($context['menu_buttons']['pm'])) {
        $context['menu_buttons']['pm']['alttitle'] = $context['menu_buttons']['pm']['title'] . ' [' . $context['user']['unread_messages'] . ']';
        $context['menu_buttons']['pm']['title'] .= ' [<strong>' . $context['user']['unread_messages'] . '</strong>]';
    }
}
Beispiel #12
0
function get_main_menu_groups()
{
    global $smcFunc;
    if (($groups = cache_get_data('char_main_menu_groups', 300)) === null) {
        $groups = [];
        $request = $smcFunc['db_query']('', '
			SELECT mg.id_group, mg.group_name
			FROM {db_prefix}membergroups AS mg
			INNER JOIN {db_prefix}characters AS chars ON (chars.main_char_group = mg.id_group)
			WHERE chars.char_sheet != 0
			GROUP BY mg.id_group
			ORDER BY mg.badge_order, mg.group_name');
        while ($row = $smcFunc['db_fetch_assoc']($request)) {
            $groups[$row['id_group']] = $row['group_name'];
        }
        $smcFunc['db_free_result']($request);
        cache_put_data('char_main_menu_groups', $groups, 300);
    }
    return $groups;
}
/**
 *	Defines user permissions, most importantly concerning ticket visibility
 *
 *	Populates specific parameters in $user_info, mostly to add {} abstract variables in $smcFunc['db_query'] data calls.
 *	The foremost one of these is {query_see_ticket}, an SQL clause constructed to ensure ticket visibility is maintained given the
 *	active user's permission set.
 *
 *	Prior to 1.1 this was in Subs-SimpleDesk.php
 *
 *	@see shd_db_query()
 *	@since 1.0
*/
function shd_load_user_perms()
{
    global $user_info, $context, $smcFunc, $modSettings;
    // OK, have we been here before? If we have, we're done.
    if (!empty($user_info['query_see_ticket'])) {
        return;
    }
    // Right, we're loading the current user.
    shd_load_role_templates();
    // If they're a guest, bail; if they're not a forum admin (who can do anything), figure out what permissions they have
    if (!empty($user_info['is_guest'])) {
        $user_info['shd_permissions'] = array();
        $user_info['query_see_ticket'] = '1=0';
        return;
    } elseif (empty($user_info['is_admin'])) {
        $permissions_cache = 'shd_permissions_' . implode('-', $user_info['groups']);
        $perm_cache_time = 300;
        $temp = cache_get_data($permissions_cache, $perm_cache_time);
        if ($temp === null || time() - $perm_cache_time > $modSettings['settings_updated']) {
            $role_permissions = array();
            // 1. Get all the roles that conceivably apply to this user.
            $query = $smcFunc['db_query']('', '
				SELECT hdrg.id_role, hdr.template
				FROM {db_prefix}helpdesk_role_groups AS hdrg
					INNER JOIN {db_prefix}helpdesk_roles AS hdr ON (hdrg.id_role = hdr.id_role)
				WHERE hdrg.id_group IN ({array_int:groups})', array('groups' => $user_info['groups']));
            $roles = array();
            while ($row = $smcFunc['db_fetch_assoc']($query)) {
                $role_permissions[$row['id_role']] = $context['shd_permissions']['roles'][$row['template']]['permissions'];
                $roles[$row['id_role']] = true;
            }
            $smcFunc['db_free_result']($query);
            // 1a. Get all the departments these roles are in.
            $depts = array();
            if (!empty($roles)) {
                $query = $smcFunc['db_query']('', '
					SELECT id_role, id_dept
					FROM {db_prefix}helpdesk_dept_roles
					WHERE id_role IN ({array_int:roles})', array('roles' => array_keys($roles)));
                while ($row = $smcFunc['db_fetch_assoc']($query)) {
                    $depts[$row['id_role']][] = $row['id_dept'];
                }
                $smcFunc['db_free_result']($query);
            }
            $denied = array();
            // 2.1. Apply role specific rules against their parent templates
            if (!empty($depts)) {
                $query = $smcFunc['db_query']('', '
					SELECT id_role, permission, add_type
					FROM {db_prefix}helpdesk_role_permissions
					WHERE id_role IN ({array_int:roles})', array('roles' => array_keys($roles)));
                while ($row = $smcFunc['db_fetch_assoc']($query)) {
                    if ($row['add_type'] == ROLEPERM_DENY) {
                        $denied[$row['permission']] = true;
                    } else {
                        $role_permissions[$row['id_role']][$row['permission']] = $row['add_type'];
                    }
                }
                $smcFunc['db_free_result']($query);
            }
            // 2.2 Having loaded all the roles, and applied role specific changes, fuse them all together
            $user_info['shd_permissions'] = array();
            if (!empty($depts) && !empty($role_permissions)) {
                foreach ($role_permissions as $role => $perm_list) {
                    if (empty($depts[$role])) {
                        continue;
                    }
                    foreach ($perm_list as $perm => $value) {
                        if ($value == ROLEPERM_ALLOW) {
                            $user_info['shd_permissions'][$perm] = isset($user_info['shd_permissions'][$perm]) ? array_merge($user_info['shd_permissions'][$perm], $depts[$role]) : $depts[$role];
                        }
                    }
                }
            }
            // 2.3 Apply any deny restrictions
            if (!empty($denied)) {
                foreach ($denied as $perm => $value) {
                    if (isset($user_info['shd_permissions'][$perm])) {
                        unset($user_info['shd_permissions'][$perm]);
                    }
                }
            }
            cache_put_data($permissions_cache, $user_info['shd_permissions'], $perm_cache_time);
        } else {
            $user_info['shd_permissions'] = $temp;
        }
    } elseif ($user_info['is_admin']) {
        // Figure out what departments there are, because these are the departments in which they have any given permission.
        $context['shd_depts_list'] = array();
        $query = $smcFunc['db_query']('', '
			SELECT id_dept
			FROM {db_prefix}helpdesk_depts');
        while ($row = $smcFunc['db_fetch_assoc']($query)) {
            $context['shd_depts_list'][] = (int) $row['id_dept'];
        }
        $smcFunc['db_free_result']($query);
    }
    $tickets_any_dept = shd_allowed_to('shd_view_ticket_any', false);
    $tickets_own_dept = shd_allowed_to('shd_view_ticket_own', false);
    if (!empty($tickets_any_dept) && !empty($tickets_own_dept)) {
        $tickets_own_dept = array_diff($tickets_any_dept, $tickets_own_dept);
    }
    if ($user_info['is_admin']) {
        $user_info['query_see_ticket'] = '1=1';
    } elseif (!shd_allowed_to('access_helpdesk', 0)) {
        $user_info['query_see_ticket'] = '1=0';
    } else {
        // What departments can we see private tickets in?
        $tickets_private_any_dept = shd_allowed_to('shd_view_ticket_private_any', false);
        $tickets_private_own_dept = shd_allowed_to('shd_view_ticket_private_own', false);
        $clauses = array();
        $privacy_clauses = array();
        // Departments where we can see anything. Requires the ability to see any ticket, plus any private.
        $tickets_any_private = array_intersect($tickets_any_dept, $tickets_private_any_dept);
        // Departments where we can see our own private tickets. Requires the ability to see any/own ticket in that department, plus own private.
        $tickets_own_private = array_intersect(array_merge($tickets_any_dept, $tickets_own_dept), $tickets_private_own_dept);
        // Departments where we can see any private tickets. Requires ability to see any ticket, then excludes matching private rule.
        $tickets_any_nonprivate = array_diff($tickets_any_dept, $tickets_any_private);
        // Departments where we can see our own non private tickets. Requires ability to see own ticket, excludes matching private rule.
        $tickets_own_nonprivate = array_diff($tickets_own_dept, $tickets_own_private);
        if (!empty($tickets_any_private)) {
            // Depts where we can see private tickets, thus we don't need to check anything else for this part.
            $privacy_clauses[] = '(hdt.id_dept IN (' . implode(',', $tickets_any_private) . '))';
        }
        if (!empty($tickets_own_private)) {
            // Depts where we can see our own private tickets, so need to validate id_dept and id_member_started, but we can discount checking private here.
            $privacy_clauses[] = '(hdt.id_dept IN (' . implode(',', $tickets_own_private) . ') AND hdt.id_member_started = {int:user_info_id})';
        }
        if (!empty($tickets_any_nonprivate)) {
            // Depts where we can see nonprivate tickets. We need to validate privacy on these but that's it.
            $privacy_clauses[] = '(hdt.id_dept IN (' . implode(',', $tickets_any_nonprivate) . ') AND hdt.private = 0)';
        }
        if (!empty($tickets_own_nonprivate)) {
            // Depts where we can see our own nonprivate tickets. Validate id_dept, id_member_started and private.
            $privacy_clauses[] = '(hdt.id_dept IN (' . implode(',', $tickets_own_nonprivate) . ') AND hdt.private = 0 AND hdt.id_member_started = {int:user_info_id})';
        }
        if (!empty($privacy_clauses)) {
            $clauses[] = implode(' OR ', $privacy_clauses);
        } else {
            $clauses[] = '1=0';
        }
        // Cannot access anything!
        // That's the core stuff done. We also need to ensure that closed tickets aren't visible either.
        $depts_closed_any = shd_allowed_to('shd_view_closed_any', false);
        $depts_closed_own = shd_allowed_to('shd_view_closed_own', false);
        $depts_closed_own = array_diff($depts_closed_own, $depts_closed_any);
        if (empty($depts_closed_any) && empty($depts_closed_own)) {
            // No access at all. Disable all access to closed tickets.
            $clauses[] = 'hdt.status != 3';
        } elseif (!empty($depts_closed_any) && empty($depts_closed_own)) {
            // Only where we can access 'all closed' but not 'any of our own closed', e.g. admins
            $clauses[] = 'hdt.status != 3 OR (hdt.status = 3 AND hdt.id_dept IN (' . implode(',', $depts_closed_any) . '))';
        } elseif (!empty($depts_closed_any) && !empty($depts_closed_own)) {
            // So we have a mixture
            $clauses[] = 'hdt.status != 3 OR (hdt.status = 3 AND (hdt.id_dept IN (' . implode(',', $depts_closed_any) . ') OR (hdt.id_member_started = {int:user_info_id} AND hdt.id_dept IN (' . implode(',', $depts_closed_own) . '))))';
        } elseif (empty($depts_closed_any) && !empty($depts_closed_own)) {
            // We can't ever see 'any', but we can see our own
            $clauses[] = 'hdt.status != 3 OR (hdt.status = 3 AND hdt.id_dept IN (' . implode(',', $depts_closed_own) . ') AND hdt.id_member_started = {int:user_info_id})';
        }
        // And finally, deleted tickets.
        $depts_deleted = shd_allowed_to('shd_access_recyclebin', false);
        if (empty($depts_deleted)) {
            $clauses[] = 'hdt.status != 6';
        } else {
            $clauses[] = 'hdt.status != 6 OR (hdt.status = 6 AND hdt.id_dept IN (' . implode(',', $depts_deleted) . '))';
        }
        // Finally, assemble into $user_info.
        if (empty($clauses)) {
            $user_info['query_see_ticket'] = '1=0';
        } else {
            $user_info['query_see_ticket'] = '((' . implode(') AND (', $clauses) . '))';
        }
    }
}
Beispiel #14
0
function cache_quick_get($key, $file, $function, $params, $level = 1)
{
    global $modSettings, $sourcedir;
    // Refresh the cache if either:
    // 1. Caching is disabled.
    // 2. The cache level isn't high enough.
    // 3. The item has not been cached or the cached item expired.
    // 4. The cached item has a custom expiration condition evaluating to true.
    // 5. The expire time set in the cache item has passed (needed for Zend).
    if (empty($modSettings['cache_enable']) || $modSettings['cache_enable'] < $level || !is_array($cache_block = cache_get_data($key, 3600)) || !empty($cache_block['refresh_eval']) && eval($cache_block['refresh_eval']) || !empty($cache_block['expires']) && $cache_block['expires'] < time()) {
        require_once $sourcedir . '/' . $file;
        $cache_block = call_user_func_array($function, $params);
        if (!empty($modSettings['cache_enable']) && $modSettings['cache_enable'] >= $level) {
            cache_put_data($key, $cache_block, $cache_block['expires'] - time());
        }
    }
    // Some cached data may need a freshening up after retrieval.
    if (!empty($cache_block['post_retri_eval'])) {
        eval($cache_block['post_retri_eval']);
    }
    return $cache_block['data'];
}
 /**
  * This has it's own custom search.
  *
  * @param mixed[] $search_params
  * @param mixed[] $search_words
  * @param string[] $excluded_words
  * @param int[] $participants
  * @param string[] $search_results
  */
 public function searchQuery($search_params, $search_words, $excluded_words, &$participants, &$search_results)
 {
     global $user_info, $context, $modSettings;
     // Only request the results if they haven't been cached yet.
     if (($cached_results = cache_get_data('searchql_results_' . md5($user_info['query_see_board'] . '_' . $context['params']))) === null) {
         // Create an instance of the sphinx client and set a few options.
         $mySphinx = @mysql_connect(($modSettings['sphinx_searchd_server'] === 'localhost' ? '127.0.0.1' : $modSettings['sphinx_searchd_server']) . ':' . (int) $modSettings['sphinxql_searchd_port']);
         // No connection, daemon not running?  log the error
         if ($mySphinx === false) {
             fatal_lang_error('error_no_search_daemon');
         }
         // Compile different options for our query
         $query = 'SELECT *' . (empty($search_params['topic']) ? ', COUNT(*) num' : '') . ', (weight() + (relevance/1000)) rank FROM elkarte_index';
         // Construct the (binary mode & |) query.
         $where_match = $this->_constructQuery($search_params['search']);
         // Nothing to search, return zero results
         if (trim($where_match) === '') {
             return 0;
         }
         if ($search_params['subject_only']) {
             $where_match = '@subject ' . $where_match;
         }
         $query .= ' WHERE MATCH(\'' . $where_match . '\')';
         // Set the limits based on the search parameters.
         $extra_where = array();
         if (!empty($search_params['min_msg_id']) || !empty($search_params['max_msg_id'])) {
             $extra_where[] = 'id >= ' . $search_params['min_msg_id'] . ' AND id <= ' . (empty($search_params['max_msg_id']) ? (int) $modSettings['maxMsgID'] : $search_params['max_msg_id']);
         }
         if (!empty($search_params['topic'])) {
             $extra_where[] = 'id_topic = ' . (int) $search_params['topic'];
         }
         if (!empty($search_params['brd'])) {
             $extra_where[] = 'id_board IN (' . implode(',', $search_params['brd']) . ')';
         }
         if (!empty($search_params['memberlist'])) {
             $extra_where[] = 'id_member IN (' . implode(',', $search_params['memberlist']) . ')';
         }
         if (!empty($extra_where)) {
             $query .= ' AND ' . implode(' AND ', $extra_where);
         }
         // Put together a sort string; besides the main column sort (relevance, id_topic, or num_replies)
         $search_params['sort_dir'] = strtoupper($search_params['sort_dir']);
         $sphinx_sort = $search_params['sort'] === 'id_msg' ? 'id_topic' : $search_params['sort'];
         // Add secondary sorting based on relevance value (if not the main sort method) and age
         $sphinx_sort .= ' ' . $search_params['sort_dir'] . ($search_params['sort'] === 'relevance' ? '' : ', relevance DESC') . ', poster_time DESC';
         // Replace relevance with the returned rank value, rank uses sphinx weight + our own computed field weight relevance
         $sphinx_sort = str_replace('relevance ', 'rank ', $sphinx_sort);
         // Grouping by topic id makes it return only one result per topic, so don't set that for in-topic searches
         if (empty($search_params['topic'])) {
             $query .= ' GROUP BY id_topic WITHIN GROUP ORDER BY ' . $sphinx_sort;
         }
         $query .= ' ORDER BY ' . $sphinx_sort;
         $query .= ' LIMIT 0,' . (int) $modSettings['sphinx_max_results'];
         // Set any options needed, like field weights
         $query .= ' OPTION field_weights=(subject=' . (!empty($modSettings['search_weight_subject']) ? $modSettings['search_weight_subject'] * 200 : 1000) . ',body=1000)';
         // Execute the search query.
         $request = mysql_query($query, $mySphinx);
         // Can a connection to the daemon be made?
         if ($request === false) {
             // Just log the error.
             if (mysql_error($mySphinx)) {
                 log_error(mysql_error($mySphinx));
             }
             fatal_lang_error('error_no_search_daemon');
         }
         // Get the relevant information from the search results.
         $cached_results = array('num_results' => 0, 'matches' => array());
         if (mysql_num_rows($request) != 0) {
             while ($match = mysql_fetch_assoc($request)) {
                 if (empty($search_params['topic'])) {
                     $num = isset($match['num']) ? $match['num'] : (isset($match['@count']) ? $match['@count'] : 0);
                 } else {
                     $num = 0;
                 }
                 $cached_results['matches'][$match['id']] = array('id' => $match['id_topic'], 'relevance' => round($match['relevance'] / 10000, 1) . '%', 'num_matches' => $num, 'matches' => array());
             }
         }
         mysql_free_result($request);
         mysql_close($mySphinx);
         $cached_results['num_results'] = count($cached_results['matches']);
         // Store the search results in the cache.
         cache_put_data('searchql_results_' . md5($user_info['query_see_board'] . '_' . $context['params']), $cached_results, 600);
     }
     $participants = array();
     foreach (array_slice(array_keys($cached_results['matches']), $_REQUEST['start'], $modSettings['search_results_per_page']) as $msgID) {
         $context['topics'][$msgID] = $cached_results['matches'][$msgID];
         $participants[$cached_results['matches'][$msgID]['id']] = false;
     }
     // Sentences need to be broken up in words for proper highlighting.
     $search_results = array();
     foreach ($search_words as $orIndex => $words) {
         $search_results = array_merge($search_results, $search_words[$orIndex]['subject_words']);
     }
     return $cached_results['num_results'];
 }
Beispiel #16
0
function theme_postbox($msg)
{
    global $txt, $modSettings, $db_prefix;
    global $context, $settings, $user_info;
    // Switch between default images and back... mostly in case you don't have an PersonalMessage template, but do ahve a Post template.
    if (isset($settings['use_default_images']) && $settings['use_default_images'] == 'defaults' && isset($settings['default_template'])) {
        $temp1 = $settings['theme_url'];
        $settings['theme_url'] = $settings['default_theme_url'];
        $temp2 = $settings['images_url'];
        $settings['images_url'] = $settings['default_images_url'];
        $temp3 = $settings['theme_dir'];
        $settings['theme_dir'] = $settings['default_theme_dir'];
    }
    // Load the Post template and language file.
    loadLanguage('Post');
    loadTemplate('Post');
    // Initialize smiley array...
    $context['smileys'] = array('postform' => array(), 'popup' => array());
    // Load smileys - don't bother to run a query if we're not using the database's ones anyhow.
    if (empty($modSettings['smiley_enable']) && $user_info['smiley_set'] != 'none') {
        $context['smileys']['postform'][] = array('smileys' => array(array('code' => ':)', 'filename' => 'smiley.gif', 'description' => $txt[287]), array('code' => ';)', 'filename' => 'wink.gif', 'description' => $txt[292]), array('code' => ':D', 'filename' => 'cheesy.gif', 'description' => $txt[289]), array('code' => ';D', 'filename' => 'grin.gif', 'description' => $txt[293]), array('code' => '>:(', 'filename' => 'angry.gif', 'description' => $txt[288]), array('code' => ':(', 'filename' => 'sad.gif', 'description' => $txt[291]), array('code' => ':o', 'filename' => 'shocked.gif', 'description' => $txt[294]), array('code' => '8)', 'filename' => 'cool.gif', 'description' => $txt[295]), array('code' => '???', 'filename' => 'huh.gif', 'description' => $txt[296]), array('code' => '::)', 'filename' => 'rolleyes.gif', 'description' => $txt[450]), array('code' => ':P', 'filename' => 'tongue.gif', 'description' => $txt[451]), array('code' => ':-[', 'filename' => 'embarrassed.gif', 'description' => $txt[526]), array('code' => ':-X', 'filename' => 'lipsrsealed.gif', 'description' => $txt[527]), array('code' => ':-\\', 'filename' => 'undecided.gif', 'description' => $txt[528]), array('code' => ':-*', 'filename' => 'kiss.gif', 'description' => $txt[529]), array('code' => ':\'(', 'filename' => 'cry.gif', 'description' => $txt[530])), 'last' => true);
    } elseif ($user_info['smiley_set'] != 'none') {
        if (($temp = cache_get_data('posting_smileys', 480)) == null) {
            $request = db_query("\n\t\t\t\tSELECT code, filename, description, smileyRow, hidden\n\t\t\t\tFROM {$db_prefix}smileys\n\t\t\t\tWHERE hidden IN (0, 2)\n\t\t\t\tORDER BY smileyRow, smileyOrder", __FILE__, __LINE__);
            while ($row = mysql_fetch_assoc($request)) {
                $row['code'] = htmlspecialchars($row['code']);
                $row['filename'] = htmlspecialchars($row['filename']);
                $row['description'] = htmlspecialchars($row['description']);
                $context['smileys'][empty($row['hidden']) ? 'postform' : 'popup'][$row['smileyRow']]['smileys'][] = $row;
            }
            mysql_free_result($request);
            cache_put_data('posting_smileys', $context['smileys'], 480);
        } else {
            $context['smileys'] = $temp;
        }
    }
    // Clean house... add slashes to the code for javascript.
    foreach (array_keys($context['smileys']) as $location) {
        foreach ($context['smileys'][$location] as $j => $row) {
            $n = count($context['smileys'][$location][$j]['smileys']);
            for ($i = 0; $i < $n; $i++) {
                $context['smileys'][$location][$j]['smileys'][$i]['code'] = addslashes($context['smileys'][$location][$j]['smileys'][$i]['code']);
                $context['smileys'][$location][$j]['smileys'][$i]['js_description'] = addslashes($context['smileys'][$location][$j]['smileys'][$i]['description']);
            }
            $context['smileys'][$location][$j]['smileys'][$n - 1]['last'] = true;
        }
        if (!empty($context['smileys'][$location])) {
            $context['smileys'][$location][count($context['smileys'][$location]) - 1]['last'] = true;
        }
    }
    $settings['smileys_url'] = $modSettings['smileys_url'] . '/' . $user_info['smiley_set'];
    // Allow for things to be overridden.
    if (!isset($context['post_box_columns'])) {
        $context['post_box_columns'] = 60;
    }
    if (!isset($context['post_box_rows'])) {
        $context['post_box_rows'] = 12;
    }
    if (!isset($context['post_box_name'])) {
        $context['post_box_name'] = 'message';
    }
    if (!isset($context['post_form'])) {
        $context['post_form'] = 'postmodify';
    }
    // Set a flag so the sub template knows what to do...
    $context['show_bbc'] = !empty($modSettings['enableBBC']) && !empty($settings['show_bbc']);
    // Generate a list of buttons that shouldn't be shown - this should be the fastest way to do this.
    if (!empty($modSettings['disabledBBC'])) {
        $disabled_tags = explode(',', $modSettings['disabledBBC']);
        foreach ($disabled_tags as $tag) {
            $context['disabled_tags'][trim($tag)] = true;
        }
    }
    // Go!  Supa-sub-template-smash!
    template_postbox($msg);
    // Switch the URLs back... now we're back to whatever the main sub template is.  (like folder in PersonalMessage.)
    if (isset($settings['use_default_images']) && $settings['use_default_images'] == 'defaults' && isset($settings['default_template'])) {
        $settings['theme_url'] = $temp1;
        $settings['images_url'] = $temp2;
        $settings['theme_dir'] = $temp3;
    }
}
Beispiel #17
0
function ShowXmlFeed()
{
    global $db_prefix, $board, $board_info, $context, $scripturl, $txt, $modSettings, $user_info;
    global $query_this_board;
    // If it's not enabled, die.
    if (empty($modSettings['xmlnews_enable'])) {
        obExit(false);
    }
    loadLanguage('Stats');
    // Default to latest 5.  No more than 255, please.
    $_GET['limit'] = empty($_GET['limit']) || (int) $_GET['limit'] < 1 ? 5 : min((int) $_GET['limit'], 255);
    // Handle the cases where a board, boards, or category is asked for.
    if (!empty($_REQUEST['c']) && empty($board)) {
        $_REQUEST['c'] = explode(',', $_REQUEST['c']);
        foreach ($_REQUEST['c'] as $i => $c) {
            $_REQUEST['c'][$i] = (int) $c;
        }
        if (count($_REQUEST['c']) == 1) {
            $request = db_query("\n\t\t\t\tSELECT name\n\t\t\t\tFROM {$db_prefix}categories\n\t\t\t\tWHERE ID_CAT = " . (int) $_REQUEST['c'][0], __FILE__, __LINE__);
            list($feed_title) = mysql_fetch_row($request);
            mysql_free_result($request);
            $feed_title = ' - ' . strip_tags($feed_title);
        }
        $request = db_query("\n\t\t\tSELECT b.ID_BOARD, b.numPosts\n\t\t\tFROM {$db_prefix}boards AS b\n\t\t\tWHERE b.ID_CAT IN (" . implode(', ', $_REQUEST['c']) . ")\n\t\t\t\tAND {$user_info['query_see_board']}", __FILE__, __LINE__);
        $total_cat_posts = 0;
        $boards = array();
        while ($row = mysql_fetch_assoc($request)) {
            $boards[] = $row['ID_BOARD'];
            $total_cat_posts += $row['numPosts'];
        }
        mysql_free_result($request);
        if (!empty($boards)) {
            $query_this_board = 'b.ID_BOARD IN (' . implode(', ', $boards) . ')';
        }
        // Try to limit the number of messages we look through.
        if ($total_cat_posts > 100 && $total_cat_posts > $modSettings['totalMessages'] / 15) {
            $query_this_board .= '
			AND m.ID_MSG >= ' . max(0, $modSettings['maxMsgID'] - 400 - $_GET['limit'] * 5);
        }
    } elseif (!empty($_REQUEST['boards'])) {
        $_REQUEST['boards'] = explode(',', $_REQUEST['boards']);
        foreach ($_REQUEST['boards'] as $i => $b) {
            $_REQUEST['boards'][$i] = (int) $b;
        }
        $request = db_query("\n\t\t\tSELECT b.ID_BOARD, b.numPosts, b.name\n\t\t\tFROM {$db_prefix}boards AS b\n\t\t\tWHERE b.ID_BOARD IN (" . implode(', ', $_REQUEST['boards']) . ")\n\t\t\t\tAND {$user_info['query_see_board']}\n\t\t\tLIMIT " . count($_REQUEST['boards']), __FILE__, __LINE__);
        // Either the board specified doesn't exist or you have no access.
        if (mysql_num_rows($request) == 0) {
            fatal_lang_error('smf232');
        }
        $total_posts = 0;
        $boards = array();
        while ($row = mysql_fetch_assoc($request)) {
            if (count($_REQUEST['boards']) == 1) {
                $feed_title = ' - ' . strip_tags($row['name']);
            }
            $boards[] = $row['ID_BOARD'];
            $total_posts += $row['numPosts'];
        }
        mysql_free_result($request);
        if (!empty($boards)) {
            $query_this_board = 'b.ID_BOARD IN (' . implode(', ', $boards) . ')';
        }
        // The more boards, the more we're going to look through...
        if ($total_posts > 100 && $total_posts > $modSettings['totalMessages'] / 12) {
            $query_this_board .= '
			AND m.ID_MSG >= ' . max(0, $modSettings['maxMsgID'] - 500 - $_GET['limit'] * 5);
        }
    } elseif (!empty($board)) {
        $request = db_query("\n\t\t\tSELECT numPosts\n\t\t\tFROM {$db_prefix}boards\n\t\t\tWHERE ID_BOARD = {$board}\n\t\t\tLIMIT 1", __FILE__, __LINE__);
        list($total_posts) = mysql_fetch_row($request);
        mysql_free_result($request);
        $feed_title = ' - ' . strip_tags($board_info['name']);
        $query_this_board = 'b.ID_BOARD = ' . $board;
        // Try to look through just a few messages, if at all possible.
        if ($total_posts > 80 && $total_posts > $modSettings['totalMessages'] / 10) {
            $query_this_board .= '
			AND m.ID_MSG >= ' . max(0, $modSettings['maxMsgID'] - 600 - $_GET['limit'] * 5);
        }
    } else {
        $query_this_board = $user_info['query_see_board'] . (!empty($modSettings['recycle_enable']) && $modSettings['recycle_board'] > 0 ? "\n\t\t\tAND b.ID_BOARD != {$modSettings['recycle_board']}" : '') . '
			AND m.ID_MSG >= ' . max(0, $modSettings['maxMsgID'] - 100 - $_GET['limit'] * 5);
    }
    // Show in rss or proprietary format?
    $xml_format = isset($_GET['type']) && in_array($_GET['type'], array('smf', 'rss', 'rss2', 'atom', 'rdf')) ? $_GET['type'] : 'smf';
    // !!! Birthdays?
    // List all the different types of data they can pull.
    $subActions = array('recent' => array('getXmlRecent', 'recent-post'), 'news' => array('getXmlNews', 'article'), 'members' => array('getXmlMembers', 'member'), 'profile' => array('getXmlProfile', null));
    if (empty($_GET['sa']) || !isset($subActions[$_GET['sa']])) {
        $_GET['sa'] = 'recent';
    }
    // Get the associative array representing the xml.
    if ($user_info['is_guest'] && !empty($modSettings['cache_enable']) && $modSettings['cache_enable'] >= 2) {
        $xml = cache_get_data('xmlfeed-' . $xml_format . ':' . md5(serialize($_GET)), 240);
    }
    if (empty($xml)) {
        $xml = $subActions[$_GET['sa']][0]($xml_format);
        if ($user_info['is_guest'] && !empty($modSettings['cache_enable']) && $modSettings['cache_enable'] >= 2) {
            cache_put_data('xmlfeed-' . $xml_format . ':' . md5(serialize($_GET)), $xml, 240);
        }
    }
    $feed_title = htmlspecialchars(strip_tags($context['forum_name'])) . (isset($feed_title) ? $feed_title : '');
    // This is an xml file....
    ob_end_clean();
    if (!empty($modSettings['enableCompressedOutput'])) {
        @ob_start('ob_gzhandler');
    } else {
        ob_start();
    }
    if ($xml_format == 'smf' || isset($_REQUEST['debug'])) {
        header('Content-Type: text/xml; charset=' . (empty($context['character_set']) ? 'ISO-8859-1' : $context['character_set']));
    } elseif ($xml_format == 'rss' || $xml_format == 'rss2') {
        header('Content-Type: application/rss+xml; charset=' . (empty($context['character_set']) ? 'ISO-8859-1' : $context['character_set']));
    } elseif ($xml_format == 'atom') {
        header('Content-Type: application/atom+xml; charset=' . (empty($context['character_set']) ? 'ISO-8859-1' : $context['character_set']));
    } elseif ($xml_format == 'rdf') {
        header('Content-Type: application/rdf+xml; charset=' . (empty($context['character_set']) ? 'ISO-8859-1' : $context['character_set']));
    }
    // First, output the xml header.
    echo '<?xml version="1.0" encoding="', $context['character_set'], '"?' . '>';
    // Are we outputting an rss feed or one with more information?
    if ($xml_format == 'rss' || $xml_format == 'rss2') {
        // Start with an RSS 2.0 header.
        echo '
<rss version=', $xml_format == 'rss2' ? '"2.0"' : '"0.92"', ' xml:lang="', strtr($txt['lang_locale'], '_', '-'), '">
	<channel>
		<title>', $feed_title, '</title>
		<link>', $scripturl, '</link>
		<description><![CDATA[', strip_tags($txt['xml_rss_desc']), ']]></description>';
        // Output all of the associative array, start indenting with 2 tabs, and name everything "item".
        dumpTags($xml, 2, 'item', $xml_format);
        // Output the footer of the xml.
        echo '
	</channel>
</rss>';
    } elseif ($xml_format == 'atom') {
        echo '
<feed version="0.3" xmlns="http://purl.org/atom/ns#">
	<title>', $feed_title, '</title>
	<link rel="alternate" type="text/html" href="', $scripturl, '" />

	<modified>', gmstrftime('%Y-%m-%dT%H:%M:%SZ'), '</modified>
	<tagline><![CDATA[', strip_tags($txt['xml_rss_desc']), ']]></tagline>
	<generator>SMF</generator>
	<author>
		<name>', strip_tags($context['forum_name']), '</name>
	</author>';
        dumpTags($xml, 2, 'entry', $xml_format);
        echo '
</feed>';
    } elseif ($xml_format == 'rdf') {
        echo '
<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns="http://purl.org/rss/1.0/">
	<channel rdf:about="', $scripturl, '">
		<title>', $feed_title, '</title>
		<link>', $scripturl, '</link>
		<description><![CDATA[', strip_tags($txt['xml_rss_desc']), ']]></description>
		<items>
			<rdf:Seq>';
        foreach ($xml as $item) {
            echo '
				<rdf:li rdf:resource="', $item['link'], '" />';
        }
        echo '
			</rdf:Seq>
		</items>
	</channel>
';
        dumpTags($xml, 1, 'item', $xml_format);
        echo '
</rdf:RDF>';
    } else {
        echo '
<smf:xml-feed xmlns:smf="http://www.simplemachines.org/" xmlns="http://www.simplemachines.org/xml/', $_GET['sa'], '" xml:lang="', strtr($txt['lang_locale'], '_', '-'), '">';
        // Dump out that associative array.  Indent properly.... and use the right names for the base elements.
        dumpTags($xml, 1, $subActions[$_GET['sa']][1], $xml_format);
        echo '
</smf:xml-feed>';
    }
    obExit(false);
}
function up_create_control_richedit($editorOptions)
{
    global $txt, $modSettings, $options, $smcFunc;
    global $context, $settings, $user_info, $sourcedir, $scripturl;
    require_once $sourcedir . '/Subs-Editor.php';
    // Load the Post language file... for the moment at least.
    loadLanguage('Post');
    // Every control must have a ID!
    assert(isset($editorOptions['id']));
    assert(isset($editorOptions['value']));
    // Is this the first richedit - if so we need to ensure some template stuff is initialised.
    if (empty($context['controls']['richedit'])) {
        // Some general stuff.
        $settings['smileys_url'] = $modSettings['smileys_url'] . '/' . $user_info['smiley_set'];
        // This really has some WYSIWYG stuff.
        loadTemplate('GenericControls', $context['browser']['is_ie'] ? 'editor_ie' : 'editor');
        $context['html_headers'] .= '
		<script type="text/javascript"><!-- // --><![CDATA[
			var smf_smileys_url = \'' . $settings['smileys_url'] . '\';
			var oEditorStrings= {
				wont_work: \'' . addcslashes($txt['rich_edit_wont_work'], "'") . '\',
				func_disabled: \'' . addcslashes($txt['rich_edit_function_disabled'], "'") . '\',
				prompt_text_email: \'' . addcslashes($txt['prompt_text_email'], "'") . '\',
				prompt_text_ftp: \'' . addcslashes($txt['prompt_text_ftp'], "'") . '\',
				prompt_text_url: \'' . addcslashes($txt['prompt_text_url'], "'") . '\',
				prompt_text_img: \'' . addcslashes($txt['prompt_text_img'], "'") . '\'
			}
		// ]]></script>
		<script type="text/javascript" src="' . $settings['default_theme_url'] . '/scripts/editor.js"></script>';
        $context['show_spellchecking'] = !empty($modSettings['enableSpellChecking']) && function_exists('pspell_new');
        if ($context['show_spellchecking']) {
            $context['html_headers'] .= '
				<script type="text/javascript" src="' . $settings['default_theme_url'] . '/scripts/spellcheck.js"></script>';
            // Some hidden information is needed in order to make the spell checking work.
            if (!isset($_REQUEST['xml'])) {
                $context['insert_after_template'] .= '
				<form name="spell_form" id="spell_form" method="post" accept-charset="' . $context['character_set'] . '" target="spellWindow" action="' . $scripturl . '?action=spellcheck">
					<input type="hidden" name="spellstring" value="" />
				</form>';
            }
            // Also make sure that spell check works with rich edit.
            $context['html_headers'] .= '
				<script type="text/javascript"><!-- // --><![CDATA[
				function spellCheckDone()
				{
					for (i = 0; i < smf_editorArray.length; i++)
						setTimeout("smf_editorArray[" + i + "].spellCheckEnd()", 150);
				}
				// ]]></script>';
        }
    }
    // Start off the editor...
    $context['controls']['richedit'][$editorOptions['id']] = array('id' => $editorOptions['id'], 'value' => $editorOptions['value'], 'rich_value' => addcslashes(bbc_to_html($editorOptions['value']), "'"), 'rich_active' => empty($modSettings['disable_wysiwyg']) && (!empty($options['wysiwyg_default']) || !empty($editorOptions['force_rich']) || !empty($_REQUEST[$editorOptions['id'] . '_mode'])), 'disable_smiley_box' => !empty($editorOptions['disable_smiley_box']), 'columns' => isset($editorOptions['columns']) ? $editorOptions['columns'] : 60, 'rows' => isset($editorOptions['rows']) ? $editorOptions['rows'] : 12, 'width' => isset($editorOptions['width']) ? $editorOptions['width'] : '100%', 'height' => isset($editorOptions['height']) ? $editorOptions['height'] : '150px', 'form' => isset($editorOptions['form']) ? $editorOptions['form'] : 'postmodify', 'bbc_level' => !empty($editorOptions['bbc_level']) ? $editorOptions['bbc_level'] : 'full', 'preview_type' => isset($editorOptions['preview_type']) ? (int) $editorOptions['preview_type'] : 1, 'labels' => !empty($editorOptions['labels']) ? $editorOptions['labels'] : array());
    // Switch between default images and back... mostly in case you don't have an PersonalMessage template, but do have a Post template.
    if (isset($settings['use_default_images']) && $settings['use_default_images'] == 'defaults' && isset($settings['default_template'])) {
        $temp1 = $settings['theme_url'];
        $settings['theme_url'] = $settings['default_theme_url'];
        $temp2 = $settings['images_url'];
        $settings['images_url'] = $settings['default_images_url'];
        $temp3 = $settings['theme_dir'];
        $settings['theme_dir'] = $settings['default_theme_dir'];
    }
    if (empty($context['bbc_tags'])) {
        // The below array makes it dead easy to add images to this control. Add it to the array and everything else is done for you!
        $context['bbc_tags'] = array();
        $context['bbc_tags'][] = array(array('image' => 'bold', 'code' => 'b', 'before' => '[b]', 'after' => '[/b]', 'description' => $txt['bold']), array('image' => 'italicize', 'code' => 'i', 'before' => '[i]', 'after' => '[/i]', 'description' => $txt['italic']), array('image' => 'underline', 'code' => 'u', 'before' => '[u]', 'after' => '[/u]', 'description' => $txt['underline']), array('image' => 'strike', 'code' => 's', 'before' => '[s]', 'after' => '[/s]', 'description' => $txt['strike']), array(), array('image' => 'pre', 'code' => 'pre', 'before' => '[pre]', 'after' => '[/pre]', 'description' => $txt['preformatted']), array('image' => 'left', 'code' => 'left', 'before' => '[left]', 'after' => '[/left]', 'description' => $txt['left_align']), array('image' => 'center', 'code' => 'center', 'before' => '[center]', 'after' => '[/center]', 'description' => $txt['center']), array('image' => 'right', 'code' => 'right', 'before' => '[right]', 'after' => '[/right]', 'description' => $txt['right_align']));
        $context['bbc_tags'][] = array(array('image' => 'flash', 'code' => 'flash', 'before' => '[flash=200,200]', 'after' => '[/flash]', 'description' => $txt['flash']), array('image' => 'img', 'code' => 'img', 'before' => '[img]', 'after' => '[/img]', 'description' => $txt['image']), array('image' => 'url', 'code' => 'url', 'before' => '[url]', 'after' => '[/url]', 'description' => $txt['hyperlink']), array('image' => 'email', 'code' => 'email', 'before' => '[email]', 'after' => '[/email]', 'description' => $txt['insert_email']), array('image' => 'ftp', 'code' => 'ftp', 'before' => '[ftp]', 'after' => '[/ftp]', 'description' => $txt['ftp']), array(), array('image' => 'glow', 'code' => 'glow', 'before' => '[glow=red,2,300]', 'after' => '[/glow]', 'description' => $txt['glow']), array('image' => 'shadow', 'code' => 'shadow', 'before' => '[shadow=red,left]', 'after' => '[/shadow]', 'description' => $txt['shadow']), array('image' => 'move', 'code' => 'move', 'before' => '[move]', 'after' => '[/move]', 'description' => $txt['marquee']), array(), array('image' => 'sup', 'code' => 'sup', 'before' => '[sup]', 'after' => '[/sup]', 'description' => $txt['superscript']), array('image' => 'sub', 'code' => 'sub', 'before' => '[sub]', 'after' => '[/sub]', 'description' => $txt['subscript']), array('image' => 'tele', 'code' => 'tt', 'before' => '[tt]', 'after' => '[/tt]', 'description' => $txt['teletype']), array(), array('image' => 'table', 'code' => 'table', 'before' => '[table]\\n[tr]\\n[td]', 'after' => '[/td]\\n[/tr]\\n[/table]', 'description' => $txt['table']), array('image' => 'code', 'code' => 'code', 'before' => '[code]', 'after' => '[/code]', 'description' => $txt['bbc_code']), array('image' => 'quote', 'code' => 'quote', 'before' => '[quote]', 'after' => '[/quote]', 'description' => $txt['bbc_quote']), array(), array('image' => 'list', 'code' => 'list', 'before' => '[list]\\n[li]', 'after' => '[/li]\\n[li][/li]\\n[/list]', 'description' => $txt['list']), array('image' => 'orderlist', 'code' => 'orderlist', 'before' => '[list type=decimal]\\n[li]', 'after' => '[/li]\\n[li][/li]\\n[/list]', 'description' => $txt['list']), array('image' => 'hr', 'code' => 'hr', 'before' => '[hr]', 'description' => $txt['horizontal_rule']));
        // Show the toggle?
        if (empty($modSettings['disable_wysiwyg'])) {
            $context['bbc_tags'][count($context['bbc_tags']) - 1][] = array();
            $context['bbc_tags'][count($context['bbc_tags']) - 1][] = array('image' => 'unformat', 'code' => 'unformat', 'before' => '', 'description' => $txt['unformat_text']);
            $context['bbc_tags'][count($context['bbc_tags']) - 1][] = array('image' => 'toggle', 'code' => 'toggle', 'before' => '', 'description' => $txt['toggle_view']);
        }
        foreach ($context['bbc_tags'] as $row => $tagRow) {
            $context['bbc_tags'][$row][count($tagRow) - 1]['isLast'] = true;
        }
    }
    // Initialize smiley array... if not loaded before.
    if (empty($context['smileys']) && empty($editorOptions['disable_smiley_box'])) {
        $context['smileys'] = array('postform' => array(), 'popup' => array());
        // Load smileys - don't bother to run a query if we're not using the database's ones anyhow.
        if (empty($modSettings['smiley_enable']) && $user_info['smiley_set'] != 'none') {
            $context['smileys']['postform'][] = array('smileys' => array(array('code' => ':)', 'filename' => 'smiley.gif', 'description' => $txt['icon_smiley']), array('code' => ';)', 'filename' => 'wink.gif', 'description' => $txt['icon_wink']), array('code' => ':D', 'filename' => 'cheesy.gif', 'description' => $txt['icon_cheesy']), array('code' => ';D', 'filename' => 'grin.gif', 'description' => $txt['icon_grin']), array('code' => '>:(', 'filename' => 'angry.gif', 'description' => $txt['icon_angry']), array('code' => ':(', 'filename' => 'sad.gif', 'description' => $txt['icon_sad']), array('code' => ':o', 'filename' => 'shocked.gif', 'description' => $txt['icon_shocked']), array('code' => '8)', 'filename' => 'cool.gif', 'description' => $txt['icon_cool']), array('code' => '???', 'filename' => 'huh.gif', 'description' => $txt['icon_huh']), array('code' => '::)', 'filename' => 'rolleyes.gif', 'description' => $txt['icon_rolleyes']), array('code' => ':P', 'filename' => 'tongue.gif', 'description' => $txt['icon_tongue']), array('code' => ':-[', 'filename' => 'embarrassed.gif', 'description' => $txt['icon_embarrassed']), array('code' => ':-X', 'filename' => 'lipsrsealed.gif', 'description' => $txt['icon_lips']), array('code' => ':-\\', 'filename' => 'undecided.gif', 'description' => $txt['icon_undecided']), array('code' => ':-*', 'filename' => 'kiss.gif', 'description' => $txt['icon_kiss']), array('code' => ':\'(', 'filename' => 'cry.gif', 'description' => $txt['icon_cry'], 'isLast' => true)), 'isLast' => true);
        } elseif ($user_info['smiley_set'] != 'none') {
            if (($temp = cache_get_data('posting_smileys', 480)) == null) {
                $request = $smcFunc['db_query']('', '
					SELECT code, filename, description, smiley_row, hidden
					FROM {db_prefix}smileys
					WHERE hidden IN (0, 2)
					ORDER BY smiley_row, smiley_order', array());
                while ($row = $smcFunc['db_fetch_assoc']($request)) {
                    $row['filename'] = htmlspecialchars($row['filename']);
                    $row['description'] = htmlspecialchars($row['description']);
                    $context['smileys'][empty($row['hidden']) ? 'postform' : 'popup'][$row['smiley_row']]['smileys'][] = $row;
                }
                $smcFunc['db_free_result']($request);
                foreach ($context['smileys'] as $section => $smileyRows) {
                    foreach ($smileyRows as $rowIndex => $smileys) {
                        $context['smileys'][$section][$rowIndex]['smileys'][count($smileys['smileys']) - 1]['isLast'] = true;
                    }
                    if (!empty($smileyRows)) {
                        $context['smileys'][$section][count($smileyRows) - 1]['isLast'] = true;
                    }
                }
                cache_put_data('posting_smileys', $context['smileys'], 480);
            } else {
                $context['smileys'] = $temp;
            }
        }
    }
    // Set a flag so the sub template knows what to do...
    $context['show_bbc'] = !empty($modSettings['enableBBC']) && !empty($settings['show_bbc']);
    // Generate a list of buttons that shouldn't be shown - this should be the fastest way to do this.
    $disabled_tags = array();
    if (!empty($modSettings['disabledBBC'])) {
        $disabled_tags = explode(',', $modSettings['disabledBBC']);
    }
    if (empty($modSettings['enableEmbeddedFlash'])) {
        $disabled_tags[] = 'flash';
    }
    foreach ($disabled_tags as $tag) {
        if ($tag == 'list') {
            $context['disabled_tags']['orderlist'] = true;
        }
        $context['disabled_tags'][trim($tag)] = true;
    }
    // Switch the URLs back... now we're back to whatever the main sub template is.  (like folder in PersonalMessage.)
    if (isset($settings['use_default_images']) && $settings['use_default_images'] == 'defaults' && isset($settings['default_template'])) {
        $settings['theme_url'] = $temp1;
        $settings['images_url'] = $temp2;
        $settings['theme_dir'] = $temp3;
    }
}
function SpiderCheck()
{
    global $modSettings, $smcFunc;
    if (isset($_SESSION['id_robot'])) {
        unset($_SESSION['id_robot']);
    }
    $_SESSION['robot_check'] = time();
    // We cache the spider data for five minutes if we can.
    if (!empty($modSettings['cache_enable'])) {
        $spider_data = cache_get_data('spider_search', 300);
    }
    if (!isset($spider_data) || $spider_data === NULL) {
        $request = $smcFunc['db_query']('spider_check', '
			SELECT id_spider, user_agent, ip_info
			FROM {db_prefix}spiders', array());
        $spider_data = array();
        while ($row = $smcFunc['db_fetch_assoc']($request)) {
            $spider_data[] = $row;
        }
        $smcFunc['db_free_result']($request);
        if (!empty($modSettings['cache_enable'])) {
            cache_put_data('spider_search', $spider_data, 300);
        }
    }
    if (empty($spider_data)) {
        return false;
    }
    // Only do these bits once.
    $ci_user_agent = strtolower($_SERVER['HTTP_USER_AGENT']);
    preg_match('/^(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})$/', $_SERVER['REMOTE_ADDR'], $ip_parts);
    foreach ($spider_data as $spider) {
        // User agent is easy.
        if (!empty($spider['user_agent']) && strpos($ci_user_agent, strtolower($spider['user_agent'])) !== false) {
            $_SESSION['id_robot'] = $spider['id_spider'];
        } elseif (!empty($ip_parts)) {
            $ips = explode(',', $spider['ip_info']);
            foreach ($ips as $ip) {
                $ip = ip2range($ip);
                if (!empty($ip)) {
                    foreach ($ip as $key => $value) {
                        if ($value['low'] > $ip_parts[$key + 1] || $value['high'] < $ip_parts[$key + 1]) {
                            break;
                        } elseif ($key == 3) {
                            $_SESSION['id_robot'] = $spider['id_spider'];
                        }
                    }
                }
            }
        }
        if (isset($_SESSION['id_robot'])) {
            break;
        }
    }
    // If this is low server tracking then log the spider here as oppossed to the main logging function.
    if (!empty($modSettings['spider_mode']) && $modSettings['spider_mode'] == 1 && !empty($_SESSION['id_robot'])) {
        logSpider();
    }
    return !empty($_SESSION['id_robot']) ? $_SESSION['id_robot'] : 0;
}
function up_print_MultiBlock($position)
{
    global $context, $scripturl, $ultimateportalSettings, $user_info;
    if ($position == 'header') {
        if (!empty($ultimateportalSettings['up_reduce_site_overload'])) {
            if (cache_get_data('mbk_header', 1800) === NULL) {
                LoadBlocksHEADERPortal("and enable=1");
                cache_put_data('mbk_header', !empty($context['block-' . $position]), 1800);
                cache_put_data('exists_multi' . $position, $context['exists_multi' . $position], 1800);
            } else {
                $context['block-' . $position] = cache_get_data('mbk_header', 1800);
                $context['exists_multi' . $position] = cache_get_data('exists_multi' . $position, 1800);
            }
        } else {
            LoadBlocksHEADERPortal("and enable=1");
        }
    }
    if ($position == 'footer') {
        if (!empty($ultimateportalSettings['up_reduce_site_overload'])) {
            if (cache_get_data('mbk_footer', 1800) === NULL) {
                LoadBlocksFOOTERPortal("and enable=1");
                cache_put_data('mbk_footer', !empty($context['block-' . $position]), 1800);
                cache_put_data('exists_multi' . $position, $context['exists_multi' . $position], 1800);
            } else {
                $context['block-' . $position] = cache_get_data('mbk_footer', 1800);
                $context['exists_multi' . $position] = cache_get_data('exists_multi' . $position, 1800);
            }
        } else {
            LoadBlocksFOOTERPortal("and enable=1");
        }
    }
    if (!empty($context['exists_multi' . $position])) {
        echo '
		<table id="up_bk_table_main" style="width:100%" cellpadding="3" cellspacing="0">
		<tr>
		<td>';
        foreach ($context['block-' . $position] as $multiblock) {
            $title = $user_info['is_admin'] ? '<a href="' . $scripturl . '?action=adminportal;area=multiblock;sa=edit;id=' . $multiblock['id'] . ';' . $context['session_var'] . '=' . $context['session_id'] . '">' . $multiblock['mbtitle'] . '</a>' : $multiblock['mbtitle'];
            head_block('up-multiblock', $title, '-' . $multiblock['id'], $multiblock['mbk_collapse'], $multiblock['mbk_title'], $multiblock['mbk_style']);
            switch ($multiblock['design']) {
                case '1-2':
                    $column = 1;
                    //per line
                    break;
                case '2-1':
                    $column = 2;
                    //per line
                    break;
                case '3-1':
                    $column = 2;
                    //per line
                    break;
                default:
                    $column = 1;
                    //per line
                    break;
            }
            //1 Row 2 Columns
            if ($multiblock['design'] == '1-2') {
                $c1 = !empty($multiblock['vblocks']['c1']) ? count($multiblock['vblocks']['c1']) : 0;
                $c2 = !empty($multiblock['vblocks']['c2']) ? count($multiblock['vblocks']['c2']) : 0;
                echo '
				<table id="up_bk_table_main" style="width:100%" cellpadding="5" cellspacing="2">
					<tr>';
                //Now View Column 1
                if (!empty($multiblock['vblocks']['c1'])) {
                    echo '
							<td valign="top" align="left">';
                    foreach ($multiblock['vblocks']['c1'] as $vblocks) {
                        echo '
								', up_get_MBcolumn($vblocks['id']), '';
                    }
                    echo '
							</td>';
                }
                //Now View Column 2
                if (!empty($multiblock['vblocks']['c2'])) {
                    echo '
							<td valign="top" align="left">';
                    foreach ($multiblock['vblocks']['c2'] as $vblocks) {
                        echo '
								', up_get_MBcolumn($vblocks['id']), '';
                    }
                    echo '
							</td>';
                }
                echo '
					</tr>
				</table>';
                //End View Column 1
            }
            //End Design 1-2
            //2 Rows 1 Column
            if ($multiblock['design'] == '2-1') {
                $r1 = !empty($multiblock['vblocks']['r1']) ? count($multiblock['vblocks']['r1']) : 0;
                $r2 = !empty($multiblock['vblocks']['r2']) ? count($multiblock['vblocks']['r2']) : 0;
                $context['width_1'] = $r1 >= 1 && $r1 <= 2 ? '50%' : '33%';
                $context['width_2'] = $r2 >= 1 && $r2 <= 2 ? '50%' : '33%';
                $i = 1;
                //flag
                //Now View Row 1
                if (!empty($multiblock['vblocks']['r1'])) {
                    echo '
					<table id="up_bk_table_main" style="width:100%" cellpadding="5" cellspacing="2">
						<tr>
							<td colspan="3" valign="top" style="width:100%;" align="left">
								<table style="width:100%">
									<tr>';
                    $alternate = true;
                    foreach ($multiblock['vblocks']['r1'] as $vblocks) {
                        echo '
										<td valign="top" style="width:', $context['width_1'], ';" align="left">
											', up_get_MBcolumn($vblocks['id']), '
										</td>';
                        $i++;
                        if ($i == $column + 1) {
                            echo '
											</tr><tr>';
                            $i = 1;
                        }
                    }
                    echo '
									</tr>
								</table>
							</td>	
						</tr>
					</table>';
                }
                //End View Row 1
                //Now View Row 2
                if (!empty($multiblock['vblocks']['r2'])) {
                    $i = 1;
                    //flag
                    echo '
					<table id="up_bk_table_main" style="width:100%" cellpadding="5" cellspacing="2">
						<tr>
							<td colspan="3" valign="top" style="width:100%;" align="left">
								<table style="width:100%">
									<tr>';
                    $alternate = true;
                    foreach ($multiblock['vblocks']['r2'] as $vblocks) {
                        echo '
										<td valign="top" style="width:', $context['width_2'], ';" align="left">
											', up_get_MBcolumn($vblocks['id']), '
										</td>';
                        $i++;
                        if ($i == $column + 1) {
                            echo '
											</tr><tr>';
                            $i = 1;
                        }
                    }
                    echo '
									</tr>
								</table>
							</td>	
						</tr>
					</table>';
                }
                //End View Row 2
            }
            //End Design 2-1
            //3 Rows 1 Column
            if ($multiblock['design'] == '3-1') {
                $r1 = !empty($multiblock['vblocks']['r1']) ? count($multiblock['vblocks']['r1']) : 0;
                $r2 = !empty($multiblock['vblocks']['r2']) ? count($multiblock['vblocks']['r2']) : 0;
                $r3 = !empty($multiblock['vblocks']['r3']) ? count($multiblock['vblocks']['r3']) : 0;
                $context['width_1'] = $r1 >= 1 && $r1 <= 2 ? '50%' : '33%';
                $context['width_2'] = $r2 >= 1 && $r2 <= 2 ? '50%' : '33%';
                $context['width_3'] = $r3 >= 1 && $r3 <= 2 ? '50%' : '33%';
                $i = 1;
                //flag
                //Now View Row 1
                if (!empty($multiblock['vblocks']['r1'])) {
                    echo '
					<table id="up_bk_table_main" style="width:100%" cellpadding="5" cellspacing="2">
						<tr>
							<td colspan="3" valign="top" style="width:100%;" align="left">
								<table style="width:100%">
									<tr>';
                    $alternate = true;
                    foreach ($multiblock['vblocks']['r1'] as $vblocks) {
                        echo '
										<td valign="top" style="width:', $context['width_1'], ';" align="left">
											', up_get_MBcolumn($vblocks['id']), '
										</td>';
                        $i++;
                        if ($i == $column + 1) {
                            echo '
											</tr><tr>';
                            $i = 1;
                        }
                    }
                    echo '
									</tr>
								</table>
							</td>	
						</tr>
					</table>';
                }
                //End View Row 1
                //Now View Row 2
                if (!empty($multiblock['vblocks']['r2'])) {
                    $i = 1;
                    //flag
                    echo '
					<table id="up_bk_table_main" style="width:100%" cellpadding="5" cellspacing="2">
						<tr>
							<td colspan="3" valign="top" style="width:100%;" align="left">
								<table style="width:100%">
									<tr>';
                    $alternate = true;
                    foreach ($multiblock['vblocks']['r2'] as $vblocks) {
                        echo '
										<td valign="top" style="width:', $context['width_2'], ';" align="left">
											', up_get_MBcolumn($vblocks['id']), '
										</td>';
                        $i++;
                        if ($i == $column + 1) {
                            echo '
											</tr><tr>';
                            $i = 1;
                        }
                    }
                    echo '
									</tr>
								</table>
							</td>	
						</tr>
					</table>';
                }
                //End View Row 2
                //Now View Row 3
                if (!empty($multiblock['vblocks']['r3'])) {
                    $i = 1;
                    //flag
                    echo '
					<table id="up_bk_table_main" style="width:100%" cellpadding="5" cellspacing="2">
						<tr>
							<td colspan="3" valign="top" style="width:100%;" align="left">
								<table style="width:100%">
									<tr>';
                    $alternate = true;
                    foreach ($multiblock['vblocks']['r3'] as $vblocks) {
                        echo '
										<td valign="top" style="width:', $context['width_3'], ';" align="left">
											', up_get_MBcolumn($vblocks['id']), '
										</td>';
                        $i++;
                        if ($i == $column + 1) {
                            echo '
											</tr><tr>';
                            $i = 1;
                        }
                    }
                    echo '
									</tr>
								</table>
							</td>	
						</tr>
					</table>';
                }
                //End View Row 3
            }
            //End Design 3-1
            footer_block($multiblock['mbk_style']);
        }
        echo '
		</td>
		</tr>
		</table>';
    }
}
function smf_db_error($db_string, $connection = null)
{
    global $txt, $context, $sourcedir, $webmaster_email, $modSettings;
    global $forum_version, $db_connection, $db_last_error, $db_persist;
    global $db_server, $db_user, $db_passwd, $db_name, $db_show_debug, $ssi_db_user, $ssi_db_passwd;
    global $smcFunc;
    // Get the file and line numbers.
    list($file, $line) = smf_db_error_backtrace('', '', 'return', __FILE__, __LINE__);
    // Decide which connection to use
    $connection = $connection == null ? $db_connection : $connection;
    // This is the error message...
    $query_error = mysql_error($connection);
    $query_errno = mysql_errno($connection);
    // Error numbers:
    //    1016: Can't open file '....MYI'
    //    1030: Got error ??? from table handler.
    //    1034: Incorrect key file for table.
    //    1035: Old key file for table.
    //    1205: Lock wait timeout exceeded.
    //    1213: Deadlock found.
    //    2006: Server has gone away.
    //    2013: Lost connection to server during query.
    // Log the error.
    if ($query_errno != 1213 && $query_errno != 1205 && function_exists('log_error')) {
        log_error($txt['database_error'] . ': ' . $query_error . (!empty($modSettings['enableErrorQueryLogging']) ? "\n\n{$db_string}" : ''), 'database', $file, $line);
    }
    // Database error auto fixing ;).
    if (function_exists('cache_get_data') && (!isset($modSettings['autoFixDatabase']) || $modSettings['autoFixDatabase'] == '1')) {
        // Force caching on, just for the error checking.
        $old_cache = @$modSettings['cache_enable'];
        $modSettings['cache_enable'] = '1';
        if (($temp = cache_get_data('db_last_error', 600)) !== null) {
            $db_last_error = max(@$db_last_error, $temp);
        }
        if (@$db_last_error < time() - 3600 * 24 * 3) {
            // We know there's a problem... but what?  Try to auto detect.
            if ($query_errno == 1030 && strpos($query_error, ' 127 ') !== false) {
                preg_match_all('~(?:[\\n\\r]|^)[^\']+?(?:FROM|JOIN|UPDATE|TABLE) ((?:[^\\n\\r(]+?(?:, )?)*)~s', $db_string, $matches);
                $fix_tables = array();
                foreach ($matches[1] as $tables) {
                    $tables = array_unique(explode(',', $tables));
                    foreach ($tables as $table) {
                        // Now, it's still theoretically possible this could be an injection.  So backtick it!
                        if (trim($table) != '') {
                            $fix_tables[] = '`' . strtr(trim($table), array('`' => '')) . '`';
                        }
                    }
                }
                $fix_tables = array_unique($fix_tables);
            } elseif ($query_errno == 1016) {
                if (preg_match('~\'([^\\.\']+)~', $query_error, $match) != 0) {
                    $fix_tables = array('`' . $match[1] . '`');
                }
            } elseif ($query_errno == 1034 || $query_errno == 1035) {
                preg_match('~\'([^\']+?)\'~', $query_error, $match);
                $fix_tables = array('`' . $match[1] . '`');
            }
        }
        // Check for errors like 145... only fix it once every three days, and send an email. (can't use empty because it might not be set yet...)
        if (!empty($fix_tables)) {
            // Subs-Admin.php for updateSettingsFile(), Subs-Post.php for sendmail().
            require_once $sourcedir . '/Subs-Admin.php';
            require_once $sourcedir . '/Subs-Post.php';
            // Make a note of the REPAIR...
            cache_put_data('db_last_error', time(), 600);
            if (($temp = cache_get_data('db_last_error', 600)) === null) {
                updateSettingsFile(array('db_last_error' => time()));
            }
            // Attempt to find and repair the broken table.
            foreach ($fix_tables as $table) {
                $smcFunc['db_query']('', "\r\n\t\t\t\t\tREPAIR TABLE {$table}", false, false);
            }
            // And send off an email!
            sendmail($webmaster_email, $txt['database_error'], $txt['tried_to_repair']);
            $modSettings['cache_enable'] = $old_cache;
            // Try the query again...?
            $ret = $smcFunc['db_query']('', $db_string, false, false);
            if ($ret !== false) {
                return $ret;
            }
        } else {
            $modSettings['cache_enable'] = $old_cache;
        }
        // Check for the "lost connection" or "deadlock found" errors - and try it just one more time.
        if (in_array($query_errno, array(1205, 1213, 2006, 2013))) {
            if (in_array($query_errno, array(2006, 2013)) && $db_connection == $connection) {
                // Are we in SSI mode?  If so try that username and password first
                if (SMF == 'SSI' && !empty($ssi_db_user) && !empty($ssi_db_passwd)) {
                    if (empty($db_persist)) {
                        $db_connection = @mysql_connect($db_server, $ssi_db_user, $ssi_db_passwd);
                    } else {
                        $db_connection = @mysql_pconnect($db_server, $ssi_db_user, $ssi_db_passwd);
                    }
                }
                // Fall back to the regular username and password if need be
                if (!$db_connection) {
                    if (empty($db_persist)) {
                        $db_connection = @mysql_connect($db_server, $db_user, $db_passwd);
                    } else {
                        $db_connection = @mysql_pconnect($db_server, $db_user, $db_passwd);
                    }
                }
                if (!$db_connection || !@mysql_select_db($db_name, $db_connection)) {
                    $db_connection = false;
                }
            }
            if ($db_connection) {
                // Try a deadlock more than once more.
                for ($n = 0; $n < 4; $n++) {
                    $ret = $smcFunc['db_query']('', $db_string, false, false);
                    $new_errno = mysql_errno($db_connection);
                    if ($ret !== false || in_array($new_errno, array(1205, 1213))) {
                        break;
                    }
                }
                // If it failed again, shucks to be you... we're not trying it over and over.
                if ($ret !== false) {
                    return $ret;
                }
            }
        } elseif ($query_errno == 1030 && (strpos($query_error, ' -1 ') !== false || strpos($query_error, ' 28 ') !== false || strpos($query_error, ' 12 ') !== false)) {
            if (!isset($txt)) {
                $query_error .= ' - check database storage space.';
            } else {
                if (!isset($txt['mysql_error_space'])) {
                    loadLanguage('Errors');
                }
                $query_error .= !isset($txt['mysql_error_space']) ? ' - check database storage space.' : $txt['mysql_error_space'];
            }
        }
    }
    // Nothing's defined yet... just die with it.
    if (empty($context) || empty($txt)) {
        die($query_error);
    }
    // Show an error message, if possible.
    $context['error_title'] = $txt['database_error'];
    if (allowedTo('admin_forum')) {
        $context['error_message'] = nl2br($query_error) . '<br />' . $txt['file'] . ': ' . $file . '<br />' . $txt['line'] . ': ' . $line;
    } else {
        $context['error_message'] = $txt['try_again'];
    }
    // A database error is often the sign of a database in need of upgrade.  Check forum versions, and if not identical suggest an upgrade... (not for Demo/CVS versions!)
    if (allowedTo('admin_forum') && !empty($forum_version) && $forum_version != 'SMF ' . @$modSettings['smfVersion'] && strpos($forum_version, 'Demo') === false && strpos($forum_version, 'CVS') === false) {
        $context['error_message'] .= '<br /><br />' . sprintf($txt['database_error_versions'], $forum_version, $modSettings['smfVersion']);
    }
    if (allowedTo('admin_forum') && isset($db_show_debug) && $db_show_debug === true) {
        $context['error_message'] .= '<br /><br />' . nl2br($db_string);
    }
    // It's already been logged... don't log it again.
    fatal_error($context['error_message'], false);
}
Beispiel #22
0
/**
 * This function reads from the database the addons credits,
 * and returns them in an array for display in credits section of the site.
 * The addons copyright, license, title informations are those saved from <license>
 * and <credits> tags in package.xml.
 *
 * @return array
 */
function addonsCredits()
{
    global $txt;
    $db = database();
    if (($credits = cache_get_data('addons_credits', 86400)) === null) {
        $credits = array();
        $request = $db->query('substring', '
			SELECT version, name, credits
			FROM {db_prefix}log_packages
			WHERE install_state = {int:installed_adds}
				AND credits != {string:empty}
				AND SUBSTRING(filename, 1, 9) != {string:old_patch_name}
				AND SUBSTRING(filename, 1, 9) != {string:patch_name}', array('installed_adds' => 1, 'old_patch_name' => 'smf_patch', 'patch_name' => 'elk_patch', 'empty' => ''));
        while ($row = $db->fetch_assoc($request)) {
            $credit_info = unserialize($row['credits']);
            $copyright = empty($credit_info['copyright']) ? '' : $txt['credits_copyright'] . ' &copy; ' . Util::htmlspecialchars($credit_info['copyright']);
            $license = empty($credit_info['license']) ? '' : $txt['credits_license'] . ': ' . Util::htmlspecialchars($credit_info['license']);
            $version = $txt['credits_version'] . '' . $row['version'];
            $title = (empty($credit_info['title']) ? $row['name'] : Util::htmlspecialchars($credit_info['title'])) . ': ' . $version;
            // build this one out and stash it away
            $name = empty($credit_info['url']) ? $title : '<a href="' . $credit_info['url'] . '">' . $title . '</a>';
            $credits[] = $name . (!empty($license) ? ' | ' . $license : '') . (!empty($copyright) ? ' | ' . $copyright : '');
        }
        cache_put_data('addons_credits', $credits, 86400);
    }
    return $credits;
}
Beispiel #23
0
function create_control_verification(&$verificationOptions, $do_test = false)
{
    global $txt, $modSettings, $options, $smcFunc;
    global $context, $settings, $user_info, $sourcedir, $scripturl;
    // First verification means we need to set up some bits...
    if (empty($context['controls']['verification'])) {
        // The template
        loadTemplate('GenericControls');
        // Some javascript ma'am?
        if (!empty($verificationOptions['override_visual']) || !empty($modSettings['visual_verification_type']) && !isset($verificationOptions['override_visual'])) {
            $context['html_headers'] .= '
		<script type="text/javascript" src="' . $settings['default_theme_url'] . '/scripts/captcha.js"></script>';
        }
        $context['use_graphic_library'] = in_array('gd', get_loaded_extensions());
        // Skip I, J, L, O, Q, S and Z.
        $context['standard_captcha_range'] = array_merge(range('A', 'H'), array('K', 'M', 'N', 'P', 'R'), range('T', 'Y'));
    }
    // Always have an ID.
    assert(isset($verificationOptions['id']));
    $isNew = !isset($context['controls']['verification'][$verificationOptions['id']]);
    // Log this into our collection.
    if ($isNew) {
        $context['controls']['verification'][$verificationOptions['id']] = array('id' => $verificationOptions['id'], 'show_visual' => !empty($verificationOptions['override_visual']) || !empty($modSettings['visual_verification_type']) && !isset($verificationOptions['override_visual']), 'number_questions' => isset($verificationOptions['override_qs']) ? $verificationOptions['override_qs'] : (!empty($modSettings['qa_verification_number']) ? $modSettings['qa_verification_number'] : 0), 'max_errors' => isset($verificationOptions['max_errors']) ? $verificationOptions['max_errors'] : 3, 'image_href' => $scripturl . '?action=verificationcode;vid=' . $verificationOptions['id'] . ';rand=' . md5(mt_rand()), 'text_value' => '', 'questions' => array());
    }
    $thisVerification =& $context['controls']['verification'][$verificationOptions['id']];
    // Add javascript for the object.
    if ($context['controls']['verification'][$verificationOptions['id']]['show_visual'] && !WIRELESS) {
        $context['insert_after_template'] .= '
			<script type="text/javascript"><!-- // --><![CDATA[
				var verification' . $verificationOptions['id'] . 'Handle = new smfCaptcha("' . $thisVerification['image_href'] . '", "' . $verificationOptions['id'] . '", ' . ($context['use_graphic_library'] ? 1 : 0) . ');
			// ]]></script>';
    }
    // Is there actually going to be anything?
    if (empty($thisVerification['show_visual']) && empty($thisVerification['number_questions'])) {
        return false;
    } elseif (!$isNew && !$do_test) {
        return true;
    }
    // If we want questions do we have a cache of all the IDs?
    if (!empty($thisVerification['number_questions']) && empty($modSettings['question_id_cache'])) {
        if (($modSettings['question_id_cache'] = cache_get_data('verificationQuestionIds', 300)) == null) {
            $request = $smcFunc['db_query']('', '
				SELECT id_comment
				FROM {db_prefix}log_comments
				WHERE comment_type = {string:ver_test}', array('ver_test' => 'ver_test'));
            $modSettings['question_id_cache'] = array();
            while ($row = $smcFunc['db_fetch_assoc']($request)) {
                $modSettings['question_id_cache'][] = $row['id_comment'];
            }
            $smcFunc['db_free_result']($request);
            if (!empty($modSettings['cache_enable'])) {
                cache_put_data('verificationQuestionIds', $modSettings['question_id_cache'], 300);
            }
        }
    }
    if (!isset($_SESSION[$verificationOptions['id'] . '_vv'])) {
        $_SESSION[$verificationOptions['id'] . '_vv'] = array();
    }
    // Do we need to refresh the verification?
    if (!$do_test && (!empty($_SESSION[$verificationOptions['id'] . '_vv']['did_pass']) || empty($_SESSION[$verificationOptions['id'] . '_vv']['count']) || $_SESSION[$verificationOptions['id'] . '_vv']['count'] > 3) && empty($verificationOptions['dont_refresh'])) {
        $force_refresh = true;
    } else {
        $force_refresh = false;
    }
    // This can also force a fresh, although unlikely.
    if ($thisVerification['show_visual'] && empty($_SESSION[$verificationOptions['id'] . '_vv']['code']) || $thisVerification['number_questions'] && empty($_SESSION[$verificationOptions['id'] . '_vv']['q'])) {
        $force_refresh = true;
    }
    $verification_errors = array();
    // Start with any testing.
    if ($do_test) {
        // This cannot happen!
        if (!isset($_SESSION[$verificationOptions['id'] . '_vv']['count'])) {
            fatal_lang_error('no_access', false);
        }
        // ... nor this!
        if ($thisVerification['number_questions'] && (!isset($_SESSION[$verificationOptions['id'] . '_vv']['q']) || !isset($_REQUEST[$verificationOptions['id'] . '_vv']['q']))) {
            fatal_lang_error('no_access', false);
        }
        if ($thisVerification['show_visual'] && (empty($_REQUEST[$verificationOptions['id'] . '_vv']['code']) || empty($_SESSION[$verificationOptions['id'] . '_vv']['code']) || strtoupper($_REQUEST[$verificationOptions['id'] . '_vv']['code']) !== $_SESSION[$verificationOptions['id'] . '_vv']['code'])) {
            $verification_errors[] = 'wrong_verification_code';
        }
        if ($thisVerification['number_questions']) {
            // Get the answers and see if they are all right!
            $request = $smcFunc['db_query']('', '
				SELECT id_comment, recipient_name AS answer
				FROM {db_prefix}log_comments
				WHERE comment_type = {string:ver_test}
					AND id_comment IN ({array_int:comment_ids})', array('ver_test' => 'ver_test', 'comment_ids' => $_SESSION[$verificationOptions['id'] . '_vv']['q']));
            $incorrectQuestions = array();
            while ($row = $smcFunc['db_fetch_assoc']($request)) {
                if (empty($_REQUEST[$verificationOptions['id'] . '_vv']['q'][$row['id_comment']]) || trim($smcFunc['htmlspecialchars'](strtolower($_REQUEST[$verificationOptions['id'] . '_vv']['q'][$row['id_comment']]))) != strtolower($row['answer'])) {
                    $incorrectQuestions[] = $row['id_comment'];
                }
            }
            $smcFunc['db_free_result']($request);
            if (!empty($incorrectQuestions)) {
                $verification_errors[] = 'wrong_verification_answer';
            }
        }
    }
    // Any errors means we refresh potentially.
    if (!empty($verification_errors)) {
        if (empty($_SESSION[$verificationOptions['id'] . '_vv']['errors'])) {
            $_SESSION[$verificationOptions['id'] . '_vv']['errors'] = 0;
        } elseif ($_SESSION[$verificationOptions['id'] . '_vv']['errors'] > $thisVerification['max_errors']) {
            $force_refresh = true;
        }
        // Keep a track of these.
        $_SESSION[$verificationOptions['id'] . '_vv']['errors']++;
    }
    // Are we refreshing then?
    if ($force_refresh) {
        // Assume nothing went before.
        $_SESSION[$verificationOptions['id'] . '_vv']['count'] = 0;
        $_SESSION[$verificationOptions['id'] . '_vv']['errors'] = 0;
        $_SESSION[$verificationOptions['id'] . '_vv']['did_pass'] = false;
        $_SESSION[$verificationOptions['id'] . '_vv']['q'] = array();
        $_SESSION[$verificationOptions['id'] . '_vv']['code'] = '';
        // Generating a new image.
        if ($thisVerification['show_visual']) {
            // Are we overriding the range?
            $character_range = !empty($verificationOptions['override_range']) ? $verificationOptions['override_range'] : $context['standard_captcha_range'];
            for ($i = 0; $i < 6; $i++) {
                $_SESSION[$verificationOptions['id'] . '_vv']['code'] .= $character_range[array_rand($character_range)];
            }
        }
        // Getting some new questions?
        if ($thisVerification['number_questions']) {
            // Pick some random IDs
            $questionIDs = array();
            if ($thisVerification['number_questions'] == 1) {
                $questionIDs[] = $modSettings['question_id_cache'][array_rand($modSettings['question_id_cache'], $thisVerification['number_questions'])];
            } else {
                foreach (array_rand($modSettings['question_id_cache'], $thisVerification['number_questions']) as $index) {
                    $questionIDs[] = $modSettings['question_id_cache'][$index];
                }
            }
        }
    } else {
        // Same questions as before.
        $questionIDs = !empty($_SESSION[$verificationOptions['id'] . '_vv']['q']) ? $_SESSION[$verificationOptions['id'] . '_vv']['q'] : array();
        $thisVerification['text_value'] = !empty($_REQUEST[$verificationOptions['id'] . '_vv']['code']) ? $smcFunc['htmlspecialchars']($_REQUEST[$verificationOptions['id'] . '_vv']['code']) : '';
    }
    // Have we got some questions to load?
    if (!empty($questionIDs)) {
        $request = $smcFunc['db_query']('', '
			SELECT id_comment, body AS question
			FROM {db_prefix}log_comments
			WHERE comment_type = {string:ver_test}
				AND id_comment IN ({array_int:comment_ids})', array('ver_test' => 'ver_test', 'comment_ids' => $questionIDs));
        $_SESSION[$verificationOptions['id'] . '_vv']['q'] = array();
        while ($row = $smcFunc['db_fetch_assoc']($request)) {
            $thisVerification['questions'][] = array('id' => $row['id_comment'], 'q' => parse_bbc($row['question']), 'is_error' => !empty($incorrectQuestions) && in_array($row['id_comment'], $incorrectQuestions), 'a' => isset($_REQUEST[$verificationOptions['id'] . '_vv'], $_REQUEST[$verificationOptions['id'] . '_vv']['q'], $_REQUEST[$verificationOptions['id'] . '_vv']['q'][$row['id_comment']]) ? $smcFunc['htmlspecialchars']($_REQUEST[$verificationOptions['id'] . '_vv']['q'][$row['id_comment']]) : '');
            $_SESSION[$verificationOptions['id'] . '_vv']['q'][] = $row['id_comment'];
        }
        $smcFunc['db_free_result']($request);
    }
    $_SESSION[$verificationOptions['id'] . '_vv']['count'] = empty($_SESSION[$verificationOptions['id'] . '_vv']['count']) ? 1 : $_SESSION[$verificationOptions['id'] . '_vv']['count'] + 1;
    // Return errors if we have them.
    if (!empty($verification_errors)) {
        return $verification_errors;
    } elseif ($do_test) {
        $_SESSION[$verificationOptions['id'] . '_vv']['did_pass'] = true;
    }
    // Say that everything went well chaps.
    return true;
}
function Display()
{
    global $scripturl, $txt, $modSettings, $context, $settings;
    global $options, $sourcedir, $user_info, $board_info, $topic, $board;
    global $attachments, $messages_request, $topicinfo, $language, $smcFunc;
    // What are you gonna display if these are empty?!
    if (empty($topic)) {
        fatal_lang_error('no_board', false);
    }
    // Load the proper template and/or sub template.
    if (WIRELESS) {
        $context['sub_template'] = WIRELESS_PROTOCOL . '_display';
    } else {
        loadTemplate('Display');
    }
    // Not only does a prefetch make things slower for the server, but it makes it impossible to know if they read it.
    if (isset($_SERVER['HTTP_X_MOZ']) && $_SERVER['HTTP_X_MOZ'] == 'prefetch') {
        ob_end_clean();
        header('HTTP/1.1 403 Prefetch Forbidden');
        die;
    }
    // How much are we sticking on each page?
    $context['messages_per_page'] = empty($modSettings['disableCustomPerPage']) && !empty($options['messages_per_page']) && !WIRELESS ? $options['messages_per_page'] : $modSettings['defaultMaxMessages'];
    // Let's do some work on what to search index.
    if (count($_GET) > 2) {
        foreach ($_GET as $k => $v) {
            if (!in_array($k, array('topic', 'board', 'start', session_name()))) {
                $context['robot_no_index'] = true;
            }
        }
    }
    if (!empty($_REQUEST['start']) && (!is_numeric($_REQUEST['start']) || $_REQUEST['start'] % $context['messages_per_page'] != 0)) {
        $context['robot_no_index'] = true;
    }
    // Find the previous or next topic.  Make a fuss if there are no more.
    if (isset($_REQUEST['prev_next']) && ($_REQUEST['prev_next'] == 'prev' || $_REQUEST['prev_next'] == 'next')) {
        // No use in calculating the next topic if there's only one.
        if ($board_info['num_topics'] > 1) {
            // Just prepare some variables that are used in the query.
            $gt_lt = $_REQUEST['prev_next'] == 'prev' ? '>' : '<';
            $order = $_REQUEST['prev_next'] == 'prev' ? '' : ' DESC';
            $request = $smcFunc['db_query']('', '
				SELECT t2.id_topic
				FROM {db_prefix}topics AS t
					INNER JOIN {db_prefix}topics AS t2 ON (' . (empty($modSettings['enableStickyTopics']) ? '
					t2.id_last_msg ' . $gt_lt . ' t.id_last_msg' : '
					(t2.id_last_msg ' . $gt_lt . ' t.id_last_msg AND t2.is_sticky ' . $gt_lt . '= t.is_sticky) OR t2.is_sticky ' . $gt_lt . ' t.is_sticky') . ')
				WHERE t.id_topic = {int:current_topic}
					AND t2.id_board = {int:current_board}' . (!$modSettings['postmod_active'] || allowedTo('approve_posts') ? '' : '
					AND (t2.approved = {int:is_approved} OR (t2.id_member_started != {int:id_member_started} AND t2.id_member_started = {int:current_member}))') . '
				ORDER BY' . (empty($modSettings['enableStickyTopics']) ? '' : ' t2.is_sticky' . $order . ',') . ' t2.id_last_msg' . $order . '
				LIMIT 1', array('current_board' => $board, 'current_member' => $user_info['id'], 'current_topic' => $topic, 'is_approved' => 1, 'id_member_started' => 0));
            // No more left.
            if ($smcFunc['db_num_rows']($request) == 0) {
                $smcFunc['db_free_result']($request);
                // Roll over - if we're going prev, get the last - otherwise the first.
                $request = $smcFunc['db_query']('', '
					SELECT id_topic
					FROM {db_prefix}topics
					WHERE id_board = {int:current_board}' . (!$modSettings['postmod_active'] || allowedTo('approve_posts') ? '' : '
						AND (approved = {int:is_approved} OR (id_member_started != {int:id_member_started} AND id_member_started = {int:current_member}))') . '
					ORDER BY' . (empty($modSettings['enableStickyTopics']) ? '' : ' is_sticky' . $order . ',') . ' id_last_msg' . $order . '
					LIMIT 1', array('current_board' => $board, 'current_member' => $user_info['id'], 'is_approved' => 1, 'id_member_started' => 0));
            }
            // Now you can be sure $topic is the id_topic to view.
            list($topic) = $smcFunc['db_fetch_row']($request);
            $smcFunc['db_free_result']($request);
            $context['current_topic'] = $topic;
        }
        // Go to the newest message on this topic.
        $_REQUEST['start'] = 'new';
    }
    // Add 1 to the number of views of this topic.
    if (empty($_SESSION['last_read_topic']) || $_SESSION['last_read_topic'] != $topic) {
        $smcFunc['db_query']('', '
			UPDATE {db_prefix}topics
			SET num_views = num_views + 1
			WHERE id_topic = {int:current_topic}', array('current_topic' => $topic));
        $_SESSION['last_read_topic'] = $topic;
    }
    // Get all the important topic info.
    $request = $smcFunc['db_query']('', '
		SELECT
			t.num_replies, t.num_views, t.locked, ms.subject, t.is_sticky, t.id_poll,
			t.id_member_started, t.id_first_msg, t.id_last_msg, t.approved, t.unapproved_posts,
			' . ($user_info['is_guest'] ? 't.id_last_msg + 1' : 'IFNULL(lt.id_msg, IFNULL(lmr.id_msg, -1)) + 1') . ' AS new_from
			' . (!empty($modSettings['recycle_board']) && $modSettings['recycle_board'] == $board ? ', id_previous_board, id_previous_topic' : '') . '
		FROM {db_prefix}topics AS t
			INNER JOIN {db_prefix}messages AS ms ON (ms.id_msg = t.id_first_msg)' . ($user_info['is_guest'] ? '' : '
			LEFT JOIN {db_prefix}log_topics AS lt ON (lt.id_topic = {int:current_topic} AND lt.id_member = {int:current_member})
			LEFT JOIN {db_prefix}log_mark_read AS lmr ON (lmr.id_board = {int:current_board} AND lmr.id_member = {int:current_member})') . '
		WHERE t.id_topic = {int:current_topic}
		LIMIT 1', array('current_member' => $user_info['id'], 'current_topic' => $topic, 'current_board' => $board));
    if ($smcFunc['db_num_rows']($request) == 0) {
        fatal_lang_error('not_a_topic', false);
    }
    $topicinfo = $smcFunc['db_fetch_assoc']($request);
    $smcFunc['db_free_result']($request);
    $context['real_num_replies'] = $context['num_replies'] = $topicinfo['num_replies'];
    $context['topic_first_message'] = $topicinfo['id_first_msg'];
    $context['topic_last_message'] = $topicinfo['id_last_msg'];
    // Add up unapproved replies to get real number of replies...
    if ($modSettings['postmod_active'] && allowedTo('approve_posts')) {
        $context['real_num_replies'] += $topicinfo['unapproved_posts'] - ($topicinfo['approved'] ? 0 : 1);
    }
    // If this topic has unapproved posts, we need to work out how many posts the user can see, for page indexing.
    if ($modSettings['postmod_active'] && $topicinfo['unapproved_posts'] && !$user_info['is_guest'] && !allowedTo('approve_posts')) {
        $request = $smcFunc['db_query']('', '
			SELECT COUNT(id_member) AS my_unapproved_posts
			FROM {db_prefix}messages
			WHERE id_topic = {int:current_topic}
				AND id_member = {int:current_member}
				AND approved = 0', array('current_topic' => $topic, 'current_member' => $user_info['id']));
        list($myUnapprovedPosts) = $smcFunc['db_fetch_row']($request);
        $smcFunc['db_free_result']($request);
        $context['total_visible_posts'] = $context['num_replies'] + $myUnapprovedPosts + ($topicinfo['approved'] ? 1 : 0);
    } else {
        $context['total_visible_posts'] = $context['num_replies'] + $topicinfo['unapproved_posts'] + ($topicinfo['approved'] ? 1 : 0);
    }
    // When was the last time this topic was replied to?  Should we warn them about it?
    $request = $smcFunc['db_query']('', '
		SELECT poster_time
		FROM {db_prefix}messages
		WHERE id_msg = {int:id_last_msg}
		LIMIT 1', array('id_last_msg' => $topicinfo['id_last_msg']));
    list($lastPostTime) = $smcFunc['db_fetch_row']($request);
    $smcFunc['db_free_result']($request);
    $context['oldTopicError'] = !empty($modSettings['oldTopicDays']) && $lastPostTime + $modSettings['oldTopicDays'] * 86400 < time() && empty($sticky);
    // The start isn't a number; it's information about what to do, where to go.
    if (!is_numeric($_REQUEST['start'])) {
        // Redirect to the page and post with new messages, originally by Omar Bazavilvazo.
        if ($_REQUEST['start'] == 'new') {
            // Guests automatically go to the last post.
            if ($user_info['is_guest']) {
                $context['start_from'] = $context['total_visible_posts'] - 1;
                $_REQUEST['start'] = empty($options['view_newest_first']) ? $context['start_from'] : 0;
            } else {
                // Find the earliest unread message in the topic. (the use of topics here is just for both tables.)
                $request = $smcFunc['db_query']('', '
					SELECT IFNULL(lt.id_msg, IFNULL(lmr.id_msg, -1)) + 1 AS new_from
					FROM {db_prefix}topics AS t
						LEFT JOIN {db_prefix}log_topics AS lt ON (lt.id_topic = {int:current_topic} AND lt.id_member = {int:current_member})
						LEFT JOIN {db_prefix}log_mark_read AS lmr ON (lmr.id_board = {int:current_board} AND lmr.id_member = {int:current_member})
					WHERE t.id_topic = {int:current_topic}
					LIMIT 1', array('current_board' => $board, 'current_member' => $user_info['id'], 'current_topic' => $topic));
                list($new_from) = $smcFunc['db_fetch_row']($request);
                $smcFunc['db_free_result']($request);
                // Fall through to the next if statement.
                $_REQUEST['start'] = 'msg' . $new_from;
            }
        }
        // Start from a certain time index, not a message.
        if (substr($_REQUEST['start'], 0, 4) == 'from') {
            $timestamp = (int) substr($_REQUEST['start'], 4);
            if ($timestamp === 0) {
                $_REQUEST['start'] = 0;
            } else {
                // Find the number of messages posted before said time...
                $request = $smcFunc['db_query']('', '
					SELECT COUNT(*)
					FROM {db_prefix}messages
					WHERE poster_time < {int:timestamp}
						AND id_topic = {int:current_topic}' . ($modSettings['postmod_active'] && $topicinfo['unapproved_posts'] && !allowedTo('approve_posts') ? '
						AND (approved = {int:is_approved}' . ($user_info['is_guest'] ? '' : ' OR id_member = {int:current_member}') . ')' : ''), array('current_topic' => $topic, 'current_member' => $user_info['id'], 'is_approved' => 1, 'timestamp' => $timestamp));
                list($context['start_from']) = $smcFunc['db_fetch_row']($request);
                $smcFunc['db_free_result']($request);
                // Handle view_newest_first options, and get the correct start value.
                $_REQUEST['start'] = empty($options['view_newest_first']) ? $context['start_from'] : $context['total_visible_posts'] - $context['start_from'] - 1;
            }
        } elseif (substr($_REQUEST['start'], 0, 3) == 'msg') {
            $virtual_msg = (int) substr($_REQUEST['start'], 3);
            if (!$topicinfo['unapproved_posts'] && $virtual_msg >= $topicinfo['id_last_msg']) {
                $context['start_from'] = $context['total_visible_posts'] - 1;
            } elseif (!$topicinfo['unapproved_posts'] && $virtual_msg <= $topicinfo['id_first_msg']) {
                $context['start_from'] = 0;
            } else {
                // Find the start value for that message......
                $request = $smcFunc['db_query']('', '
					SELECT COUNT(*)
					FROM {db_prefix}messages
					WHERE id_msg < {int:virtual_msg}
						AND id_topic = {int:current_topic}' . ($modSettings['postmod_active'] && $topicinfo['unapproved_posts'] && !allowedTo('approve_posts') ? '
						AND (approved = {int:is_approved}' . ($user_info['is_guest'] ? '' : ' OR id_member = {int:current_member}') . ')' : ''), array('current_member' => $user_info['id'], 'current_topic' => $topic, 'virtual_msg' => $virtual_msg, 'is_approved' => 1, 'no_member' => 0));
                list($context['start_from']) = $smcFunc['db_fetch_row']($request);
                $smcFunc['db_free_result']($request);
            }
            // We need to reverse the start as well in this case.
            $_REQUEST['start'] = empty($options['view_newest_first']) ? $context['start_from'] : $context['total_visible_posts'] - $context['start_from'] - 1;
        }
    }
    // Create a previous next string if the selected theme has it as a selected option.
    $context['previous_next'] = $modSettings['enablePreviousNext'] ? '<a href="' . $scripturl . '?topic=' . $topic . '.0;prev_next=prev#new">' . $txt['previous_next_back'] . '</a> <a href="' . $scripturl . '?topic=' . $topic . '.0;prev_next=next#new">' . $txt['previous_next_forward'] . '</a>' : '';
    // Check if spellchecking is both enabled and actually working. (for quick reply.)
    $context['show_spellchecking'] = !empty($modSettings['enableSpellChecking']) && function_exists('pspell_new');
    // Do we need to show the visual verification image?
    $context['require_verification'] = !$user_info['is_mod'] && !$user_info['is_admin'] && !empty($modSettings['posts_require_captcha']) && ($user_info['posts'] < $modSettings['posts_require_captcha'] || $user_info['is_guest'] && $modSettings['posts_require_captcha'] == -1);
    if ($context['require_verification']) {
        require_once $sourcedir . '/Subs-Editor.php';
        $verificationOptions = array('id' => 'post');
        $context['require_verification'] = create_control_verification($verificationOptions);
        $context['visual_verification_id'] = $verificationOptions['id'];
    }
    // Are we showing signatures - or disabled fields?
    $context['signature_enabled'] = substr($modSettings['signature_settings'], 0, 1) == 1;
    $context['disabled_fields'] = isset($modSettings['disabled_profile_fields']) ? array_flip(explode(',', $modSettings['disabled_profile_fields'])) : array();
    // Censor the title...
    censorText($topicinfo['subject']);
    $context['page_title'] = $topicinfo['subject'];
    // Is this already an article?
    $request = $smcFunc['db_query']('', '
		SELECT id_message
		FROM {db_prefix}sp_articles
		WHERE id_message = {int:message}', array('message' => $context['topic_first_message']));
    list($context['topic_is_article']) = $smcFunc['db_fetch_row']($request);
    $smcFunc['db_free_result']($request);
    // Is this topic sticky, or can it even be?
    $topicinfo['is_sticky'] = empty($modSettings['enableStickyTopics']) ? '0' : $topicinfo['is_sticky'];
    // Default this topic to not marked for notifications... of course...
    $context['is_marked_notify'] = false;
    // Did we report a post to a moderator just now?
    $context['report_sent'] = isset($_GET['reportsent']);
    // Let's get nosey, who is viewing this topic?
    if (!empty($settings['display_who_viewing'])) {
        // Start out with no one at all viewing it.
        $context['view_members'] = array();
        $context['view_members_list'] = array();
        $context['view_num_hidden'] = 0;
        // Search for members who have this topic set in their GET data.
        $request = $smcFunc['db_query']('', '
			SELECT
				lo.id_member, lo.log_time, mem.real_name, mem.member_name, mem.show_online,
				mg.online_color, mg.id_group, mg.group_name
			FROM {db_prefix}log_online AS lo
				LEFT JOIN {db_prefix}members AS mem ON (mem.id_member = lo.id_member)
				LEFT JOIN {db_prefix}membergroups AS mg ON (mg.id_group = CASE WHEN mem.id_group = {int:reg_id_group} THEN mem.id_post_group ELSE mem.id_group END)
			WHERE INSTR(lo.url, {string:in_url_string}) > 0 OR lo.session = {string:session}', array('reg_id_group' => 0, 'in_url_string' => 's:5:"topic";i:' . $topic . ';', 'session' => $user_info['is_guest'] ? 'ip' . $user_info['ip'] : session_id()));
        while ($row = $smcFunc['db_fetch_assoc']($request)) {
            if (empty($row['id_member'])) {
                continue;
            }
            if (!empty($row['online_color'])) {
                $link = '<a href="' . $scripturl . '?action=profile;u=' . $row['id_member'] . '" style="color: ' . $row['online_color'] . ';">' . $row['real_name'] . '</a>';
            } else {
                $link = '<a href="' . $scripturl . '?action=profile;u=' . $row['id_member'] . '">' . $row['real_name'] . '</a>';
            }
            $is_buddy = in_array($row['id_member'], $user_info['buddies']);
            if ($is_buddy) {
                $link = '<strong>' . $link . '</strong>';
            }
            // Add them both to the list and to the more detailed list.
            if (!empty($row['show_online']) || allowedTo('moderate_forum')) {
                $context['view_members_list'][$row['log_time'] . $row['member_name']] = empty($row['show_online']) ? '<em>' . $link . '</em>' : $link;
            }
            $context['view_members'][$row['log_time'] . $row['member_name']] = array('id' => $row['id_member'], 'username' => $row['member_name'], 'name' => $row['real_name'], 'group' => $row['id_group'], 'href' => $scripturl . '?action=profile;u=' . $row['id_member'], 'link' => $link, 'is_buddy' => $is_buddy, 'hidden' => empty($row['show_online']));
            if (empty($row['show_online'])) {
                $context['view_num_hidden']++;
            }
        }
        // The number of guests is equal to the rows minus the ones we actually used ;).
        $context['view_num_guests'] = $smcFunc['db_num_rows']($request) - count($context['view_members']);
        $smcFunc['db_free_result']($request);
        // Sort the list.
        krsort($context['view_members']);
        krsort($context['view_members_list']);
    }
    // If all is set, but not allowed... just unset it.
    $can_show_all = !empty($modSettings['enableAllMessages']) && $context['total_visible_posts'] > $context['messages_per_page'] && $context['total_visible_posts'] < $modSettings['enableAllMessages'];
    if (isset($_REQUEST['all']) && !$can_show_all) {
        unset($_REQUEST['all']);
    } elseif (isset($_REQUEST['all'])) {
        $_REQUEST['start'] = -1;
    }
    // Construct the page index, allowing for the .START method...
    $context['page_index'] = constructPageIndex($scripturl . '?topic=' . $topic . '.%1$d', $_REQUEST['start'], $context['total_visible_posts'], $context['messages_per_page'], true);
    $context['start'] = $_REQUEST['start'];
    // This is information about which page is current, and which page we're on - in case you don't like the constructed page index. (again, wireles..)
    $context['page_info'] = array('current_page' => $_REQUEST['start'] / $context['messages_per_page'] + 1, 'num_pages' => floor(($context['total_visible_posts'] - 1) / $context['messages_per_page']) + 1);
    // Figure out all the link to the next/prev/first/last/etc. for wireless mainly.
    $context['links'] = array('first' => $_REQUEST['start'] >= $context['messages_per_page'] ? $scripturl . '?topic=' . $topic . '.0' : '', 'prev' => $_REQUEST['start'] >= $context['messages_per_page'] ? $scripturl . '?topic=' . $topic . '.' . ($_REQUEST['start'] - $context['messages_per_page']) : '', 'next' => $_REQUEST['start'] + $context['messages_per_page'] < $context['total_visible_posts'] ? $scripturl . '?topic=' . $topic . '.' . ($_REQUEST['start'] + $context['messages_per_page']) : '', 'last' => $_REQUEST['start'] + $context['messages_per_page'] < $context['total_visible_posts'] ? $scripturl . '?topic=' . $topic . '.' . floor($context['total_visible_posts'] / $context['messages_per_page']) * $context['messages_per_page'] : '', 'up' => $scripturl . '?board=' . $board . '.0');
    // If they are viewing all the posts, show all the posts, otherwise limit the number.
    if ($can_show_all) {
        if (isset($_REQUEST['all'])) {
            // No limit! (actually, there is a limit, but...)
            $context['messages_per_page'] = -1;
            $context['page_index'] .= empty($modSettings['compactTopicPagesEnable']) ? '<strong>' . $txt['all'] . '</strong> ' : '[<strong>' . $txt['all'] . '</strong>] ';
            // Set start back to 0...
            $_REQUEST['start'] = 0;
        } else {
            $context['page_index'] .= '&nbsp;<a href="' . $scripturl . '?topic=' . $topic . '.0;all">' . $txt['all'] . '</a> ';
        }
    }
    // Build the link tree.
    $context['linktree'][] = array('url' => $scripturl . '?topic=' . $topic . '.0', 'name' => $topicinfo['subject'], 'extra_before' => $settings['linktree_inline'] ? $txt['topic'] . ': ' : '');
    // Build a list of this board's moderators.
    $context['moderators'] =& $board_info['moderators'];
    $context['link_moderators'] = array();
    if (!empty($board_info['moderators'])) {
        // Add a link for each moderator...
        foreach ($board_info['moderators'] as $mod) {
            $context['link_moderators'][] = '<a href="' . $scripturl . '?action=profile;u=' . $mod['id'] . '" title="' . $txt['board_moderator'] . '">' . $mod['name'] . '</a>';
        }
        // And show it after the board's name.
        $context['linktree'][count($context['linktree']) - 2]['extra_after'] = ' (' . (count($context['link_moderators']) == 1 ? $txt['moderator'] : $txt['moderators']) . ': ' . implode(', ', $context['link_moderators']) . ')';
    }
    // Information about the current topic...
    $context['is_locked'] = $topicinfo['locked'];
    $context['is_sticky'] = $topicinfo['is_sticky'];
    $context['is_very_hot'] = $topicinfo['num_replies'] >= $modSettings['hotTopicVeryPosts'];
    $context['is_hot'] = $topicinfo['num_replies'] >= $modSettings['hotTopicPosts'];
    $context['is_approved'] = $topicinfo['approved'];
    // We don't want to show the poll icon in the topic class here, so pretend it's not one.
    $context['is_poll'] = false;
    determineTopicClass($context);
    $context['is_poll'] = $topicinfo['id_poll'] > 0 && $modSettings['pollMode'] == '1' && allowedTo('poll_view');
    // Did this user start the topic or not?
    $context['user']['started'] = $user_info['id'] == $topicinfo['id_member_started'] && !$user_info['is_guest'];
    $context['topic_starter_id'] = $topicinfo['id_member_started'];
    // Set the topic's information for the template.
    $context['subject'] = $topicinfo['subject'];
    $context['num_views'] = $topicinfo['num_views'];
    $context['mark_unread_time'] = $topicinfo['new_from'];
    // Set a canonical URL for this page.
    $context['canonical_url'] = $scripturl . '?topic=' . $topic . '.' . $context['start'];
    // For quick reply we need a response prefix in the default forum language.
    if (!isset($context['response_prefix']) && !($context['response_prefix'] = cache_get_data('response_prefix', 600))) {
        if ($language === $user_info['language']) {
            $context['response_prefix'] = $txt['response_prefix'];
        } else {
            loadLanguage('index', $language, false);
            $context['response_prefix'] = $txt['response_prefix'];
            loadLanguage('index');
        }
        cache_put_data('response_prefix', $context['response_prefix'], 600);
    }
    // If we want to show event information in the topic, prepare the data.
    if (allowedTo('calendar_view') && !empty($modSettings['cal_showInTopic']) && !empty($modSettings['cal_enabled'])) {
        // First, try create a better time format, ignoring the "time" elements.
        if (preg_match('~%[AaBbCcDdeGghjmuYy](?:[^%]*%[AaBbCcDdeGghjmuYy])*~', $user_info['time_format'], $matches) == 0 || empty($matches[0])) {
            $date_string = $user_info['time_format'];
        } else {
            $date_string = $matches[0];
        }
        // Any calendar information for this topic?
        $request = $smcFunc['db_query']('', '
			SELECT cal.id_event, cal.start_date, cal.end_date, cal.title, cal.id_member, mem.real_name
			FROM {db_prefix}calendar AS cal
				LEFT JOIN {db_prefix}members AS mem ON (mem.id_member = cal.id_member)
			WHERE cal.id_topic = {int:current_topic}
			ORDER BY start_date', array('current_topic' => $topic));
        $context['linked_calendar_events'] = array();
        while ($row = $smcFunc['db_fetch_assoc']($request)) {
            // Prepare the dates for being formatted.
            $start_date = sscanf($row['start_date'], '%04d-%02d-%02d');
            $start_date = mktime(12, 0, 0, $start_date[1], $start_date[2], $start_date[0]);
            $end_date = sscanf($row['end_date'], '%04d-%02d-%02d');
            $end_date = mktime(12, 0, 0, $end_date[1], $end_date[2], $end_date[0]);
            $context['linked_calendar_events'][] = array('id' => $row['id_event'], 'title' => $row['title'], 'can_edit' => allowedTo('calendar_edit_any') || $row['id_member'] == $user_info['id'] && allowedTo('calendar_edit_own'), 'modify_href' => $scripturl . '?action=post;msg=' . $topicinfo['id_first_msg'] . ';topic=' . $topic . '.0;calendar;eventid=' . $row['id_event'] . ';' . $context['session_var'] . '=' . $context['session_id'], 'start_date' => timeformat($start_date, $date_string, 'none'), 'start_timestamp' => $start_date, 'end_date' => timeformat($end_date, $date_string, 'none'), 'end_timestamp' => $end_date, 'is_last' => false);
        }
        $smcFunc['db_free_result']($request);
        if (!empty($context['linked_calendar_events'])) {
            $context['linked_calendar_events'][count($context['linked_calendar_events']) - 1]['is_last'] = true;
        }
    }
    // Create the poll info if it exists.
    if ($context['is_poll']) {
        // Get the question and if it's locked.
        $request = $smcFunc['db_query']('', '
			SELECT
				p.question, p.voting_locked, p.hide_results, p.expire_time, p.max_votes, p.change_vote,
				p.guest_vote, p.id_member, IFNULL(mem.real_name, p.poster_name) AS poster_name, p.num_guest_voters, p.reset_poll
			FROM {db_prefix}polls AS p
				LEFT JOIN {db_prefix}members AS mem ON (mem.id_member = p.id_member)
			WHERE p.id_poll = {int:id_poll}
			LIMIT 1', array('id_poll' => $topicinfo['id_poll']));
        $pollinfo = $smcFunc['db_fetch_assoc']($request);
        $smcFunc['db_free_result']($request);
        $request = $smcFunc['db_query']('', '
			SELECT COUNT(DISTINCT id_member) AS total
			FROM {db_prefix}log_polls
			WHERE id_poll = {int:id_poll}
				AND id_member != {int:not_guest}', array('id_poll' => $topicinfo['id_poll'], 'not_guest' => 0));
        list($pollinfo['total']) = $smcFunc['db_fetch_row']($request);
        $smcFunc['db_free_result']($request);
        // Total voters needs to include guest voters
        $pollinfo['total'] += $pollinfo['num_guest_voters'];
        // Get all the options, and calculate the total votes.
        $request = $smcFunc['db_query']('', '
			SELECT pc.id_choice, pc.label, pc.votes, IFNULL(lp.id_choice, -1) AS voted_this
			FROM {db_prefix}poll_choices AS pc
				LEFT JOIN {db_prefix}log_polls AS lp ON (lp.id_choice = pc.id_choice AND lp.id_poll = {int:id_poll} AND lp.id_member = {int:current_member} AND lp.id_member != {int:not_guest})
			WHERE pc.id_poll = {int:id_poll}', array('current_member' => $user_info['id'], 'id_poll' => $topicinfo['id_poll'], 'not_guest' => 0));
        $pollOptions = array();
        $realtotal = 0;
        $pollinfo['has_voted'] = false;
        while ($row = $smcFunc['db_fetch_assoc']($request)) {
            censorText($row['label']);
            $pollOptions[$row['id_choice']] = $row;
            $realtotal += $row['votes'];
            $pollinfo['has_voted'] |= $row['voted_this'] != -1;
        }
        $smcFunc['db_free_result']($request);
        // If this is a guest we need to do our best to work out if they have voted, and what they voted for.
        if ($user_info['is_guest'] && $pollinfo['guest_vote'] && allowedTo('poll_vote')) {
            if (!empty($_COOKIE['guest_poll_vote']) && preg_match('~^[0-9,;]+$~', $_COOKIE['guest_poll_vote']) && strpos($_COOKIE['guest_poll_vote'], ';' . $topicinfo['id_poll'] . ',') !== false) {
                // ;id,timestamp,[vote,vote...]; etc
                $guestinfo = explode(';', $_COOKIE['guest_poll_vote']);
                // Find the poll we're after.
                foreach ($guestinfo as $i => $guestvoted) {
                    $guestvoted = explode(',', $guestvoted);
                    if ($guestvoted[0] == $topicinfo['id_poll']) {
                        break;
                    }
                }
                // Has the poll been reset since guest voted?
                if ($pollinfo['reset_poll'] > $guestvoted[1]) {
                    // Remove the poll info from the cookie to allow guest to vote again
                    unset($guestinfo[$i]);
                    if (!empty($guestinfo)) {
                        $_COOKIE['guest_poll_vote'] = ';' . implode(';', $guestinfo);
                    } else {
                        unset($_COOKIE['guest_poll_vote']);
                    }
                } else {
                    // What did they vote for?
                    unset($guestvoted[0], $guestvoted[1]);
                    foreach ($pollOptions as $choice => $details) {
                        $pollOptions[$choice]['voted_this'] = in_array($choice, $guestvoted) ? 1 : -1;
                        $pollinfo['has_voted'] |= $pollOptions[$choice]['voted_this'] != -1;
                    }
                    unset($choice, $details, $guestvoted);
                }
                unset($guestinfo, $guestvoted, $i);
            }
        }
        // Set up the basic poll information.
        $context['poll'] = array('id' => $topicinfo['id_poll'], 'image' => 'normal_' . (empty($pollinfo['voting_locked']) ? 'poll' : 'locked_poll'), 'question' => parse_bbc($pollinfo['question']), 'total_votes' => $pollinfo['total'], 'change_vote' => !empty($pollinfo['change_vote']), 'is_locked' => !empty($pollinfo['voting_locked']), 'options' => array(), 'lock' => allowedTo('poll_lock_any') || $context['user']['started'] && allowedTo('poll_lock_own'), 'edit' => allowedTo('poll_edit_any') || $context['user']['started'] && allowedTo('poll_edit_own'), 'allowed_warning' => $pollinfo['max_votes'] > 1 ? sprintf($txt['poll_options6'], min(count($pollOptions), $pollinfo['max_votes'])) : '', 'is_expired' => !empty($pollinfo['expire_time']) && $pollinfo['expire_time'] < time(), 'expire_time' => !empty($pollinfo['expire_time']) ? timeformat($pollinfo['expire_time']) : 0, 'has_voted' => !empty($pollinfo['has_voted']), 'starter' => array('id' => $pollinfo['id_member'], 'name' => $row['poster_name'], 'href' => $pollinfo['id_member'] == 0 ? '' : $scripturl . '?action=profile;u=' . $pollinfo['id_member'], 'link' => $pollinfo['id_member'] == 0 ? $row['poster_name'] : '<a href="' . $scripturl . '?action=profile;u=' . $pollinfo['id_member'] . '">' . $row['poster_name'] . '</a>'));
        // Make the lock and edit permissions defined above more directly accessible.
        $context['allow_lock_poll'] = $context['poll']['lock'];
        $context['allow_edit_poll'] = $context['poll']['edit'];
        // You're allowed to vote if:
        // 1. the poll did not expire, and
        // 2. you're either not a guest OR guest voting is enabled... and
        // 3. you're not trying to view the results, and
        // 4. the poll is not locked, and
        // 5. you have the proper permissions, and
        // 6. you haven't already voted before.
        $context['allow_vote'] = !$context['poll']['is_expired'] && (!$user_info['is_guest'] || $pollinfo['guest_vote'] && allowedTo('poll_vote')) && empty($pollinfo['voting_locked']) && allowedTo('poll_vote') && !$context['poll']['has_voted'];
        // You're allowed to view the results if:
        // 1. you're just a super-nice-guy, or
        // 2. anyone can see them (hide_results == 0), or
        // 3. you can see them after you voted (hide_results == 1), or
        // 4. you've waited long enough for the poll to expire. (whether hide_results is 1 or 2.)
        $context['allow_poll_view'] = allowedTo('moderate_board') || $pollinfo['hide_results'] == 0 || $pollinfo['hide_results'] == 1 && $context['poll']['has_voted'] || $context['poll']['is_expired'];
        $context['poll']['show_results'] = $context['allow_poll_view'] && (isset($_REQUEST['viewresults']) || isset($_REQUEST['viewResults']));
        $context['show_view_results_button'] = $context['allow_vote'] && (!$context['allow_poll_view'] || !$context['poll']['show_results'] || !$context['poll']['has_voted']);
        // You're allowed to change your vote if:
        // 1. the poll did not expire, and
        // 2. you're not a guest... and
        // 3. the poll is not locked, and
        // 4. you have the proper permissions, and
        // 5. you have already voted, and
        // 6. the poll creator has said you can!
        $context['allow_change_vote'] = !$context['poll']['is_expired'] && !$user_info['is_guest'] && empty($pollinfo['voting_locked']) && allowedTo('poll_vote') && $context['poll']['has_voted'] && $context['poll']['change_vote'];
        // You're allowed to return to voting options if:
        // 1. you are (still) allowed to vote.
        // 2. you are currently seeing the results.
        $context['allow_return_vote'] = $context['allow_vote'] && $context['poll']['show_results'];
        // Calculate the percentages and bar lengths...
        $divisor = $realtotal == 0 ? 1 : $realtotal;
        // Determine if a decimal point is needed in order for the options to add to 100%.
        $precision = $realtotal == 100 ? 0 : 1;
        // Now look through each option, and...
        foreach ($pollOptions as $i => $option) {
            // First calculate the percentage, and then the width of the bar...
            $bar = round($option['votes'] * 100 / $divisor, $precision);
            $barWide = $bar == 0 ? 1 : floor($bar * 8 / 3);
            // Now add it to the poll's contextual theme data.
            $context['poll']['options'][$i] = array('id' => 'options-' . $i, 'percent' => $bar, 'votes' => $option['votes'], 'voted_this' => $option['voted_this'] != -1, '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>', 'bar_ndt' => $bar > 0 ? '<div class="bar" style="width: ' . ($bar * 3.5 + 4) . 'px;"><div style="width: ' . $bar * 3.5 . 'px;"></div></div>' : '', 'bar_width' => $barWide, 'option' => parse_bbc($option['label']), 'vote_button' => '<input type="' . ($pollinfo['max_votes'] > 1 ? 'checkbox' : 'radio') . '" name="options[]" id="options-' . $i . '" value="' . $i . '" class="input_' . ($pollinfo['max_votes'] > 1 ? 'check' : 'radio') . '" />');
        }
    }
    // Calculate the fastest way to get the messages!
    $ascending = empty($options['view_newest_first']);
    $start = $_REQUEST['start'];
    $limit = $context['messages_per_page'];
    $firstIndex = 0;
    if ($start >= $context['total_visible_posts'] / 2 && $context['messages_per_page'] != -1) {
        $ascending = !$ascending;
        $limit = $context['total_visible_posts'] <= $start + $limit ? $context['total_visible_posts'] - $start : $limit;
        $start = $context['total_visible_posts'] <= $start + $limit ? 0 : $context['total_visible_posts'] - $start - $limit;
        $firstIndex = $limit - 1;
    }
    // Get each post and poster in this topic.
    $request = $smcFunc['db_query']('display_get_post_poster', '
		SELECT id_msg, id_member, approved
		FROM {db_prefix}messages
		WHERE id_topic = {int:current_topic}' . (!$modSettings['postmod_active'] || allowedTo('approve_posts') ? '' : (!empty($modSettings['db_mysql_group_by_fix']) ? '' : '
		GROUP BY id_msg') . '
		HAVING (approved = {int:is_approved}' . ($user_info['is_guest'] ? '' : ' OR id_member = {int:current_member}') . ')') . '
		ORDER BY id_msg ' . ($ascending ? '' : 'DESC') . ($context['messages_per_page'] == -1 ? '' : '
		LIMIT ' . $start . ', ' . $limit), array('current_member' => $user_info['id'], 'current_topic' => $topic, 'is_approved' => 1, 'blank_id_member' => 0));
    $messages = array();
    $all_posters = array();
    while ($row = $smcFunc['db_fetch_assoc']($request)) {
        if (!empty($row['id_member'])) {
            $all_posters[$row['id_msg']] = $row['id_member'];
        }
        $messages[] = $row['id_msg'];
    }
    $smcFunc['db_free_result']($request);
    $posters = array_unique($all_posters);
    // Guests can't mark topics read or for notifications, just can't sorry.
    if (!$user_info['is_guest']) {
        $mark_at_msg = max($messages);
        if ($mark_at_msg >= $topicinfo['id_last_msg']) {
            $mark_at_msg = $modSettings['maxMsgID'];
        }
        if ($mark_at_msg >= $topicinfo['new_from']) {
            $smcFunc['db_insert']($topicinfo['new_from'] == 0 ? 'ignore' : 'replace', '{db_prefix}log_topics', array('id_member' => 'int', 'id_topic' => 'int', 'id_msg' => 'int'), array($user_info['id'], $topic, $mark_at_msg), array('id_member', 'id_topic'));
        }
        // Check for notifications on this topic OR board.
        $request = $smcFunc['db_query']('', '
			SELECT sent, id_topic
			FROM {db_prefix}log_notify
			WHERE (id_topic = {int:current_topic} OR id_board = {int:current_board})
				AND id_member = {int:current_member}
			LIMIT 2', array('current_board' => $board, 'current_member' => $user_info['id'], 'current_topic' => $topic));
        $do_once = true;
        while ($row = $smcFunc['db_fetch_assoc']($request)) {
            // Find if this topic is marked for notification...
            if (!empty($row['id_topic'])) {
                $context['is_marked_notify'] = true;
            }
            // Only do this once, but mark the notifications as "not sent yet" for next time.
            if (!empty($row['sent']) && $do_once) {
                $smcFunc['db_query']('', '
					UPDATE {db_prefix}log_notify
					SET sent = {int:is_not_sent}
					WHERE (id_topic = {int:current_topic} OR id_board = {int:current_board})
						AND id_member = {int:current_member}', array('current_board' => $board, 'current_member' => $user_info['id'], 'current_topic' => $topic, 'is_not_sent' => 0));
                $do_once = false;
            }
        }
        // Have we recently cached the number of new topics in this board, and it's still a lot?
        if (isset($_REQUEST['topicseen']) && isset($_SESSION['topicseen_cache'][$board]) && $_SESSION['topicseen_cache'][$board] > 5) {
            $_SESSION['topicseen_cache'][$board]--;
        } elseif (isset($_REQUEST['topicseen'])) {
            // Use the mark read tables... and the last visit to figure out if this should be read or not.
            $request = $smcFunc['db_query']('', '
				SELECT COUNT(*)
				FROM {db_prefix}topics AS t
					LEFT JOIN {db_prefix}log_boards AS lb ON (lb.id_board = {int:current_board} AND lb.id_member = {int:current_member})
					LEFT JOIN {db_prefix}log_topics AS lt ON (lt.id_topic = t.id_topic AND lt.id_member = {int:current_member})
				WHERE t.id_board = {int:current_board}
					AND t.id_last_msg > IFNULL(lb.id_msg, 0)
					AND t.id_last_msg > IFNULL(lt.id_msg, 0)' . (empty($_SESSION['id_msg_last_visit']) ? '' : '
					AND t.id_last_msg > {int:id_msg_last_visit}'), array('current_board' => $board, 'current_member' => $user_info['id'], 'id_msg_last_visit' => (int) $_SESSION['id_msg_last_visit']));
            list($numNewTopics) = $smcFunc['db_fetch_row']($request);
            $smcFunc['db_free_result']($request);
            // If there're no real new topics in this board, mark the board as seen.
            if (empty($numNewTopics)) {
                $_REQUEST['boardseen'] = true;
            } else {
                $_SESSION['topicseen_cache'][$board] = $numNewTopics;
            }
        } elseif (isset($_SESSION['topicseen_cache'][$board])) {
            $_SESSION['topicseen_cache'][$board]--;
        }
        // Mark board as seen if we came using last post link from BoardIndex. (or other places...)
        if (isset($_REQUEST['boardseen'])) {
            $smcFunc['db_insert']('replace', '{db_prefix}log_boards', array('id_msg' => 'int', 'id_member' => 'int', 'id_board' => 'int'), array($modSettings['maxMsgID'], $user_info['id'], $board), array('id_member', 'id_board'));
        }
    }
    $attachments = array();
    // If there _are_ messages here... (probably an error otherwise :!)
    if (!empty($messages)) {
        // Fetch attachments.
        if (!empty($modSettings['attachmentEnable']) && allowedTo('view_attachments')) {
            $request = $smcFunc['db_query']('', '
				SELECT
					a.id_attach, a.id_folder, a.id_msg, a.filename, a.file_hash, IFNULL(a.size, 0) AS filesize, a.downloads, a.approved,
					a.width, a.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') . '
				FROM {db_prefix}attachments AS a' . (empty($modSettings['attachmentShowImages']) || empty($modSettings['attachmentThumbnails']) ? '' : '
					LEFT JOIN {db_prefix}attachments AS thumb ON (thumb.id_attach = a.id_thumb)') . '
				WHERE a.id_msg IN ({array_int:message_list})
					AND a.attachment_type = {int:attachment_type}', array('message_list' => $messages, 'attachment_type' => 0, 'is_approved' => 1));
            $temp = array();
            while ($row = $smcFunc['db_fetch_assoc']($request)) {
                if (!$row['approved'] && $modSettings['postmod_active'] && !allowedTo('approve_posts') && (!isset($all_posters[$row['id_msg']]) || $all_posters[$row['id_msg']] != $user_info['id'])) {
                    continue;
                }
                $temp[$row['id_attach']] = $row;
                if (!isset($attachments[$row['id_msg']])) {
                    $attachments[$row['id_msg']] = array();
                }
            }
            $smcFunc['db_free_result']($request);
            // This is better than sorting it with the query...
            ksort($temp);
            foreach ($temp as $row) {
                $attachments[$row['id_msg']][] = $row;
            }
        }
        // What?  It's not like it *couldn't* be only guests in this topic...
        if (!empty($posters)) {
            loadMemberData($posters);
        }
        $messages_request = $smcFunc['db_query']('', '
			SELECT
				id_msg, icon, subject, poster_time, poster_ip, id_member, modified_time, modified_name, body,
				smileys_enabled, poster_name, poster_email, approved,
				id_msg_modified < {int:new_from} AS is_read
			FROM {db_prefix}messages
			WHERE id_msg IN ({array_int:message_list})
			ORDER BY id_msg' . (empty($options['view_newest_first']) ? '' : ' DESC'), array('message_list' => $messages, 'new_from' => $topicinfo['new_from']));
        // Go to the last message if the given time is beyond the time of the last message.
        if (isset($context['start_from']) && $context['start_from'] >= $topicinfo['num_replies']) {
            $context['start_from'] = $topicinfo['num_replies'];
        }
        // Since the anchor information is needed on the top of the page we load these variables beforehand.
        $context['first_message'] = isset($messages[$firstIndex]) ? $messages[$firstIndex] : $messages[0];
        if (empty($options['view_newest_first'])) {
            $context['first_new_message'] = isset($context['start_from']) && $_REQUEST['start'] == $context['start_from'];
        } else {
            $context['first_new_message'] = isset($context['start_from']) && $_REQUEST['start'] == $topicinfo['num_replies'] - $context['start_from'];
        }
    } else {
        $messages_request = false;
        $context['first_message'] = 0;
        $context['first_new_message'] = false;
    }
    $context['jump_to'] = array('label' => addslashes(un_htmlspecialchars($txt['jump_to'])), 'board_name' => htmlspecialchars(strtr(strip_tags($board_info['name']), array('&amp;' => '&'))), 'child_level' => $board_info['child_level']);
    // Set the callback.  (do you REALIZE how much memory all the messages would take?!?)
    $context['get_message'] = 'prepareDisplayContext';
    // Now set all the wonderful, wonderful permissions... like moderation ones...
    $common_permissions = array('can_approve' => 'approve_posts', 'can_ban' => 'manage_bans', 'can_sticky' => 'make_sticky', 'can_merge' => 'merge_any', 'can_split' => 'split_any', 'calendar_post' => 'calendar_post', 'can_mark_notify' => 'mark_any_notify', 'can_send_topic' => 'send_topic', 'can_send_pm' => 'pm_send', 'can_report_moderator' => 'report_any', 'can_moderate_forum' => 'moderate_forum', 'can_issue_warning' => 'issue_warning', 'can_restore_topic' => 'move_any', 'can_restore_msg' => 'move_any');
    foreach ($common_permissions as $contextual => $perm) {
        $context[$contextual] = allowedTo($perm);
    }
    // Permissions with _any/_own versions.  $context[YYY] => ZZZ_any/_own.
    $anyown_permissions = array('can_move' => 'move', 'can_lock' => 'lock', 'can_delete' => 'remove', 'can_add_poll' => 'poll_add', 'can_remove_poll' => 'poll_remove', 'can_reply' => 'post_reply', 'can_reply_unapproved' => 'post_unapproved_replies');
    foreach ($anyown_permissions as $contextual => $perm) {
        $context[$contextual] = allowedTo($perm . '_any') || $context['user']['started'] && allowedTo($perm . '_own');
    }
    // Cleanup all the permissions with extra stuff...
    $context['can_mark_notify'] &= !$context['user']['is_guest'];
    $context['can_sticky'] &= !empty($modSettings['enableStickyTopics']);
    $context['calendar_post'] &= !empty($modSettings['cal_enabled']);
    $context['can_add_poll'] &= $modSettings['pollMode'] == '1' && $topicinfo['id_poll'] <= 0;
    $context['can_remove_poll'] &= $modSettings['pollMode'] == '1' && $topicinfo['id_poll'] > 0;
    $context['can_reply'] &= empty($topicinfo['locked']) || allowedTo('moderate_board');
    $context['can_reply_unapproved'] &= $modSettings['postmod_active'] && (empty($topicinfo['locked']) || allowedTo('moderate_board'));
    $context['can_issue_warning'] &= in_array('w', $context['admin_features']) && $modSettings['warning_settings'][0] == 1;
    // Handle approval flags...
    $context['can_reply_approved'] = $context['can_reply'];
    $context['can_reply'] |= $context['can_reply_unapproved'];
    $context['can_quote'] = $context['can_reply'] && (empty($modSettings['disabledBBC']) || !in_array('quote', explode(',', $modSettings['disabledBBC'])));
    $context['can_mark_unread'] = !$user_info['is_guest'] && $settings['show_mark_read'];
    $context['can_send_topic'] = (!$modSettings['postmod_active'] || $topicinfo['approved']) && allowedTo('send_topic');
    // Start this off for quick moderation - it will be or'd for each post.
    $context['can_remove_post'] = allowedTo('delete_any') || allowedTo('delete_replies') && $context['user']['started'];
    // Can restore topic?  That's if the topic is in the recycle board and has a previous restore state.
    $context['can_restore_topic'] &= !empty($modSettings['recycle_enable']) && $modSettings['recycle_board'] == $board && !empty($topicinfo['id_previous_board']);
    $context['can_restore_msg'] &= !empty($modSettings['recycle_enable']) && $modSettings['recycle_board'] == $board && !empty($topicinfo['id_previous_topic']);
    // Wireless shows a "more" if you can do anything special.
    if (WIRELESS && WIRELESS_PROTOCOL != 'wap') {
        $context['wireless_more'] = $context['can_sticky'] || $context['can_lock'] || allowedTo('modify_any');
        $context['wireless_moderate'] = isset($_GET['moderate']) ? ';moderate' : '';
    }
    // Load up the "double post" sequencing magic.
    if (!empty($options['display_quick_reply'])) {
        checkSubmitOnce('register');
        $context['name'] = isset($_SESSION['guest_name']) ? $_SESSION['guest_name'] : '';
        $context['email'] = isset($_SESSION['guest_email']) ? $_SESSION['guest_email'] : '';
    }
}
Beispiel #25
0
function MoveTopic2()
{
    global $txt, $board, $topic, $scripturl, $sourcedir, $modSettings, $context;
    global $board, $language, $user_info, $smcFunc;
    if (empty($topic)) {
        fatal_lang_error('no_access', false);
    }
    // You can't choose to have a redirection topic and use an empty reason.
    if (isset($_POST['postRedirect']) && (!isset($_POST['reason']) || trim($_POST['reason']) == '')) {
        fatal_lang_error('movetopic_no_reason', false);
    }
    // Make sure this form hasn't been submitted before.
    checkSubmitOnce('check');
    $request = $smcFunc['db_query']('', '
		SELECT id_member_started, id_first_msg, approved
		FROM {db_prefix}topics
		WHERE id_topic = {int:current_topic}
		LIMIT 1', array('current_topic' => $topic));
    list($id_member_started, $id_first_msg, $context['is_approved']) = $smcFunc['db_fetch_row']($request);
    $smcFunc['db_free_result']($request);
    // Can they see it?
    if (!$context['is_approved']) {
        isAllowedTo('approve_posts');
    }
    // Can they move topics on this board?
    if (!allowedTo('move_any')) {
        if ($id_member_started == $user_info['id']) {
            isAllowedTo('move_own');
            $boards = array_merge(boardsAllowedTo('move_own'), boardsAllowedTo('move_any'));
        } else {
            isAllowedTo('move_any');
        }
    } else {
        $boards = boardsAllowedTo('move_any');
    }
    // If this topic isn't approved don't let them move it if they can't approve it!
    if ($modSettings['postmod_active'] && !$context['is_approved'] && !allowedTo('approve_posts')) {
        // Only allow them to move it to other boards they can't approve it in.
        $can_approve = boardsAllowedTo('approve_posts');
        $boards = array_intersect($boards, $can_approve);
    }
    checkSession();
    require_once $sourcedir . '/Subs-Post.php';
    // The destination board must be numeric.
    $_POST['toboard'] = (int) $_POST['toboard'];
    // Make sure they can see the board they are trying to move to (and get whether posts count in the target board).
    $request = $smcFunc['db_query']('', '
		SELECT b.count_posts, b.name, m.subject
		FROM {db_prefix}boards AS b
			INNER JOIN {db_prefix}topics AS t ON (t.id_topic = {int:current_topic})
			INNER JOIN {db_prefix}messages AS m ON (m.id_msg = t.id_first_msg)
		WHERE {query_see_board}
			AND b.id_board = {int:to_board}
			AND b.redirect = {string:blank_redirect}
		LIMIT 1', array('current_topic' => $topic, 'to_board' => $_POST['toboard'], 'blank_redirect' => ''));
    if ($smcFunc['db_num_rows']($request) == 0) {
        fatal_lang_error('no_board');
    }
    list($pcounter, $board_name, $subject) = $smcFunc['db_fetch_row']($request);
    $smcFunc['db_free_result']($request);
    // Remember this for later.
    $_SESSION['move_to_topic'] = $_POST['toboard'];
    // Rename the topic...
    if (isset($_POST['reset_subject'], $_POST['custom_subject']) && $_POST['custom_subject'] != '') {
        $_POST['custom_subject'] = strtr($smcFunc['htmltrim']($smcFunc['htmlspecialchars']($_POST['custom_subject'])), array("\r" => '', "\n" => '', "\t" => ''));
        // Keep checking the length.
        if ($smcFunc['strlen']($_POST['custom_subject']) > 100) {
            $_POST['custom_subject'] = $smcFunc['substr']($_POST['custom_subject'], 0, 100);
        }
        // If it's still valid move onwards and upwards.
        if ($_POST['custom_subject'] != '') {
            if (isset($_POST['enforce_subject'])) {
                // Get a response prefix, but in the forum's default language.
                if (!isset($context['response_prefix']) && !($context['response_prefix'] = cache_get_data('response_prefix'))) {
                    if ($language === $user_info['language']) {
                        $context['response_prefix'] = $txt['response_prefix'];
                    } else {
                        loadLanguage('index', $language, false);
                        $context['response_prefix'] = $txt['response_prefix'];
                        loadLanguage('index');
                    }
                    cache_put_data('response_prefix', $context['response_prefix'], 600);
                }
                $smcFunc['db_query']('', '
					UPDATE {db_prefix}messages
					SET subject = {string:subject}
					WHERE id_topic = {int:current_topic}', array('current_topic' => $topic, 'subject' => $context['response_prefix'] . $_POST['custom_subject']));
            }
            $smcFunc['db_query']('', '
				UPDATE {db_prefix}messages
				SET subject = {string:custom_subject}
				WHERE id_msg = {int:id_first_msg}', array('id_first_msg' => $id_first_msg, 'custom_subject' => $_POST['custom_subject']));
            // Fix the subject cache.
            updateStats('subject', $topic, $_POST['custom_subject']);
        }
    }
    // Create a link to this in the old board.
    //!!! Does this make sense if the topic was unapproved before? I'd just about say so.
    if (isset($_POST['postRedirect'])) {
        // Should be in the boardwide language.
        if ($user_info['language'] != $language) {
            loadLanguage('index', $language);
        }
        $_POST['reason'] = $smcFunc['htmlspecialchars']($_POST['reason'], ENT_QUOTES);
        preparsecode($_POST['reason']);
        // Add a URL onto the message.
        $_POST['reason'] = strtr($_POST['reason'], array($txt['movetopic_auto_board'] => '[url=' . $scripturl . '?board=' . $_POST['toboard'] . '.0]' . $board_name . '[/url]', $txt['movetopic_auto_topic'] => '[iurl]' . $scripturl . '?topic=' . $topic . '.0[/iurl]'));
        $msgOptions = array('subject' => $txt['moved'] . ': ' . $subject, 'body' => $_POST['reason'], 'icon' => 'moved', 'smileys_enabled' => 1);
        $topicOptions = array('board' => $board, 'lock_mode' => 1, 'mark_as_read' => true);
        $posterOptions = array('id' => $user_info['id'], 'update_post_count' => empty($pcounter));
        createPost($msgOptions, $topicOptions, $posterOptions);
    }
    $request = $smcFunc['db_query']('', '
		SELECT count_posts
		FROM {db_prefix}boards
		WHERE id_board = {int:current_board}
		LIMIT 1', array('current_board' => $board));
    list($pcounter_from) = $smcFunc['db_fetch_row']($request);
    $smcFunc['db_free_result']($request);
    if ($pcounter_from != $pcounter) {
        $request = $smcFunc['db_query']('', '
			SELECT id_member
			FROM {db_prefix}messages
			WHERE id_topic = {int:current_topic}
				AND approved = {int:is_approved}', array('current_topic' => $topic, 'is_approved' => 1));
        $posters = array();
        while ($row = $smcFunc['db_fetch_assoc']($request)) {
            if (!isset($posters[$row['id_member']])) {
                $posters[$row['id_member']] = 0;
            }
            $posters[$row['id_member']]++;
        }
        $smcFunc['db_free_result']($request);
        foreach ($posters as $id_member => $posts) {
            // The board we're moving from counted posts, but not to.
            if (empty($pcounter_from)) {
                updateMemberData($id_member, array('posts' => 'posts - ' . $posts));
            } else {
                updateMemberData($id_member, array('posts' => 'posts + ' . $posts));
            }
        }
    }
    // Do the move (includes statistics update needed for the redirect topic).
    moveTopics($topic, $_POST['toboard']);
    // Log that they moved this topic.
    if (!allowedTo('move_own') || $id_member_started != $user_info['id']) {
        logAction('move', array('topic' => $topic, 'board_from' => $board, 'board_to' => $_POST['toboard']));
    }
    // Notify people that this topic has been moved?
    sendNotifications($topic, 'move');
    // Why not go back to the original board in case they want to keep moving?
    if (!isset($_REQUEST['goback'])) {
        redirectexit('board=' . $board . '.0');
    } else {
        redirectexit('topic=' . $topic . '.0');
    }
}
    /**
     * Updates the cache of questions IDs
     */
    private function _refreshQuestionsCache()
    {
        global $modSettings;
        $db = database();
        if (($modSettings['question_id_cache'] = cache_get_data('verificationQuestionIds', 300)) == null) {
            $request = $db->query('', '
				SELECT id_question, language
				FROM {db_prefix}antispam_questions', array());
            $modSettings['question_id_cache'] = array();
            while ($row = $db->fetch_assoc($request)) {
                $modSettings['question_id_cache'][$row['language']][] = $row['id_question'];
            }
            $db->free_result($request);
            if (!empty($modSettings['cache_enable'])) {
                cache_put_data('verificationQuestionIds', $modSettings['question_id_cache'], 300);
            }
        }
    }
Beispiel #27
0
/**
 * Send a new message?
 */
function MessagePost()
{
    global $txt, $sourcedir, $scripturl, $modSettings;
    global $context, $options, $smcFunc, $language, $user_info;
    isAllowedTo('pm_send');
    loadLanguage('PersonalMessage');
    // Just in case it was loaded from somewhere else.
    if (!WIRELESS) {
        loadTemplate('PersonalMessage');
        $context['sub_template'] = 'send';
    }
    // Extract out the spam settings - cause it's neat.
    list($modSettings['max_pm_recipients'], $modSettings['pm_posts_verification'], $modSettings['pm_posts_per_hour']) = explode(',', $modSettings['pm_spam_settings']);
    // Set the title...
    $context['page_title'] = $txt['send_message'];
    $context['reply'] = isset($_REQUEST['pmsg']) || isset($_REQUEST['quote']);
    // Check whether we've gone over the limit of messages we can send per hour.
    if (!empty($modSettings['pm_posts_per_hour']) && !allowedTo(array('admin_forum', 'moderate_forum', 'send_mail')) && $user_info['mod_cache']['bq'] == '0=1' && $user_info['mod_cache']['gq'] == '0=1') {
        // How many messages have they sent this last hour?
        $request = $smcFunc['db_query']('', '
			SELECT COUNT(pr.id_pm) AS post_count
			FROM {db_prefix}personal_messages AS pm
				INNER JOIN {db_prefix}pm_recipients AS pr ON (pr.id_pm = pm.id_pm)
			WHERE pm.id_member_from = {int:current_member}
				AND pm.msgtime > {int:msgtime}', array('current_member' => $user_info['id'], 'msgtime' => time() - 3600));
        list($postCount) = $smcFunc['db_fetch_row']($request);
        $smcFunc['db_free_result']($request);
        if (!empty($postCount) && $postCount >= $modSettings['pm_posts_per_hour']) {
            fatal_lang_error('pm_too_many_per_hour', true, array($modSettings['pm_posts_per_hour']));
        }
    }
    // Quoting/Replying to a message?
    if (!empty($_REQUEST['pmsg'])) {
        $pmsg = (int) $_REQUEST['pmsg'];
        // Make sure this is yours.
        if (!isAccessiblePM($pmsg)) {
            fatal_lang_error('no_access', false);
        }
        // Work out whether this is one you've received?
        $request = $smcFunc['db_query']('', '
			SELECT
				id_pm
			FROM {db_prefix}pm_recipients
			WHERE id_pm = {int:id_pm}
				AND id_member = {int:current_member}
			LIMIT 1', array('current_member' => $user_info['id'], 'id_pm' => $pmsg));
        $isReceived = $smcFunc['db_num_rows']($request) != 0;
        $smcFunc['db_free_result']($request);
        // Get the quoted message (and make sure you're allowed to see this quote!).
        $request = $smcFunc['db_query']('', '
			SELECT
				pm.id_pm, CASE WHEN pm.id_pm_head = {int:id_pm_head_empty} THEN pm.id_pm ELSE pm.id_pm_head END AS pm_head,
				pm.body, pm.subject, pm.msgtime, mem.member_name, IFNULL(mem.id_member, 0) AS id_member,
				IFNULL(mem.real_name, pm.from_name) AS real_name
			FROM {db_prefix}personal_messages AS pm' . (!$isReceived ? '' : '
				INNER JOIN {db_prefix}pm_recipients AS pmr ON (pmr.id_pm = {int:id_pm})') . '
				LEFT JOIN {db_prefix}members AS mem ON (mem.id_member = pm.id_member_from)
			WHERE pm.id_pm = {int:id_pm}' . (!$isReceived ? '
				AND pm.id_member_from = {int:current_member}' : '
				AND pmr.id_member = {int:current_member}') . '
			LIMIT 1', array('current_member' => $user_info['id'], 'id_pm_head_empty' => 0, 'id_pm' => $pmsg));
        if ($smcFunc['db_num_rows']($request) == 0) {
            fatal_lang_error('pm_not_yours', false);
        }
        $row_quoted = $smcFunc['db_fetch_assoc']($request);
        $smcFunc['db_free_result']($request);
        // Censor the message.
        censorText($row_quoted['subject']);
        censorText($row_quoted['body']);
        // Add 'Re: ' to it....
        if (!isset($context['response_prefix']) && !($context['response_prefix'] = cache_get_data('response_prefix'))) {
            if ($language === $user_info['language']) {
                $context['response_prefix'] = $txt['response_prefix'];
            } else {
                loadLanguage('index', $language, false);
                $context['response_prefix'] = $txt['response_prefix'];
                loadLanguage('index');
            }
            cache_put_data('response_prefix', $context['response_prefix'], 600);
        }
        $form_subject = $row_quoted['subject'];
        if ($context['reply'] && trim($context['response_prefix']) != '' && $smcFunc['strpos']($form_subject, trim($context['response_prefix'])) !== 0) {
            $form_subject = $context['response_prefix'] . $form_subject;
        }
        if (isset($_REQUEST['quote'])) {
            // Remove any nested quotes and <br />...
            $form_message = preg_replace('~<br ?/?' . '>~i', "\n", $row_quoted['body']);
            if (!empty($modSettings['removeNestedQuotes'])) {
                $form_message = preg_replace(array('~\\n?\\[quote.*?\\].+?\\[/quote\\]\\n?~is', '~^\\n~', '~\\[/quote\\]~'), '', $form_message);
            }
            if (empty($row_quoted['id_member'])) {
                $form_message = '[quote author=&quot;' . $row_quoted['real_name'] . '&quot;]' . "\n" . $form_message . "\n" . '[/quote]';
            } else {
                $form_message = '[quote author=' . $row_quoted['real_name'] . ' link=action=profile;u=' . $row_quoted['id_member'] . ' date=' . $row_quoted['msgtime'] . ']' . "\n" . $form_message . "\n" . '[/quote]';
            }
        } else {
            $form_message = '';
        }
        // Do the BBC thang on the message.
        $row_quoted['body'] = parse_bbc($row_quoted['body'], true, 'pm' . $row_quoted['id_pm']);
        // Set up the quoted message array.
        $context['quoted_message'] = array('id' => $row_quoted['id_pm'], 'pm_head' => $row_quoted['pm_head'], 'member' => array('name' => $row_quoted['real_name'], 'username' => $row_quoted['member_name'], 'id' => $row_quoted['id_member'], 'href' => !empty($row_quoted['id_member']) ? $scripturl . '?action=profile;u=' . $row_quoted['id_member'] : '', 'link' => !empty($row_quoted['id_member']) ? '<a href="' . $scripturl . '?action=profile;u=' . $row_quoted['id_member'] . '">' . $row_quoted['real_name'] . '</a>' : $row_quoted['real_name']), 'subject' => $row_quoted['subject'], 'time' => timeformat($row_quoted['msgtime']), 'timestamp' => forum_time(true, $row_quoted['msgtime']), 'body' => $row_quoted['body']);
    } else {
        $context['quoted_message'] = false;
        $form_subject = '';
        $form_message = '';
    }
    $context['recipients'] = array('to' => array(), 'bcc' => array());
    // Sending by ID?  Replying to all?  Fetch the real_name(s).
    if (isset($_REQUEST['u'])) {
        // If the user is replying to all, get all the other members this was sent to..
        if ($_REQUEST['u'] == 'all' && isset($row_quoted)) {
            // Firstly, to reply to all we clearly already have $row_quoted - so have the original member from.
            if ($row_quoted['id_member'] != $user_info['id']) {
                $context['recipients']['to'][] = array('id' => $row_quoted['id_member'], 'name' => htmlspecialchars($row_quoted['real_name']));
            }
            // Now to get the others.
            $request = $smcFunc['db_query']('', '
				SELECT mem.id_member, mem.real_name
				FROM {db_prefix}pm_recipients AS pmr
					INNER JOIN {db_prefix}members AS mem ON (mem.id_member = pmr.id_member)
				WHERE pmr.id_pm = {int:id_pm}
					AND pmr.id_member != {int:current_member}
					AND pmr.bcc = {int:not_bcc}', array('current_member' => $user_info['id'], 'id_pm' => $pmsg, 'not_bcc' => 0));
            while ($row = $smcFunc['db_fetch_assoc']($request)) {
                $context['recipients']['to'][] = array('id' => $row['id_member'], 'name' => $row['real_name']);
            }
            $smcFunc['db_free_result']($request);
        } else {
            $_REQUEST['u'] = explode(',', $_REQUEST['u']);
            foreach ($_REQUEST['u'] as $key => $uID) {
                $_REQUEST['u'][$key] = (int) $uID;
            }
            $_REQUEST['u'] = array_unique($_REQUEST['u']);
            $request = $smcFunc['db_query']('', '
				SELECT id_member, real_name
				FROM {db_prefix}members
				WHERE id_member IN ({array_int:member_list})
				LIMIT ' . count($_REQUEST['u']), array('member_list' => $_REQUEST['u']));
            while ($row = $smcFunc['db_fetch_assoc']($request)) {
                $context['recipients']['to'][] = array('id' => $row['id_member'], 'name' => $row['real_name']);
            }
            $smcFunc['db_free_result']($request);
        }
        // Get a literal name list in case the user has JavaScript disabled.
        $names = array();
        foreach ($context['recipients']['to'] as $to) {
            $names[] = $to['name'];
        }
        $context['to_value'] = empty($names) ? '' : '&quot;' . implode('&quot;, &quot;', $names) . '&quot;';
    } else {
        $context['to_value'] = '';
    }
    // Set the defaults...
    $context['subject'] = $form_subject;
    $context['message'] = str_replace(array('"', '<', '>', '&nbsp;'), array('&quot;', '&lt;', '&gt;', ' '), $form_message);
    $context['post_error'] = array();
    $context['copy_to_outbox'] = !empty($options['copy_to_outbox']);
    // And build the link tree.
    $context['linktree'][] = array('url' => $scripturl . '?action=pm;sa=send', 'name' => $txt['new_message']);
    $modSettings['disable_wysiwyg'] = !empty($modSettings['disable_wysiwyg']) || empty($modSettings['enableBBC']);
    // Are PM drafts enabled?
    $context['drafts_pm_save'] = !empty($modSettings['drafts_enabled']) && !empty($modSettings['drafts_pm_enabled']) && allowedTo('pm_draft');
    $context['drafts_autosave'] = !empty($context['drafts_pm_save']) && !empty($modSettings['drafts_autosave_enabled']) && allowedTo('pm_autosave_draft');
    // Generate a list of drafts that they can load in to the editor
    if (!empty($context['drafts_pm_save'])) {
        require_once $sourcedir . '/Drafts.php';
        $pm_seed = isset($_REQUEST['pmsg']) ? $_REQUEST['pmsg'] : (isset($_REQUEST['quote']) ? $_REQUEST['quote'] : 0);
        ShowDrafts($user_info['id'], $pm_seed, 1);
    }
    // Needed for the WYSIWYG editor.
    require_once $sourcedir . '/Subs-Editor.php';
    // Now create the editor.
    $editorOptions = array('id' => 'message', 'value' => $context['message'], 'height' => '175px', 'width' => '100%', 'labels' => array('post_button' => $txt['send_message']), 'preview_type' => 2);
    create_control_richedit($editorOptions);
    // Store the ID for old compatibility.
    $context['post_box_name'] = $editorOptions['id'];
    $context['bcc_value'] = '';
    $context['require_verification'] = !$user_info['is_admin'] && !empty($modSettings['pm_posts_verification']) && $user_info['posts'] < $modSettings['pm_posts_verification'];
    if ($context['require_verification']) {
        $verificationOptions = array('id' => 'pm');
        $context['require_verification'] = create_control_verification($verificationOptions);
        $context['visual_verification_id'] = $verificationOptions['id'];
    }
    // Register this form and get a sequence number in $context.
    checkSubmitOnce('register');
}
function ModBlockReportedPosts()
{
    global $context, $user_info, $scripturl, $smcFunc;
    // Got the info already?
    $cachekey = md5(serialize($user_info['mod_cache']['bq']));
    $context['reported_posts'] = array();
    if ($user_info['mod_cache']['bq'] == '0=1') {
        return 'reported_posts_block';
    }
    if (($reported_posts = cache_get_data('reported_posts_' . $cachekey, 90)) === null) {
        // By George, that means we in a position to get the reports, jolly good.
        $request = $smcFunc['db_query']('', '
			SELECT lr.id_report, lr.id_msg, lr.id_topic, lr.id_board, lr.id_member, lr.subject,
				lr.num_reports, IFNULL(mem.real_name, lr.membername) AS author_name,
				IFNULL(mem.id_member, 0) AS id_author
			FROM {db_prefix}log_reported AS lr
				LEFT JOIN {db_prefix}members AS mem ON (mem.id_member = lr.id_member)
			WHERE ' . ($user_info['mod_cache']['bq'] == '1=1' || $user_info['mod_cache']['bq'] == '0=1' ? $user_info['mod_cache']['bq'] : 'lr.' . $user_info['mod_cache']['bq']) . '
				AND lr.closed = {int:not_closed}
				AND lr.ignore_all = {int:not_ignored}
			ORDER BY lr.time_updated DESC
			LIMIT 10', array('not_closed' => 0, 'not_ignored' => 0));
        $reported_posts = array();
        while ($row = $smcFunc['db_fetch_assoc']($request)) {
            $reported_posts[] = $row;
        }
        $smcFunc['db_free_result']($request);
        // Cache it.
        cache_put_data('reported_posts_' . $cachekey, $reported_posts, 90);
    }
    $context['reported_posts'] = array();
    foreach ($reported_posts as $i => $row) {
        $context['reported_posts'][] = array('id' => $row['id_report'], 'alternate' => $i % 2, 'topic_href' => $scripturl . '?topic=' . $row['id_topic'] . '.msg' . $row['id_msg'] . '#msg' . $row['id_msg'], 'report_href' => $scripturl . '?action=moderate;area=reports;report=' . $row['id_report'], 'author' => array('id' => $row['id_author'], 'name' => $row['author_name'], 'link' => $row['id_author'] ? '<a href="' . $scripturl . '?action=profile;u=' . $row['id_author'] . '">' . $row['author_name'] . '</a>' : $row['author_name'], 'href' => $scripturl . '?action=profile;u=' . $row['id_author']), 'comments' => array(), 'subject' => $row['subject'], 'num_reports' => $row['num_reports']);
    }
    return 'reported_posts_block';
}
Beispiel #29
0
function loadTheme($ID_THEME = 0, $initialize = true)
{
    global $ID_MEMBER, $user_info, $board_info, $sc;
    global $db_prefix, $txt, $boardurl, $scripturl, $mbname, $modSettings;
    global $context, $settings, $options;
    // The theme was specified by parameter.
    if (!empty($ID_THEME)) {
        $ID_THEME = (int) $ID_THEME;
    } elseif (!empty($board_info['theme']) && $board_info['override_theme']) {
        $ID_THEME = $board_info['theme'];
    } elseif (!empty($_REQUEST['theme']) && (!empty($modSettings['theme_allow']) || allowedTo('admin_forum'))) {
        $ID_THEME = (int) $_REQUEST['theme'];
        $_SESSION['ID_THEME'] = $ID_THEME;
    } elseif (!empty($_SESSION['ID_THEME']) && (!empty($modSettings['theme_allow']) || allowedTo('admin_forum'))) {
        $ID_THEME = (int) $_SESSION['ID_THEME'];
    } elseif (!empty($user_info['theme']) && !isset($_REQUEST['theme']) && (!empty($modSettings['theme_allow']) || allowedTo('admin_forum'))) {
        $ID_THEME = $user_info['theme'];
    } elseif (!empty($board_info['theme'])) {
        $ID_THEME = $board_info['theme'];
    } else {
        $ID_THEME = $modSettings['theme_guests'];
    }
    // Verify the ID_THEME... no foul play.
    if (empty($modSettings['theme_default']) && $ID_THEME == 1 && !allowedTo('admin_forum')) {
        $ID_THEME = $modSettings['theme_guests'];
    } elseif (!empty($modSettings['knownThemes']) && !empty($modSettings['theme_allow']) && !allowedTo('admin_forum')) {
        $themes = explode(',', $modSettings['knownThemes']);
        if (!in_array($ID_THEME, $themes)) {
            $ID_THEME = $modSettings['theme_guests'];
        } else {
            $ID_THEME = (int) $ID_THEME;
        }
    } else {
        $ID_THEME = (int) $ID_THEME;
    }
    $member = empty($ID_MEMBER) ? -1 : $ID_MEMBER;
    if (!empty($modSettings['cache_enable']) && $modSettings['cache_enable'] >= 2 && ($temp = cache_get_data('theme_settings-' . $ID_THEME . ':' . $member, 60)) != null) {
        $themeData = $temp;
        $flag = true;
    } elseif (($temp = cache_get_data('theme_settings-' . $ID_THEME, 90)) != null) {
        $themeData = $temp + array($member => array());
    } else {
        $themeData = array(-1 => array(), 0 => array(), $member => array());
    }
    if (empty($flag)) {
        // Load variables from the current or default theme, global or this user's.
        $result = db_query("\n\t\t\tSELECT variable, value, ID_MEMBER, ID_THEME\n\t\t\tFROM {$db_prefix}themes\n\t\t\tWHERE ID_MEMBER" . (empty($themeData[0]) ? " IN (-1, 0, {$member})" : " = {$member}") . "\n\t\t\t\tAND ID_THEME" . ($ID_THEME == 1 ? ' = 1' : " IN ({$ID_THEME}, 1)"), __FILE__, __LINE__);
        // Pick between $settings and $options depending on whose data it is.
        while ($row = mysql_fetch_assoc($result)) {
            // There are just things we shouldn't be able to change as members.
            if ($row['ID_MEMBER'] != 0 && in_array($row['variable'], array('actual_theme_url', 'actual_images_url', 'base_theme_dir', 'base_theme_url', 'default_images_url', 'default_theme_dir', 'default_theme_url', 'default_template', 'images_url', 'number_recent_posts', 'smiley_sets_default', 'theme_dir', 'theme_id', 'theme_layers', 'theme_templates', 'theme_url'))) {
                continue;
            }
            // If this is the theme_dir of the default theme, store it.
            if (in_array($row['variable'], array('theme_dir', 'theme_url', 'images_url')) && $row['ID_THEME'] == '1' && empty($row['ID_MEMBER'])) {
                $themeData[0]['default_' . $row['variable']] = $row['value'];
            }
            // If this isn't set yet, is a theme option, or is not the default theme..
            if (!isset($themeData[$row['ID_MEMBER']][$row['variable']]) || $row['ID_THEME'] != '1') {
                $themeData[$row['ID_MEMBER']][$row['variable']] = substr($row['variable'], 0, 5) == 'show_' ? $row['value'] == '1' : $row['value'];
            }
        }
        mysql_free_result($result);
        if (!empty($themeData[-1])) {
            foreach ($themeData[-1] as $k => $v) {
                if (!isset($themeData[$member][$k])) {
                    $themeData[$member][$k] = $v;
                }
            }
        }
        if (!empty($modSettings['cache_enable']) && $modSettings['cache_enable'] >= 2) {
            cache_put_data('theme_settings-' . $ID_THEME . ':' . $member, $themeData, 60);
        } elseif (!isset($temp)) {
            cache_put_data('theme_settings-' . $ID_THEME, array(-1 => $themeData[-1], 0 => $themeData[0]), 90);
        }
    }
    $settings = $themeData[0];
    $options = $themeData[$member];
    $settings['theme_id'] = $ID_THEME;
    $settings['actual_theme_url'] = $settings['theme_url'];
    $settings['actual_images_url'] = $settings['images_url'];
    $settings['actual_theme_dir'] = $settings['theme_dir'];
    if (!$initialize) {
        return;
    }
    // Check to see if they're accessing it from the wrong place.
    if (isset($_SERVER['HTTP_HOST']) || isset($_SERVER['SERVER_NAME'])) {
        $detected_url = isset($_SERVER['HTTPS']) && strtolower($_SERVER['HTTPS']) == 'on' ? 'https://' : 'http://';
        $detected_url .= empty($_SERVER['HTTP_HOST']) ? $_SERVER['SERVER_NAME'] . (empty($_SERVER['SERVER_PORT']) || $_SERVER['SERVER_PORT'] == '80' ? '' : ':' . $_SERVER['SERVER_PORT']) : $_SERVER['HTTP_HOST'];
        $temp = preg_replace('~/' . basename($scripturl) . '(/.+)?$~', '', strtr(dirname($_SERVER['PHP_SELF']), '\\', '/'));
        if ($temp != '/') {
            $detected_url .= $temp;
        }
    }
    if (isset($detected_url) && $detected_url != $boardurl) {
        // Try #1 - check if it's in a list of alias addresses.
        if (!empty($modSettings['forum_alias_urls'])) {
            $aliases = explode(',', $modSettings['forum_alias_urls']);
            foreach ($aliases as $alias) {
                // Rip off all the boring parts, spaces, etc.
                if ($detected_url == trim($alias) || strtr($detected_url, array('http://' => '', 'https://' => '')) == trim($alias)) {
                    $do_fix = true;
                }
            }
        }
        // Hmm... check #2 - is it just different by a www?  Send them to the correct place!!
        if (empty($do_fix) && strtr($detected_url, array('://' => '://www.')) == $boardurl && (empty($_GET) || count($_GET) == 1)) {
            // Okay, this seems weird, but we don't want an endless loop - this will make $_GET not empty ;).
            if (empty($_GET)) {
                redirectexit('www');
            } else {
                list($k, $v) = each($_GET);
                if ($k != 'www') {
                    redirectexit('www;' . $k . '=' . $v);
                }
            }
        }
        // #3 is just a check for SSL...
        if (strtr($detected_url, array('https://' => 'http://')) == $boardurl) {
            $do_fix = true;
        }
        // Okay, #4 - perhaps it's an IP address?  We're gonna want to use that one, then. (assuming it's the IP or something...)
        if (!empty($do_fix) || preg_match('~^http[s]://[\\d\\.:]+($|/)~', $detected_url) == 1) {
            // Caching is good ;).
            $oldurl = $boardurl;
            // Fix $boardurl and $scripturl.
            $boardurl = $detected_url;
            $scripturl = strtr($scripturl, array($oldurl => $boardurl));
            $_SERVER['REQUEST_URL'] = strtr($_SERVER['REQUEST_URL'], array($oldurl => $boardurl));
            // Fix the theme urls...
            $settings['theme_url'] = strtr($settings['theme_url'], array($oldurl => $boardurl));
            $settings['default_theme_url'] = strtr($settings['default_theme_url'], array($oldurl => $boardurl));
            $settings['actual_theme_url'] = strtr($settings['actual_theme_url'], array($oldurl => $boardurl));
            $settings['images_url'] = strtr($settings['images_url'], array($oldurl => $boardurl));
            $settings['default_images_url'] = strtr($settings['default_images_url'], array($oldurl => $boardurl));
            $settings['actual_images_url'] = strtr($settings['actual_images_url'], array($oldurl => $boardurl));
            // And just a few mod settings :).
            $modSettings['smileys_url'] = strtr($modSettings['smileys_url'], array($oldurl => $boardurl));
            $modSettings['avatar_url'] = strtr($modSettings['avatar_url'], array($oldurl => $boardurl));
            // Clean up after loadBoard().
            foreach ($board_info['moderators'] as $k => $dummy) {
                $board_info['moderators'][$k]['href'] = strtr($dummy['href'], array($oldurl => $boardurl));
                $board_info['moderators'][$k]['link'] = strtr($dummy['link'], array('"' . $oldurl => '"' . $boardurl));
            }
            foreach ($context['linktree'] as $k => $dummy) {
                $context['linktree'][$k]['url'] = strtr($dummy['url'], array($oldurl => $boardurl));
            }
        }
    }
    // Set up the contextual user array.
    $context['user'] = array('id' => &$ID_MEMBER, 'is_logged' => !$user_info['is_guest'], 'is_guest' => &$user_info['is_guest'], 'is_admin' => &$user_info['is_admin'], 'is_mod' => false, 'username' => &$user_info['username'], 'language' => &$user_info['language'], 'email' => &$user_info['email']);
    if ($context['user']['is_guest']) {
        $context['user']['name'] =& $txt[28];
    } else {
        $context['user']['name'] =& $user_info['name'];
    }
    // Determine the current smiley set.
    $user_info['smiley_set'] = !in_array($user_info['smiley_set'], explode(',', $modSettings['smiley_sets_known'])) && $user_info['smiley_set'] != 'none' || empty($modSettings['smiley_sets_enable']) ? !empty($settings['smiley_sets_default']) ? $settings['smiley_sets_default'] : $modSettings['smiley_sets_default'] : $user_info['smiley_set'];
    $context['user']['smiley_set'] =& $user_info['smiley_set'];
    // Some basic information...
    if (!isset($context['html_headers'])) {
        $context['html_headers'] = '';
    }
    $context['menu_separator'] = !empty($settings['use_image_buttons']) ? ' ' : ' | ';
    $context['session_id'] =& $sc;
    $context['forum_name'] =& $mbname;
    $context['current_action'] = isset($_REQUEST['action']) ? $_REQUEST['action'] : null;
    $context['current_subaction'] = isset($_REQUEST['sa']) ? $_REQUEST['sa'] : null;
    if (isset($modSettings['load_average'])) {
        $context['load_average'] = $modSettings['load_average'];
    }
    // This determines the server... not used in many places, except for login fixing.
    $context['server'] = array('is_iis' => isset($_SERVER['SERVER_SOFTWARE']) && strpos($_SERVER['SERVER_SOFTWARE'], 'Microsoft-IIS') !== false, 'is_apache' => isset($_SERVER['SERVER_SOFTWARE']) && strpos($_SERVER['SERVER_SOFTWARE'], 'Apache') !== false, 'is_cgi' => isset($_SERVER['SERVER_SOFTWARE']) && strpos(php_sapi_name(), 'cgi') !== false, 'is_windows' => stristr(PHP_OS, 'WIN') !== false, 'iso_case_folding' => ord(strtolower(chr(138))) === 154, 'complex_preg_chars' => @version_compare(PHP_VERSION, '4.3.3') != -1);
    // A bug in some versions of IIS under CGI (older ones) makes cookie setting not work with Location: headers.
    $context['server']['needs_login_fix'] = $context['server']['is_cgi'];
    // The following determines the user agent (browser) as best it can.
    $context['browser'] = array('is_opera' => strpos($_SERVER['HTTP_USER_AGENT'], 'Opera') !== false, 'is_opera6' => strpos($_SERVER['HTTP_USER_AGENT'], 'Opera 6') !== false, 'is_opera7' => strpos($_SERVER['HTTP_USER_AGENT'], 'Opera 7') !== false || strpos($_SERVER['HTTP_USER_AGENT'], 'Opera/7') !== false, 'is_opera8' => strpos($_SERVER['HTTP_USER_AGENT'], 'Opera 8') !== false || strpos($_SERVER['HTTP_USER_AGENT'], 'Opera/8') !== false, 'is_ie4' => strpos($_SERVER['HTTP_USER_AGENT'], 'MSIE 4') !== false && strpos($_SERVER['HTTP_USER_AGENT'], 'WebTV') === false, 'is_safari' => strpos($_SERVER['HTTP_USER_AGENT'], 'Safari') !== false, 'is_mac_ie' => strpos($_SERVER['HTTP_USER_AGENT'], 'MSIE 5.') !== false && strpos($_SERVER['HTTP_USER_AGENT'], 'Mac') !== false, 'is_web_tv' => strpos($_SERVER['HTTP_USER_AGENT'], 'WebTV') !== false, 'is_konqueror' => strpos($_SERVER['HTTP_USER_AGENT'], 'Konqueror') !== false, 'is_firefox' => strpos($_SERVER['HTTP_USER_AGENT'], 'Firefox') !== false, 'is_firefox1' => strpos($_SERVER['HTTP_USER_AGENT'], 'Firefox/1.') !== false, 'is_firefox2' => strpos($_SERVER['HTTP_USER_AGENT'], 'Firefox/2.') !== false);
    $context['browser']['is_gecko'] = strpos($_SERVER['HTTP_USER_AGENT'], 'Gecko') !== false && !$context['browser']['is_safari'] && !$context['browser']['is_konqueror'];
    // Internet Explorer 5 and 6 are often "emulated".
    $context['browser']['is_ie7'] = strpos($_SERVER['HTTP_USER_AGENT'], 'MSIE 7') !== false && !$context['browser']['is_opera'] && !$context['browser']['is_gecko'] && !$context['browser']['is_web_tv'];
    $context['browser']['is_ie6'] = strpos($_SERVER['HTTP_USER_AGENT'], 'MSIE 6') !== false && !$context['browser']['is_opera'] && !$context['browser']['is_gecko'] && !$context['browser']['is_web_tv'];
    $context['browser']['is_ie5.5'] = strpos($_SERVER['HTTP_USER_AGENT'], 'MSIE 5.5') !== false && !$context['browser']['is_opera'] && !$context['browser']['is_gecko'] && !$context['browser']['is_web_tv'];
    $context['browser']['is_ie5'] = strpos($_SERVER['HTTP_USER_AGENT'], 'MSIE 5.0') !== false && !$context['browser']['is_opera'] && !$context['browser']['is_gecko'] && !$context['browser']['is_web_tv'];
    $context['browser']['is_ie'] = $context['browser']['is_ie4'] || $context['browser']['is_ie5'] || $context['browser']['is_ie5.5'] || $context['browser']['is_ie6'] || $context['browser']['is_ie7'];
    $context['browser']['needs_size_fix'] = ($context['browser']['is_ie5'] || $context['browser']['is_ie5.5'] || $context['browser']['is_ie4'] || $context['browser']['is_opera6']) && strpos($_SERVER['HTTP_USER_AGENT'], 'Mac') === false;
    // This isn't meant to be reliable, it's just meant to catch most bots to prevent PHPSESSID from showing up.
    $ci_user_agent = strtolower($_SERVER['HTTP_USER_AGENT']);
    $context['browser']['possibly_robot'] = strpos($_SERVER['HTTP_USER_AGENT'], 'Mozilla') === false && strpos($_SERVER['HTTP_USER_AGENT'], 'Opera') === false || strpos($ci_user_agent, 'googlebot') !== false || strpos($ci_user_agent, 'slurp') !== false || strpos($ci_user_agent, 'crawl') !== false;
    // Robots shouldn't be logging in or registering.  So, they aren't a bot.  Better to be wrong than sorry (or people won't be able to log in!), anyway.
    if (isset($_REQUEST['action']) && in_array($_REQUEST['action'], array('login', 'login2', 'register')) || !$context['user']['is_guest']) {
        $context['browser']['possibly_robot'] = false;
    }
    // Set the top level linktree up.
    array_unshift($context['linktree'], array('url' => &$scripturl, 'name' => &$context['forum_name']));
    $txt = array();
    $simpleActions = array('findmember', 'helpadmin', 'printpage', 'quotefast', 'spellcheck');
    // Wireless mode?  Load up the wireless stuff.
    if (WIRELESS) {
        $context['template_layers'] = array(WIRELESS_PROTOCOL);
        loadTemplate('Wireless');
        loadLanguage('Wireless');
        loadLanguage('index');
    } elseif (isset($_REQUEST['xml'])) {
        loadLanguage('index');
        loadTemplate('Xml');
        $context['template_layers'] = array();
    } elseif (!empty($_REQUEST['action']) && in_array($_REQUEST['action'], $simpleActions)) {
        loadLanguage('index');
        $context['template_layers'] = array();
    } else {
        // Custom templates to load, or just default?
        if (isset($settings['theme_templates'])) {
            $templates = explode(',', $settings['theme_templates']);
        } else {
            $templates = array('index');
        }
        // Custom template layers?
        if (isset($settings['theme_layers'])) {
            $context['template_layers'] = explode(',', $settings['theme_layers']);
        } else {
            $context['template_layers'] = array('main');
        }
        // Load each template.... and attempt to load its associated language file.
        foreach ($templates as $template) {
            loadTemplate($template);
            loadLanguage($template, '', false);
        }
    }
    // Load the Modifications language file, always ;). (but don't sweat it if it doesn't exist.)
    loadLanguage('Modifications', '', false);
    // Initialize the theme.
    loadSubTemplate('init', 'ignore');
    if (isset($settings['use_default_images']) && $settings['use_default_images'] == 'always') {
        $settings['theme_url'] = $settings['default_theme_url'];
        $settings['images_url'] = $settings['default_images_url'];
        $settings['theme_dir'] = $settings['default_theme_dir'];
    }
    // Set the character set from the template.
    $context['character_set'] = empty($modSettings['global_character_set']) ? $txt['lang_character_set'] : $modSettings['global_character_set'];
    $context['utf8'] = $context['character_set'] === 'UTF-8' && (strpos(strtolower(PHP_OS), 'win') === false || @version_compare(PHP_VERSION, '4.2.3') != -1);
    $context['right_to_left'] = !empty($txt['lang_rtl']);
    $context['tabindex'] = 1;
    // Fix font size with HTML 4.01, etc.
    if (isset($settings['doctype'])) {
        $context['browser']['needs_size_fix'] |= $settings['doctype'] == 'html' && $context['browser']['is_ie6'];
    }
    // Compatibility.
    if (!isset($settings['theme_version'])) {
        $modSettings['memberCount'] = $modSettings['totalMembers'];
    }
}
Beispiel #30
0
/**
 * Creates a box that can be used for richedit stuff like BBC, Smileys etc.
 * @param mixed[] $editorOptions associative array of options => value
 *  must contain:
 *   - id => unique id for the css
 *   - value => text for the editor or blank
 *  Optionaly
 *   - height => height of the intial box
 *   - width => width of the box (100%)
 *   - force_rich => force wysiwyg to be enabled
 *   - disable_smiley_box => boolean to turn off the smiley box
 *   - labels => array(
 *       - 'post_button' => $txt['for post button'],
 *     ),
 *   - preview_type => 2 how to act on preview click, see template_control_richedit_buttons
 */
function create_control_richedit($editorOptions)
{
    global $txt, $modSettings, $options, $context, $settings, $user_info, $scripturl;
    static $bbc_tags;
    $db = database();
    // Load the Post language file... for the moment at least.
    loadLanguage('Post');
    if (!empty($context['drafts_save']) || !empty($context['drafts_pm_save'])) {
        loadLanguage('Drafts');
    }
    // Every control must have a ID!
    assert(isset($editorOptions['id']));
    assert(isset($editorOptions['value']));
    // Is this the first richedit - if so we need to ensure things are initialised and that we load all of the needed files
    if (empty($context['controls']['richedit'])) {
        // Store the name / ID we are creating for template compatibility.
        $context['post_box_name'] = $editorOptions['id'];
        // Some general stuff.
        $settings['smileys_url'] = $modSettings['smileys_url'] . '/' . $user_info['smiley_set'];
        if (!empty($context['drafts_autosave']) && !empty($options['drafts_autosave_enabled'])) {
            $context['drafts_autosave_frequency'] = empty($modSettings['drafts_autosave_frequency']) ? 30000 : $modSettings['drafts_autosave_frequency'] * 1000;
        }
        // This really has some WYSIWYG stuff.
        loadTemplate('GenericControls', 'jquery.sceditor');
        if (!empty($context['theme_variant']) && file_exists($settings['theme_dir'] . '/css/' . $context['theme_variant'] . '/jquery.sceditor.elk' . $context['theme_variant'] . '.css')) {
            loadCSSFile($context['theme_variant'] . '/jquery.sceditor.elk' . $context['theme_variant'] . '.css');
        }
        // JS makes the editor go round
        loadJavascriptFile(array('jquery.sceditor.min.js', 'jquery.sceditor.bbcode.min.js', 'jquery.sceditor.elkarte.js', 'post.js', 'splittag.plugin.js', 'dropAttachments.js'));
        addJavascriptVar(array('post_box_name' => $editorOptions['id'], 'elk_smileys_url' => $settings['smileys_url'], 'bbc_quote_from' => $txt['quote_from'], 'bbc_quote' => $txt['quote'], 'bbc_search_on' => $txt['search_on']), true);
        // Editor language file
        if (!empty($txt['lang_locale'])) {
            loadJavascriptFile($scripturl . '?action=jslocale;sa=sceditor', array('defer' => true), 'sceditor_language');
        }
        // Drafts?
        if ((!empty($context['drafts_save']) || !empty($context['drafts_pm_save'])) && !empty($context['drafts_autosave']) && !empty($options['drafts_autosave_enabled'])) {
            loadJavascriptFile('drafts.plugin.js');
        }
        // Mentions?
        if (!empty($context['mentions_enabled'])) {
            loadJavascriptFile(array('jquery.atwho.js', 'jquery.caret.min.js', 'mentioning.plugin.js'));
        }
        // Our not so concise shortcut line
        $context['shortcuts_text'] = $txt['shortcuts' . (!empty($context['drafts_save']) || !empty($context['drafts_pm_save']) ? '_drafts' : '') . (isBrowser('is_firefox') ? '_firefox' : '')];
        // Spellcheck?
        $context['show_spellchecking'] = !empty($modSettings['enableSpellChecking']) && function_exists('pspell_new');
        if ($context['show_spellchecking']) {
            // Some hidden information is needed in order to make spell check work.
            if (!isset($_REQUEST['xml'])) {
                $context['insert_after_template'] .= '
		<form name="spell_form" id="spell_form" method="post" accept-charset="UTF-8" target="spellWindow" action="' . $scripturl . '?action=spellcheck">
			<input type="hidden" name="spellstring" value="" />
			<input type="hidden" name="fulleditor" value="" />
		</form>';
            }
            loadJavascriptFile('spellcheck.js', array('defer' => true));
        }
    }
    // Start off the editor...
    $context['controls']['richedit'][$editorOptions['id']] = array('id' => $editorOptions['id'], 'value' => $editorOptions['value'], 'rich_active' => !empty($options['wysiwyg_default']) || !empty($editorOptions['force_rich']) || !empty($_REQUEST[$editorOptions['id'] . '_mode']), 'disable_smiley_box' => !empty($editorOptions['disable_smiley_box']), 'columns' => isset($editorOptions['columns']) ? $editorOptions['columns'] : 60, 'rows' => isset($editorOptions['rows']) ? $editorOptions['rows'] : 18, 'width' => isset($editorOptions['width']) ? $editorOptions['width'] : '100%', 'height' => isset($editorOptions['height']) ? $editorOptions['height'] : '250px', 'form' => isset($editorOptions['form']) ? $editorOptions['form'] : 'postmodify', 'bbc_level' => !empty($editorOptions['bbc_level']) ? $editorOptions['bbc_level'] : 'full', 'preview_type' => isset($editorOptions['preview_type']) ? (int) $editorOptions['preview_type'] : 1, 'labels' => !empty($editorOptions['labels']) ? $editorOptions['labels'] : array(), 'locale' => !empty($txt['lang_locale']) ? $txt['lang_locale'] : 'en_US');
    // Switch between default images and back... mostly in case you don't have an PersonalMessage template, but do have a Post template.
    if (isset($settings['use_default_images']) && $settings['use_default_images'] == 'defaults' && isset($settings['default_template'])) {
        $temp1 = $settings['theme_url'];
        $settings['theme_url'] = $settings['default_theme_url'];
        $temp2 = $settings['images_url'];
        $settings['images_url'] = $settings['default_images_url'];
        $temp3 = $settings['theme_dir'];
        $settings['theme_dir'] = $settings['default_theme_dir'];
    }
    if (empty($bbc_tags)) {
        // The below array is used to show a command button in the editor, the execution
        // and display details of any added buttons must be defined in the javascript files
        // see  jquery.sceditor.elkarte.js under the $.sceditor.plugins.bbcode.bbcode area
        // for examples of how to use the .set command to add codes.  Include your new
        // JS with addInlineJavascript() or loadJavascriptFile()
        $bbc_tags['row1'] = array(array('bold', 'italic', 'underline', 'strike', 'superscript', 'subscript'), array('left', 'center', 'right', 'pre', 'tt'), array('font', 'size', 'color'));
        $bbc_tags['row2'] = array(array('quote', 'code', 'table'), array('bulletlist', 'orderedlist', 'horizontalrule'), array('spoiler', 'footnote'), array('image', 'link', 'email'));
        // Allow mods to add BBC buttons to the toolbar, actions are defined in the JS
        call_integration_hook('integrate_bbc_buttons', array(&$bbc_tags));
        // Show the wysiwyg format and toggle buttons?
        $bbc_tags['row2'][] = array('removeformat', 'source');
        // Generate a list of buttons that shouldn't be shown
        $disabled_tags = array();
        if (!empty($modSettings['disabledBBC'])) {
            $disabled_tags = explode(',', $modSettings['disabledBBC']);
        }
        // Map codes to tags
        $translate_tags_to_code = array('b' => 'bold', 'i' => 'italic', 'u' => 'underline', 's' => 'strike', 'img' => 'image', 'url' => 'link', 'sup' => 'superscript', 'sub' => 'subscript', 'hr' => 'horizontalrule');
        // Remove the toolbar buttons for any bbc tags that have been turned off in the ACP
        foreach ($disabled_tags as $tag) {
            // list is special, its prevents two tags
            if ($tag === 'list') {
                $context['disabled_tags']['bulletlist'] = true;
                $context['disabled_tags']['orderedlist'] = true;
            } elseif (isset($translate_tags_to_code[$tag])) {
                $context['disabled_tags'][$translate_tags_to_code[$tag]] = true;
            }
            // Tag is the same as the code, like font, color, size etc
            $context['disabled_tags'][trim($tag)] = true;
        }
        // Build our toolbar, taking in to account any bbc codes from integration
        $context['bbc_toolbar'] = array();
        foreach ($bbc_tags as $row => $tagRow) {
            if (!isset($context['bbc_toolbar'][$row])) {
                $context['bbc_toolbar'][$row] = array();
            }
            $tagsRow = array();
            // For each row of buttons defined, lets build our tags
            foreach ($tagRow as $tags) {
                foreach ($tags as $tag) {
                    // Just add this code in the existing grouping
                    if (!isset($context['disabled_tags'][$tag])) {
                        $tagsRow[] = $tag;
                    }
                }
                // If the row is not empty, and the last added tag is not a space, add a space.
                if (!empty($tagsRow) && $tagsRow[count($tagsRow) - 1] != 'space') {
                    $tagsRow[] = 'space';
                }
            }
            // Build that beautiful button row
            if (!empty($tagsRow)) {
                $context['bbc_toolbar'][$row][] = implode(',', $tagsRow);
            }
        }
    }
    // Initialize smiley array... if not loaded before.
    if (empty($context['smileys']) && empty($editorOptions['disable_smiley_box'])) {
        $context['smileys'] = array('postform' => array(), 'popup' => array());
        // Load smileys - don't bother to run a query if we're not using the database's ones anyhow.
        if (empty($modSettings['smiley_enable']) && $user_info['smiley_set'] != 'none') {
            $context['smileys']['postform'][] = array('smileys' => array(array('code' => ':)', 'filename' => 'smiley.gif', 'description' => $txt['icon_smiley']), array('code' => ';)', 'filename' => 'wink.gif', 'description' => $txt['icon_wink']), array('code' => ':D', 'filename' => 'cheesy.gif', 'description' => $txt['icon_cheesy']), array('code' => ';D', 'filename' => 'grin.gif', 'description' => $txt['icon_grin']), array('code' => '>:(', 'filename' => 'angry.gif', 'description' => $txt['icon_angry']), array('code' => ':))', 'filename' => 'laugh.gif', 'description' => $txt['icon_laugh']), array('code' => ':(', 'filename' => 'sad.gif', 'description' => $txt['icon_sad']), array('code' => ':o', 'filename' => 'shocked.gif', 'description' => $txt['icon_shocked']), array('code' => '8)', 'filename' => 'cool.gif', 'description' => $txt['icon_cool']), array('code' => '???', 'filename' => 'huh.gif', 'description' => $txt['icon_huh']), array('code' => '::)', 'filename' => 'rolleyes.gif', 'description' => $txt['icon_rolleyes']), array('code' => ':P', 'filename' => 'tongue.gif', 'description' => $txt['icon_tongue']), array('code' => ':-[', 'filename' => 'embarrassed.gif', 'description' => $txt['icon_embarrassed']), array('code' => ':-X', 'filename' => 'lipsrsealed.gif', 'description' => $txt['icon_lips']), array('code' => ':-\\', 'filename' => 'undecided.gif', 'description' => $txt['icon_undecided']), array('code' => ':-*', 'filename' => 'kiss.gif', 'description' => $txt['icon_kiss']), array('code' => 'O:)', 'filename' => 'angel.gif', 'description' => $txt['icon_angel']), array('code' => ':\'(', 'filename' => 'cry.gif', 'description' => $txt['icon_cry'], 'isLast' => true)), 'isLast' => true);
        } elseif ($user_info['smiley_set'] != 'none') {
            if (($temp = cache_get_data('posting_smileys', 480)) == null) {
                $request = $db->query('', '
					SELECT code, filename, description, smiley_row, hidden
					FROM {db_prefix}smileys
					WHERE hidden IN (0, 2)
					ORDER BY smiley_row, smiley_order', array());
                while ($row = $db->fetch_assoc($request)) {
                    $row['filename'] = htmlspecialchars($row['filename'], ENT_COMPAT, 'UTF-8');
                    $row['description'] = htmlspecialchars($row['description'], ENT_COMPAT, 'UTF-8');
                    $context['smileys'][empty($row['hidden']) ? 'postform' : 'popup'][$row['smiley_row']]['smileys'][] = $row;
                }
                $db->free_result($request);
                foreach ($context['smileys'] as $section => $smileyRows) {
                    $last_row = null;
                    foreach ($smileyRows as $rowIndex => $smileys) {
                        $context['smileys'][$section][$rowIndex]['smileys'][count($smileys['smileys']) - 1]['isLast'] = true;
                        $last_row = $rowIndex;
                    }
                    if ($last_row !== null) {
                        $context['smileys'][$section][$last_row]['isLast'] = true;
                    }
                }
                cache_put_data('posting_smileys', $context['smileys'], 480);
            } else {
                $context['smileys'] = $temp;
            }
            // The smiley popup may take advantage of Jquery UI ....
            if (!empty($context['smileys']['popup'])) {
                $modSettings['jquery_include_ui'] = true;
            }
        }
    }
    // Set a flag so the sub template knows what to do...
    $context['show_bbc'] = !empty($modSettings['enableBBC']) && !empty($settings['show_bbc']);
    // Switch the URLs back... now we're back to whatever the main sub template is.  (like folder in PersonalMessage.)
    if (isset($settings['use_default_images']) && $settings['use_default_images'] == 'defaults' && isset($settings['default_template'])) {
        $settings['theme_url'] = $temp1;
        $settings['images_url'] = $temp2;
        $settings['theme_dir'] = $temp3;
    }
    if (!empty($editorOptions['live_errors'])) {
        loadLanguage('Errors');
        addInlineJavascript('
	error_txts[\'no_subject\'] = ' . JavaScriptEscape($txt['error_no_subject']) . ';
	error_txts[\'no_message\'] = ' . JavaScriptEscape($txt['error_no_message']) . ';

	var subject_err = new errorbox_handler({
		self: \'subject_err\',
		error_box_id: \'post_error\',
		error_checks: [{
			code: \'no_subject\',
			efunction: function(box_value) {
				if (box_value.length === 0)
					return true;
				else
					return false;
			}
		}],
		check_id: "post_subject"
	});

	var body_err_' . $editorOptions['id'] . ' = new errorbox_handler({
		self: \'body_err_' . $editorOptions['id'] . '\',
		error_box_id: \'post_error\',
		error_checks: [{
			code: \'no_message\',
			efunction: function(box_value) {
				if (box_value.length === 0)
					return true;
				else
					return false;
			}
		}],
		editor_id: \'' . $editorOptions['id'] . '\',
		editor: ' . JavaScriptEscape('
		(function () {
			return $editor_data[\'' . $editorOptions['id'] . '\'].val();
		});') . '
	});', true);
    }
}