Exemple #1
0
function createPost(&$msgOptions, &$topicOptions, &$posterOptions)
{
    global $user_info, $txt, $modSettings, $smcFunc, $context;
    // Set optional parameters to the default value.
    $msgOptions['icon'] = empty($msgOptions['icon']) ? 'xx' : $msgOptions['icon'];
    $msgOptions['smileys_enabled'] = !empty($msgOptions['smileys_enabled']);
    $msgOptions['attachments'] = empty($msgOptions['attachments']) ? array() : $msgOptions['attachments'];
    $msgOptions['approved'] = isset($msgOptions['approved']) ? (int) $msgOptions['approved'] : 1;
    $topicOptions['id'] = empty($topicOptions['id']) ? 0 : (int) $topicOptions['id'];
    $topicOptions['poll'] = isset($topicOptions['poll']) ? (int) $topicOptions['poll'] : null;
    $topicOptions['lock_mode'] = isset($topicOptions['lock_mode']) ? $topicOptions['lock_mode'] : null;
    $topicOptions['sticky_mode'] = isset($topicOptions['sticky_mode']) ? $topicOptions['sticky_mode'] : null;
    $posterOptions['id'] = empty($posterOptions['id']) ? 0 : (int) $posterOptions['id'];
    $posterOptions['ip'] = empty($posterOptions['ip']) ? $user_info['ip'] : $posterOptions['ip'];
    // We need to know if the topic is approved. If we're told that's great - if not find out.
    if (!$modSettings['postmod_active']) {
        $topicOptions['is_approved'] = true;
    } elseif (!empty($topicOptions['id']) && !isset($topicOptions['is_approved'])) {
        $request = $smcFunc['db_query']('', '
			SELECT approved
			FROM {db_prefix}topics
			WHERE id_topic = {int:id_topic}
			LIMIT 1', array('id_topic' => $topicOptions['id']));
        list($topicOptions['is_approved']) = $smcFunc['db_fetch_row']($request);
        $smcFunc['db_free_result']($request);
    }
    // If nothing was filled in as name/e-mail address, try the member table.
    if (!isset($posterOptions['name']) || $posterOptions['name'] == '' || empty($posterOptions['email']) && !empty($posterOptions['id'])) {
        if (empty($posterOptions['id'])) {
            $posterOptions['id'] = 0;
            $posterOptions['name'] = $txt['guest_title'];
            $posterOptions['email'] = '';
        } elseif ($posterOptions['id'] != $user_info['id']) {
            $request = $smcFunc['db_query']('', '
				SELECT member_name, email_address
				FROM {db_prefix}members
				WHERE id_member = {int:id_member}
				LIMIT 1', array('id_member' => $posterOptions['id']));
            // Couldn't find the current poster?
            if ($smcFunc['db_num_rows']($request) == 0) {
                trigger_error('createPost(): Invalid member id ' . $posterOptions['id'], E_USER_NOTICE);
                $posterOptions['id'] = 0;
                $posterOptions['name'] = $txt['guest_title'];
                $posterOptions['email'] = '';
            } else {
                list($posterOptions['name'], $posterOptions['email']) = $smcFunc['db_fetch_row']($request);
            }
            $smcFunc['db_free_result']($request);
        } else {
            $posterOptions['name'] = $user_info['name'];
            $posterOptions['email'] = $user_info['email'];
        }
    }
    // It's do or die time: forget any user aborts!
    $previous_ignore_user_abort = ignore_user_abort(true);
    $new_topic = empty($topicOptions['id']);
    // Insert the post.
    $smcFunc['db_insert']('', '{db_prefix}messages', array('id_board' => 'int', 'id_topic' => 'int', 'id_member' => 'int', 'subject' => 'string-255', 'body' => !empty($modSettings['max_messageLength']) && $modSettings['max_messageLength'] > 65534 ? 'string-' . $modSettings['max_messageLength'] : 'string-65534', 'poster_name' => 'string-255', 'poster_email' => 'string-255', 'poster_time' => 'int', 'poster_ip' => 'string-255', 'smileys_enabled' => 'int', 'modified_name' => 'string', 'icon' => 'string-16', 'approved' => 'int'), array($topicOptions['board'], $topicOptions['id'], $posterOptions['id'], $msgOptions['subject'], $msgOptions['body'], $posterOptions['name'], $posterOptions['email'], time(), $posterOptions['ip'], $msgOptions['smileys_enabled'] ? 1 : 0, '', $msgOptions['icon'], $msgOptions['approved']), array('id_msg'));
    $msgOptions['id'] = $smcFunc['db_insert_id']('{db_prefix}messages', 'id_msg');
    // Something went wrong creating the message...
    if (empty($msgOptions['id'])) {
        return false;
    }
    // Fix the attachments.
    if (!empty($msgOptions['attachments'])) {
        $smcFunc['db_query']('', '
			UPDATE {db_prefix}attachments
			SET id_msg = {int:id_msg}
			WHERE id_attach IN ({array_int:attachment_list})', array('attachment_list' => $msgOptions['attachments'], 'id_msg' => $msgOptions['id']));
    }
    // Insert a new topic (if the topicID was left empty.)
    if ($new_topic) {
        $smcFunc['db_insert']('', '{db_prefix}topics', array('id_board' => 'int', 'id_member_started' => 'int', 'id_member_updated' => 'int', 'id_first_msg' => 'int', 'id_last_msg' => 'int', 'locked' => 'int', 'is_sticky' => 'int', 'num_views' => 'int', 'id_poll' => 'int', 'unapproved_posts' => 'int', 'approved' => 'int'), array($topicOptions['board'], $posterOptions['id'], $posterOptions['id'], $msgOptions['id'], $msgOptions['id'], $topicOptions['lock_mode'] === null ? 0 : $topicOptions['lock_mode'], $topicOptions['sticky_mode'] === null ? 0 : $topicOptions['sticky_mode'], 0, $topicOptions['poll'] === null ? 0 : $topicOptions['poll'], $msgOptions['approved'] ? 0 : 1, $msgOptions['approved']), array('id_topic'));
        $topicOptions['id'] = $smcFunc['db_insert_id']('{db_prefix}topics', 'id_topic');
        // The topic couldn't be created for some reason.
        if (empty($topicOptions['id'])) {
            // We should delete the post that did work, though...
            $smcFunc['db_query']('', '
				DELETE FROM {db_prefix}messages
				WHERE id_msg = {int:id_msg}', array('id_msg' => $msgOptions['id']));
            return false;
        }
        // Fix the message with the topic.
        $smcFunc['db_query']('', '
			UPDATE {db_prefix}messages
			SET id_topic = {int:id_topic}
			WHERE id_msg = {int:id_msg}', array('id_topic' => $topicOptions['id'], 'id_msg' => $msgOptions['id']));
        // There's been a new topic AND a new post today.
        trackStats(array('topics' => '+', 'posts' => '+'));
        updateStats('topic', true);
        updateStats('subject', $topicOptions['id'], $msgOptions['subject']);
        // What if we want to export new topics out to a CMS?
        call_integration_hook('integrate_create_topic', array($msgOptions, $topicOptions, $posterOptions));
    } else {
        $countChange = $msgOptions['approved'] ? 'num_replies = num_replies + 1' : 'unapproved_posts = unapproved_posts + 1';
        // Update the number of replies and the lock/sticky status.
        $smcFunc['db_query']('', '
			UPDATE {db_prefix}topics
			SET
				' . ($msgOptions['approved'] ? 'id_member_updated = {int:poster_id}, id_last_msg = {int:id_msg},' : '') . '
				' . $countChange . ($topicOptions['lock_mode'] === null ? '' : ',
				locked = {int:locked}') . ($topicOptions['sticky_mode'] === null ? '' : ',
				is_sticky = {int:is_sticky}') . '
			WHERE id_topic = {int:id_topic}', array('poster_id' => $posterOptions['id'], 'id_msg' => $msgOptions['id'], 'locked' => $topicOptions['lock_mode'], 'is_sticky' => $topicOptions['sticky_mode'], 'id_topic' => $topicOptions['id']));
        // One new post has been added today.
        trackStats(array('posts' => '+'));
    }
    // Creating is modifying...in a way.
    //!!! Why not set id_msg_modified on the insert?
    $smcFunc['db_query']('', '
		UPDATE {db_prefix}messages
		SET id_msg_modified = {int:id_msg}
		WHERE id_msg = {int:id_msg}', array('id_msg' => $msgOptions['id']));
    // Increase the number of posts and topics on the board.
    if ($msgOptions['approved']) {
        $smcFunc['db_query']('', '
			UPDATE {db_prefix}boards
			SET num_posts = num_posts + 1' . ($new_topic ? ', num_topics = num_topics + 1' : '') . '
			WHERE id_board = {int:id_board}', array('id_board' => $topicOptions['board']));
    } else {
        $smcFunc['db_query']('', '
			UPDATE {db_prefix}boards
			SET unapproved_posts = unapproved_posts + 1' . ($new_topic ? ', unapproved_topics = unapproved_topics + 1' : '') . '
			WHERE id_board = {int:id_board}', array('id_board' => $topicOptions['board']));
        // Add to the approval queue too.
        $smcFunc['db_insert']('', '{db_prefix}approval_queue', array('id_msg' => 'int'), array($msgOptions['id']), array());
    }
    // Mark inserted topic as read (only for the user calling this function).
    if (!empty($topicOptions['mark_as_read']) && !$user_info['is_guest']) {
        // Since it's likely they *read* it before replying, let's try an UPDATE first.
        if (!$new_topic) {
            $smcFunc['db_query']('', '
				UPDATE {db_prefix}log_topics
				SET id_msg = {int:id_msg}
				WHERE id_member = {int:current_member}
					AND id_topic = {int:id_topic}', array('current_member' => $posterOptions['id'], 'id_msg' => $msgOptions['id'], 'id_topic' => $topicOptions['id']));
            $flag = $smcFunc['db_affected_rows']() != 0;
        }
        if (empty($flag)) {
            $smcFunc['db_insert']('ignore', '{db_prefix}log_topics', array('id_topic' => 'int', 'id_member' => 'int', 'id_msg' => 'int'), array($topicOptions['id'], $posterOptions['id'], $msgOptions['id']), array('id_topic', 'id_member'));
        }
    }
    // If there's a custom search index, it needs updating...
    if (!empty($modSettings['search_custom_index_config'])) {
        $customIndexSettings = unserialize($modSettings['search_custom_index_config']);
        $inserts = array();
        foreach (text2words($msgOptions['body'], $customIndexSettings['bytes_per_word'], true) as $word) {
            $inserts[] = array($word, $msgOptions['id']);
        }
        if (!empty($inserts)) {
            $smcFunc['db_insert']('ignore', '{db_prefix}log_search_words', array('id_word' => 'int', 'id_msg' => 'int'), $inserts, array('id_word', 'id_msg'));
        }
    }
    // Increase the post counter for the user that created the post.
    if (!empty($posterOptions['update_post_count']) && !empty($posterOptions['id']) && $msgOptions['approved']) {
        // Are you the one that happened to create this post?
        if ($user_info['id'] == $posterOptions['id']) {
            $user_info['posts']++;
        }
        updateMemberData($posterOptions['id'], array('posts' => '+'));
    }
    // They've posted, so they can make the view count go up one if they really want. (this is to keep views >= replies...)
    $_SESSION['last_read_topic'] = 0;
    // Better safe than sorry.
    if (isset($_SESSION['topicseen_cache'][$topicOptions['board']])) {
        $_SESSION['topicseen_cache'][$topicOptions['board']]--;
    }
    // Update all the stats so everyone knows about this new topic and message.
    updateStats('message', true, $msgOptions['id']);
    // Update the last message on the board assuming it's approved AND the topic is.
    if ($msgOptions['approved']) {
        updateLastMessages($topicOptions['board'], $new_topic || !empty($topicOptions['is_approved']) ? $msgOptions['id'] : 0);
    }
    // Alright, done now... we can abort now, I guess... at least this much is done.
    ignore_user_abort($previous_ignore_user_abort);
    // Success.
    return true;
}
Exemple #2
0
/**
 * The main dispatcher.
 * This delegates to each area.
 */
function elk_main()
{
    global $modSettings, $user_info, $topic, $board_info, $context;
    // Special case: session keep-alive, output a transparent pixel.
    if (isset($_GET['action']) && $_GET['action'] == 'keepalive') {
        header('Content-Type: image/gif');
        die("GIF89a€!ù,D;");
    }
    // We should set our security headers now.
    frameOptionsHeader();
    securityOptionsHeader();
    // Load the user's cookie (or set as guest) and load their settings.
    loadUserSettings();
    // Load the current board's information.
    loadBoard();
    // Load the current user's permissions.
    loadPermissions();
    // Load BadBehavior before we go much further
    loadBadBehavior();
    // Attachments don't require the entire theme to be loaded.
    if (isset($_REQUEST['action']) && $_REQUEST['action'] == 'dlattach' && (!empty($modSettings['allow_guestAccess']) && $user_info['is_guest'])) {
        detectBrowser();
    } else {
        loadTheme();
    }
    // Check if the user should be disallowed access.
    is_not_banned();
    // If we are in a topic and don't have permission to approve it then duck out now.
    if (!empty($topic) && empty($board_info['cur_topic_approved']) && !allowedTo('approve_posts') && ($user_info['id'] != $board_info['cur_topic_starter'] || $user_info['is_guest'])) {
        fatal_lang_error('not_a_topic', false);
    }
    $no_stat_actions = array('dlattach', 'findmember', 'jsoption', 'requestmembers', 'jslocale', 'xmlpreview', 'suggest', '.xml', 'xmlhttp', 'verificationcode', 'viewquery', 'viewadminfile');
    call_integration_hook('integrate_pre_log_stats', array(&$no_stat_actions));
    // Do some logging, unless this is an attachment, avatar, toggle of editor buttons, theme option, XML feed etc.
    if (empty($_REQUEST['action']) || !in_array($_REQUEST['action'], $no_stat_actions)) {
        // I see you!
        writeLog();
        // Track forum statistics and hits...?
        if (!empty($modSettings['hitStats'])) {
            trackStats(array('hits' => '+'));
        }
    }
    unset($no_stat_actions);
    // What shall we do?
    require_once SOURCEDIR . '/SiteDispatcher.class.php';
    $dispatcher = new Site_Dispatcher();
    // Show where we came from, and go
    $context['site_action'] = $dispatcher->site_action();
    $context['site_action'] = !empty($context['site_action']) ? $context['site_action'] : (isset($_REQUEST['action']) ? $_REQUEST['action'] : '');
    $dispatcher->dispatch();
}
/**
 * Sends a personal message from the specified person to the specified people
 * ($from defaults to the user)
 *
 * @package PersonalMessage
 * @param mixed[] $recipients - an array containing the arrays 'to' and 'bcc', both containing id_member's.
 * @param string $subject - should have no slashes and no html entities
 * @param string $message - should have no slashes and no html entities
 * @param bool $store_outbox
 * @param mixed[]|null $from - an array with the id, name, and username of the member.
 * @param int $pm_head - the ID of the chain being replied to - if any.
 * @return mixed[] an array with log entries telling how many recipients were successful and which recipients it failed to send to.
 */
function sendpm($recipients, $subject, $message, $store_outbox = true, $from = null, $pm_head = 0)
{
    global $scripturl, $txt, $user_info, $language, $modSettings, $webmaster_email;
    $db = database();
    // Make sure the PM language file is loaded, we might need something out of it.
    loadLanguage('PersonalMessage');
    // Needed for our email and post functions
    require_once SUBSDIR . '/Mail.subs.php';
    require_once SUBSDIR . '/Post.subs.php';
    // Initialize log array.
    $log = array('failed' => array(), 'sent' => array());
    if ($from === null) {
        $from = array('id' => $user_info['id'], 'name' => $user_info['name'], 'username' => $user_info['username']);
    } else {
        $user_info['name'] = $from['name'];
    }
    // This is the one that will go in their inbox.
    $htmlmessage = Util::htmlspecialchars($message, ENT_QUOTES, 'UTF-8', true);
    preparsecode($htmlmessage);
    $htmlsubject = strtr(Util::htmlspecialchars($subject), array("\r" => '', "\n" => '', "\t" => ''));
    if (Util::strlen($htmlsubject) > 100) {
        $htmlsubject = Util::substr($htmlsubject, 0, 100);
    }
    // Make sure is an array
    if (!is_array($recipients)) {
        $recipients = array($recipients);
    }
    // Integrated PMs
    call_integration_hook('integrate_personal_message', array(&$recipients, &$from, &$subject, &$message));
    // Get a list of usernames and convert them to IDs.
    $usernames = array();
    foreach ($recipients as $rec_type => $rec) {
        foreach ($rec as $id => $member) {
            if (!is_numeric($recipients[$rec_type][$id])) {
                $recipients[$rec_type][$id] = Util::strtolower(trim(preg_replace('/[<>&"\'=\\\\]/', '', $recipients[$rec_type][$id])));
                $usernames[$recipients[$rec_type][$id]] = 0;
            }
        }
    }
    if (!empty($usernames)) {
        $request = $db->query('pm_find_username', '
			SELECT
				id_member, member_name
			FROM {db_prefix}members
			WHERE ' . (defined('DB_CASE_SENSITIVE') ? 'LOWER(member_name)' : 'member_name') . ' IN ({array_string:usernames})', array('usernames' => array_keys($usernames)));
        while ($row = $db->fetch_assoc($request)) {
            if (isset($usernames[Util::strtolower($row['member_name'])])) {
                $usernames[Util::strtolower($row['member_name'])] = $row['id_member'];
            }
        }
        $db->free_result($request);
        // Replace the usernames with IDs. Drop usernames that couldn't be found.
        foreach ($recipients as $rec_type => $rec) {
            foreach ($rec as $id => $member) {
                if (is_numeric($recipients[$rec_type][$id])) {
                    continue;
                }
                if (!empty($usernames[$member])) {
                    $recipients[$rec_type][$id] = $usernames[$member];
                } else {
                    $log['failed'][$id] = sprintf($txt['pm_error_user_not_found'], $recipients[$rec_type][$id]);
                    unset($recipients[$rec_type][$id]);
                }
            }
        }
    }
    // Make sure there are no duplicate 'to' members.
    $recipients['to'] = array_unique($recipients['to']);
    // Only 'bcc' members that aren't already in 'to'.
    $recipients['bcc'] = array_diff(array_unique($recipients['bcc']), $recipients['to']);
    // Combine 'to' and 'bcc' recipients.
    $all_to = array_merge($recipients['to'], $recipients['bcc']);
    // Check no-one will want it deleted right away!
    $request = $db->query('', '
		SELECT
			id_member, criteria, is_or
		FROM {db_prefix}pm_rules
		WHERE id_member IN ({array_int:to_members})
			AND delete_pm = {int:delete_pm}', array('to_members' => $all_to, 'delete_pm' => 1));
    $deletes = array();
    // Check whether we have to apply anything...
    while ($row = $db->fetch_assoc($request)) {
        $criteria = unserialize($row['criteria']);
        // Note we don't check the buddy status, cause deletion from buddy = madness!
        $delete = false;
        foreach ($criteria as $criterium) {
            if ($criterium['t'] == 'mid' && $criterium['v'] == $from['id'] || $criterium['t'] == 'gid' && in_array($criterium['v'], $user_info['groups']) || $criterium['t'] == 'sub' && strpos($subject, $criterium['v']) !== false || $criterium['t'] == 'msg' && strpos($message, $criterium['v']) !== false) {
                $delete = true;
            } elseif (!$row['is_or']) {
                $delete = false;
                break;
            }
        }
        if ($delete) {
            $deletes[$row['id_member']] = 1;
        }
    }
    $db->free_result($request);
    // Load the membergrounp message limits.
    static $message_limit_cache = array();
    if (!allowedTo('moderate_forum') && empty($message_limit_cache)) {
        $request = $db->query('', '
			SELECT
				id_group, max_messages
			FROM {db_prefix}membergroups', array());
        while ($row = $db->fetch_assoc($request)) {
            $message_limit_cache[$row['id_group']] = $row['max_messages'];
        }
        $db->free_result($request);
    }
    // Load the groups that are allowed to read PMs.
    // @todo move into a separate function on $permission.
    $allowed_groups = array();
    $disallowed_groups = array();
    $request = $db->query('', '
		SELECT
			id_group, add_deny
		FROM {db_prefix}permissions
		WHERE permission = {string:read_permission}', array('read_permission' => 'pm_read'));
    while ($row = $db->fetch_assoc($request)) {
        if (empty($row['add_deny'])) {
            $disallowed_groups[] = $row['id_group'];
        } else {
            $allowed_groups[] = $row['id_group'];
        }
    }
    $db->free_result($request);
    if (empty($modSettings['permission_enable_deny'])) {
        $disallowed_groups = array();
    }
    $request = $db->query('', '
		SELECT
			member_name, real_name, id_member, email_address, lngfile,
			pm_email_notify, personal_messages,' . (allowedTo('moderate_forum') ? ' 0' : '
			(receive_from = {int:admins_only}' . (empty($modSettings['enable_buddylist']) ? '' : ' OR
			(receive_from = {int:buddies_only} AND FIND_IN_SET({string:from_id}, buddy_list) = 0) OR
			(receive_from = {int:not_on_ignore_list} AND FIND_IN_SET({string:from_id}, pm_ignore_list) != 0)') . ')') . ' AS ignored,
			FIND_IN_SET({string:from_id}, buddy_list) != 0 AS is_buddy, is_activated,
			additional_groups, id_group, id_post_group
		FROM {db_prefix}members
		WHERE id_member IN ({array_int:recipients})
		ORDER BY lngfile
		LIMIT {int:count_recipients}', array('not_on_ignore_list' => 1, 'buddies_only' => 2, 'admins_only' => 3, 'recipients' => $all_to, 'count_recipients' => count($all_to), 'from_id' => $from['id']));
    $notifications = array();
    while ($row = $db->fetch_assoc($request)) {
        // Don't do anything for members to be deleted!
        if (isset($deletes[$row['id_member']])) {
            continue;
        }
        // We need to know this members groups.
        $groups = explode(',', $row['additional_groups']);
        $groups[] = $row['id_group'];
        $groups[] = $row['id_post_group'];
        $message_limit = -1;
        // For each group see whether they've gone over their limit - assuming they're not an admin.
        if (!in_array(1, $groups)) {
            foreach ($groups as $id) {
                if (isset($message_limit_cache[$id]) && $message_limit != 0 && $message_limit < $message_limit_cache[$id]) {
                    $message_limit = $message_limit_cache[$id];
                }
            }
            if ($message_limit > 0 && $message_limit <= $row['personal_messages']) {
                $log['failed'][$row['id_member']] = sprintf($txt['pm_error_data_limit_reached'], $row['real_name']);
                unset($all_to[array_search($row['id_member'], $all_to)]);
                continue;
            }
            // Do they have any of the allowed groups?
            if (count(array_intersect($allowed_groups, $groups)) == 0 || count(array_intersect($disallowed_groups, $groups)) != 0) {
                $log['failed'][$row['id_member']] = sprintf($txt['pm_error_user_cannot_read'], $row['real_name']);
                unset($all_to[array_search($row['id_member'], $all_to)]);
                continue;
            }
        }
        // Note that PostgreSQL can return a lowercase t/f for FIND_IN_SET
        if (!empty($row['ignored']) && $row['ignored'] != 'f' && $row['id_member'] != $from['id']) {
            $log['failed'][$row['id_member']] = sprintf($txt['pm_error_ignored_by_user'], $row['real_name']);
            unset($all_to[array_search($row['id_member'], $all_to)]);
            continue;
        }
        // If the receiving account is banned (>=10) or pending deletion (4), refuse to send the PM.
        if ($row['is_activated'] >= 10 || $row['is_activated'] == 4 && !$user_info['is_admin']) {
            $log['failed'][$row['id_member']] = sprintf($txt['pm_error_user_cannot_read'], $row['real_name']);
            unset($all_to[array_search($row['id_member'], $all_to)]);
            continue;
        }
        // Send a notification, if enabled - taking the buddy list into account.
        if (!empty($row['email_address']) && ($row['pm_email_notify'] == 1 || $row['pm_email_notify'] > 1 && (!empty($modSettings['enable_buddylist']) && $row['is_buddy'])) && $row['is_activated'] == 1) {
            $notifications[empty($row['lngfile']) || empty($modSettings['userLanguage']) ? $language : $row['lngfile']][] = $row['email_address'];
        }
        $log['sent'][$row['id_member']] = sprintf(isset($txt['pm_successfully_sent']) ? $txt['pm_successfully_sent'] : '', $row['real_name']);
    }
    $db->free_result($request);
    // Only 'send' the message if there are any recipients left.
    if (empty($all_to)) {
        return $log;
    }
    // Track the pm count for our stats
    if (!empty($modSettings['trackStats'])) {
        trackStats(array('pm' => '+'));
    }
    // Insert the message itself and then grab the last insert id.
    $db->insert('', '{db_prefix}personal_messages', array('id_pm_head' => 'int', 'id_member_from' => 'int', 'deleted_by_sender' => 'int', 'from_name' => 'string-255', 'msgtime' => 'int', 'subject' => 'string-255', 'body' => 'string-65534'), array($pm_head, $from['id'], $store_outbox ? 0 : 1, $from['username'], time(), $htmlsubject, $htmlmessage), array('id_pm'));
    $id_pm = $db->insert_id('{db_prefix}personal_messages', 'id_pm');
    // Add the recipients.
    if (!empty($id_pm)) {
        // If this is new we need to set it part of it's own conversation.
        if (empty($pm_head)) {
            $db->query('', '
				UPDATE {db_prefix}personal_messages
				SET id_pm_head = {int:id_pm_head}
				WHERE id_pm = {int:id_pm_head}', array('id_pm_head' => $id_pm));
        }
        // Some people think manually deleting personal_messages is fun... it's not. We protect against it though :)
        $db->query('', '
			DELETE FROM {db_prefix}pm_recipients
			WHERE id_pm = {int:id_pm}', array('id_pm' => $id_pm));
        $insertRows = array();
        $to_list = array();
        foreach ($all_to as $to) {
            $insertRows[] = array($id_pm, $to, in_array($to, $recipients['bcc']) ? 1 : 0, isset($deletes[$to]) ? 1 : 0, 1);
            if (!in_array($to, $recipients['bcc'])) {
                $to_list[] = $to;
            }
        }
        $db->insert('insert', '{db_prefix}pm_recipients', array('id_pm' => 'int', 'id_member' => 'int', 'bcc' => 'int', 'deleted' => 'int', 'is_new' => 'int'), $insertRows, array('id_pm', 'id_member'));
    }
    $maillist = !empty($modSettings['maillist_enabled']) && !empty($modSettings['pbe_pm_enabled']);
    // If they have post by email enabled, override disallow_sendBody
    if (!$maillist && !empty($modSettings['disallow_sendBody'])) {
        $message = '';
        censorText($subject);
    } else {
        require_once SUBSDIR . '/Emailpost.subs.php';
        pbe_prepare_text($message, $subject);
    }
    $to_names = array();
    if (count($to_list) > 1) {
        require_once SUBSDIR . '/Members.subs.php';
        $result = getBasicMemberData($to_list);
        foreach ($result as $row) {
            $to_names[] = un_htmlspecialchars($row['real_name']);
        }
    }
    $replacements = array('SUBJECT' => $subject, 'MESSAGE' => $message, 'SENDER' => un_htmlspecialchars($from['name']), 'READLINK' => $scripturl . '?action=pm;pmsg=' . $id_pm . '#msg' . $id_pm, 'REPLYLINK' => $scripturl . '?action=pm;sa=send;f=inbox;pmsg=' . $id_pm . ';quote;u=' . $from['id'], 'TOLIST' => implode(', ', $to_names));
    // Select the right template
    $email_template = ($maillist && empty($modSettings['disallow_sendBody']) ? 'pbe_' : '') . 'new_pm' . (empty($modSettings['disallow_sendBody']) ? '_body' : '') . (!empty($to_names) ? '_tolist' : '');
    foreach ($notifications as $lang => $notification_list) {
        // Using maillist functionality
        if ($maillist) {
            $sender_details = query_sender_wrapper($from['id']);
            $from_wrapper = !empty($modSettings['maillist_mail_from']) ? $modSettings['maillist_mail_from'] : (empty($modSettings['maillist_sitename_address']) ? $webmaster_email : $modSettings['maillist_sitename_address']);
            // Add in the signature
            $replacements['SIGNATURE'] = $sender_details['signature'];
            // And off it goes, looking a bit more personal
            $mail = loadEmailTemplate($email_template, $replacements, $lang);
            $reference = !empty($pm_head) ? $pm_head : null;
            sendmail($notification_list, $mail['subject'], $mail['body'], $from['name'], 'p' . $id_pm, false, 2, null, true, $from_wrapper, $reference);
        } else {
            // Off the notification email goes!
            $mail = loadEmailTemplate($email_template, $replacements, $lang);
            sendmail($notification_list, $mail['subject'], $mail['body'], null, 'p' . $id_pm, false, 2, null, true);
        }
    }
    // Integrated After PMs
    call_integration_hook('integrate_personal_message_after', array(&$id_pm, &$log, &$recipients, &$from, &$subject, &$message));
    // Back to what we were on before!
    loadLanguage('index+PersonalMessage');
    // Add one to their unread and read message counts.
    foreach ($all_to as $k => $id) {
        if (isset($deletes[$id])) {
            unset($all_to[$k]);
        }
    }
    if (!empty($all_to)) {
        updateMemberData($all_to, array('personal_messages' => '+', 'unread_messages' => '+', 'new_pm' => 1));
    }
    return $log;
}
Exemple #4
0
/**
 * Sends a group of emails from the mail queue.
 *
 * - Allows a batch of emails to be released every 5 to 10 seconds (based on per period limits)
 * - If batch size is not set, will determine a size such that it sends in 1/2 the period (buffer)
 *
 * @package Mail
 * @param int|false $batch_size = false the number to send each loop
 * @param boolean $override_limit = false bypassing our limit flaf
 * @param boolean $force_send = false
 * @return boolean
 */
function reduceMailQueue($batch_size = false, $override_limit = false, $force_send = false)
{
    global $modSettings, $context, $webmaster_email, $scripturl;
    // Do we have another script to send out the queue?
    if (!empty($modSettings['mail_queue_use_cron']) && empty($force_send)) {
        return false;
    }
    // How many emails can we send each time we are called in a period
    if (!$batch_size) {
        // Batch size has been set in the ACP, use it
        if (!empty($modSettings['mail_batch_size'])) {
            $batch_size = $modSettings['mail_batch_size'];
        } elseif (empty($modSettings['mail_period_limit'])) {
            $batch_size = 5;
        } else {
            // Based on the number of times we will potentially be called each minute
            $delay = !empty($modSettings['mail_queue_delay']) ? $modSettings['mail_queue_delay'] : (!empty($modSettings['mail_period_limit']) && $modSettings['mail_period_limit'] <= 5 ? 10 : 5);
            $batch_size = ceil($modSettings['mail_period_limit'] / ceil(60 / $delay));
            $batch_size = $batch_size == 1 && $modSettings['mail_period_limit'] > 1 ? 2 : $batch_size;
        }
    }
    // If we came with a timestamp, and that doesn't match the next event, then someone else has beaten us.
    if (isset($_GET['ts']) && $_GET['ts'] != $modSettings['mail_next_send'] && empty($force_send)) {
        return false;
    }
    // Prepare to send each email, and log that for future proof.
    require_once SUBSDIR . '/Maillist.subs.php';
    // Set the delay for the next sending
    if (!$override_limit) {
        // Update next send time for our mail queue, if there was something to update. Otherwise bail out :P
        $delay = updateNextSendTime();
        if ($delay === false) {
            return false;
        }
        $modSettings['mail_next_send'] = time() + $delay;
    }
    // If we're not overriding, do we have quota left in this mail period limit?
    if (!$override_limit && !empty($modSettings['mail_period_limit'])) {
        // See if we have quota left to send another batch_size this minute or if we have to wait
        list($mail_time, $mail_number) = isset($modSettings['mail_recent']) ? explode('|', $modSettings['mail_recent']) : array(0, 0);
        // Nothing worth noting...
        if (empty($mail_number) || $mail_time < time() - 60) {
            $mail_time = time();
            $mail_number = $batch_size;
        } elseif ($mail_number < $modSettings['mail_period_limit']) {
            // If this is likely one of the last cycles for this period, then send any remaining quota
            if ($mail_time - (time() - 60) < $delay * 2) {
                $batch_size = $modSettings['mail_period_limit'] - $mail_number;
            } elseif ($mail_number + $batch_size > $modSettings['mail_period_limit']) {
                $batch_size = $modSettings['mail_period_limit'] - $mail_number;
            }
            $mail_number += $batch_size;
        } else {
            return false;
        }
        // Reflect that we're about to send some, do it now to be safe.
        updateSettings(array('mail_recent' => $mail_time . '|' . $mail_number));
    }
    // Now we know how many we're sending, let's send them.
    list($ids, $emails) = emailsInfo($batch_size);
    // Delete, delete, delete!!!
    if (!empty($ids)) {
        deleteMailQueueItems($ids);
    }
    // Don't believe we have any left after this batch?
    if (count($ids) < $batch_size) {
        resetNextSendTime();
    }
    if (empty($ids)) {
        return false;
    }
    // We have some to send, lets send them!
    $sent = array();
    $failed_emails = array();
    // Use sendmail or SMTP
    $use_sendmail = empty($modSettings['mail_type']) || $modSettings['smtp_host'] == '';
    // Line breaks need to be \r\n only in windows or for SMTP.
    $line_break = !empty($context['server']['is_windows']) || !$use_sendmail ? "\r\n" : "\n";
    foreach ($emails as $key => $email) {
        // Use the right mail resource
        if ($use_sendmail) {
            $email['subject'] = strtr($email['subject'], array("\r" => '', "\n" => ''));
            if (!empty($modSettings['mail_strip_carriage'])) {
                $email['body'] = strtr($email['body'], array("\r" => ''));
                $email['headers'] = strtr($email['headers'], array("\r" => ''));
            }
            $need_break = substr($email['headers'], -1) === "\n" || substr($email['headers'], -1) === "\r" ? false : true;
            // Create our unique reply to email header if this message needs one
            $unq_id = '';
            $unq_head = '';
            if (!empty($modSettings['maillist_enabled']) && $email['message_id'] !== null && strpos($email['headers'], 'List-Id: <') !== false) {
                $unq_head = md5($scripturl . microtime() . rand()) . '-' . $email['message_id'];
                $encoded_unq_head = base64_encode($line_break . $line_break . '[' . $unq_head . ']' . $line_break);
                $unq_id = ($need_break ? $line_break : '') . 'Message-ID: <' . $unq_head . strstr(empty($modSettings['maillist_mail_from']) ? $webmaster_email : $modSettings['maillist_mail_from'], '@') . '>';
                $email['body_fail'] = $email['body'];
                $email['body'] = mail_insert_key($email['body'], $unq_head, $encoded_unq_head, $line_break);
            } elseif ($email['message_id'] !== null && empty($modSettings['mail_no_message_id'])) {
                $unq_id = ($need_break ? $line_break : '') . 'Message-ID: <' . md5($scripturl . microtime()) . '-' . $email['message_id'] . strstr(empty($modSettings['maillist_mail_from']) ? $webmaster_email : $modSettings['maillist_mail_from'], '@') . '>';
            }
            // No point logging a specific error here, as we have no language. PHP error is helpful anyway...
            $result = mail(strtr($email['to'], array("\r" => '', "\n" => '')), $email['subject'], $email['body'], $email['headers'] . $unq_id);
            // If it sent, keep a record so we can save it in our allowed to reply log
            if (!empty($unq_head) && $result) {
                $sent[] = array($unq_head, time(), $email['to']);
            }
            // Track total emails sent
            if ($result && !empty($modSettings['trackStats'])) {
                trackStats(array('email' => '+'));
            }
            // Try to stop a timeout, this would be bad...
            @set_time_limit(300);
            if (function_exists('apache_reset_timeout')) {
                @apache_reset_timeout();
            }
        } else {
            $result = smtp_mail(array($email['to']), $email['subject'], $email['body'], $email['send_html'] ? $email['headers'] : 'Mime-Version: 1.0' . "\r\n" . $email['headers'], $email['priority'], $email['message_id']);
        }
        // Hopefully it sent?
        if (!$result) {
            $failed_emails[] = array(time(), $email['to'], $email['body_fail'], $email['subject'], $email['headers'], $email['send_html'], $email['priority'], $email['private'], $email['message_id']);
        }
    }
    // Clear out the stat cache.
    trackStats();
    // Log each of the sent emails.
    if (!empty($sent)) {
        log_email($sent);
    }
    // Any emails that didn't send?
    if (!empty($failed_emails)) {
        // If it failed, add it back to the queue
        updateFailedQueue($failed_emails);
        return false;
    } elseif (!empty($modSettings['mail_failed_attempts'])) {
        updateSuccessQueue();
    }
    // Had something to send...
    return true;
}
Exemple #5
0
function obExit($header = null, $do_footer = null, $from_index = false, $from_fatal_error = false)
{
    global $context, $settings, $modSettings, $txt, $smcFunc;
    static $header_done = false, $footer_done = false, $level = 0, $has_fatal_error = false;
    // Attempt to prevent a recursive loop.
    ++$level;
    if ($level > 1 && !$from_fatal_error && !$has_fatal_error) {
        exit;
    }
    if ($from_fatal_error) {
        $has_fatal_error = true;
    }
    // Clear out the stat cache.
    trackStats();
    // If we have mail to send, send it.
    if (!empty($context['flush_mail'])) {
        AddMailQueue(true);
    }
    $do_header = $header === null ? !$header_done : $header;
    if ($do_footer === null) {
        $do_footer = $do_header;
    }
    // Has the template/header been done yet?
    if ($do_header) {
        // Was the page title set last minute? Also update the HTML safe one.
        if (!empty($context['page_title']) && empty($context['page_title_html_safe'])) {
            $context['page_title_html_safe'] = $smcFunc['htmlspecialchars'](un_htmlspecialchars($context['page_title']));
        }
        // Start up the session URL fixer.
        ob_start('ob_sessrewrite');
        if (!empty($settings['output_buffers']) && is_string($settings['output_buffers'])) {
            $buffers = explode(',', $settings['output_buffers']);
        } elseif (!empty($settings['output_buffers'])) {
            $buffers = $settings['output_buffers'];
        } else {
            $buffers = array();
        }
        if (isset($modSettings['integrate_buffer'])) {
            $buffers = array_merge(explode(',', $modSettings['integrate_buffer']), $buffers);
        }
        if (!empty($buffers)) {
            foreach ($buffers as $function) {
                $function = trim($function);
                $call = strpos($function, '::') !== false ? explode('::', $function) : $function;
                // Is it valid?
                if (is_callable($call)) {
                    ob_start($call);
                }
            }
        }
        // Display the screen in the logical order.
        template_header();
        $header_done = true;
    }
    if ($do_footer) {
        if (WIRELESS && !isset($context['sub_template'])) {
            fatal_lang_error('wireless_error_notyet', false);
        }
        // Just show the footer, then.
        loadSubTemplate(isset($context['sub_template']) ? $context['sub_template'] : 'main');
        // Anything special to put out?
        if (!empty($context['insert_after_template']) && !isset($_REQUEST['xml'])) {
            echo $context['insert_after_template'];
        }
        // Just so we don't get caught in an endless loop of errors from the footer...
        if (!$footer_done) {
            $footer_done = true;
            template_footer();
            // (since this is just debugging... it's okay that it's after </html>.)
            if (!isset($_REQUEST['xml'])) {
                db_debug_junk();
            }
        }
    }
    // Remember this URL in case someone doesn't like sending HTTP_REFERER.
    if (strpos($_SERVER['REQUEST_URL'], 'action=dlattach') === false && strpos($_SERVER['REQUEST_URL'], 'action=viewsmfile') === false) {
        $_SESSION['old_url'] = $_SERVER['REQUEST_URL'];
    }
    // For session check verfication.... don't switch browsers...
    $_SESSION['USER_AGENT'] = $_SERVER['HTTP_USER_AGENT'];
    if (!empty($settings['strict_doctype'])) {
        // The theme author wants to use the STRICT doctype (only God knows why).
        $temp = ob_get_contents();
        if (function_exists('ob_clean')) {
            ob_clean();
        } else {
            ob_end_clean();
            ob_start('ob_sessrewrite');
        }
        echo strtr($temp, array('var smf_iso_case_folding' => 'var target_blank = \'_blank\'; var smf_iso_case_folding', 'target="_blank"' => 'onclick="this.target=target_blank"'));
    }
    // Hand off the output to the portal, etc. we're integrated with.
    call_integration_hook('integrate_exit', array($do_footer && !WIRELESS));
    // Don't exit if we're coming from index.php; that will pass through normally.
    if (!$from_index || WIRELESS) {
        exit;
    }
}
function method_create_topic($is_post = false, $new_api = false)
{
    global $mobdb, $mobsettings, $modSettings, $context, $scripturl, $sourcedir, $user_info, $board, $topic, $func, $language, $txt, $sc;
    // We need these for creating topics
    require_once $sourcedir . '/Subs-Post.php';
    require_once $sourcedir . '/Post.php';
    // Guest? No entry
    if ($user_info['is_guest']) {
        createErrorResponse(21);
    }
    // Figure out the parameters
    if ($is_post) {
        if ($new_api) {
            $_POST['board'] = intval($context['mob_request']['params'][0][0]);
            $_POST['topic'] = intval($context['mob_request']['params'][1][0]);
            $_POST['icon'] = 'xx';
            $_POST['topic'] = intval($context['mob_request']['params'][1][0]);
            $_POST['subject'] = utf8ToAscii(base64_decode($context['mob_request']['params'][2][0]));
            $_POST['message'] = utf8ToAscii(base64_decode($context['mob_request']['params'][3][0]));
            $_POST['sc'] = $sc = '';
            //$_POST['attachments'] = isset($request_params[4]) ? explode('.', implode('.', $request_params[4])) : array();
            tt_clean_request();
            loadBoard();
            loadPermissions();
            // Get a response prefix (like 'Re:') in the default forum 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);
            }
            $_POST['subject'] = $context['response_prefix'] . $_POST['subject'];
            $post_id = Post2();
            outputRPCNewTopic($post_id, 1, true);
        } else {
            $id_topic = (int) $context['mob_request']['params'][0][0];
            $body = base64_decode($context['mob_request']['params'][2][0]);
            $subject = base64_decode($context['mob_request']['params'][3][0]);
            if (isset($context['mob_request']['params'][4]) && $context['mob_request']['params'][4][0]) {
                $id_attach = (int) $context['mob_request']['params'][4][0];
            }
        }
    } else {
        if ($new_api) {
            $_POST['board'] = intval($context['mob_request']['params'][0][0]);
            $_POST['icon'] = 'xx';
            $_POST['subject'] = utf8ToAscii(base64_decode($context['mob_request']['params'][1][0]));
            $_POST['message'] = utf8ToAscii(base64_decode($context['mob_request']['params'][2][0]));
            $_POST['sc'] = $sc = '';
            //$_POST['attachments'] = isset($request_params[4]) ? explode('.', implode('.', $request_params[4])) : array();
            tt_clean_request();
            loadBoard();
            loadPermissions();
            Post2();
            outputRPCNewTopic($topic, 1, false);
        } else {
            $id_board = (int) $context['mob_request']['params'][0][0];
            $subject = base64_decode($context['mob_request']['params'][1][0]);
            $body = base64_decode($context['mob_request']['params'][3][0]);
            if (isset($context['mob_request']['params'][4]) && $context['mob_request']['params'][4][0]) {
                $id_attach = (int) $context['mob_request']['params'][4][0];
            }
        }
    }
    $subject = utf8ToAscii($subject);
    $body = utf8ToAscii($body);
    $_POST['subject'] = $subject;
    $_POST['message'] = $body;
    // Get a response prefix (like 'Re:') in the default forum 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);
    }
    if ($is_post) {
        $subject = $context['response_prefix'] . $subject;
    }
    // Trim out the whitespace
    $subject = trim($subject);
    $body = trim($body);
    // Missing? Oh man
    if ($is_post) {
        if (!$is_post && empty($id_board) || empty($body) || isset($id_attach) && empty($id_attach) || isset($id_topic) && empty($id_topic)) {
            createErrorResponse(8);
        }
    } else {
        if (!$is_post && empty($id_board) || empty($body) || empty($subject) || isset($id_attach) && empty($id_attach) || isset($id_topic) && empty($id_topic)) {
            createErrorResponse(8);
        }
    }
    // Does this board exist?
    $mobdb->query('
        SELECT b.ID_BOARD
        FROM ' . (!empty($id_topic) ? '{db_prefix}topics AS t
            INNER JOIN {db_prefix}boards AS b ON (t.ID_BOARD = b.ID_BOARD)' : '{db_prefix}boards AS b') . '
        WHERE {query_see_board}
            AND ' . (!empty($id_topic) ? 't.ID_TOPIC' : 'b.ID_BOARD') . ' = {int:value}', array('value' => empty($id_topic) ? $id_board : $id_topic));
    if ($mobdb->num_rows() == 0) {
        createErrorResponse(4);
    }
    list($id_board) = $mobdb->fetch_row();
    $mobdb->free_result();
    // Can we actually post?
    if (!isset($id_topic)) {
        if (allowedTo('post_new', $id_board)) {
            $can_post = 1;
        } elseif ($modSettings['postmod_active'] && !allowedTo('post_new', $id_board) && allowedTo('post_unapproved_topics', $id_board)) {
            $can_post = 2;
        } else {
            createErrorResponse(25);
        }
    } else {
        $mobdb->query('
            SELECT locked, isSticky AS is_sticky, 1 AS approved, numReplies AS num_replies, ID_FIRST_MSG AS id_first_msg, ID_MEMBER_STARTED AS id_member_started, ID_BOARD AS id_board,
                ID_POLL AS id_poll
            FROM {db_prefix}topics
            WHERE id_topic = {int:current_topic}
            LIMIT 1', array('current_topic' => $id_topic));
        $topic_info = $mobdb->fetch_assoc();
        $mobdb->free_result();
        if ($topic_info['id_board'] != $id_board) {
            createErrorResponse(25);
        }
        // Locked?
        if ($topic_info['locked'] && !allowedTo('moderate_board', $id_board)) {
            createErrorResponse(25);
        }
        // Is this this guy's topic?
        if ($topic_info['id_member_started'] == $user_info['id']) {
            if (allowedTo('post_reply_own', $id_board)) {
                $can_post = 1;
            } elseif ($modSettings['postmod_active'] && !allowedTo('post_reply_own', $id_board) && allowedTo('post_unapproved_replies_own', $id_board)) {
                $can_post = 2;
            } else {
                createErrorResponse(25);
            }
        } else {
            if (allowedTo('post_reply_any', $id_board)) {
                $can_post = 1;
            } elseif ($modSettings['postmod_active'] && !allowedTo('post_reply_any', $id_board) && allowedTo('post_unapproved_replies_any', $id_board)) {
                $can_post = 2;
            } else {
                createErrorResponse(2);
            }
        }
    }
    // Alright, we passed the security tests, lets check the inputs
    //$subject = strtr(htmlspecialchars($subject), array("\r" => '', "\n" => '', "\t" => ''));
    //$body = htmlspecialchars($body);
    ######## Added by Sean to fix the issue can not post##############
    $subject = addslashes__recursive($subject);
    $body = addslashes__recursive($body);
    // Set up the inputs for the form.
    $body = $func['htmlspecialchars']($body, ENT_QUOTES);
    preparsecode($body);
    $subject = strtr($func['htmlspecialchars']($subject), array("\r" => '', "\n" => '', "\t" => ''));
    ##################################################################
    if (strlen($subject) > 100) {
        $subject = substr($subject, 0, 100);
    }
    // Are the attachments valid?
    if (isset($id_attach)) {
        // Does it even exist?
        $mobdb->query('
            SELECT a.ID_ATTACH, a.ID_THUMB
            FROM {db_prefix}attachments AS a
            WHERE a.ID_ATTACH = {int:attach}', array('attach' => $id_attach));
        // Not found?
        if ($mobdb->num_rows() == 0) {
            unset($id_attach);
        }
        list($id_attach, $id_thumb) = $mobdb->fetch_row();
        $mobdb->free_result();
    }
    // Get the parameters ready
    $msgOptions = array('id' => 0, 'subject' => $subject, 'body' => $body, 'icon' => isset($id_attach) ? 'clip' : 'xx', 'smileys_enabled' => true, 'attachments' => isset($id_attach) ? array($id_attach, $id_thumb) : null, 'approved' => $can_post == 2 ? false : true);
    $topicOptions = array('id' => isset($id_topic) ? $id_topic : 0, 'board' => $id_board, 'poll' => isset($topic_info) ? $topic_info['id_poll'] : null, 'lock_mode' => isset($topic_info) ? $topic_info['locked'] : null, 'sticky_mode' => isset($topic_info) ? $topic_info['is_sticky'] : null, 'mark_as_read' => true, 'is_approved' => $can_post == 2 ? false : true);
    $posterOptions = array('id' => $user_info['id'], 'name' => $user_info['name'], 'email' => $user_info['email'], 'update_post_count' => true);
    // Actually create the topic...
    createPost($msgOptions, $topicOptions, $posterOptions);
    if (empty($topicOptions['id'])) {
        createErrorResponse(8);
    }
    $id_topic = $topicOptions['id'];
    trackStats();
    // Notifications anyone?
    $notifyData = array('body' => $body, 'subject' => $subject, 'name' => $user_info['name'], 'poster' => $user_info['id'], 'msg' => $msgOptions['id'], 'board' => $id_board, 'topic' => $id_topic);
    //!!! Stupid fix for SMF 1.1
    $board = $id_board;
    $topic = $id_topic;
    if (!$is_post) {
        notifyMembersBoard($notifyData);
    }
    // Send out the response
    outputRPCNewTopic($is_post ? $msgOptions['id'] : $topicOptions['id'], $can_post, $is_post);
}
Exemple #7
0
function obExit($header = null, $do_footer = null, $from_index = false)
{
    global $context, $settings, $modSettings, $txt;
    static $header_done = false, $footer_done = false;
    // Clear out the stat cache.
    trackStats();
    $do_header = $header === null ? !$header_done : $header;
    if ($do_footer === null) {
        $do_footer = $do_header;
    }
    // Has the template/header been done yet?
    if ($do_header) {
        // Start up the session URL fixer.
        ob_start('ob_sessrewrite');
        // Just in case we have anything bad already in there...
        if ((isset($_REQUEST['debug']) || isset($_REQUEST['xml']) || WIRELESS && WIRELESS_PROTOCOL == 'wap') && in_array($txt['lang_locale'], array('UTF-8', 'ISO-8859-1'))) {
            ob_start('validate_unicode__recursive');
        }
        if (!empty($settings['output_buffers']) && is_string($settings['output_buffers'])) {
            $buffers = explode(',', $settings['output_buffers']);
        } elseif (!empty($settings['output_buffers'])) {
            $buffers = $settings['output_buffers'];
        } else {
            $buffers = array();
        }
        if (isset($modSettings['integrate_buffer'])) {
            $buffers = array_merge(explode(',', $modSettings['integrate_buffer']), $buffers);
        }
        if (!empty($buffers)) {
            foreach ($buffers as $buffer_function) {
                if (function_exists(trim($buffer_function))) {
                    ob_start(trim($buffer_function));
                }
            }
        }
        // Display the screen in the logical order.
        template_header();
        $header_done = true;
    }
    if ($do_footer) {
        if (WIRELESS && !isset($context['sub_template'])) {
            fatal_lang_error('wireless_error_notyet', false);
        }
        // Just show the footer, then.
        loadSubTemplate(isset($context['sub_template']) ? $context['sub_template'] : 'main');
        // Just so we don't get caught in an endless loop of errors from the footer...
        if (!$footer_done) {
            $footer_done = true;
            template_footer();
            // (since this is just debugging... it's okay that it's after </html>.)
            if (!isset($_REQUEST['xml'])) {
                db_debug_junk();
            }
        }
    }
    // Remember this URL in case someone doesn't like sending HTTP_REFERER.
    if (strpos($_SERVER['REQUEST_URL'], 'action=dlattach') === false) {
        $_SESSION['old_url'] = $_SERVER['REQUEST_URL'];
    }
    // For session check verfication.... don't switch browsers...
    $_SESSION['USER_AGENT'] = $_SERVER['HTTP_USER_AGENT'];
    // Hand off the output to the portal, etc. we're integrated with.
    if (isset($modSettings['integrate_exit'], $context['template_layers']) && in_array('main', $context['template_layers']) && function_exists($modSettings['integrate_exit'])) {
        call_user_func($modSettings['integrate_exit'], $do_footer && !WIRELESS);
    }
    // Don't exit if we're coming from index.php; that will pass through normally.
    if (!$from_index || WIRELESS) {
        exit;
    }
}
Exemple #8
0
/**
 * Create a post, either as new topic (id_topic = 0) or in an existing one.
 *
 * The input parameters of this function assume:
 * - Strings have been escaped.
 * - Integers have been cast to integer.
 * - Mandatory parameters are set.
 *
 * @package Posts
 * @param mixed[] $msgOptions
 * @param mixed[] $topicOptions
 * @param mixed[] $posterOptions
 */
function createPost(&$msgOptions, &$topicOptions, &$posterOptions)
{
    global $user_info, $txt, $modSettings;
    $db = database();
    // Set optional parameters to the default value.
    $msgOptions['icon'] = empty($msgOptions['icon']) ? 'xx' : $msgOptions['icon'];
    $msgOptions['smileys_enabled'] = !empty($msgOptions['smileys_enabled']);
    $msgOptions['attachments'] = empty($msgOptions['attachments']) ? array() : $msgOptions['attachments'];
    $msgOptions['approved'] = isset($msgOptions['approved']) ? (int) $msgOptions['approved'] : 1;
    $topicOptions['id'] = empty($topicOptions['id']) ? 0 : (int) $topicOptions['id'];
    $topicOptions['poll'] = isset($topicOptions['poll']) ? (int) $topicOptions['poll'] : null;
    $topicOptions['lock_mode'] = isset($topicOptions['lock_mode']) ? $topicOptions['lock_mode'] : null;
    $topicOptions['sticky_mode'] = isset($topicOptions['sticky_mode']) ? $topicOptions['sticky_mode'] : null;
    $topicOptions['redirect_expires'] = isset($topicOptions['redirect_expires']) ? $topicOptions['redirect_expires'] : null;
    $topicOptions['redirect_topic'] = isset($topicOptions['redirect_topic']) ? $topicOptions['redirect_topic'] : null;
    $posterOptions['id'] = empty($posterOptions['id']) ? 0 : (int) $posterOptions['id'];
    $posterOptions['ip'] = empty($posterOptions['ip']) ? $user_info['ip'] : $posterOptions['ip'];
    // We need to know if the topic is approved. If we're told that's great - if not find out.
    if (!$modSettings['postmod_active']) {
        $topicOptions['is_approved'] = true;
    } elseif (!empty($topicOptions['id']) && !isset($topicOptions['is_approved'])) {
        $request = $db->query('', '
			SELECT approved
			FROM {db_prefix}topics
			WHERE id_topic = {int:id_topic}
			LIMIT 1', array('id_topic' => $topicOptions['id']));
        list($topicOptions['is_approved']) = $db->fetch_row($request);
        $db->free_result($request);
    }
    // If nothing was filled in as name/email address, try the member table.
    if (!isset($posterOptions['name']) || $posterOptions['name'] == '' || empty($posterOptions['email']) && !empty($posterOptions['id'])) {
        if (empty($posterOptions['id'])) {
            $posterOptions['id'] = 0;
            $posterOptions['name'] = $txt['guest_title'];
            $posterOptions['email'] = '';
        } elseif ($posterOptions['id'] != $user_info['id']) {
            require_once SUBSDIR . '/Members.subs.php';
            $result = getBasicMemberData($posterOptions['id']);
            // Couldn't find the current poster?
            if (empty($result)) {
                trigger_error('createPost(): Invalid member id ' . $posterOptions['id'], E_USER_NOTICE);
                $posterOptions['id'] = 0;
                $posterOptions['name'] = $txt['guest_title'];
                $posterOptions['email'] = '';
            } else {
                $posterOptions['name'] = $result['member_name'];
                $posterOptions['email'] = $result['email_address'];
            }
        } else {
            $posterOptions['name'] = $user_info['name'];
            $posterOptions['email'] = $user_info['email'];
        }
    }
    // It's do or die time: forget any user aborts!
    $previous_ignore_user_abort = ignore_user_abort(true);
    $new_topic = empty($topicOptions['id']);
    $message_columns = array('id_board' => 'int', 'id_topic' => 'int', 'id_member' => 'int', 'subject' => 'string-255', 'body' => !empty($modSettings['max_messageLength']) && $modSettings['max_messageLength'] > 65534 ? 'string-' . $modSettings['max_messageLength'] : (empty($modSettings['max_messageLength']) ? 'string' : 'string-65534'), 'poster_name' => 'string-255', 'poster_email' => 'string-255', 'poster_time' => 'int', 'poster_ip' => 'string-255', 'smileys_enabled' => 'int', 'modified_name' => 'string', 'icon' => 'string-16', 'approved' => 'int');
    $message_parameters = array('id_board' => $topicOptions['board'], 'id_topic' => $topicOptions['id'], 'id_member' => $posterOptions['id'], 'subject' => $msgOptions['subject'], 'body' => $msgOptions['body'], 'poster_name' => $posterOptions['name'], 'poster_email' => $posterOptions['email'], 'poster_time' => empty($posterOptions['time']) ? time() : $posterOptions['time'], 'poster_ip' => $posterOptions['ip'], 'smileys_enabled' => $msgOptions['smileys_enabled'] ? 1 : 0, 'modified_name' => '', 'icon' => $msgOptions['icon'], 'approved' => $msgOptions['approved']);
    // What if we want to do anything with posts?
    call_integration_hook('integrate_before_create_post', array(&$msgOptions, &$topicOptions, &$posterOptions, &$message_columns, &$message_parameters));
    // Insert the post.
    $db->insert('', '{db_prefix}messages', $message_columns, $message_parameters, array('id_msg'));
    $msgOptions['id'] = $db->insert_id('{db_prefix}messages', 'id_msg');
    // Something went wrong creating the message...
    if (empty($msgOptions['id'])) {
        return false;
    }
    // Fix the attachments.
    if (!empty($msgOptions['attachments'])) {
        $db->query('', '
			UPDATE {db_prefix}attachments
			SET id_msg = {int:id_msg}
			WHERE id_attach IN ({array_int:attachment_list})', array('attachment_list' => $msgOptions['attachments'], 'id_msg' => $msgOptions['id']));
    }
    // What if we want to export new posts out to a CMS?
    call_integration_hook('integrate_create_post', array($msgOptions, $topicOptions, $posterOptions, $message_columns, $message_parameters));
    // Insert a new topic (if the topicID was left empty.)
    if ($new_topic) {
        $topic_columns = array('id_board' => 'int', 'id_member_started' => 'int', 'id_member_updated' => 'int', 'id_first_msg' => 'int', 'id_last_msg' => 'int', 'locked' => 'int', 'is_sticky' => 'int', 'num_views' => 'int', 'id_poll' => 'int', 'unapproved_posts' => 'int', 'approved' => 'int', 'redirect_expires' => 'int', 'id_redirect_topic' => 'int');
        $topic_parameters = array('id_board' => $topicOptions['board'], 'id_member_started' => $posterOptions['id'], 'id_member_updated' => $posterOptions['id'], 'id_first_msg' => $msgOptions['id'], 'id_last_msg' => $msgOptions['id'], 'locked' => $topicOptions['lock_mode'] === null ? 0 : $topicOptions['lock_mode'], 'is_sticky' => $topicOptions['sticky_mode'] === null ? 0 : $topicOptions['sticky_mode'], 'num_views' => 0, 'id_poll' => $topicOptions['poll'] === null ? 0 : $topicOptions['poll'], 'unapproved_posts' => $msgOptions['approved'] ? 0 : 1, 'approved' => $msgOptions['approved'], 'redirect_expires' => $topicOptions['redirect_expires'] === null ? 0 : $topicOptions['redirect_expires'], 'id_redirect_topic' => $topicOptions['redirect_topic'] === null ? 0 : $topicOptions['redirect_topic']);
        call_integration_hook('integrate_before_create_topic', array(&$msgOptions, &$topicOptions, &$posterOptions, &$topic_columns, &$topic_parameters));
        $db->insert('', '{db_prefix}topics', $topic_columns, $topic_parameters, array('id_topic'));
        $topicOptions['id'] = $db->insert_id('{db_prefix}topics', 'id_topic');
        // The topic couldn't be created for some reason.
        if (empty($topicOptions['id'])) {
            // We should delete the post that did work, though...
            $db->query('', '
				DELETE FROM {db_prefix}messages
				WHERE id_msg = {int:id_msg}', array('id_msg' => $msgOptions['id']));
            return false;
        }
        // Fix the message with the topic.
        $db->query('', '
			UPDATE {db_prefix}messages
			SET id_topic = {int:id_topic}
			WHERE id_msg = {int:id_msg}', array('id_topic' => $topicOptions['id'], 'id_msg' => $msgOptions['id']));
        // There's been a new topic AND a new post today.
        trackStats(array('topics' => '+', 'posts' => '+'));
        updateStats('topic', true);
        updateStats('subject', $topicOptions['id'], $msgOptions['subject']);
        // What if we want to export new topics out to a CMS?
        call_integration_hook('integrate_create_topic', array($msgOptions, $topicOptions, $posterOptions));
    } else {
        $update_parameters = array('poster_id' => $posterOptions['id'], 'id_msg' => $msgOptions['id'], 'locked' => $topicOptions['lock_mode'], 'is_sticky' => $topicOptions['sticky_mode'], 'id_topic' => $topicOptions['id'], 'counter_increment' => 1);
        if ($msgOptions['approved']) {
            $topics_columns = array('id_member_updated = {int:poster_id}', 'id_last_msg = {int:id_msg}', 'num_replies = num_replies + {int:counter_increment}');
        } else {
            $topics_columns = array('unapproved_posts = unapproved_posts + {int:counter_increment}');
        }
        if ($topicOptions['lock_mode'] !== null) {
            $topics_columns[] = 'locked = {int:locked}';
        }
        if ($topicOptions['sticky_mode'] !== null) {
            $topics_columns[] = 'is_sticky = {int:is_sticky}';
        }
        call_integration_hook('integrate_before_modify_topic', array(&$topics_columns, &$update_parameters, &$msgOptions, &$topicOptions, &$posterOptions));
        // Update the number of replies and the lock/sticky status.
        $db->query('', '
			UPDATE {db_prefix}topics
			SET
				' . implode(', ', $topics_columns) . '
			WHERE id_topic = {int:id_topic}', $update_parameters);
        // One new post has been added today.
        trackStats(array('posts' => '+'));
    }
    // Creating is modifying...in a way.
    // @todo id_msg_modified needs to be set when you create a post, now this query is
    // the only place it does get set for post creation.  Why not set it on the insert?
    $db->query('', '
		UPDATE {db_prefix}messages
		SET id_msg_modified = {int:id_msg}
		WHERE id_msg = {int:id_msg}', array('id_msg' => $msgOptions['id']));
    // Increase the number of posts and topics on the board.
    if ($msgOptions['approved']) {
        $db->query('', '
			UPDATE {db_prefix}boards
			SET num_posts = num_posts + 1' . ($new_topic ? ', num_topics = num_topics + 1' : '') . '
			WHERE id_board = {int:id_board}', array('id_board' => $topicOptions['board']));
    } else {
        $db->query('', '
			UPDATE {db_prefix}boards
			SET unapproved_posts = unapproved_posts + 1' . ($new_topic ? ', unapproved_topics = unapproved_topics + 1' : '') . '
			WHERE id_board = {int:id_board}', array('id_board' => $topicOptions['board']));
        // Add to the approval queue too.
        $db->insert('', '{db_prefix}approval_queue', array('id_msg' => 'int'), array($msgOptions['id']), array());
    }
    // Mark inserted topic as read (only for the user calling this function).
    if (!empty($topicOptions['mark_as_read']) && !$user_info['is_guest']) {
        // Since it's likely they *read* it before replying, let's try an UPDATE first.
        if (!$new_topic) {
            $db->query('', '
				UPDATE {db_prefix}log_topics
				SET id_msg = {int:id_msg}
				WHERE id_member = {int:current_member}
					AND id_topic = {int:id_topic}', array('current_member' => $posterOptions['id'], 'id_msg' => $msgOptions['id'], 'id_topic' => $topicOptions['id']));
            $flag = $db->affected_rows() != 0;
        }
        if (empty($flag)) {
            require_once SUBSDIR . '/Topic.subs.php';
            markTopicsRead(array($posterOptions['id'], $topicOptions['id'], $msgOptions['id'], 0), false);
        }
    }
    // If there's a custom search index, it may need updating...
    require_once SUBSDIR . '/Search.subs.php';
    $searchAPI = findSearchAPI();
    if (is_callable(array($searchAPI, 'postCreated'))) {
        $searchAPI->postCreated($msgOptions, $topicOptions, $posterOptions);
    }
    // Increase the post counter for the user that created the post.
    if (!empty($posterOptions['update_post_count']) && !empty($posterOptions['id']) && $msgOptions['approved']) {
        // Are you the one that happened to create this post?
        if ($user_info['id'] == $posterOptions['id']) {
            $user_info['posts']++;
        }
        updateMemberData($posterOptions['id'], array('posts' => '+'));
    }
    // They've posted, so they can make the view count go up one if they really want. (this is to keep views >= replies...)
    $_SESSION['last_read_topic'] = 0;
    // Better safe than sorry.
    if (isset($_SESSION['topicseen_cache'][$topicOptions['board']])) {
        $_SESSION['topicseen_cache'][$topicOptions['board']]--;
    }
    // Update all the stats so everyone knows about this new topic and message.
    updateStats('message', true, $msgOptions['id']);
    // Update the last message on the board assuming it's approved AND the topic is.
    if ($msgOptions['approved']) {
        updateLastMessages($topicOptions['board'], $new_topic || !empty($topicOptions['is_approved']) ? $msgOptions['id'] : 0);
    }
    // Alright, done now... we can abort now, I guess... at least this much is done.
    ignore_user_abort($previous_ignore_user_abort);
    // Success.
    return true;
}
Exemple #9
0
function BoardIndex()
{
    global $txt, $scripturl, $db_prefix, $ID_MEMBER, $user_info, $sourcedir;
    global $modSettings, $context, $settings;
    // For wireless, we use the Wireless template...
    if (WIRELESS) {
        $context['sub_template'] = WIRELESS_PROTOCOL . '_boardindex';
    } else {
        loadTemplate('BoardIndex');
    }
    // Remember the most recent topic for optimizing the recent posts feature.
    $most_recent_topic = array('timestamp' => 0, 'ref' => null);
    // Find all boards and categories, as well as related information.  This will be sorted by the natural order of boards and categories, which we control.
    $result_boards = db_query("\n\t\tSELECT\n\t\t\tc.name AS catName, c.ID_CAT, b.ID_BOARD, b.name AS boardName, b.description,\n\t\t\tb.numPosts, b.numTopics, b.ID_PARENT, IFNULL(m.posterTime, 0) AS posterTime,\n\t\t\tIFNULL(mem.memberName, m.posterName) AS posterName, m.subject, m.ID_TOPIC,\n\t\t\tIFNULL(mem.realName, m.posterName) AS realName," . ($user_info['is_guest'] ? "\n\t\t\t1 AS isRead, 0 AS new_from" : "\n\t\t\t(IFNULL(lb.ID_MSG, 0) >= b.ID_MSG_UPDATED) AS isRead, IFNULL(lb.ID_MSG, -1) + 1 AS new_from,\n\t\t\tc.canCollapse, IFNULL(cc.ID_MEMBER, 0) AS isCollapsed") . ",\n\t\t\tIFNULL(mem.ID_MEMBER, 0) AS ID_MEMBER, m.ID_MSG,\n\t\t\tIFNULL(mods_mem.ID_MEMBER, 0) AS ID_MODERATOR, mods_mem.realName AS modRealName\n\t\tFROM {$db_prefix}boards AS b\n\t\t\tLEFT JOIN {$db_prefix}categories AS c ON (c.ID_CAT = b.ID_CAT)\n\t\t\tLEFT JOIN {$db_prefix}messages AS m ON (m.ID_MSG = b.ID_LAST_MSG)\n\t\t\tLEFT JOIN {$db_prefix}members AS mem ON (mem.ID_MEMBER = m.ID_MEMBER)" . (!$user_info['is_guest'] ? "\n\t\t\tLEFT JOIN {$db_prefix}log_boards AS lb ON (lb.ID_BOARD = b.ID_BOARD AND lb.ID_MEMBER = {$ID_MEMBER})\n\t\t\tLEFT JOIN {$db_prefix}collapsed_categories AS cc ON (cc.ID_CAT = c.ID_CAT AND cc.ID_MEMBER = {$ID_MEMBER})" : '') . "\n\t\t\tLEFT JOIN {$db_prefix}moderators AS mods ON (mods.ID_BOARD = b.ID_BOARD)\n\t\t\tLEFT JOIN {$db_prefix}members AS mods_mem ON (mods_mem.ID_MEMBER = mods.ID_MEMBER)\n\t\tWHERE {$user_info['query_see_board']}" . (empty($modSettings['countChildPosts']) ? "\n\t\t\tAND b.childLevel <= 1" : ''), __FILE__, __LINE__);
    // Run through the categories and boards....
    $context['categories'] = array();
    while ($row_board = mysql_fetch_assoc($result_boards)) {
        // Haven't set this category yet.
        if (empty($context['categories'][$row_board['ID_CAT']])) {
            $context['categories'][$row_board['ID_CAT']] = array('id' => $row_board['ID_CAT'], 'name' => $row_board['catName'], 'is_collapsed' => isset($row_board['canCollapse']) && $row_board['canCollapse'] == 1 && $row_board['isCollapsed'] > 0, 'can_collapse' => isset($row_board['canCollapse']) && $row_board['canCollapse'] == 1, 'collapse_href' => isset($row_board['canCollapse']) ? $scripturl . '?action=collapse;c=' . $row_board['ID_CAT'] . ';sa=' . ($row_board['isCollapsed'] > 0 ? 'expand' : 'collapse;') . '#' . $row_board['ID_CAT'] : '', 'collapse_image' => isset($row_board['canCollapse']) ? '<img src="' . $settings['images_url'] . '/' . ($row_board['isCollapsed'] > 0 ? 'expand.gif" alt="+"' : 'collapse.gif" alt="-"') . ' border="0" />' : '', 'href' => $scripturl . '#' . $row_board['ID_CAT'], 'boards' => array(), 'new' => false);
            $context['categories'][$row_board['ID_CAT']]['link'] = '<a name="' . $row_board['ID_CAT'] . '" href="' . (isset($row_board['canCollapse']) ? $context['categories'][$row_board['ID_CAT']]['collapse_href'] : $context['categories'][$row_board['ID_CAT']]['href']) . '">' . $row_board['catName'] . '</a>';
        }
        // If this board has new posts in it (and isn't the recycle bin!) then the category is new.
        if (empty($modSettings['recycle_enable']) || $modSettings['recycle_board'] != $row_board['ID_BOARD']) {
            $context['categories'][$row_board['ID_CAT']]['new'] |= empty($row_board['isRead']) && $row_board['posterName'] != '';
        }
        // Collapsed category - don't do any of this.
        if ($context['categories'][$row_board['ID_CAT']]['is_collapsed']) {
            continue;
        }
        // Let's save some typing.  Climbing the array might be slower, anyhow.
        $this_category =& $context['categories'][$row_board['ID_CAT']]['boards'];
        // This is a parent board.
        if (empty($row_board['ID_PARENT'])) {
            // Is this a new board, or just another moderator?
            if (!isset($this_category[$row_board['ID_BOARD']])) {
                // Not a child.
                $isChild = false;
                $this_category[$row_board['ID_BOARD']] = array('new' => empty($row_board['isRead']), 'id' => $row_board['ID_BOARD'], 'name' => $row_board['boardName'], 'description' => $row_board['description'], 'moderators' => array(), 'link_moderators' => array(), 'children' => array(), 'link_children' => array(), 'children_new' => false, 'topics' => $row_board['numTopics'], 'posts' => $row_board['numPosts'], 'href' => $scripturl . '?board=' . $row_board['ID_BOARD'] . '.0', 'link' => '<a href="' . $scripturl . '?board=' . $row_board['ID_BOARD'] . '.0">' . $row_board['boardName'] . '</a>');
            }
            if (!empty($row_board['ID_MODERATOR'])) {
                $this_category[$row_board['ID_BOARD']]['moderators'][$row_board['ID_MODERATOR']] = array('id' => $row_board['ID_MODERATOR'], 'name' => $row_board['modRealName'], 'href' => $scripturl . '?action=profile;u=' . $row_board['ID_MODERATOR'], 'link' => '<a href="' . $scripturl . '?action=profile;u=' . $row_board['ID_MODERATOR'] . '" title="' . $txt[62] . '">' . $row_board['modRealName'] . '</a>');
                $this_category[$row_board['ID_BOARD']]['link_moderators'][] = '<a href="' . $scripturl . '?action=profile;u=' . $row_board['ID_MODERATOR'] . '" title="' . $txt[62] . '">' . $row_board['modRealName'] . '</a>';
            }
        } elseif (isset($this_category[$row_board['ID_PARENT']]['children']) && !isset($this_category[$row_board['ID_PARENT']]['children'][$row_board['ID_BOARD']])) {
            // A valid child!
            $isChild = true;
            $this_category[$row_board['ID_PARENT']]['children'][$row_board['ID_BOARD']] = array('id' => $row_board['ID_BOARD'], 'name' => $row_board['boardName'], 'description' => $row_board['description'], 'new' => empty($row_board['isRead']) && $row_board['posterName'] != '', 'topics' => $row_board['numTopics'], 'posts' => $row_board['numPosts'], 'href' => $scripturl . '?board=' . $row_board['ID_BOARD'] . '.0', 'link' => '<a href="' . $scripturl . '?board=' . $row_board['ID_BOARD'] . '.0">' . $row_board['boardName'] . '</a>');
            // Counting child board posts is... slow :/.
            if (!empty($modSettings['countChildPosts'])) {
                $this_category[$row_board['ID_PARENT']]['posts'] += $row_board['numPosts'];
                $this_category[$row_board['ID_PARENT']]['topics'] += $row_board['numTopics'];
            }
            // Does this board contain new boards?
            $this_category[$row_board['ID_PARENT']]['children_new'] |= empty($row_board['isRead']);
            // This is easier to use in many cases for the theme....
            $this_category[$row_board['ID_PARENT']]['link_children'][] =& $this_category[$row_board['ID_PARENT']]['children'][$row_board['ID_BOARD']]['link'];
        } elseif (!empty($modSettings['countChildPosts'])) {
            if (!isset($parent_map)) {
                $parent_map = array();
            }
            if (!isset($parent_map[$row_board['ID_PARENT']])) {
                foreach ($this_category as $id => $board) {
                    if (!isset($board['children'][$row_board['ID_PARENT']])) {
                        continue;
                    }
                    $parent_map[$row_board['ID_PARENT']] = array(&$this_category[$id], &$this_category[$id]['children'][$row_board['ID_PARENT']]);
                    $parent_map[$row_board['ID_BOARD']] = array(&$this_category[$id], &$this_category[$id]['children'][$row_board['ID_PARENT']]);
                    break;
                }
            }
            if (isset($parent_map[$row_board['ID_PARENT']])) {
                $parent_map[$row_board['ID_PARENT']][0]['posts'] += $row_board['numPosts'];
                $parent_map[$row_board['ID_PARENT']][0]['topics'] += $row_board['numTopics'];
                $parent_map[$row_board['ID_PARENT']][1]['posts'] += $row_board['numPosts'];
                $parent_map[$row_board['ID_PARENT']][1]['topics'] += $row_board['numTopics'];
                continue;
            }
            continue;
        } else {
            continue;
        }
        // Prepare the subject, and make sure it's not too long.
        censorText($row_board['subject']);
        $row_board['short_subject'] = shorten_subject($row_board['subject'], 24);
        $this_last_post = array('id' => $row_board['ID_MSG'], 'time' => $row_board['posterTime'] > 0 ? timeformat($row_board['posterTime']) : $txt[470], 'timestamp' => forum_time(true, $row_board['posterTime']), 'subject' => $row_board['short_subject'], 'member' => array('id' => $row_board['ID_MEMBER'], 'username' => $row_board['posterName'] != '' ? $row_board['posterName'] : $txt[470], 'name' => $row_board['realName'], 'href' => $row_board['posterName'] != '' && !empty($row_board['ID_MEMBER']) ? $scripturl . '?action=profile;u=' . $row_board['ID_MEMBER'] : '', 'link' => $row_board['posterName'] != '' ? !empty($row_board['ID_MEMBER']) ? '<a href="' . $scripturl . '?action=profile;u=' . $row_board['ID_MEMBER'] . '">' . $row_board['realName'] . '</a>' : $row_board['realName'] : $txt[470]), 'start' => 'msg' . $row_board['new_from'], 'topic' => $row_board['ID_TOPIC']);
        // Provide the href and link.
        if ($row_board['subject'] != '') {
            $this_last_post['href'] = $scripturl . '?topic=' . $row_board['ID_TOPIC'] . '.msg' . ($user_info['is_guest'] ? $modSettings['maxMsgID'] : $row_board['new_from']) . (empty($row_board['isRead']) ? ';boardseen' : '') . '#new';
            $this_last_post['link'] = '<a href="' . $this_last_post['href'] . '" title="' . $row_board['subject'] . '">' . $row_board['short_subject'] . '</a>';
        } else {
            $this_last_post['href'] = '';
            $this_last_post['link'] = $txt[470];
        }
        // Set the last post in the parent board.
        if (empty($row_board['ID_PARENT']) || $isChild && !empty($row_board['posterTime']) && $this_category[$row_board['ID_PARENT']]['last_post']['timestamp'] < forum_time(true, $row_board['posterTime'])) {
            $this_category[$isChild ? $row_board['ID_PARENT'] : $row_board['ID_BOARD']]['last_post'] = $this_last_post;
        }
        // Just in the child...?
        if ($isChild) {
            $this_category[$row_board['ID_PARENT']]['children'][$row_board['ID_BOARD']]['last_post'] = $this_last_post;
            // If there are no posts in this board, it really can't be new...
            $this_category[$row_board['ID_PARENT']]['children'][$row_board['ID_BOARD']]['new'] &= $row_board['posterName'] != '';
        } elseif ($row_board['posterName'] == '') {
            $this_category[$row_board['ID_BOARD']]['new'] = false;
        }
        // Determine a global most recent topic.
        if (!empty($row_board['posterTime']) && forum_time(true, $row_board['posterTime']) > $most_recent_topic['timestamp']) {
            $most_recent_topic = array('timestamp' => forum_time(true, $row_board['posterTime']), 'ref' => &$this_category[$isChild ? $row_board['ID_PARENT'] : $row_board['ID_BOARD']]['last_post']);
        }
    }
    mysql_free_result($result_boards);
    // Load the users online right now.
    $result = db_query("\n\t\tSELECT\n\t\t\tlo.ID_MEMBER, lo.logTime, mem.realName, mem.memberName, mem.showOnline,\n\t\t\tmg.onlineColor, mg.ID_GROUP, mg.groupName\n\t\tFROM {$db_prefix}log_online AS lo\n\t\t\tLEFT JOIN {$db_prefix}members AS mem ON (mem.ID_MEMBER = lo.ID_MEMBER)\n\t\t\tLEFT JOIN {$db_prefix}membergroups AS mg ON (mg.ID_GROUP = IF(mem.ID_GROUP = 0, mem.ID_POST_GROUP, mem.ID_GROUP))", __FILE__, __LINE__);
    $context['users_online'] = array();
    $context['list_users_online'] = array();
    $context['online_groups'] = array();
    $context['num_guests'] = 0;
    $context['num_buddies'] = 0;
    $context['num_users_hidden'] = 0;
    $context['show_buddies'] = !empty($user_info['buddies']);
    while ($row = mysql_fetch_assoc($result)) {
        if (empty($row['realName'])) {
            $context['num_guests']++;
            continue;
        } elseif (empty($row['showOnline']) && !allowedTo('moderate_forum')) {
            $context['num_users_hidden']++;
            continue;
        }
        // Some basic color coding...
        if (!empty($row['onlineColor'])) {
            $link = '<a href="' . $scripturl . '?action=profile;u=' . $row['ID_MEMBER'] . '" style="color: ' . $row['onlineColor'] . ';">' . $row['realName'] . '</a>';
        } else {
            $link = '<a href="' . $scripturl . '?action=profile;u=' . $row['ID_MEMBER'] . '">' . $row['realName'] . '</a>';
        }
        $is_buddy = in_array($row['ID_MEMBER'], $user_info['buddies']);
        if ($is_buddy) {
            $context['num_buddies']++;
            $link = '<b>' . $link . '</b>';
        }
        $context['users_online'][$row['logTime'] . $row['memberName']] = array('id' => $row['ID_MEMBER'], 'username' => $row['memberName'], 'name' => $row['realName'], 'group' => $row['ID_GROUP'], 'href' => $scripturl . '?action=profile;u=' . $row['ID_MEMBER'], 'link' => $link, 'is_buddy' => $is_buddy, 'hidden' => empty($row['showOnline']));
        $context['list_users_online'][$row['logTime'] . $row['memberName']] = empty($row['showOnline']) ? '<i>' . $link . '</i>' : $link;
        if (!isset($context['online_groups'][$row['ID_GROUP']])) {
            $context['online_groups'][$row['ID_GROUP']] = array('id' => $row['ID_GROUP'], 'name' => $row['groupName'], 'color' => $row['onlineColor']);
        }
    }
    mysql_free_result($result);
    krsort($context['users_online']);
    krsort($context['list_users_online']);
    ksort($context['online_groups']);
    $context['num_users_online'] = count($context['users_online']) + $context['num_users_hidden'];
    // Track most online statistics?
    if (!empty($modSettings['trackStats'])) {
        // Determine the most users online - both all time and per day.
        $total_users = $context['num_guests'] + $context['num_users_online'];
        // More members on now than ever were?  Update it!
        if (!isset($modSettings['mostOnline']) || $total_users >= $modSettings['mostOnline']) {
            updateSettings(array('mostOnline' => $total_users, 'mostDate' => time()));
        }
        $date = strftime('%Y-%m-%d', forum_time(false));
        // One or more stats are not up-to-date?
        if (!isset($modSettings['mostOnlineUpdated']) || $modSettings['mostOnlineUpdated'] != $date) {
            $request = db_query("\n\t\t\t\tSELECT mostOn\n\t\t\t\tFROM {$db_prefix}log_activity\n\t\t\t\tWHERE date = '{$date}'\n\t\t\t\tLIMIT 1", __FILE__, __LINE__);
            // The log_activity hasn't got an entry for today?
            if (mysql_num_rows($request) == 0) {
                db_query("\n\t\t\t\t\tINSERT IGNORE INTO {$db_prefix}log_activity\n\t\t\t\t\t\t(date, mostOn)\n\t\t\t\t\tVALUES ('{$date}', {$total_users})", __FILE__, __LINE__);
            } else {
                list($modSettings['mostOnlineToday']) = mysql_fetch_row($request);
                if ($total_users > $modSettings['mostOnlineToday']) {
                    trackStats(array('mostOn' => $total_users));
                }
                $total_users = max($total_users, $modSettings['mostOnlineToday']);
            }
            mysql_free_result($request);
            updateSettings(array('mostOnlineUpdated' => $date, 'mostOnlineToday' => $total_users));
        } elseif ($total_users > $modSettings['mostOnlineToday']) {
            trackStats(array('mostOn' => $total_users));
            updateSettings(array('mostOnlineUpdated' => $date, 'mostOnlineToday' => $total_users));
        }
    }
    // Set the latest member.
    $context['latest_member'] =& $context['common_stats']['latest_member'];
    // Load the most recent post?
    if (!empty($settings['number_recent_posts']) && $settings['number_recent_posts'] == 1 || $settings['show_sp1_info']) {
        $context['latest_post'] = $most_recent_topic['ref'];
    }
    if (!empty($settings['number_recent_posts']) && $settings['number_recent_posts'] > 1) {
        require_once $sourcedir . '/Recent.php';
        if (($context['latest_posts'] = cache_get_data('boardindex-latest_posts:' . md5($user_info['query_see_board'] . $user_info['language']), 180)) == null) {
            $context['latest_posts'] = getLastPosts($settings['number_recent_posts']);
            cache_put_data('boardindex-latest_posts:' . md5($user_info['query_see_board'] . $user_info['language']), $context['latest_posts'], 180);
        }
        // We have to clean up the cached data a bit.
        foreach ($context['latest_posts'] as $k => $post) {
            $context['latest_posts'][$k]['time'] = timeformat($post['raw_timestamp']);
            $context['latest_posts'][$k]['timestamp'] = forum_time(true, $post['raw_timestamp']);
        }
    }
    $settings['display_recent_bar'] = !empty($settings['number_recent_posts']) ? $settings['number_recent_posts'] : 0;
    $settings['show_member_bar'] &= allowedTo('view_mlist');
    $context['show_stats'] = allowedTo('view_stats') && !empty($modSettings['trackStats']);
    $context['show_member_list'] = allowedTo('view_mlist');
    $context['show_who'] = allowedTo('who_view') && !empty($modSettings['who_enabled']);
    // Set some permission related settings.
    $context['show_login_bar'] = $user_info['is_guest'] && !empty($modSettings['enableVBStyleLogin']);
    $context['show_calendar'] = allowedTo('calendar_view') && !empty($modSettings['cal_enabled']);
    // Load the calendar?
    if ($context['show_calendar']) {
        $context['show_calendar'] = calendarDoIndex();
    }
    $context['page_title'] = $txt[18];
}
Exemple #10
0
function registerMember(&$regOptions)
{
    global $scripturl, $txt, $modSettings, $db_prefix, $context, $sourcedir;
    global $user_info, $options, $settings, $func;
    loadLanguage('Login');
    // We'll need some external functions.
    require_once $sourcedir . '/Subs-Auth.php';
    require_once $sourcedir . '/Subs-Post.php';
    // Registration from the admin center, let them sweat a little more.
    if ($regOptions['interface'] == 'admin') {
        is_not_guest();
        isAllowedTo('moderate_forum');
    } elseif ($regOptions['interface'] == 'guest') {
        spamProtection('register');
        // You cannot register twice...
        if (empty($user_info['is_guest'])) {
            redirectexit();
        }
        // Make sure they didn't just register with this session.
        if (!empty($_SESSION['just_registered']) && empty($modSettings['disableRegisterCheck'])) {
            fatal_lang_error('register_only_once', false);
        }
    }
    // No name?!  How can you register with no name?
    if (empty($regOptions['username'])) {
        fatal_lang_error(37, false);
    }
    // Spaces and other odd characters are evil...
    $regOptions['username'] = preg_replace('~[\\t\\n\\r\\x0B\\0' . ($context['utf8'] ? $context['server']['complex_preg_chars'] ? '\\x{A0}' : pack('C*', 0xc2, 0xa0) : '\\xA0') . ']+~' . ($context['utf8'] ? 'u' : ''), ' ', $regOptions['username']);
    // Don't use too long a name.
    if ($func['strlen']($regOptions['username']) > 25) {
        $regOptions['username'] = $func['htmltrim']($func['substr']($regOptions['username'], 0, 25));
    }
    // Only these characters are permitted.
    if (preg_match('~[<>&"\'=\\\\]~', $regOptions['username']) != 0 || $regOptions['username'] == '_' || $regOptions['username'] == '|' || strpos($regOptions['username'], '[code') !== false || strpos($regOptions['username'], '[/code') !== false) {
        fatal_lang_error(240, false);
    }
    if (stristr($regOptions['username'], $txt[28]) !== false) {
        fatal_lang_error(244, true, array($txt[28]));
    }
    // !!! Separate the sprintf?
    if (empty($regOptions['email']) || preg_match('~^[0-9A-Za-z=_+\\-/][0-9A-Za-z=_\'+\\-/\\.]*@[\\w\\-]+(\\.[\\w\\-]+)*(\\.[\\w]{2,6})$~', stripslashes($regOptions['email'])) === 0 || strlen(stripslashes($regOptions['email'])) > 255) {
        fatal_error(sprintf($txt[500], $regOptions['username']), false);
    }
    if (!empty($regOptions['check_reserved_name']) && isReservedName($regOptions['username'], 0, false)) {
        if ($regOptions['password'] == 'chocolate cake') {
            fatal_error('Sorry, I don\'t take bribes... you\'ll need to come up with a different name.', false);
        }
        fatal_error('(' . htmlspecialchars($regOptions['username']) . ') ' . $txt[473], false);
    }
    // Generate a validation code if it's supposed to be emailed.
    $validation_code = '';
    if ($regOptions['require'] == 'activation') {
        $validation_code = generateValidationCode();
    }
    // If you haven't put in a password generated one.
    if ($regOptions['interface'] == 'admin' && $regOptions['password'] == '') {
        mt_srand(time() + 1277);
        $regOptions['password'] = generateValidationCode();
        $regOptions['password_check'] = $regOptions['password'];
    } elseif ($regOptions['password'] != $regOptions['password_check']) {
        fatal_lang_error(213, false);
    }
    // That's kind of easy to guess...
    if ($regOptions['password'] == '') {
        fatal_lang_error(91, false);
    }
    // Now perform hard password validation as required.
    if (!empty($regOptions['check_password_strength'])) {
        $passwordError = validatePassword($regOptions['password'], $regOptions['username'], array($regOptions['email']));
        // Password isn't legal?
        if ($passwordError != null) {
            fatal_lang_error('profile_error_password_' . $passwordError, false);
        }
    }
    // You may not be allowed to register this email.
    if (!empty($regOptions['check_email_ban'])) {
        isBannedEmail($regOptions['email'], 'cannot_register', $txt['ban_register_prohibited']);
    }
    // Check if the email address is in use.
    $request = db_query("\n\t\tSELECT ID_MEMBER\n\t\tFROM {$db_prefix}members\n\t\tWHERE emailAddress = '{$regOptions['email']}'\n\t\t\tOR emailAddress = '{$regOptions['username']}'\n\t\tLIMIT 1", __FILE__, __LINE__);
    // !!! Separate the sprintf?
    if (mysql_num_rows($request) != 0) {
        fatal_error(sprintf($txt[730], htmlspecialchars($regOptions['email'])), false);
    }
    mysql_free_result($request);
    // Some of these might be overwritten. (the lower ones that are in the arrays below.)
    $regOptions['register_vars'] = array('memberName' => "'{$regOptions['username']}'", 'emailAddress' => "'{$regOptions['email']}'", 'passwd' => '\'' . sha1(strtolower($regOptions['username']) . $regOptions['password']) . '\'', 'passwordSalt' => '\'' . substr(md5(mt_rand()), 0, 4) . '\'', 'posts' => 0, 'dateRegistered' => time(), 'memberIP' => "'{$user_info['ip']}'", 'memberIP2' => "'{$_SERVER['BAN_CHECK_IP']}'", 'validation_code' => "'{$validation_code}'", 'realName' => "'{$regOptions['username']}'", 'personalText' => '\'' . addslashes($modSettings['default_personalText']) . '\'', 'pm_email_notify' => 1, 'ID_THEME' => 0, 'ID_POST_GROUP' => 4, 'lngfile' => "''", 'buddy_list' => "''", 'pm_ignore_list' => "''", 'messageLabels' => "''", 'personalText' => "''", 'websiteTitle' => "''", 'websiteUrl' => "''", 'location' => "''", 'ICQ' => "''", 'AIM' => "''", 'YIM' => "''", 'MSN' => "''", 'timeFormat' => "''", 'signature' => "''", 'avatar' => "''", 'usertitle' => "''", 'secretQuestion' => "''", 'secretAnswer' => "''", 'additionalGroups' => "''", 'smileySet' => "''");
    // Setup the activation status on this new account so it is correct - firstly is it an under age account?
    if ($regOptions['require'] == 'coppa') {
        $regOptions['register_vars']['is_activated'] = 5;
        // !!! This should be changed.  To what should be it be changed??
        $regOptions['register_vars']['validation_code'] = "''";
    } elseif ($regOptions['require'] == 'nothing') {
        $regOptions['register_vars']['is_activated'] = 1;
    } elseif ($regOptions['require'] == 'activation') {
        $regOptions['register_vars']['is_activated'] = 0;
    } else {
        $regOptions['register_vars']['is_activated'] = 3;
    }
    if (isset($regOptions['memberGroup'])) {
        // Make sure the ID_GROUP will be valid, if this is an administator.
        $regOptions['register_vars']['ID_GROUP'] = $regOptions['memberGroup'] == 1 && !allowedTo('admin_forum') ? 0 : $regOptions['memberGroup'];
        // Check if this group is assignable.
        $unassignableGroups = array(-1, 3);
        $request = db_query("\n\t\t\tSELECT ID_GROUP\n\t\t\tFROM {$db_prefix}membergroups\n\t\t\tWHERE minPosts != -1", __FILE__, __LINE__);
        while ($row = mysql_fetch_assoc($request)) {
            $unassignableGroups[] = $row['ID_GROUP'];
        }
        mysql_free_result($request);
        if (in_array($regOptions['register_vars']['ID_GROUP'], $unassignableGroups)) {
            $regOptions['register_vars']['ID_GROUP'] = 0;
        }
    }
    // Integrate optional member settings to be set.
    if (!empty($regOptions['extra_register_vars'])) {
        foreach ($regOptions['extra_register_vars'] as $var => $value) {
            $regOptions['register_vars'][$var] = $value;
        }
    }
    // Integrate optional user theme options to be set.
    $theme_vars = array();
    if (!empty($regOptions['theme_vars'])) {
        foreach ($regOptions['theme_vars'] as $var => $value) {
            $theme_vars[$var] = $value;
        }
    }
    // Call an optional function to validate the users' input.
    if (isset($modSettings['integrate_register']) && function_exists($modSettings['integrate_register'])) {
        $modSettings['integrate_register']($regOptions, $theme_vars);
    }
    // Register them into the database.
    db_query("\n\t\tINSERT INTO {$db_prefix}members\n\t\t\t(" . implode(', ', array_keys($regOptions['register_vars'])) . ")\n\t\tVALUES (" . implode(', ', $regOptions['register_vars']) . ')', __FILE__, __LINE__);
    $memberID = db_insert_id();
    // Grab their real name and send emails using it.
    $realName = substr($regOptions['register_vars']['realName'], 1, -1);
    // Update the number of members and latest member's info - and pass the name, but remove the 's.
    updateStats('member', $memberID, $realName);
    // Theme variables too?
    if (!empty($theme_vars)) {
        $setString = '';
        foreach ($theme_vars as $var => $val) {
            $setString .= "\n\t\t\t\t({$memberID}, SUBSTRING('{$var}', 1, 255), SUBSTRING('{$val}', 1, 65534)),";
        }
        db_query("\n\t\t\tINSERT INTO {$db_prefix}themes\n\t\t\t\t(ID_MEMBER, variable, value)\n\t\t\tVALUES " . substr($setString, 0, -1), __FILE__, __LINE__);
    }
    // If it's enabled, increase the registrations for today.
    trackStats(array('registers' => '+'));
    // Administrative registrations are a bit different...
    if ($regOptions['interface'] == 'admin') {
        if ($regOptions['require'] == 'activation') {
            $email_message = 'register_activate_message';
        } elseif (!empty($regOptions['send_welcome_email'])) {
            $email_message = 'register_immediate_message';
        }
        if (isset($email_message)) {
            sendmail($regOptions['email'], $txt['register_subject'], sprintf($txt[$email_message], $realName, $regOptions['username'], $regOptions['password'], $validation_code, $scripturl . '?action=activate;u=' . $memberID . ';code=' . $validation_code));
        }
        // All admins are finished here.
        return $memberID;
    }
    // Can post straight away - welcome them to your fantastic community...
    if ($regOptions['require'] == 'nothing') {
        if (!empty($regOptions['send_welcome_email'])) {
            sendmail($regOptions['email'], $txt['register_subject'], sprintf($txt['register_immediate_message'], $realName, $regOptions['username'], $regOptions['password']));
        }
        // Send admin their notification.
        adminNotify('standard', $memberID, $regOptions['username']);
    } elseif ($regOptions['require'] == 'activation' || $regOptions['require'] == 'coppa') {
        sendmail($regOptions['email'], $txt['register_subject'], sprintf($txt['register_activate_message'], $realName, $regOptions['username'], $regOptions['password'], $validation_code, $scripturl . '?action=activate;u=' . $memberID . ';code=' . $validation_code));
    } else {
        sendmail($regOptions['email'], $txt['register_subject'], sprintf($txt['register_pending_message'], $realName, $regOptions['username'], $regOptions['password']));
        // Admin gets informed here...
        adminNotify('approval', $memberID, $regOptions['username']);
    }
    // Okay, they're for sure registered... make sure the session is aware of this for security. (Just married :P!)
    $_SESSION['just_registered'] = 1;
    return $memberID;
}
Exemple #11
0
 public static function obExit($header = null, $do_footer = null, $from_index = false, $from_fatal_error = false)
 {
     global $context, $modSettings;
     static $header_done = false, $footer_done = false, $level = 0, $has_fatal_error = false;
     // Attempt to prevent a recursive loop.
     ++$level;
     if ($level > 1 && !$from_fatal_error && !$has_fatal_error) {
         exit;
     }
     if ($from_fatal_error) {
         $has_fatal_error = true;
     }
     // Clear out the stat cache.
     trackStats();
     // If we have mail to send, send it.
     if (!empty($context['flush_mail'])) {
         AddMailQueue(true);
     }
     $do_header = $header === null ? !$header_done : $header;
     if ($do_footer === null) {
         $do_footer = $do_header;
     }
     // Has the template/header been done yet?
     if ($do_header) {
         // Was the page title set last minute? Also update the HTML safe one.
         if (!empty($context['page_title']) && empty($context['page_title_html_safe'])) {
             $context['page_title_html_safe'] = $context['forum_name_html_safe'] . ' - ' . commonAPI::htmlspecialchars(un_htmlspecialchars($context['page_title']));
         }
         // Start up the session URL fixer.
         ob_start('ob_sessrewrite');
         HookAPI::integrateOB();
         //if(!empty($modSettings['simplesef_enable']))
         //	ob_start('SimpleSEF::ob_simplesef');
         // Display the screen in the logical order.
         self::template_header();
         $header_done = true;
     }
     if ($do_footer) {
         if (WIRELESS && !isset($context['sub_template'])) {
             fatal_lang_error('wireless_error_notyet', false);
         }
         self::Display();
         // Just so we don't get caught in an endless loop of errors from the footer...
         if (!$footer_done) {
             $footer_done = true;
             // (since this is just debugging... it's okay that it's after </html>.)
             if (!isset($_REQUEST['xml'])) {
                 db_debug_junk();
             }
         }
     }
     // Remember this URL in case someone doesn't like sending HTTP_REFERER.
     if (strpos($_SERVER['REQUEST_URL'], 'action=dlattach') === false && strpos($_SERVER['REQUEST_URL'], 'action=viewsmfile') === false) {
         $_SESSION['old_url'] = $_SERVER['REQUEST_URL'];
     }
     // For session check verfication.... don't switch browsers...
     $_SESSION['USER_AGENT'] = $_SERVER['HTTP_USER_AGENT'];
     // Hand off the output to the portal, etc. we're integrated with.
     HookAPI::callHook('integrate_exit', array($do_footer));
     if (!empty($modSettings['simplesef_enable'])) {
         SimpleSEF::fixXMLOutput($do_footer);
     }
     // Don't exit if we're coming from index.php; that will pass through normally.
     if (!$from_index) {
         exit;
     }
 }
Exemple #12
0
function smf_main()
{
    global $modSettings, $settings, $user_info, $board, $topic, $board_info, $maintenance, $sourcedir, $request_name, $txt, $user_settings, $mobiquo_config, $topic_per_page, $limit_num;
    // Load the user's cookie (or set as guest) and load their settings.
    loadUserSettings();
    // Load the current board's information.
    loadBoard();
    // Load the current user's permissions.
    loadPermissions();
    // Attachments don't require the entire theme to be loaded.
    loadTheme();
    header('Mobiquo_is_login:'******'context']['user']['is_logged'] ? 'true' : 'false'));
    // Check if the user should be disallowed access.
    if (!in_array($request_name, array('get_config', 'login'))) {
        is_not_banned();
    }
    // If we are in a topic and don't have permission to approve it then duck out now.
    if (!empty($topic) && empty($board_info['cur_topic_approved']) && !allowedTo('approve_posts') && ($user_info['id'] != $board_info['cur_topic_starter'] || $user_info['is_guest'])) {
        //fatal_lang_error('not_a_topic', false);
        get_error('The topic is not approved');
    }
    // Do some logging, unless this is an attachment, avatar, toggle of editor buttons, theme option, XML feed etc.
    if (empty($_REQUEST['action']) || !in_array($_REQUEST['action'], array('dlattach', 'findmember', 'jseditor', 'jsoption', 'requestmembers', 'smstats', '.xml', 'xmlhttp', 'verificationcode', 'viewquery', 'viewsmfile'))) {
        // Log this user as online.
        writeLog();
        // Track forum statistics and hits...?
        if (!empty($modSettings['hitStats'])) {
            trackStats(array('hits' => '+'));
        }
    }
    // Is the forum in maintenance mode? (doesn't apply to administrators.)
    if (!empty($maintenance) && !allowedTo('admin_forum')) {
        if ($request_name != 'get_config' && $request_name != 'login') {
            get_error($txt['maintain_mode_on']);
        }
    } elseif (empty($modSettings['allow_guestAccess']) && $user_info['is_guest'] && (!isset($_REQUEST['action']) || !in_array($_REQUEST['action'], array('push_content_check', 'user_subscription', 'set_api_key', 'reset_push_slug', 'prefetch_account', 'update_password', 'forget_password', 'sign_in', 'coppa', 'login', 'login2', 'register', 'register2', 'reminder', 'activate', 'help', 'smstats', 'mailq', 'verificationcode', 'openidreturn')))) {
        if ($request_name != 'get_config' && $request_name != 'prefetch_account') {
            loadLanguage('Login');
            get_error($txt['only_members_can_access']);
            //require_once($sourcedir . '/Subs-Auth.php');
            //return 'KickGuest';
        }
    }
    //-------------transform input data to local character set if needed
    utf8_to_local();
    //-------------change some setting for tapatalk display
    $settings['message_index_preview'] = 1;
    $modSettings['todayMod_bak'] = $modSettings['todayMod'];
    $modSettings['todayMod'] = 0;
    $user_settings['pm_prefs'] = 0;
    $user_info['user_time_format'] = $user_info['time_format'];
    $user_info['time_format'] = '%Y%m%dT%H:%M:%S+00:00';
    $modSettings['disableCustomPerPage'] = 1;
    $modSettings['disableCheckUA'] = 1;
    $modSettings['defaultMaxMessages'] = isset($limit_num) ? $limit_num : 20;
    $modSettings['defaultMaxMembers'] = 100;
    $modSettings['search_results_per_page'] = isset($topic_per_page) && $topic_per_page > 0 ? $topic_per_page : 20;
    $modSettings['defaultMaxTopics'] = isset($topic_per_page) && $topic_per_page > 0 ? $topic_per_page : 20;
    $modSettings['disable_pm_verification'] = $mobiquo_config['disable_pm_verification'];
    //-------------do something before action--------------
    if (function_exists('before_action_' . $request_name)) {
        call_user_func('before_action_' . $request_name);
    }
    if (empty($_REQUEST['action']) && !empty($board)) {
        if (empty($topic)) {
            require_once 'include/MessageIndex.php';
            return 'MessageIndex';
        } else {
            require_once 'include/Display.php';
            return 'Display';
        }
    }
    // Here's the monstrous $_REQUEST['action'] array - $_REQUEST['action'] => array($file, $function).
    $actionArray = array('activate' => array('Register.php', 'Activate'), 'admin' => array('Admin.php', 'AdminMain'), 'announce' => array('Post.php', 'AnnounceTopic'), 'attachapprove' => array('ManageAttachments.php', 'ApproveAttach'), 'buddy' => array('Subs-Members.php', 'BuddyListToggle'), 'calendar' => array('Calendar.php', 'CalendarMain'), 'clock' => array('Calendar.php', 'clock'), 'collapse' => array('BoardIndex.php', 'CollapseCategory'), 'coppa' => array('Register.php', 'CoppaForm'), 'credits' => array('Who.php', 'Credits'), 'deletemsg' => array('RemoveTopic.php', 'DeleteMessage'), 'display' => array('Display.php', 'Display'), 'dlattach' => array('Display.php', 'Download'), 'editpoll' => array('Poll.php', 'EditPoll'), 'editpoll2' => array('Poll.php', 'EditPoll2'), 'emailuser' => array('SendTopic.php', 'EmailUser'), 'findmember' => array('Subs-Auth.php', 'JSMembers'), 'groups' => array('Groups.php', 'Groups'), 'help' => array('Help.php', 'ShowHelp'), 'helpadmin' => array('Help.php', 'ShowAdminHelp'), 'im' => array('PersonalMessage.php', 'MessageMain'), 'jseditor' => array('Subs-Editor.php', 'EditorMain'), 'jsmodify' => array('Post.php', 'JavaScriptModify'), 'jsoption' => array('Themes.php', 'SetJavaScript'), 'lock' => array('LockTopic.php', 'LockTopic'), 'lockvoting' => array('Poll.php', 'LockVoting'), 'login' => array('LogInOut.php', 'Login'), 'login2' => array('LogInOut.php', 'Login2'), 'logout' => array('LogInOut.php', 'Logout'), 'markasread' => array('Subs-Boards.php', 'MarkRead'), 'mergetopics' => array('SplitTopics.php', 'MergeTopics'), 'mlist' => array('Memberlist.php', 'Memberlist'), 'moderate' => array('ModerationCenter.php', 'ModerationMain'), 'modifycat' => array('ManageBoards.php', 'ModifyCat'), 'modifykarma' => array('Karma.php', 'ModifyKarma'), 'movetopic' => array('MoveTopic.php', 'MoveTopic'), 'movetopic2' => array('MoveTopic.php', 'MoveTopic2'), 'notify' => array('Notify.php', 'Notify'), 'notifyboard' => array('Notify.php', 'BoardNotify'), 'openidreturn' => array('Subs-OpenID.php', 'smf_openID_return'), 'pm' => array('PersonalMessage.php', 'MessageMain'), 'post' => array('Post.php', 'Post'), 'post2' => array('Post.php', 'Post2'), 'printpage' => array('Printpage.php', 'PrintTopic'), 'profile' => array('Profile.php', 'ModifyProfile'), 'quotefast' => array('Post.php', 'QuoteFast'), 'quickmod' => array('MessageIndex.php', 'QuickModeration'), 'quickmod2' => array('Display.php', 'QuickInTopicModeration'), 'recent' => array('Recent.php', 'RecentPosts'), 'register' => array('Register.php', 'Register'), 'register2' => array('Register.php', 'Register2'), 'reminder' => array('Reminder.php', 'RemindMe'), 'removepoll' => array('Poll.php', 'RemovePoll'), 'removetopic2' => array('RemoveTopic.php', 'RemoveTopic2'), 'reporttm' => array('SendTopic.php', 'ReportToModerator'), 'requestmembers' => array('Subs-Auth.php', 'RequestMembers'), 'restoretopic' => array('RemoveTopic.php', 'RestoreTopic'), 'search' => array('Search.php', 'PlushSearch1'), 'search2' => array('Search.php', 'PlushSearch2'), 'sendtopic' => array('SendTopic.php', 'EmailUser'), 'smstats' => array('Stats.php', 'SMStats'), 'suggest' => array('Subs-Editor.php', 'AutoSuggestHandler'), 'spellcheck' => array('Subs-Post.php', 'SpellCheck'), 'splittopics' => array('SplitTopics.php', 'SplitTopics'), 'stats' => array('Stats.php', 'DisplayStats'), 'sticky' => array('LockTopic.php', 'Sticky'), 'theme' => array('Themes.php', 'ThemesMain'), 'trackip' => array('Profile-View.php', 'trackIP'), 'about:mozilla' => array('Karma.php', 'BookOfUnknown'), 'about:unknown' => array('Karma.php', 'BookOfUnknown'), 'unread' => array('Recent.php', 'UnreadTopics'), 'unreadreplies' => array('Recent.php', 'UnreadTopics'), 'verificationcode' => array('Register.php', 'VerificationCode'), 'viewprofile' => array('Profile.php', 'ModifyProfile'), 'vote' => array('Poll.php', 'Vote'), 'viewquery' => array('ViewQuery.php', 'ViewQuery'), 'viewsmfile' => array('Admin.php', 'DisplayAdminFile'), 'who' => array('Who.php', 'Who'), '.xml' => array('News.php', 'ShowXmlFeed'), 'xmlhttp' => array('Xml.php', 'XMLhttpMain'));
    // Allow modifying $actionArray easily.
    call_integration_hook('integrate_actions', array(&$actionArray));
    //error_log($request_name.'-'.$_REQUEST['action']);   //for debugging
    // Get the function and file to include - if it's not there, do the board index.
    if (!isset($_REQUEST['action']) || !isset($actionArray[$_REQUEST['action']])) {
        if (function_exists('action_' . $request_name)) {
            return 'action_' . $request_name;
        } else {
            get_error('Invalid action');
        }
    }
    $local_action = array('login2', 'post', 'post2', 'who', 'profile', 'notify', 'notifyboard', 'markasread', 'unread', 'search2', 'pm', 'logout');
    // Otherwise, it was set - so let's go to that action.
    if (in_array($_REQUEST['action'], $local_action)) {
        if (file_exists(TT_ROOT . 'include/' . $actionArray[$_REQUEST['action']][0])) {
            require_once TT_ROOT . 'include/' . $actionArray[$_REQUEST['action']][0];
        } else {
            if (file_exists($sourcedir . '/' . $actionArray[$_REQUEST['action']][0])) {
                require_once $sourcedir . '/' . $actionArray[$_REQUEST['action']][0];
            }
        }
    } else {
        if (file_exists($sourcedir . '/' . $actionArray[$_REQUEST['action']][0])) {
            require_once $sourcedir . '/' . $actionArray[$_REQUEST['action']][0];
        }
    }
    return $actionArray[$_REQUEST['action']][1];
}
Exemple #13
0
/**
 * Registers a member to the forum.
 *
 * What it does:
 * - Allows two types of interface: 'guest' and 'admin'. The first
 * - includes hammering protection, the latter can perform the registration silently.
 * - The strings used in the options array are assumed to be escaped.
 * - Allows to perform several checks on the input, e.g. reserved names.
 * - The function will adjust member statistics.
 * - If an error is detected will fatal error on all errors unless return_errors is true.
 *
 * @package Members
 * @uses Auth.subs.php
 * @uses Mail.subs.php
 * @param mixed[] $regOptions
 * @param string $error_context
 * @return integer the ID of the newly created member
 */
function registerMember(&$regOptions, $error_context = 'register')
{
    global $scripturl, $txt, $modSettings, $user_info;
    $db = database();
    loadLanguage('Login');
    // We'll need some external functions.
    require_once SUBSDIR . '/Auth.subs.php';
    require_once SUBSDIR . '/Mail.subs.php';
    // Put any errors in here.
    $reg_errors = Error_Context::context($error_context, 0);
    // Registration from the admin center, let them sweat a little more.
    if ($regOptions['interface'] == 'admin') {
        is_not_guest();
        isAllowedTo('moderate_forum');
    } elseif ($regOptions['interface'] == 'guest') {
        // You cannot register twice...
        if (empty($user_info['is_guest'])) {
            redirectexit();
        }
        // Make sure they didn't just register with this session.
        if (!empty($_SESSION['just_registered']) && empty($modSettings['disableRegisterCheck'])) {
            fatal_lang_error('register_only_once', false);
        }
    }
    // What method of authorization are we going to use?
    if (empty($regOptions['auth_method']) || !in_array($regOptions['auth_method'], array('password', 'openid'))) {
        if (!empty($regOptions['openid'])) {
            $regOptions['auth_method'] = 'openid';
        } else {
            $regOptions['auth_method'] = 'password';
        }
    }
    // Spaces and other odd characters are evil...
    $regOptions['username'] = trim(preg_replace('~[\\t\\n\\r \\x0B\\0\\x{A0}\\x{AD}\\x{2000}-\\x{200F}\\x{201F}\\x{202F}\\x{3000}\\x{FEFF}]+~u', ' ', $regOptions['username']));
    // Valid emails only
    require_once SUBSDIR . '/DataValidator.class.php';
    if (!Data_Validator::is_valid($regOptions, array('email' => 'valid_email|required|max_length[255]'), array('email' => 'trim'))) {
        $reg_errors->addError('bad_email');
    }
    validateUsername(0, $regOptions['username'], $error_context, !empty($regOptions['check_reserved_name']));
    // Generate a validation code if it's supposed to be emailed.
    $validation_code = '';
    if ($regOptions['require'] == 'activation') {
        $validation_code = generateValidationCode();
    }
    // If you haven't put in a password generate one.
    if ($regOptions['interface'] == 'admin' && $regOptions['password'] == '' && $regOptions['auth_method'] == 'password') {
        mt_srand(time() + 1277);
        $regOptions['password'] = generateValidationCode();
        $regOptions['password_check'] = $regOptions['password'];
    } elseif ($regOptions['password'] != $regOptions['password_check'] && $regOptions['auth_method'] == 'password') {
        $reg_errors->addError('passwords_dont_match');
    }
    // That's kind of easy to guess...
    if ($regOptions['password'] == '') {
        if ($regOptions['auth_method'] == 'password') {
            $reg_errors->addError('no_password');
        } else {
            $regOptions['password'] = sha1(mt_rand());
        }
    }
    // Now perform hard password validation as required.
    if (!empty($regOptions['check_password_strength']) && $regOptions['password'] != '') {
        $passwordError = validatePassword($regOptions['password'], $regOptions['username'], array($regOptions['email']));
        // Password isn't legal?
        if ($passwordError != null) {
            $reg_errors->addError('profile_error_password_' . $passwordError);
        }
    }
    // You may not be allowed to register this email.
    if (!empty($regOptions['check_email_ban'])) {
        isBannedEmail($regOptions['email'], 'cannot_register', $txt['ban_register_prohibited']);
    }
    // Check if the email address is in use.
    $request = $db->query('', '
		SELECT id_member
		FROM {db_prefix}members
		WHERE email_address = {string:email_address}
			OR email_address = {string:username}
		LIMIT 1', array('email_address' => $regOptions['email'], 'username' => $regOptions['username']));
    if ($db->num_rows($request) != 0) {
        $reg_errors->addError(array('email_in_use', array(htmlspecialchars($regOptions['email'], ENT_COMPAT, 'UTF-8'))));
    }
    $db->free_result($request);
    // Perhaps someone else wants to check this user
    call_integration_hook('integrate_register_check', array(&$regOptions, &$reg_errors));
    // If there's any errors left return them at once!
    if ($reg_errors->hasErrors()) {
        return false;
    }
    $reservedVars = 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');
    // Can't change reserved vars.
    if (isset($regOptions['theme_vars']) && count(array_intersect(array_keys($regOptions['theme_vars']), $reservedVars)) != 0) {
        fatal_lang_error('no_theme');
    }
    // New password hash
    require_once SUBSDIR . '/Auth.subs.php';
    // Some of these might be overwritten. (the lower ones that are in the arrays below.)
    $regOptions['register_vars'] = array('member_name' => $regOptions['username'], 'email_address' => $regOptions['email'], 'passwd' => validateLoginPassword($regOptions['password'], '', $regOptions['username'], true), 'password_salt' => substr(md5(mt_rand()), 0, 4), 'posts' => 0, 'date_registered' => !empty($regOptions['time']) ? $regOptions['time'] : time(), 'member_ip' => $regOptions['interface'] == 'admin' ? '127.0.0.1' : $regOptions['ip'], 'member_ip2' => $regOptions['interface'] == 'admin' ? '127.0.0.1' : $regOptions['ip2'], 'validation_code' => $validation_code, 'real_name' => $regOptions['username'], 'personal_text' => $modSettings['default_personal_text'], 'pm_email_notify' => 1, 'id_theme' => 0, 'id_post_group' => 4, 'lngfile' => '', 'buddy_list' => '', 'pm_ignore_list' => '', 'message_labels' => '', 'website_title' => '', 'website_url' => '', 'location' => '', 'time_format' => '', 'signature' => '', 'avatar' => '', 'usertitle' => '', 'secret_question' => '', 'secret_answer' => '', 'additional_groups' => '', 'ignore_boards' => '', 'smiley_set' => '', 'openid_uri' => !empty($regOptions['openid']) ? $regOptions['openid'] : '');
    // Setup the activation status on this new account so it is correct - firstly is it an under age account?
    if ($regOptions['require'] == 'coppa') {
        $regOptions['register_vars']['is_activated'] = 5;
        // @todo This should be changed.  To what should be it be changed??
        $regOptions['register_vars']['validation_code'] = '';
    } elseif ($regOptions['require'] == 'nothing') {
        $regOptions['register_vars']['is_activated'] = 1;
    } elseif ($regOptions['require'] == 'activation') {
        $regOptions['register_vars']['is_activated'] = 0;
    } else {
        $regOptions['register_vars']['is_activated'] = 3;
    }
    if (isset($regOptions['memberGroup'])) {
        // Make sure the id_group will be valid, if this is an administator.
        $regOptions['register_vars']['id_group'] = $regOptions['memberGroup'] == 1 && !allowedTo('admin_forum') ? 0 : $regOptions['memberGroup'];
        // Check if this group is assignable.
        $unassignableGroups = array(-1, 3);
        $request = $db->query('', '
			SELECT id_group
			FROM {db_prefix}membergroups
			WHERE min_posts != {int:min_posts}' . (allowedTo('admin_forum') ? '' : '
				OR group_type = {int:is_protected}'), array('min_posts' => -1, 'is_protected' => 1));
        while ($row = $db->fetch_assoc($request)) {
            $unassignableGroups[] = $row['id_group'];
        }
        $db->free_result($request);
        if (in_array($regOptions['register_vars']['id_group'], $unassignableGroups)) {
            $regOptions['register_vars']['id_group'] = 0;
        }
    }
    // Integrate optional member settings to be set.
    if (!empty($regOptions['extra_register_vars'])) {
        foreach ($regOptions['extra_register_vars'] as $var => $value) {
            $regOptions['register_vars'][$var] = $value;
        }
    }
    // Integrate optional user theme options to be set.
    $theme_vars = array();
    if (!empty($regOptions['theme_vars'])) {
        foreach ($regOptions['theme_vars'] as $var => $value) {
            $theme_vars[$var] = $value;
        }
    }
    // Right, now let's prepare for insertion.
    $knownInts = array('date_registered', 'posts', 'id_group', 'last_login', 'personal_messages', 'unread_messages', 'notifications', 'new_pm', 'pm_prefs', 'gender', 'hide_email', 'show_online', 'pm_email_notify', 'karma_good', 'karma_bad', 'notify_announcements', 'notify_send_body', 'notify_regularity', 'notify_types', 'id_theme', 'is_activated', 'id_msg_last_visit', 'id_post_group', 'total_time_logged_in', 'warning');
    $knownFloats = array('time_offset');
    // Call an optional function to validate the users' input.
    call_integration_hook('integrate_register', array(&$regOptions, &$theme_vars, &$knownInts, &$knownFloats));
    $column_names = array();
    $values = array();
    foreach ($regOptions['register_vars'] as $var => $val) {
        $type = 'string';
        if (in_array($var, $knownInts)) {
            $type = 'int';
        } elseif (in_array($var, $knownFloats)) {
            $type = 'float';
        } elseif ($var == 'birthdate') {
            $type = 'date';
        }
        $column_names[$var] = $type;
        $values[$var] = $val;
    }
    // Register them into the database.
    $db->insert('', '{db_prefix}members', $column_names, $values, array('id_member'));
    $memberID = $db->insert_id('{db_prefix}members', 'id_member');
    // Update the number of members and latest member's info - and pass the name, but remove the 's.
    if ($regOptions['register_vars']['is_activated'] == 1) {
        updateMemberStats($memberID, $regOptions['register_vars']['real_name']);
    } else {
        updateMemberStats();
    }
    // Theme variables too?
    if (!empty($theme_vars)) {
        $inserts = array();
        foreach ($theme_vars as $var => $val) {
            $inserts[] = array($memberID, $var, $val);
        }
        $db->insert('insert', '{db_prefix}themes', array('id_member' => 'int', 'variable' => 'string-255', 'value' => 'string-65534'), $inserts, array('id_member', 'variable'));
    }
    // If it's enabled, increase the registrations for today.
    trackStats(array('registers' => '+'));
    // Administrative registrations are a bit different...
    if ($regOptions['interface'] == 'admin') {
        if ($regOptions['require'] == 'activation') {
            $email_message = 'admin_register_activate';
        } elseif (!empty($regOptions['send_welcome_email'])) {
            $email_message = 'admin_register_immediate';
        }
        if (isset($email_message)) {
            $replacements = array('REALNAME' => $regOptions['register_vars']['real_name'], 'USERNAME' => $regOptions['username'], 'PASSWORD' => $regOptions['password'], 'FORGOTPASSWORDLINK' => $scripturl . '?action=reminder', 'ACTIVATIONLINK' => $scripturl . '?action=activate;u=' . $memberID . ';code=' . $validation_code, 'ACTIVATIONLINKWITHOUTCODE' => $scripturl . '?action=activate;u=' . $memberID, 'ACTIVATIONCODE' => $validation_code);
            $emaildata = loadEmailTemplate($email_message, $replacements);
            sendmail($regOptions['email'], $emaildata['subject'], $emaildata['body'], null, null, false, 0);
        }
    } else {
        // Can post straight away - welcome them to your fantastic community...
        if ($regOptions['require'] == 'nothing') {
            if (!empty($regOptions['send_welcome_email'])) {
                $replacements = array('REALNAME' => $regOptions['register_vars']['real_name'], 'USERNAME' => $regOptions['username'], 'PASSWORD' => $regOptions['password'], 'FORGOTPASSWORDLINK' => $scripturl . '?action=reminder', 'OPENID' => !empty($regOptions['openid']) ? $regOptions['openid'] : '');
                $emaildata = loadEmailTemplate('register_' . ($regOptions['auth_method'] == 'openid' ? 'openid_' : '') . 'immediate', $replacements);
                sendmail($regOptions['email'], $emaildata['subject'], $emaildata['body'], null, null, false, 0);
            }
            // Send admin their notification.
            require_once SUBSDIR . '/Notification.subs.php';
            sendAdminNotifications('standard', $memberID, $regOptions['username']);
        } elseif ($regOptions['require'] == 'activation' || $regOptions['require'] == 'coppa') {
            $replacements = array('REALNAME' => $regOptions['register_vars']['real_name'], 'USERNAME' => $regOptions['username'], 'PASSWORD' => $regOptions['password'], 'FORGOTPASSWORDLINK' => $scripturl . '?action=reminder', 'OPENID' => !empty($regOptions['openid']) ? $regOptions['openid'] : '');
            if ($regOptions['require'] == 'activation') {
                $replacements += array('ACTIVATIONLINK' => $scripturl . '?action=activate;u=' . $memberID . ';code=' . $validation_code, 'ACTIVATIONLINKWITHOUTCODE' => $scripturl . '?action=activate;u=' . $memberID, 'ACTIVATIONCODE' => $validation_code);
            } else {
                $replacements += array('COPPALINK' => $scripturl . '?action=coppa;u=' . $memberID);
            }
            $emaildata = loadEmailTemplate('register_' . ($regOptions['auth_method'] == 'openid' ? 'openid_' : '') . ($regOptions['require'] == 'activation' ? 'activate' : 'coppa'), $replacements);
            sendmail($regOptions['email'], $emaildata['subject'], $emaildata['body'], null, null, false, 0);
        } else {
            $replacements = array('REALNAME' => $regOptions['register_vars']['real_name'], 'USERNAME' => $regOptions['username'], 'PASSWORD' => $regOptions['password'], 'FORGOTPASSWORDLINK' => $scripturl . '?action=reminder', 'OPENID' => !empty($regOptions['openid']) ? $regOptions['openid'] : '');
            $emaildata = loadEmailTemplate('register_' . ($regOptions['auth_method'] == 'openid' ? 'openid_' : '') . 'pending', $replacements);
            sendmail($regOptions['email'], $emaildata['subject'], $emaildata['body'], null, null, false, 0);
            // Admin gets informed here...
            require_once SUBSDIR . '/Notification.subs.php';
            sendAdminNotifications('approval', $memberID, $regOptions['username']);
        }
        // Okay, they're for sure registered... make sure the session is aware of this for security. (Just married :P!)
        $_SESSION['just_registered'] = 1;
    }
    // If they are for sure registered, let other people to know about it
    call_integration_hook('integrate_register_after', array($regOptions, $memberID));
    return $memberID;
}
Exemple #14
0
function createPost(&$msgOptions, &$topicOptions, &$posterOptions)
{
    global $user_info, $txt, $modSettings, $context, $sourcedir;
    // Set optional parameters to the default value.
    $msgOptions['icon'] = empty($msgOptions['icon']) ? 'xx' : $msgOptions['icon'];
    $msgOptions['smileys_enabled'] = !empty($msgOptions['smileys_enabled']);
    $msgOptions['attachments'] = empty($msgOptions['attachments']) ? array() : $msgOptions['attachments'];
    $msgOptions['approved'] = isset($msgOptions['approved']) ? (int) $msgOptions['approved'] : 1;
    $msgOptions['locked'] = 0;
    $topicOptions['id'] = empty($topicOptions['id']) ? 0 : (int) $topicOptions['id'];
    $topicOptions['poll'] = isset($topicOptions['poll']) ? (int) $topicOptions['poll'] : null;
    $topicOptions['lock_mode'] = isset($topicOptions['lock_mode']) ? $topicOptions['lock_mode'] : null;
    $topicOptions['sticky_mode'] = isset($topicOptions['sticky_mode']) ? $topicOptions['sticky_mode'] : null;
    $posterOptions['id'] = empty($posterOptions['id']) ? 0 : (int) $posterOptions['id'];
    $posterOptions['ip'] = empty($posterOptions['ip']) ? $user_info['ip'] : $posterOptions['ip'];
    $context['can_tag_users'] = allowedTo('tag_users');
    $tagged_users = handleUserTags($msgOptions['body']);
    // We need to know if the topic is approved. If we're told that's great - if not find out.
    if (!$modSettings['postmod_active']) {
        $topicOptions['is_approved'] = true;
    } elseif (!empty($topicOptions['id']) && !isset($topicOptions['is_approved'])) {
        $request = smf_db_query('
			SELECT approved
			FROM {db_prefix}topics
			WHERE id_topic = {int:id_topic}
			LIMIT 1', array('id_topic' => $topicOptions['id']));
        list($topicOptions['is_approved']) = mysql_fetch_row($request);
        mysql_free_result($request);
    }
    // If nothing was filled in as name/e-mail address, try the member table.
    if (!isset($posterOptions['name']) || $posterOptions['name'] == '' || empty($posterOptions['email']) && !empty($posterOptions['id'])) {
        if (empty($posterOptions['id'])) {
            $posterOptions['id'] = 0;
            $posterOptions['name'] = $txt['guest_title'];
            $posterOptions['email'] = '';
        } elseif ($posterOptions['id'] != $user_info['id']) {
            $request = smf_db_query('
				SELECT member_name, email_address, real_name
				FROM {db_prefix}members
				WHERE id_member = {int:id_member}
				LIMIT 1', array('id_member' => $posterOptions['id']));
            // Couldn't find the current poster?
            if (mysql_num_rows($request) == 0) {
                trigger_error('createPost(): Invalid member id ' . $posterOptions['id'], E_USER_NOTICE);
                $posterOptions['id'] = 0;
                $posterOptions['name'] = $txt['guest_title'];
                $posterOptions['email'] = '';
            } else {
                list($posterOptions['name'], $posterOptions['email'], $posterOptions['real_name']) = mysql_fetch_row($request);
            }
            mysql_free_result($request);
        } else {
            $posterOptions['name'] = $posterOptions['real_name'] = $user_info['name'];
            $posterOptions['email'] = $user_info['email'];
        }
    } else {
        $posterOptions['real_name'] = $user_info['name'];
    }
    // It's do or die time: forget any user aborts!
    $previous_ignore_user_abort = ignore_user_abort(true);
    $new_topic = empty($topicOptions['id']);
    // decide whether we should just update the last post or append a new one
    $automerge_posts = false;
    $want_automerge = isset($_REQUEST['want_automerge']) && $_REQUEST['want_automerge'] > 0 ? true : false;
    if (!$new_topic && ($topicOptions['automerge'] > 0 && $want_automerge) && $topicOptions['id_member_updated'] == $posterOptions['id'] && empty($topicOptions['poll'])) {
        $result = smf_db_query('
			SELECT poster_time, modified_time, body FROM {db_prefix}messages WHERE id_msg = {int:last_id}', array('last_id' => $topicOptions['id_last_msg']));
        list($ptime, $mtime, $oldbody) = mysql_fetch_row($result);
        if (smf_db_affected_rows() != 0) {
            if ($want_automerge || time() - max($ptime, $mtime) < $topicOptions['automerge'] * 60) {
                $automerge_posts = true;
                $msg_to_update = $topicOptions['id_last_msg'];
            }
        }
        mysql_free_result($result);
    }
    // Insert the post.
    if (false === $automerge_posts) {
        smf_db_insert('', '{db_prefix}messages', array('id_board' => 'int', 'id_topic' => 'int', 'id_member' => 'int', 'subject' => 'string-255', 'body' => !empty($modSettings['max_messageLength']) && $modSettings['max_messageLength'] > 65534 ? 'string-' . $modSettings['max_messageLength'] : 'string', 'poster_name' => 'string-255', 'poster_email' => 'string-255', 'poster_time' => 'int', 'poster_ip' => 'string-255', 'smileys_enabled' => 'int', 'modified_name' => 'string', 'icon' => 'string-16', 'approved' => 'int', 'locked' => 'int'), array($topicOptions['board'], $topicOptions['id'], $posterOptions['id'], $msgOptions['subject'], $msgOptions['body'], $posterOptions['name'], $posterOptions['email'], time(), $posterOptions['ip'], $msgOptions['smileys_enabled'] ? 1 : 0, '', $msgOptions['icon'], $msgOptions['approved'], $msgOptions['locked']), array('id_msg'));
        $msgOptions['id'] = smf_db_insert_id('{db_prefix}messages', 'id_msg');
        if (count($tagged_users) > 0) {
            notifyTaggedUsers($tagged_users, array('id_topic' => $topicOptions['id'], 'id_message' => $msgOptions['id']));
        }
        // Something went wrong creating the message...
        if (empty($msgOptions['id'])) {
            return false;
        }
        $msg_to_update = $msgOptions['id'];
        // needed for later tasks
        // Fix the attachments.
        if (!empty($msgOptions['attachments'])) {
            smf_db_query('
				UPDATE {db_prefix}attachments
				SET id_msg = {int:id_msg}
				WHERE id_attach IN ({array_int:attachment_list})', array('attachment_list' => $msgOptions['attachments'], 'id_msg' => $msgOptions['id']));
        }
    } else {
        if ($msg_to_update) {
            $newbody = $oldbody . "\n[hr][size=11px][color=red][b]      Posted: [time]" . time() . "[/time][/b][/color][/size]\n" . $msgOptions['body'];
            // todo: make the separator customizable
            //todo: it should be possible to customize the separator
            smf_db_query('
				UPDATE {db_prefix}messages SET body = {string:newbody}, modified_time = {int:now},
					approved = {int:approved} WHERE id_msg = {int:id_msg}', array('newbody' => $newbody, 'now' => time(), 'id_msg' => $msg_to_update, 'approved' => $msgOptions['approved']));
            smf_db_query('DELETE FROM {db_prefix}messages_cache WHERE id_msg = {int:id_msg}', array('id_msg' => $msg_to_update));
            CacheAPI::clearCacheByPrefix('parse:' . trim($msg_to_update) . '-');
            if (count($tagged_users) > 0) {
                notifyTaggedUsers($tagged_users, array('id_topic' => $topicOptions['id'], 'id_message' => $msgOptions['id']));
            }
            if (empty($msgOptions['attachments'])) {
                $attachments[0] = -1;
            } else {
                $attachments = $msgOptions['attachments'];
            }
            // attachments must be fixed and "redirected" for the new post id...
            smf_db_query('
				UPDATE {db_prefix}attachments
				SET id_msg = {int:id_msg}
				WHERE id_attach IN ({array_int:attachment_list})', array('attachment_list' => $attachments, 'id_msg' => $msg_to_update));
        } else {
            return false;
        }
        // that should NOT happen...
    }
    // Insert a new topic (if the topicID was left empty.)
    if ($new_topic) {
        if (!isset($topicOptions['topic_prefix'])) {
            $topicOptions['topic_prefix'] = 0;
        }
        if (!isset($topicOptions['topic_layout'])) {
            $topicOptions['topic_layout'] = 0;
        }
        smf_db_insert('', '{db_prefix}topics', array('id_board' => 'int', 'id_member_started' => 'int', 'id_member_updated' => 'int', 'id_first_msg' => 'int', 'id_last_msg' => 'int', 'locked' => 'int', 'is_sticky' => 'int', 'num_views' => 'int', 'id_poll' => 'int', 'unapproved_posts' => 'int', 'approved' => 'int', 'id_prefix' => 'int', 'id_layout' => 'int'), array($topicOptions['board'], $posterOptions['id'], $posterOptions['id'], $msgOptions['id'], $msgOptions['id'], $topicOptions['lock_mode'] === null ? 0 : $topicOptions['lock_mode'], $topicOptions['sticky_mode'] === null ? 0 : $topicOptions['sticky_mode'], 0, $topicOptions['poll'] === null ? 0 : $topicOptions['poll'], $msgOptions['approved'] ? 0 : 1, $msgOptions['approved'], $topicOptions['topic_prefix'], $topicOptions['topic_layout']), array('id_topic'));
        $topicOptions['id'] = smf_db_insert_id('{db_prefix}topics', 'id_topic');
        // The topic couldn't be created for some reason.
        if (empty($topicOptions['id'])) {
            // We should delete the post that did work, though...
            smf_db_query('
				DELETE FROM {db_prefix}messages
				WHERE id_msg = {int:id_msg}', array('id_msg' => $msgOptions['id']));
            return false;
        }
        // Fix the message with the topic.
        smf_db_query('
			UPDATE {db_prefix}messages
			SET id_topic = {int:id_topic}
			WHERE id_msg = {int:id_msg}', array('id_topic' => $topicOptions['id'], 'id_msg' => $msgOptions['id']));
        // There's been a new topic AND a new post today.
        trackStats(array('topics' => '+', 'posts' => '+'));
        updateStats('topic', true);
        updateStats('subject', $topicOptions['id'], $msgOptions['subject']);
        // todo supporting code for related topics mod (should go away - the mod is not included)
        if (isset($modSettings['have_related_topics']) && $modSettings['have_related_topics']) {
            require_once $sourcedir . '/lib/Subs-Related.php';
            relatedUpdateTopics($topicOptions['id']);
        }
        // What if we want to export new topics out to a CMS?
        HookAPI::callHook('create_topic', array(&$msgOptions, &$topicOptions, &$posterOptions));
        // record the activity
        if ($modSettings['astream_active'] && !$context['no_astream']) {
            require_once $sourcedir . '/lib/Subs-Activities.php';
            aStreamAdd($posterOptions['id'], ACT_NEWTOPIC, array('member_name' => $posterOptions['real_name'], 'topic_title' => $msgOptions['subject']), $topicOptions['board'], $topicOptions['id'], $msgOptions['id'], $posterOptions['id']);
        }
    } else {
        if (false === $automerge_posts) {
            $countChange = $msgOptions['approved'] ? 'num_replies = num_replies + 1' : 'unapproved_posts = unapproved_posts + 1';
        } else {
            // the # of replies and unapproved posts does not increase if we merge
            $countChange = $msgOptions['approved'] ? 'num_replies = num_replies' : 'unapproved_posts = unapproved_posts';
        }
        // Update the number of replies and the lock/sticky status.
        smf_db_query('
			UPDATE {db_prefix}topics
			SET
				' . ($msgOptions['approved'] ? 'id_member_updated = {int:poster_id}, id_last_msg = {int:id_msg},' : '') . '
				' . $countChange . ($topicOptions['lock_mode'] === null ? '' : ',
				locked = {int:locked}') . ($topicOptions['sticky_mode'] === null ? '' : ',
				is_sticky = {int:is_sticky}') . '
			WHERE id_topic = {int:id_topic}', array('poster_id' => $posterOptions['id'], 'id_msg' => $msg_to_update, 'locked' => $topicOptions['lock_mode'], 'is_sticky' => $topicOptions['sticky_mode'], 'id_topic' => $topicOptions['id']));
        // One new post has been added today.
        if (false === $automerge_posts) {
            trackStats(array('posts' => '+'));
        }
        if ($modSettings['astream_active'] && !$context['no_astream']) {
            // add to activity stream, but do not notify when we reply to our own topic
            require_once $sourcedir . '/lib/Subs-Activities.php';
            aStreamAdd($posterOptions['id'], ACT_REPLIED, array('member_name' => $posterOptions['real_name'], 'topic_title' => $msgOptions['subject']), $topicOptions['board'], $topicOptions['id'], $msg_to_update, $topicOptions['id_member_started'], 0, $posterOptions['id'] == $topicOptions['id_member_started'] ? true : false);
        }
        HookAPI::callHook('update_topic', array(&$msgOptions, &$topicOptions, &$posterOptions));
    }
    // Creating is modifying...in a way.
    //!!! Why not set id_msg_modified on the insert?
    smf_db_query('
		UPDATE {db_prefix}messages
		SET id_msg_modified = {int:id_msg}
		WHERE id_msg = {int:id_msg}', array('id_msg' => $automerge_posts ? $modSettings['maxMsgID'] : $msg_to_update));
    // Increase the number of posts and topics on the board.
    if ($msgOptions['approved'] && false === $automerge_posts) {
        smf_db_query('
			UPDATE {db_prefix}boards
			SET num_posts = num_posts + 1' . ($new_topic ? ', num_topics = num_topics + 1' : '') . '
			WHERE id_board = {int:id_board}', array('id_board' => $topicOptions['board']));
    } else {
        if (false === $automerge_posts) {
            smf_db_query('
			UPDATE {db_prefix}boards
			SET unapproved_posts = unapproved_posts + 1' . ($new_topic ? ', unapproved_topics = unapproved_topics + 1' : '') . '
			WHERE id_board = {int:id_board}', array('id_board' => $topicOptions['board']));
            // Add to the approval queue too.
            smf_db_insert('', '{db_prefix}approval_queue', array('id_msg' => 'int'), array($msgOptions['id']), array());
        }
    }
    // Mark inserted topic as read (only for the user calling this function).
    if (!empty($topicOptions['mark_as_read']) && !$user_info['is_guest']) {
        // Since it's likely they *read* it before replying, let's try an UPDATE first.
        if (!$new_topic) {
            smf_db_query('
				UPDATE {db_prefix}log_topics
				SET id_msg = {int:id_msg}
				WHERE id_member = {int:current_member}
					AND id_topic = {int:id_topic}', array('current_member' => $posterOptions['id'], 'id_msg' => $msg_to_update, 'id_topic' => $topicOptions['id']));
            $flag = smf_db_affected_rows() != 0;
        }
        if (empty($flag)) {
            smf_db_insert('ignore', '{db_prefix}log_topics', array('id_topic' => 'int', 'id_member' => 'int', 'id_msg' => 'int'), array($topicOptions['id'], $posterOptions['id'], $msg_to_update), array('id_topic', 'id_member'));
        }
    }
    // If there's a custom search index, it needs updating...
    if (!empty($modSettings['search_custom_index_config'])) {
        $customIndexSettings = unserialize($modSettings['search_custom_index_config']);
        if ($automerge_posts) {
            $text = $newbody;
        } else {
            $text = $msgOptions['body'];
        }
        $inserts = array();
        foreach (text2words($text, $customIndexSettings['bytes_per_word'], true) as $word) {
            $inserts[] = array($word, $msg_to_update);
        }
        if (!empty($inserts)) {
            smf_db_insert('ignore', '{db_prefix}log_search_words', array('id_word' => 'int', 'id_msg' => 'int'), $inserts, array('id_word', 'id_msg'));
        }
    }
    // Increase the post counter for the user that created the post.
    if (!empty($posterOptions['update_post_count']) && !empty($posterOptions['id']) && $msgOptions['approved'] && false === $automerge_posts) {
        // Are you the one that happened to create this post?
        if ($user_info['id'] == $posterOptions['id']) {
            $user_info['posts']++;
        }
        updateMemberData($posterOptions['id'], array('posts' => '+'));
    }
    // They've posted, so they can make the view count go up one if they really want. (this is to keep views >= replies...)
    $_SESSION['last_read_topic'] = 0;
    // Better safe than sorry.
    if (isset($_SESSION['topicseen_cache'][$topicOptions['board']])) {
        $_SESSION['topicseen_cache'][$topicOptions['board']]--;
    }
    // Update all the stats so everyone knows about this new topic and message.
    if (false === $automerge_posts) {
        updateStats('message', true, $msg_to_update);
    }
    // Update the last message on the board assuming it's approved AND the topic is.
    if ($msgOptions['approved']) {
        updateLastMessages($topicOptions['board'], $new_topic || !empty($topicOptions['is_approved']) ? $msg_to_update : 0);
    }
    // Clear recent posts cache
    CacheAPI::clearCacheByPrefix('boardindex-latest_posts');
    // Alright, done now... we can abort now, I guess... at least this much is done.
    ignore_user_abort($previous_ignore_user_abort);
    // Success.
    return true;
}
Exemple #15
0
/**
 * Check if the number of users online is a record and store it.
 * @param int $total_users_online
 */
function trackStatsUsersOnline($total_users_online)
{
    global $modSettings, $smcFunc;
    $settingsToUpdate = array();
    // More members on now than ever were?  Update it!
    if (!isset($modSettings['mostOnline']) || $total_users_online >= $modSettings['mostOnline']) {
        $settingsToUpdate = array('mostOnline' => $total_users_online, 'mostDate' => time());
    }
    $date = strftime('%Y-%m-%d', forum_time(false));
    // No entry exists for today yet?
    if (!isset($modSettings['mostOnlineUpdated']) || $modSettings['mostOnlineUpdated'] != $date) {
        $request = $smcFunc['db_query']('', '
			SELECT most_on
			FROM {db_prefix}log_activity
			WHERE date = {date:date}
			LIMIT 1', array('date' => $date));
        // The log_activity hasn't got an entry for today?
        if ($smcFunc['db_num_rows']($request) === 0) {
            $smcFunc['db_insert']('ignore', '{db_prefix}log_activity', array('date' => 'date', 'most_on' => 'int'), array($date, $total_users_online), array('date'));
        } else {
            list($modSettings['mostOnlineToday']) = $smcFunc['db_fetch_row']($request);
            if ($total_users_online > $modSettings['mostOnlineToday']) {
                trackStats(array('most_on' => $total_users_online));
            }
            $total_users_online = max($total_users_online, $modSettings['mostOnlineToday']);
        }
        $smcFunc['db_free_result']($request);
        $settingsToUpdate['mostOnlineUpdated'] = $date;
        $settingsToUpdate['mostOnlineToday'] = $total_users_online;
    } elseif ($total_users_online > $modSettings['mostOnlineToday']) {
        trackStats(array('most_on' => $total_users_online));
        $settingsToUpdate['mostOnlineToday'] = $total_users_online;
    }
    if (!empty($settingsToUpdate)) {
        updateSettings($settingsToUpdate);
    }
}
Exemple #16
0
function registerMember(&$regOptions, $return_errors = false)
{
    global $scripturl, $txt, $modSettings, $context, $sourcedir;
    global $user_info, $options, $settings, $smcFunc;
    loadLanguage('Login');
    // We'll need some external functions.
    require_once $sourcedir . '/lib/Subs-Auth.php';
    require_once $sourcedir . '/lib/Subs-Post.php';
    // Put any errors in here.
    $reg_errors = array();
    // Registration from the admin center, let them sweat a little more.
    if ($regOptions['interface'] == 'admin') {
        is_not_guest();
        isAllowedTo('moderate_forum');
    } elseif ($regOptions['interface'] == 'guest') {
        // You cannot register twice...
        if (empty($user_info['is_guest'])) {
            redirectexit();
        }
        // Make sure they didn't just register with this session.
        if (!empty($_SESSION['just_registered']) && empty($modSettings['disableRegisterCheck'])) {
            fatal_lang_error('register_only_once', false);
        }
    }
    // What method of authorization are we going to use?
    if (empty($regOptions['auth_method']) || !in_array($regOptions['auth_method'], array('password', 'openid'))) {
        if (!empty($regOptions['openid'])) {
            $regOptions['auth_method'] = 'openid';
        } else {
            $regOptions['auth_method'] = 'password';
        }
    }
    // No name?!  How can you register with no name?
    if (empty($regOptions['username'])) {
        $reg_errors[] = array('lang', 'need_username');
    }
    // Spaces and other odd characters are evil...
    $regOptions['username'] = preg_replace('~[\\t\\n\\r\\x0B\\0' . ($context['server']['complex_preg_chars'] ? '\\x{A0}' : " ") . ']+~u', ' ', $regOptions['username']);
    // Don't use too long a name.
    if (commonAPI::strlen($regOptions['username']) > 25) {
        $reg_errors[] = array('lang', 'error_long_name');
    }
    // Only these characters are permitted.
    if (preg_match('~[<>&"\'=\\\\]~', preg_replace('~&#(?:\\d{1,7}|x[0-9a-fA-F]{1,6});~', '', $regOptions['username'])) != 0 || $regOptions['username'] == '_' || $regOptions['username'] == '|' || strpos($regOptions['username'], '[code') !== false || strpos($regOptions['username'], '[/code') !== false) {
        $reg_errors[] = array('lang', 'error_invalid_characters_username');
    }
    if (commonAPI::strtolower($regOptions['username']) === commonAPI::strtolower($txt['guest_title'])) {
        $reg_errors[] = array('lang', 'username_reserved', 'general', array($txt['guest_title']));
    }
    // !!! Separate the sprintf?
    if (empty($regOptions['email']) || preg_match('~^[0-9A-Za-z=_+\\-/][0-9A-Za-z=_\'+\\-/\\.]*@[\\w\\-]+(\\.[\\w\\-]+)*(\\.[\\w]{2,6})$~', $regOptions['email']) === 0 || strlen($regOptions['email']) > 255) {
        $reg_errors[] = array('done', sprintf($txt['valid_email_needed'], commonAPI::htmlspecialchars($regOptions['username'])));
    }
    if (!empty($regOptions['check_reserved_name']) && isReservedName($regOptions['username'], 0, false)) {
        if ($regOptions['password'] == 'chocolate cake') {
            $reg_errors[] = array('done', 'Sorry, I don\'t take bribes... you\'ll need to come up with a different name.');
        }
        $reg_errors[] = array('done', '(' . htmlspecialchars($regOptions['username']) . ') ' . $txt['name_in_use']);
    }
    // Generate a validation code if it's supposed to be emailed.
    $validation_code = '';
    if ($regOptions['require'] == 'activation') {
        $validation_code = generateValidationCode();
    }
    // If you haven't put in a password generate one.
    if ($regOptions['interface'] == 'admin' && $regOptions['password'] == '' && $regOptions['auth_method'] == 'password') {
        mt_srand(time() + 1277);
        $regOptions['password'] = generateValidationCode();
        $regOptions['password_check'] = $regOptions['password'];
    } elseif ($regOptions['password'] != $regOptions['password_check'] && $regOptions['auth_method'] == 'password') {
        $reg_errors[] = array('lang', 'passwords_dont_match');
    }
    // That's kind of easy to guess...
    if ($regOptions['password'] == '') {
        if ($regOptions['auth_method'] == 'password') {
            $reg_errors[] = array('lang', 'no_password');
        } else {
            $regOptions['password'] = sha1(mt_rand());
        }
    }
    // Now perform hard password validation as required.
    if (!empty($regOptions['check_password_strength'])) {
        $passwordError = validatePassword($regOptions['password'], $regOptions['username'], array($regOptions['email']));
        // Password isn't legal?
        if ($passwordError != null) {
            $reg_errors[] = array('lang', 'profile_error_password_' . $passwordError);
        }
    }
    // If they are using an OpenID that hasn't been verified yet error out.
    // !!! Change this so they can register without having to attempt a login first
    if ($regOptions['auth_method'] == 'openid' && (empty($_SESSION['openid']['verified']) || $_SESSION['openid']['openid_uri'] != $regOptions['openid'])) {
        $reg_errors[] = array('lang', 'openid_not_verified');
    }
    // You may not be allowed to register this email.
    if (!empty($regOptions['check_email_ban'])) {
        isBannedEmail($regOptions['email'], 'cannot_register', $txt['ban_register_prohibited']);
    }
    // Check if the email address is in use.
    $request = smf_db_query('
		SELECT id_member
		FROM {db_prefix}members
		WHERE email_address = {string:email_address}
			OR email_address = {string:username}
		LIMIT 1', array('email_address' => $regOptions['email'], 'username' => $regOptions['username']));
    // !!! Separate the sprintf?
    if (mysql_num_rows($request) != 0) {
        $reg_errors[] = array('lang', 'email_in_use', false, array(htmlspecialchars($regOptions['email'])));
    }
    mysql_free_result($request);
    // If we found any errors we need to do something about it right away!
    foreach ($reg_errors as $key => $error) {
        /* Note for each error:
        			0 = 'lang' if it's an index, 'done' if it's clear text.
        			1 = The text/index.
        			2 = Whether to log.
        			3 = sprintf data if necessary. */
        if ($error[0] == 'lang') {
            loadLanguage('Errors');
        }
        $message = $error[0] == 'lang' ? empty($error[3]) ? $txt[$error[1]] : vsprintf($txt[$error[1]], $error[3]) : $error[1];
        // What to do, what to do, what to do.
        if ($return_errors) {
            if (!empty($error[2])) {
                log_error($message, $error[2]);
            }
            $reg_errors[$key] = $message;
        } else {
            fatal_error($message, empty($error[2]) ? false : $error[2]);
        }
    }
    // If there's any errors left return them at once!
    if (!empty($reg_errors)) {
        return $reg_errors;
    }
    $reservedVars = 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');
    // Can't change reserved vars.
    if (isset($regOptions['theme_vars']) && array_intersect($regOptions['theme_vars'], $reservedVars) != array()) {
        fatal_lang_error('no_theme');
    }
    // Some of these might be overwritten. (the lower ones that are in the arrays below.)
    $regOptions['register_vars'] = array('member_name' => $regOptions['username'], 'email_address' => $regOptions['email'], 'passwd' => sha1(strtolower($regOptions['username']) . $regOptions['password']), 'password_salt' => substr(md5(mt_rand()), 0, 4), 'posts' => 0, 'date_registered' => time(), 'member_ip' => $regOptions['interface'] == 'admin' ? '127.0.0.1' : $user_info['ip'], 'member_ip2' => $regOptions['interface'] == 'admin' ? '127.0.0.1' : $_SERVER['BAN_CHECK_IP'], 'validation_code' => $validation_code, 'real_name' => $regOptions['username'], 'personal_text' => $modSettings['default_personal_text'], 'pm_email_notify' => 1, 'id_theme' => 0, 'id_post_group' => 4, 'lngfile' => '', 'buddy_list' => '', 'pm_ignore_list' => '', 'message_labels' => '', 'location' => '', 'time_format' => '', 'signature' => '', 'avatar' => '', 'usertitle' => '', 'secret_question' => '', 'secret_answer' => '', 'additional_groups' => '', 'ignore_boards' => '', 'smiley_set' => '', 'openid_uri' => !empty($regOptions['openid']) ? $regOptions['openid'] : '');
    // Setup the activation status on this new account so it is correct - firstly is it an under age account?
    if ($regOptions['require'] == 'coppa') {
        $regOptions['register_vars']['is_activated'] = 5;
        // !!! This should be changed.  To what should be it be changed??
        $regOptions['register_vars']['validation_code'] = '';
    } elseif ($regOptions['require'] == 'nothing') {
        $regOptions['register_vars']['is_activated'] = 1;
    } elseif ($regOptions['require'] == 'activation') {
        $regOptions['register_vars']['is_activated'] = 0;
    } else {
        $regOptions['register_vars']['is_activated'] = 3;
    }
    if (isset($regOptions['memberGroup'])) {
        // Make sure the id_group will be valid, if this is an administator.
        $regOptions['register_vars']['id_group'] = $regOptions['memberGroup'] == 1 && !allowedTo('admin_forum') ? 0 : $regOptions['memberGroup'];
        // Check if this group is assignable.
        $unassignableGroups = array(-1, 3);
        $request = smf_db_query('
			SELECT id_group
			FROM {db_prefix}membergroups
			WHERE min_posts != {int:min_posts}' . (allowedTo('admin_forum') ? '' : '
				OR group_type = {int:is_protected}'), array('min_posts' => -1, 'is_protected' => 1));
        while ($row = mysql_fetch_assoc($request)) {
            $unassignableGroups[] = $row['id_group'];
        }
        mysql_free_result($request);
        if (in_array($regOptions['register_vars']['id_group'], $unassignableGroups)) {
            $regOptions['register_vars']['id_group'] = 0;
        }
    }
    // Integrate optional member settings to be set.
    if (!empty($regOptions['extra_register_vars'])) {
        foreach ($regOptions['extra_register_vars'] as $var => $value) {
            $regOptions['register_vars'][$var] = $value;
        }
    }
    // Integrate optional user theme options to be set.
    $theme_vars = array();
    if (!empty($regOptions['theme_vars'])) {
        foreach ($regOptions['theme_vars'] as $var => $value) {
            $theme_vars[$var] = $value;
        }
    }
    // Call an optional function to validate the users' input.
    HookAPI::callHook('integrate_register', array(&$regOptions, &$theme_vars));
    // Right, now let's prepare for insertion.
    $knownInts = array('date_registered', 'posts', 'id_group', 'last_login', 'instant_messages', 'unread_messages', 'new_pm', 'pm_prefs', 'gender', 'hide_email', 'show_online', 'pm_email_notify', 'karma_good', 'karma_bad', 'notify_announcements', 'notify_send_body', 'notify_regularity', 'notify_types', 'id_theme', 'is_activated', 'id_msg_last_visit', 'id_post_group', 'total_time_logged_in', 'warning');
    $knownFloats = array('time_offset');
    $column_names = array();
    $values = array();
    foreach ($regOptions['register_vars'] as $var => $val) {
        $type = 'string';
        if (in_array($var, $knownInts)) {
            $type = 'int';
        } elseif (in_array($var, $knownFloats)) {
            $type = 'float';
        } elseif ($var == 'birthdate') {
            $type = 'date';
        }
        $column_names[$var] = $type;
        $values[$var] = $val;
    }
    // Register them into the database.
    smf_db_insert('', '{db_prefix}members', $column_names, $values, array('id_member'));
    $memberID = smf_db_insert_id('{db_prefix}members', 'id_member');
    // Update the number of members and latest member's info - and pass the name, but remove the 's.
    if ($regOptions['register_vars']['is_activated'] == 1) {
        updateStats('member', $memberID, $regOptions['register_vars']['real_name']);
    } else {
        updateStats('member');
    }
    // Theme variables too?
    if (!empty($theme_vars)) {
        $inserts = array();
        foreach ($theme_vars as $var => $val) {
            $inserts[] = array($memberID, $var, $val);
        }
        smf_db_insert('insert', '{db_prefix}themes', array('id_member' => 'int', 'variable' => 'string-255', 'value' => 'string-65534'), $inserts, array('id_member', 'variable'));
    }
    // If it's enabled, increase the registrations for today.
    trackStats(array('registers' => '+'));
    // Administrative registrations are a bit different...
    if ($regOptions['interface'] == 'admin') {
        if ($regOptions['require'] == 'activation') {
            $email_message = 'admin_register_activate';
        } elseif (!empty($regOptions['send_welcome_email'])) {
            $email_message = 'admin_register_immediate';
        }
        if (isset($email_message)) {
            $replacements = array('REALNAME' => $regOptions['register_vars']['real_name'], 'USERNAME' => $regOptions['username'], 'PASSWORD' => $regOptions['password'], 'FORGOTPASSWORDLINK' => $scripturl . '?action=reminder', 'ACTIVATIONLINK' => $scripturl . '?action=activate;u=' . $memberID . ';code=' . $validation_code, 'ACTIVATIONLINKWITHOUTCODE' => $scripturl . '?action=activate;u=' . $memberID, 'ACTIVATIONCODE' => $validation_code);
            $emaildata = loadEmailTemplate($email_message, $replacements);
            sendmail($regOptions['email'], $emaildata['subject'], $emaildata['body'], null, null, false, 0);
        }
        // All admins are finished here.
        return $memberID;
    }
    // Can post straight away - welcome them to your fantastic community...
    if ($regOptions['require'] == 'nothing') {
        if (!empty($regOptions['send_welcome_email'])) {
            $replacements = array('REALNAME' => $regOptions['register_vars']['real_name'], 'USERNAME' => $regOptions['username'], 'PASSWORD' => $regOptions['password'], 'FORGOTPASSWORDLINK' => $scripturl . '?action=reminder', 'OPENID' => !empty($regOptions['openid']) ? $regOptions['openid'] : '');
            $emaildata = loadEmailTemplate('register_' . ($regOptions['auth_method'] == 'openid' ? 'openid_' : '') . 'immediate', $replacements);
            sendmail($regOptions['email'], $emaildata['subject'], $emaildata['body'], null, null, false, 0);
        }
        // Send admin their notification.
        adminNotify('standard', $memberID, $regOptions['username']);
    } elseif ($regOptions['require'] == 'activation' || $regOptions['require'] == 'coppa') {
        $replacements = array('REALNAME' => $regOptions['register_vars']['real_name'], 'USERNAME' => $regOptions['username'], 'PASSWORD' => $regOptions['password'], 'FORGOTPASSWORDLINK' => $scripturl . '?action=reminder', 'OPENID' => !empty($regOptions['openid']) ? $regOptions['openid'] : '');
        if ($regOptions['require'] == 'activation') {
            $replacements += array('ACTIVATIONLINK' => $scripturl . '?action=activate;u=' . $memberID . ';code=' . $validation_code, 'ACTIVATIONLINKWITHOUTCODE' => $scripturl . '?action=activate;u=' . $memberID, 'ACTIVATIONCODE' => $validation_code);
        } else {
            $replacements += array('COPPALINK' => $scripturl . '?action=coppa;u=' . $memberID);
        }
        $emaildata = loadEmailTemplate('register_' . ($regOptions['auth_method'] == 'openid' ? 'openid_' : '') . ($regOptions['require'] == 'activation' ? 'activate' : 'coppa'), $replacements);
        sendmail($regOptions['email'], $emaildata['subject'], $emaildata['body'], null, null, false, 0);
    } else {
        $replacements = array('REALNAME' => $regOptions['register_vars']['real_name'], 'USERNAME' => $regOptions['username'], 'PASSWORD' => $regOptions['password'], 'FORGOTPASSWORDLINK' => $scripturl . '?action=reminder', 'OPENID' => !empty($regOptions['openid']) ? $regOptions['openid'] : '');
        $emaildata = loadEmailTemplate('register_' . ($regOptions['auth_method'] == 'openid' ? 'openid_' : '') . 'pending', $replacements);
        sendmail($regOptions['email'], $emaildata['subject'], $emaildata['body'], null, null, false, 0);
        // Admin gets informed here...
        adminNotify('approval', $memberID, $regOptions['username']);
    }
    // Okay, they're for sure registered... make sure the session is aware of this for security. (Just married :P!)
    $_SESSION['just_registered'] = 1;
    return $memberID;
}
Exemple #17
0
function smf_main()
{
    global $modSettings, $settings, $user_info, $board, $topic, $maintenance, $sourcedir;
    // Special case: session keep-alive.
    if (isset($_GET['action']) && $_GET['action'] == 'keepalive') {
        die;
    }
    // Load the user's cookie (or set as guest) and load their settings.
    loadUserSettings();
    // Load the current board's information.
    loadBoard();
    // Load the current theme.  (note that ?theme=1 will also work, may be used for guest theming.)
    loadTheme();
    // Check if the user should be disallowed access.
    //	is_not_banned();
    // Load the current user's permissions.
    loadPermissions();
    // Do some logging, unless this is an attachment, avatar, theme option or XML feed.
    if (empty($_REQUEST['action']) || !in_array($_REQUEST['action'], array('dlattach', 'jsoption', '.xml'))) {
        // Log this user as online.
        writeLog();
        // Track forum statistics and hits...?
        if (!empty($modSettings['hitStats'])) {
            trackStats(array('hits' => '+'));
        }
    }
    // Is the forum in maintenance mode? (doesn't apply to administrators.)
    if (!empty($maintenance) && !allowedTo('admin_forum')) {
        // You can only login.... otherwise, you're getting the "maintenance mode" display.
        if (isset($_REQUEST['action']) && ($_REQUEST['action'] == 'login2' || $_REQUEST['action'] == 'logout')) {
            require_once $sourcedir . '/LogInOut.php';
            return $_REQUEST['action'] == 'login2' ? 'Login2' : 'Logout';
        } else {
            require_once $sourcedir . '/Subs-Auth.php';
            return 'InMaintenance';
        }
    } elseif (empty($modSettings['allow_guestAccess']) && $user_info['is_guest'] && (!isset($_REQUEST['action']) || !in_array($_REQUEST['action'], array('coppa', 'login', 'login2', 'register', 'register2', 'reminder', 'activate', 'smstats', 'help', 'verificationcode')))) {
        require_once $sourcedir . '/Subs-Auth.php';
        return 'KickGuest';
    } elseif (empty($_REQUEST['action'])) {
        // Action and board are both empty... BoardIndex!
        if (empty($board) && empty($topic)) {
            require_once $sourcedir . '/BoardIndex.php';
            return 'BoardIndex';
        } elseif (empty($topic)) {
            require_once $sourcedir . '/MessageIndex.php';
            return 'MessageIndex';
        } else {
            require_once $sourcedir . '/Display.php';
            return 'Display';
        }
    }
    // Here's the monstrous $_REQUEST['action'] array - $_REQUEST['action'] => array($file, $function).
    $actionArray = array('activate' => array('Register.php', 'Activate'), 'admin' => array('Admin.php', 'Admin'), 'announce' => array('Post.php', 'AnnounceTopic'), 'ban' => array('ManageBans.php', 'Ban'), 'boardrecount' => array('Admin.php', 'AdminBoardRecount'), 'buddy' => array('Subs-Members.php', 'BuddyListToggle'), 'calendar' => array('Calendar.php', 'CalendarMain'), 'cleanperms' => array('Admin.php', 'CleanupPermissions'), 'collapse' => array('Subs-Boards.php', 'CollapseCategory'), 'convertentities' => array('Admin.php', 'ConvertEntities'), 'convertutf8' => array('Admin.php', 'ConvertUtf8'), 'coppa' => array('Register.php', 'CoppaForm'), 'deletemsg' => array('RemoveTopic.php', 'DeleteMessage'), 'detailedversion' => array('Admin.php', 'VersionDetail'), 'display' => array('Display.php', 'Display'), 'dlattach' => array('Display.php', 'Download'), 'dumpdb' => array('DumpDatabase.php', 'DumpDatabase2'), 'editpoll' => array('Poll.php', 'EditPoll'), 'editpoll2' => array('Poll.php', 'EditPoll2'), 'featuresettings' => array('ModSettings.php', 'ModifyFeatureSettings'), 'featuresettings2' => array('ModSettings.php', 'ModifyFeatureSettings2'), 'findmember' => array('Subs-Auth.php', 'JSMembers'), 'help' => array('Help.php', 'ShowHelp'), 'helpadmin' => array('Help.php', 'ShowAdminHelp'), 'im' => array('PersonalMessage.php', 'MessageMain'), 'jsoption' => array('Themes.php', 'SetJavaScript'), 'jsmodify' => array('Post.php', 'JavaScriptModify'), 'lock' => array('LockTopic.php', 'LockTopic'), 'lockVoting' => array('Poll.php', 'LockVoting'), 'login' => array('LogInOut.php', 'Login'), 'login2' => array('LogInOut.php', 'Login2'), 'logout' => array('LogInOut.php', 'Logout'), 'maintain' => array('Admin.php', 'Maintenance'), 'manageattachments' => array('ManageAttachments.php', 'ManageAttachments'), 'manageboards' => array('ManageBoards.php', 'ManageBoards'), 'managecalendar' => array('ManageCalendar.php', 'ManageCalendar'), 'managesearch' => array('ManageSearch.php', 'ManageSearch'), 'markasread' => array('Subs-Boards.php', 'MarkRead'), 'membergroups' => array('ManageMembergroups.php', 'ModifyMembergroups'), 'mergetopics' => array('SplitTopics.php', 'MergeTopics'), 'mlist' => array('Memberlist.php', 'Memberlist'), 'modifycat' => array('ManageBoards.php', 'ModifyCat'), 'modifykarma' => array('Karma.php', 'ModifyKarma'), 'modlog' => array('Modlog.php', 'ViewModlog'), 'movetopic' => array('MoveTopic.php', 'MoveTopic'), 'movetopic2' => array('MoveTopic.php', 'MoveTopic2'), 'news' => array('ManageNews.php', 'ManageNews'), 'notify' => array('Notify.php', 'Notify'), 'notifyboard' => array('Notify.php', 'BoardNotify'), 'optimizetables' => array('Admin.php', 'OptimizeTables'), 'packageget' => array('PackageGet.php', 'PackageGet'), 'packages' => array('Packages.php', 'Packages'), 'permissions' => array('ManagePermissions.php', 'ModifyPermissions'), 'pgdownload' => array('PackageGet.php', 'PackageGet'), 'pm' => array('PersonalMessage.php', 'MessageMain'), 'post' => array('Post.php', 'Post'), 'post2' => array('Post.php', 'Post2'), 'postsettings' => array('ManagePosts.php', 'ManagePostSettings'), 'printpage' => array('Printpage.php', 'PrintTopic'), 'profile' => array('Profile.php', 'ModifyProfile'), 'profile2' => array('Profile.php', 'ModifyProfile2'), 'quotefast' => array('Post.php', 'QuoteFast'), 'quickmod' => array('Subs-Boards.php', 'QuickModeration'), 'quickmod2' => array('Subs-Boards.php', 'QuickModeration2'), 'recent' => array('Recent.php', 'RecentPosts'), 'regcenter' => array('ManageRegistration.php', 'RegCenter'), 'register' => array('Register.php', 'Register'), 'register2' => array('Register.php', 'Register2'), 'reminder' => array('Reminder.php', 'RemindMe'), 'removetopic2' => array('RemoveTopic.php', 'RemoveTopic2'), 'removeoldtopics2' => array('RemoveTopic.php', 'RemoveOldTopics2'), 'removepoll' => array('Poll.php', 'RemovePoll'), 'repairboards' => array('RepairBoards.php', 'RepairBoards'), 'reporttm' => array('SendTopic.php', 'ReportToModerator'), 'reports' => array('Reports.php', 'ReportsMain'), 'requestmembers' => array('Subs-Auth.php', 'RequestMembers'), 'search' => array('Search.php', 'PlushSearch1'), 'search2' => array('Search.php', 'PlushSearch2'), 'sendtopic' => array('SendTopic.php', 'SendTopic'), 'serversettings' => array('ManageServer.php', 'ModifySettings'), 'serversettings2' => array('ManageServer.php', 'ModifySettings2'), 'smileys' => array('ManageSmileys.php', 'ManageSmileys'), 'smstats' => array('Stats.php', 'SMStats'), 'spellcheck' => array('Subs-Post.php', 'SpellCheck'), 'splittopics' => array('SplitTopics.php', 'SplitTopics'), 'stats' => array('Stats.php', 'DisplayStats'), 'sticky' => array('LockTopic.php', 'Sticky'), 'theme' => array('Themes.php', 'ThemesMain'), 'trackip' => array('Profile.php', 'trackIP'), 'about:mozilla' => array('Karma.php', 'BookOfUnknown'), 'about:unknown' => array('Karma.php', 'BookOfUnknown'), 'unread' => array('Recent.php', 'UnreadTopics'), 'unreadreplies' => array('Recent.php', 'UnreadTopics'), 'viewErrorLog' => array('ManageErrors.php', 'ViewErrorLog'), 'viewmembers' => array('ManageMembers.php', 'ViewMembers'), 'viewprofile' => array('Profile.php', 'ModifyProfile'), 'verificationcode' => array('Register.php', 'VerificationCode'), 'vote' => array('Poll.php', 'Vote'), 'viewquery' => array('ViewQuery.php', 'ViewQuery'), 'who' => array('Who.php', 'Who'), '.xml' => array('News.php', 'ShowXmlFeed'));
    // Get the function and file to include - if it's not there, do the board index.
    if (!isset($_REQUEST['action']) || !isset($actionArray[$_REQUEST['action']])) {
        // Catch the action with the theme?
        if (!empty($settings['catch_action'])) {
            require_once $sourcedir . '/Themes.php';
            return 'WrapAction';
        }
        // Fall through to the board index then...
        require_once $sourcedir . '/BoardIndex.php';
        return 'BoardIndex';
    }
    // Otherwise, it was set - so let's go to that action.
    require_once $sourcedir . '/' . $actionArray[$_REQUEST['action']][0];
    return $actionArray[$_REQUEST['action']][1];
}
function smf_main()
{
    global $modSettings, $settings, $user_info, $board, $topic, $board_info, $maintenance, $sourcedir;
    // Special case: session keep-alive, output a transparent pixel.
    if (isset($_GET['action']) && $_GET['action'] == 'keepalive') {
        header('Content-Type: image/gif');
        die("GIF89a€!ù,D;");
    }
    // Load the user's cookie (or set as guest) and load their settings.
    loadUserSettings();
    // Load the current board's information.
    loadBoard();
    // Load the current user's permissions.
    loadPermissions();
    // Attachments don't require the entire theme to be loaded.
    if (isset($_REQUEST['action']) && $_REQUEST['action'] == 'dlattach' && (!empty($modSettings['allow_guestAccess']) && $user_info['is_guest'])) {
        detectBrowser();
    } else {
        loadTheme();
    }
    // Check if the user should be disallowed access.
    is_not_banned();
    // If we are in a topic and don't have permission to approve it then duck out now.
    if (!empty($topic) && empty($board_info['cur_topic_approved']) && !allowedTo('approve_posts') && ($user_info['id'] != $board_info['cur_topic_starter'] || $user_info['is_guest'])) {
        fatal_lang_error('not_a_topic', false);
    }
    // Do some logging, unless this is an attachment, avatar, toggle of editor buttons, theme option, XML feed etc.
    if (empty($_REQUEST['action']) || !in_array($_REQUEST['action'], array('dlattach', 'findmember', 'jseditor', 'jsoption', 'requestmembers', 'smstats', '.xml', 'xmlhttp', 'verificationcode', 'viewquery', 'viewsmfile'))) {
        // Log this user as online.
        writeLog();
        // Don't track stats of portal xml actions.
        if (empty($_REQUEST['action']) || $_REQUEST['action'] != 'portal' || !isset($_GET['xml'])) {
            // Track forum statistics and hits...?
            if (!empty($modSettings['hitStats'])) {
                trackStats(array('hits' => '+'));
            }
        }
    }
    // Load SimplePortal.
    sportal_init();
    // Is the forum in maintenance mode? (doesn't apply to administrators.)
    if (!empty($maintenance) && !allowedTo('admin_forum')) {
        // You can only login.... otherwise, you're getting the "maintenance mode" display.
        if (isset($_REQUEST['action']) && ($_REQUEST['action'] == 'login2' || $_REQUEST['action'] == 'logout')) {
            require_once $sourcedir . '/LogInOut.php';
            return $_REQUEST['action'] == 'login2' ? 'Login2' : 'Logout';
        } else {
            require_once $sourcedir . '/Subs-Auth.php';
            return 'InMaintenance';
        }
    } elseif (empty($modSettings['allow_guestAccess']) && $user_info['is_guest'] && (!isset($_REQUEST['action']) || !in_array($_REQUEST['action'], array('coppa', 'login', 'login2', 'register', 'register2', 'reminder', 'activate', 'help', 'smstats', 'mailq', 'verificationcode', 'openidreturn')))) {
        require_once $sourcedir . '/Subs-Auth.php';
        return 'KickGuest';
    } elseif (empty($_REQUEST['action'])) {
        // Go catch it boy! Catch it!
        $sp_action = sportal_catch_action();
        if ($sp_action) {
            return $sp_action;
        }
        // Action and board are both empty... BoardIndex!
        if (empty($board) && empty($topic)) {
            require_once $sourcedir . '/BoardIndex.php';
            return 'BoardIndex';
        } elseif (empty($topic)) {
            require_once $sourcedir . '/MessageIndex.php';
            return 'MessageIndex';
        } else {
            require_once $sourcedir . '/Display.php';
            return 'Display';
        }
    }
    // Here's the monstrous $_REQUEST['action'] array - $_REQUEST['action'] => array($file, $function).
    $actionArray = array('activate' => array('Register.php', 'Activate'), 'admin' => array('Admin.php', 'AdminMain'), 'announce' => array('Post.php', 'AnnounceTopic'), 'attachapprove' => array('ManageAttachments.php', 'ApproveAttach'), 'buddy' => array('Subs-Members.php', 'BuddyListToggle'), 'calendar' => array('Calendar.php', 'CalendarMain'), 'clock' => array('Calendar.php', 'clock'), 'collapse' => array('BoardIndex.php', 'CollapseCategory'), 'coppa' => array('Register.php', 'CoppaForm'), 'credits' => array('Who.php', 'Credits'), 'deletemsg' => array('RemoveTopic.php', 'DeleteMessage'), 'display' => array('Display.php', 'Display'), 'dlattach' => array('Display.php', 'Download'), 'editpoll' => array('Poll.php', 'EditPoll'), 'editpoll2' => array('Poll.php', 'EditPoll2'), 'emailuser' => array('SendTopic.php', 'EmailUser'), 'findmember' => array('Subs-Auth.php', 'JSMembers'), 'forum' => array('BoardIndex.php', 'BoardIndex'), 'portal' => array('PortalMain.php', 'sportal_main'), 'groups' => array('Groups.php', 'Groups'), 'help' => array('Help.php', 'ShowHelp'), 'helpadmin' => array('Help.php', 'ShowAdminHelp'), 'im' => array('PersonalMessage.php', 'MessageMain'), 'jseditor' => array('Subs-Editor.php', 'EditorMain'), 'jsmodify' => array('Post.php', 'JavaScriptModify'), 'jsoption' => array('Themes.php', 'SetJavaScript'), 'lock' => array('LockTopic.php', 'LockTopic'), 'lockvoting' => array('Poll.php', 'LockVoting'), 'login' => array('LogInOut.php', 'Login'), 'login2' => array('LogInOut.php', 'Login2'), 'logout' => array('LogInOut.php', 'Logout'), 'markasread' => array('Subs-Boards.php', 'MarkRead'), 'mergetopics' => array('SplitTopics.php', 'MergeTopics'), 'mlist' => array('Memberlist.php', 'Memberlist'), 'moderate' => array('ModerationCenter.php', 'ModerationMain'), 'modifycat' => array('ManageBoards.php', 'ModifyCat'), 'modifykarma' => array('Karma.php', 'ModifyKarma'), 'movetopic' => array('MoveTopic.php', 'MoveTopic'), 'movetopic2' => array('MoveTopic.php', 'MoveTopic2'), 'notify' => array('Notify.php', 'Notify'), 'notifyboard' => array('Notify.php', 'BoardNotify'), 'openidreturn' => array('Subs-OpenID.php', 'smf_openID_return'), 'pm' => array('PersonalMessage.php', 'MessageMain'), 'post' => array('Post.php', 'Post'), 'post2' => array('Post.php', 'Post2'), 'printpage' => array('Printpage.php', 'PrintTopic'), 'profile' => array('Profile.php', 'ModifyProfile'), 'quotefast' => array('Post.php', 'QuoteFast'), 'quickmod' => array('MessageIndex.php', 'QuickModeration'), 'quickmod2' => array('Display.php', 'QuickInTopicModeration'), 'recent' => array('Recent.php', 'RecentPosts'), 'register' => array('Register.php', 'Register'), 'register2' => array('Register.php', 'Register2'), 'reminder' => array('Reminder.php', 'RemindMe'), 'removepoll' => array('Poll.php', 'RemovePoll'), 'removetopic2' => array('RemoveTopic.php', 'RemoveTopic2'), 'reporttm' => array('SendTopic.php', 'ReportToModerator'), 'requestmembers' => array('Subs-Auth.php', 'RequestMembers'), 'restoretopic' => array('RemoveTopic.php', 'RestoreTopic'), 'search' => array('Search.php', 'PlushSearch1'), 'search2' => array('Search.php', 'PlushSearch2'), 'sendtopic' => array('SendTopic.php', 'EmailUser'), 'smstats' => array('Stats.php', 'SMStats'), 'suggest' => array('Subs-Editor.php', 'AutoSuggestHandler'), 'spellcheck' => array('Subs-Post.php', 'SpellCheck'), 'splittopics' => array('SplitTopics.php', 'SplitTopics'), 'stats' => array('Stats.php', 'DisplayStats'), 'sticky' => array('LockTopic.php', 'Sticky'), 'theme' => array('Themes.php', 'ThemesMain'), 'trackip' => array('Profile-View.php', 'trackIP'), 'about:mozilla' => array('Karma.php', 'BookOfUnknown'), 'about:unknown' => array('Karma.php', 'BookOfUnknown'), 'unread' => array('Recent.php', 'UnreadTopics'), 'unreadreplies' => array('Recent.php', 'UnreadTopics'), 'verificationcode' => array('Register.php', 'VerificationCode'), 'viewprofile' => array('Profile.php', 'ModifyProfile'), 'vote' => array('Poll.php', 'Vote'), 'viewquery' => array('ViewQuery.php', 'ViewQuery'), 'viewsmfile' => array('Admin.php', 'DisplayAdminFile'), 'who' => array('Who.php', 'Who'), '.xml' => array('News.php', 'ShowXmlFeed'), 'xmlhttp' => array('Xml.php', 'XMLhttpMain'));
    // Allow modifying $actionArray easily.
    call_integration_hook('integrate_actions', array(&$actionArray));
    if (!empty($context['disable_sp'])) {
        unset($actionArray['portal'], $actionArray['forum']);
    }
    // Get the function and file to include - if it's not there, do the board index.
    if (!isset($_REQUEST['action']) || !isset($actionArray[$_REQUEST['action']])) {
        // Catch the action with the theme?
        if (!empty($settings['catch_action'])) {
            require_once $sourcedir . '/Themes.php';
            return 'WrapAction';
        }
        // Fall through to the board index then...
        require_once $sourcedir . '/BoardIndex.php';
        return 'BoardIndex';
    }
    // Otherwise, it was set - so let's go to that action.
    require_once $sourcedir . '/' . $actionArray[$_REQUEST['action']][0];
    return $actionArray[$_REQUEST['action']][1];
}
<?php

require_once "../forum/SSI.php";
$_SESSION['login_url'] = 'http://www.simplywastingtime.com';
$_SESSION['logout_url'] = 'http://www.simplywastingtime.com';
trackStats(array('hits' => '+'));
trackStats();
include_once '../includes/member_database.php';
Exemple #20
0
function createPost(&$msgOptions, &$topicOptions, &$posterOptions)
{
    global $db_prefix, $user_info, $ID_MEMBER, $txt, $modSettings;
    // Set optional parameters to the default value.
    $msgOptions['icon'] = empty($msgOptions['icon']) ? 'xx' : $msgOptions['icon'];
    $msgOptions['smileys_enabled'] = !empty($msgOptions['smileys_enabled']);
    $msgOptions['attachments'] = empty($msgOptions['attachments']) ? array() : $msgOptions['attachments'];
    $topicOptions['id'] = empty($topicOptions['id']) ? 0 : (int) $topicOptions['id'];
    $topicOptions['poll'] = isset($topicOptions['poll']) ? (int) $topicOptions['poll'] : null;
    $topicOptions['lock_mode'] = isset($topicOptions['lock_mode']) ? $topicOptions['lock_mode'] : null;
    $topicOptions['sticky_mode'] = isset($topicOptions['sticky_mode']) ? $topicOptions['sticky_mode'] : null;
    $posterOptions['id'] = empty($posterOptions['id']) ? 0 : (int) $posterOptions['id'];
    $posterOptions['ip'] = empty($posterOptions['ip']) ? $user_info['ip2'] : $posterOptions['ip'];
    // If nothing was filled in as name/e-mail address, try the member table.
    if (!isset($posterOptions['name']) || $posterOptions['name'] == '' || empty($posterOptions['email']) && !empty($posterOptions['id'])) {
        if (empty($posterOptions['id'])) {
            $posterOptions['id'] = 0;
            $posterOptions['name'] = $txt[28];
            $posterOptions['email'] = '';
        } elseif ($posterOptions['id'] != $ID_MEMBER) {
            $request = db_query("\n\t\t\t\tSELECT memberName, emailAddress\n\t\t\t\tFROM {$db_prefix}members\n\t\t\t\tWHERE ID_MEMBER = {$posterOptions['id']}\n\t\t\t\tLIMIT 1", __FILE__, __LINE__);
            // Couldn't find the current poster?
            if (mysql_num_rows($request) == 0) {
                trigger_error('createPost(): Invalid member id ' . $posterOptions['id'], E_USER_NOTICE);
                $posterOptions['id'] = 0;
                $posterOptions['name'] = $txt[28];
                $posterOptions['email'] = '';
            } else {
                list($posterOptions['name'], $posterOptions['email']) = mysql_fetch_row($request);
            }
            mysql_free_result($request);
        } else {
            $posterOptions['name'] = $user_info['name'];
            $posterOptions['email'] = $user_info['email'];
        }
        $posterOptions['email'] = addslashes($posterOptions['email']);
    }
    // It's do or die time: forget any user aborts!
    $previous_ignore_user_abort = ignore_user_abort(true);
    $new_topic = empty($topicOptions['id']);
    // Insert the post.
    db_query("\n\t\tINSERT INTO {$db_prefix}messages\n\t\t\t(ID_BOARD, ID_TOPIC, ID_MEMBER, subject, body, posterName, posterEmail, posterTime,\n\t\t\tposterIP, smileysEnabled, modifiedName, icon)\n\t\tVALUES ({$topicOptions['board']}, {$topicOptions['id']}, {$posterOptions['id']}, SUBSTRING('{$msgOptions['subject']}', 1, 255), SUBSTRING('{$msgOptions['body']}', 1, 65534), SUBSTRING('{$posterOptions['name']}', 1, 255), SUBSTRING('{$posterOptions['email']}', 1, 255), " . time() . ",\n\t\t\tSUBSTRING('{$posterOptions['ip']}', 1, 255), " . ($msgOptions['smileys_enabled'] ? '1' : '0') . ", '', SUBSTRING('{$msgOptions['icon']}', 1, 16))", __FILE__, __LINE__);
    $msgOptions['id'] = db_insert_id();
    // Something went wrong creating the message...
    if (empty($msgOptions['id'])) {
        return false;
    }
    // Fix the attachments.
    if (!empty($msgOptions['attachments'])) {
        db_query("\n\t\t\tUPDATE {$db_prefix}attachments\n\t\t\tSET ID_MSG = {$msgOptions['id']}\n\t\t\tWHERE ID_ATTACH IN (" . implode(', ', $msgOptions['attachments']) . ')', __FILE__, __LINE__);
    }
    // Insert a new topic (if the topicID was left empty.
    if ($new_topic) {
        db_query("\n\t\t\tINSERT INTO {$db_prefix}topics\n\t\t\t\t(ID_BOARD, ID_MEMBER_STARTED, ID_MEMBER_UPDATED, ID_FIRST_MSG, ID_LAST_MSG, locked, isSticky, numViews, ID_POLL)\n\t\t\tVALUES ({$topicOptions['board']}, {$posterOptions['id']}, {$posterOptions['id']}, {$msgOptions['id']}, {$msgOptions['id']},\n\t\t\t\t" . ($topicOptions['lock_mode'] === null ? '0' : $topicOptions['lock_mode']) . ', ' . ($topicOptions['sticky_mode'] === null ? '0' : $topicOptions['sticky_mode']) . ", 0, " . ($topicOptions['poll'] === null ? '0' : $topicOptions['poll']) . ')', __FILE__, __LINE__);
        $topicOptions['id'] = db_insert_id();
        // The topic couldn't be created for some reason.
        if (empty($topicOptions['id'])) {
            // We should delete the post that did work, though...
            db_query("\n\t\t\t\tDELETE FROM {$db_prefix}messages\n\t\t\t\tWHERE ID_MSG = {$msgOptions['id']}\n\t\t\t\tLIMIT 1", __FILE__, __LINE__);
            return false;
        }
        // Fix the message with the topic.
        db_query("\n\t\t\tUPDATE {$db_prefix}messages\n\t\t\tSET ID_TOPIC = {$topicOptions['id']}\n\t\t\tWHERE ID_MSG = {$msgOptions['id']}\n\t\t\tLIMIT 1", __FILE__, __LINE__);
        // There's been a new topic AND a new post today.
        trackStats(array('topics' => '+', 'posts' => '+'));
        updateStats('topic', true);
        updateStats('subject', $topicOptions['id'], $msgOptions['subject']);
    } else {
        // Update the number of replies and the lock/sticky status.
        db_query("\n\t\t\tUPDATE {$db_prefix}topics\n\t\t\tSET\n\t\t\t\tID_MEMBER_UPDATED = {$posterOptions['id']}, ID_LAST_MSG = {$msgOptions['id']},\n\t\t\t\tnumReplies = numReplies + 1" . ($topicOptions['lock_mode'] === null ? '' : ",\n\t\t\t\tlocked = {$topicOptions['lock_mode']}") . ($topicOptions['sticky_mode'] === null ? '' : ",\n\t\t\t\tisSticky = {$topicOptions['sticky_mode']}") . "\n\t\t\tWHERE ID_TOPIC = {$topicOptions['id']}\n\t\t\tLIMIT 1", __FILE__, __LINE__);
        // One new post has been added today.
        trackStats(array('posts' => '+'));
    }
    // Creating is modifying...in a way.
    db_query("\n\t\tUPDATE {$db_prefix}messages\n\t\tSET ID_MSG_MODIFIED = {$msgOptions['id']}\n\t\tWHERE ID_MSG = {$msgOptions['id']}", __FILE__, __LINE__);
    // Increase the number of posts and topics on the board.
    db_query("\n\t\tUPDATE {$db_prefix}boards\n\t\tSET numPosts = numPosts + 1" . ($new_topic ? ', numTopics = numTopics + 1' : '') . "\n\t\tWHERE ID_BOARD = {$topicOptions['board']}\n\t\tLIMIT 1", __FILE__, __LINE__);
    // Mark inserted topic as read (only for the user calling this function).
    if (!empty($topicOptions['mark_as_read']) && !$user_info['is_guest']) {
        // Since it's likely they *read* it before replying, let's try an UPDATE first.
        if (!$new_topic) {
            db_query("\n\t\t\t\tUPDATE {$db_prefix}log_topics\n\t\t\t\tSET ID_MSG = {$msgOptions['id']} + 1\n\t\t\t\tWHERE ID_MEMBER = {$ID_MEMBER}\n\t\t\t\t\tAND ID_TOPIC = {$topicOptions['id']}\n\t\t\t\tLIMIT 1", __FILE__, __LINE__);
            $flag = db_affected_rows() != 0;
        }
        if (empty($flag)) {
            db_query("\n\t\t\t\tREPLACE INTO {$db_prefix}log_topics\n\t\t\t\t\t(ID_TOPIC, ID_MEMBER, ID_MSG)\n\t\t\t\tVALUES ({$topicOptions['id']}, {$ID_MEMBER}, {$msgOptions['id']} + 1)", __FILE__, __LINE__);
        }
    }
    // If there's a custom search index, it needs updating...
    if (!empty($modSettings['search_custom_index_config'])) {
        //$index_settings = unserialize($modSettings['search_custom_index_config']);
        $inserts = '';
        foreach (text2words(stripslashes($msgOptions['body']), 4, true) as $word) {
            $inserts .= "({$word}, {$msgOptions['id']}),\n";
        }
        if (!empty($inserts)) {
            db_query("\n\t\t\t\tINSERT IGNORE INTO {$db_prefix}log_search_words\n\t\t\t\t\t(ID_WORD, ID_MSG)\n\t\t\t\tVALUES\n\t\t\t\t\t" . substr($inserts, 0, -2), __FILE__, __LINE__);
        }
    }
    // Increase the post counter for the user that created the post.
    if (!empty($posterOptions['update_post_count']) && !empty($posterOptions['id'])) {
        // Are you the one that happened to create this post?
        if ($ID_MEMBER == $posterOptions['id']) {
            $user_info['posts']++;
        }
        updateMemberData($posterOptions['id'], array('posts' => '+'));
    }
    // They've posted, so they can make the view count go up one if they really want. (this is to keep views >= replies...)
    $_SESSION['last_read_topic'] = 0;
    // Better safe than sorry.
    if (isset($_SESSION['topicseen_cache'][$topicOptions['board']])) {
        $_SESSION['topicseen_cache'][$topicOptions['board']]--;
    }
    // Update all the stats so everyone knows about this new topic and message.
    updateStats('message', true, $msgOptions['id']);
    updateLastMessages($topicOptions['board'], $msgOptions['id']);
    // Alright, done now... we can abort now, I guess... at least this much is done.
    ignore_user_abort($previous_ignore_user_abort);
    // Success.
    return true;
}
Exemple #21
0
/**
 * Ends execution.
 *
 * What it does:
 * - Takes care of template loading and remembering the previous URL.
 * - Calls ob_start() with ob_sessrewrite to fix URLs if necessary.
 *
 * @param bool|null $header = null
 * @param bool|null $do_footer = null
 * @param bool $from_index = false
 * @param bool $from_fatal_error = false
 */
function obExit($header = null, $do_footer = null, $from_index = false, $from_fatal_error = false)
{
    global $context, $txt;
    static $header_done = false, $footer_done = false, $level = 0, $has_fatal_error = false;
    // Attempt to prevent a recursive loop.
    ++$level;
    if ($level > 1 && !$from_fatal_error && !$has_fatal_error) {
        exit;
    }
    if ($from_fatal_error) {
        $has_fatal_error = true;
    }
    // Clear out the stat cache.
    trackStats();
    // If we have mail to send, send it.
    if (!empty($context['flush_mail'])) {
        // @todo this relies on 'flush_mail' being only set in AddMailQueue itself... :\
        AddMailQueue(true);
    }
    $do_header = $header === null ? !$header_done : $header;
    if ($do_footer === null) {
        $do_footer = $do_header;
    }
    // Has the template/header been done yet?
    if ($do_header) {
        // Was the page title set last minute? Also update the HTML safe one.
        if (!empty($context['page_title']) && empty($context['page_title_html_safe'])) {
            $context['page_title_html_safe'] = Util::htmlspecialchars(un_htmlspecialchars($context['page_title'])) . (!empty($context['current_page']) ? ' - ' . $txt['page'] . ' ' . ($context['current_page'] + 1) : '');
        }
        // Start up the session URL fixer.
        ob_start('ob_sessrewrite');
        call_integration_buffer();
        // Display the screen in the logical order.
        template_header();
        $header_done = true;
    }
    if ($do_footer) {
        // Show the footer.
        loadSubTemplate(isset($context['sub_template']) ? $context['sub_template'] : 'main');
        // Just so we don't get caught in an endless loop of errors from the footer...
        if (!$footer_done) {
            $footer_done = true;
            template_footer();
            // (since this is just debugging... it's okay that it's after </html>.)
            if (!isset($_REQUEST['xml'])) {
                displayDebug();
            }
        }
    }
    // Need user agent
    $req = request();
    // Remember this URL in case someone doesn't like sending HTTP_REFERER.
    $invalid_old_url = array('action=dlattach', 'action=jsoption', 'action=viewadminfile', ';xml', ';api');
    $make_old = true;
    foreach ($invalid_old_url as $url) {
        if (strpos($_SERVER['REQUEST_URL'], $url) !== false) {
            $make_old = false;
            break;
        }
    }
    if ($make_old === true) {
        $_SESSION['old_url'] = $_SERVER['REQUEST_URL'];
    }
    // For session check verification.... don't switch browsers...
    $_SESSION['USER_AGENT'] = $req->user_agent();
    // Hand off the output to the portal, etc. we're integrated with.
    call_integration_hook('integrate_exit', array($do_footer));
    // Don't exit if we're coming from index.php; that will pass through normally.
    if (!$from_index) {
        exit;
    }
}