Esempio n. 1
0
 public function validateUsernameHandle($username)
 {
     global $sourcedir, $smcFunc, $context, $txt;
     // Clean it up like mother would.
     $username = preg_replace('~[\\t\\n\\r \\x0B\\0' . ($context['utf8'] ? $context['server']['complex_preg_chars'] ? '\\x{A0}\\x{AD}\\x{2000}-\\x{200F}\\x{201F}\\x{202F}\\x{3000}\\x{FEFF}' : " ­ -‏‟ ‟ " : '\\x00-\\x08\\x0B\\x0C\\x0E-\\x19\\xA0') . ']+~' . ($context['utf8'] ? 'u' : ''), ' ', $username);
     if ($smcFunc['strlen']($username) > 25) {
         $username = $smcFunc['htmltrim']($smcFunc['substr']($username, 0, 25));
     }
     // Only these characters are permitted.
     if (preg_match('~[<>&"\'=\\\\]~', preg_replace('~&#(?:\\d{1,7}|x[0-9a-fA-F]{1,6});~', '', $username)) != 0 || $username == '_' || $username == '|' || strpos($username, '[code') !== false || strpos($username, '[/code') !== false) {
         return false;
     }
     if (stristr($username, $txt['guest_title']) !== false) {
         return false;
     }
     if (trim($username) == '') {
         return false;
     } else {
         require_once $sourcedir . '/Subs-Members.php';
         return isReservedName($username, 0, false, false) ? false : true;
     }
 }
Esempio n. 2
0
 /**
  * Actually register the member.
  * @todo split this function in two functions:
  *  - a function that handles action=register2, which needs no parameter;
  *  - a function that processes the case of OpenID verification.
  *
  * @param bool $verifiedOpenID = false
  */
 public function action_register2($verifiedOpenID = false)
 {
     global $txt, $modSettings, $context, $user_info;
     // Start collecting together any errors.
     $reg_errors = Error_Context::context('register', 0);
     // We can't validate the token and the session with OpenID enabled.
     if (!$verifiedOpenID) {
         checkSession();
         if (!validateToken('register', 'post', true, false)) {
             $reg_errors->addError('token_verification');
         }
     }
     // Did we save some open ID fields?
     if ($verifiedOpenID && !empty($context['openid_save_fields'])) {
         foreach ($context['openid_save_fields'] as $id => $value) {
             $_POST[$id] = $value;
         }
     }
     // You can't register if it's disabled.
     if (!empty($modSettings['registration_method']) && $modSettings['registration_method'] == 3) {
         fatal_lang_error('registration_disabled', false);
     }
     // If we're using an agreement checkbox, did they check it?
     if (!empty($modSettings['checkboxAgreement']) && !empty($_POST['checkbox_agreement'])) {
         $_SESSION['registration_agreed'] = true;
     }
     // Things we don't do for people who have already confirmed their OpenID allegances via register.
     if (!$verifiedOpenID) {
         // Well, if you don't agree, you can't register.
         if (!empty($modSettings['requireAgreement']) && empty($_SESSION['registration_agreed'])) {
             redirectexit();
         }
         // Make sure they came from *somewhere*, have a session.
         if (!isset($_SESSION['old_url'])) {
             redirectexit('action=register');
         }
         // If we don't require an agreement, we need a extra check for coppa.
         if (empty($modSettings['requireAgreement']) && !empty($modSettings['coppaAge'])) {
             $_SESSION['skip_coppa'] = !empty($_POST['accept_agreement']);
         }
         // Are they under age, and under age users are banned?
         if (!empty($modSettings['coppaAge']) && empty($modSettings['coppaType']) && empty($_SESSION['skip_coppa'])) {
             loadLanguage('Login');
             fatal_lang_error('under_age_registration_prohibited', false, array($modSettings['coppaAge']));
         }
         // Check the time gate for miscreants. First make sure they came from somewhere that actually set it up.
         if (empty($_SESSION['register']['timenow']) || empty($_SESSION['register']['limit'])) {
             redirectexit('action=register');
         }
         // Failing that, check the time limit for exessive speed.
         if (time() - $_SESSION['register']['timenow'] < $_SESSION['register']['limit']) {
             loadLanguage('Login');
             $reg_errors->addError('too_quickly');
         }
         // Check whether the visual verification code was entered correctly.
         if (!empty($modSettings['reg_verification'])) {
             require_once SUBSDIR . '/VerificationControls.class.php';
             $verificationOptions = array('id' => 'register');
             $context['visual_verification'] = create_control_verification($verificationOptions, true);
             if (is_array($context['visual_verification'])) {
                 foreach ($context['visual_verification'] as $error) {
                     $reg_errors->addError($error);
                 }
             }
         }
     }
     foreach ($_POST as $key => $value) {
         if (!is_array($_POST[$key])) {
             $_POST[$key] = htmltrim__recursive(str_replace(array("\n", "\r"), '', $_POST[$key]));
         }
     }
     // Collect all extra registration fields someone might have filled in.
     $possible_strings = array('birthdate', 'time_format', 'buddy_list', 'pm_ignore_list', 'smiley_set', 'personal_text', 'avatar', 'lngfile', 'location', 'secret_question', 'secret_answer', 'website_url', 'website_title');
     $possible_ints = array('pm_email_notify', 'notify_types', 'id_theme', 'gender');
     $possible_floats = array('time_offset');
     $possible_bools = array('notify_announcements', 'notify_regularity', 'notify_send_body', 'hide_email', 'show_online');
     if (isset($_POST['secret_answer']) && $_POST['secret_answer'] != '') {
         $_POST['secret_answer'] = md5($_POST['secret_answer']);
     }
     // Needed for isReservedName() and registerMember().
     require_once SUBSDIR . '/Members.subs.php';
     // Validation... even if we're not a mall.
     if (isset($_POST['real_name']) && (!empty($modSettings['allow_editDisplayName']) || allowedTo('moderate_forum'))) {
         $_POST['real_name'] = 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', ' ', $_POST['real_name']));
         if (trim($_POST['real_name']) != '' && !isReservedName($_POST['real_name']) && Util::strlen($_POST['real_name']) < 60) {
             $possible_strings[] = 'real_name';
         }
     }
     // Handle a string as a birthdate...
     if (isset($_POST['birthdate']) && $_POST['birthdate'] != '') {
         $_POST['birthdate'] = strftime('%Y-%m-%d', strtotime($_POST['birthdate']));
     } elseif (!empty($_POST['bday1']) && !empty($_POST['bday2'])) {
         $_POST['birthdate'] = sprintf('%04d-%02d-%02d', empty($_POST['bday3']) ? 0 : (int) $_POST['bday3'], (int) $_POST['bday1'], (int) $_POST['bday2']);
     }
     // By default assume email is hidden, only show it if we tell it to.
     $_POST['hide_email'] = !empty($_POST['allow_email']) ? 0 : 1;
     // Validate the passed language file.
     if (isset($_POST['lngfile']) && !empty($modSettings['userLanguage'])) {
         // Do we have any languages?
         $context['languages'] = getLanguages();
         // Did we find it?
         if (isset($context['languages'][$_POST['lngfile']])) {
             $_SESSION['language'] = $_POST['lngfile'];
         } else {
             unset($_POST['lngfile']);
         }
     } else {
         unset($_POST['lngfile']);
     }
     // Some of these fields we may not want.
     if (!empty($modSettings['registration_fields'])) {
         // But we might want some of them if the admin asks for them.
         $standard_fields = array('location', 'gender');
         $reg_fields = explode(',', $modSettings['registration_fields']);
         $exclude_fields = array_diff($standard_fields, $reg_fields);
         // Website is a little different
         if (!in_array('website', $reg_fields)) {
             $exclude_fields = array_merge($exclude_fields, array('website_url', 'website_title'));
         }
         // We used to accept signature on registration but it's being abused by spammers these days, so no more.
         $exclude_fields[] = 'signature';
     } else {
         $exclude_fields = array('signature', 'location', 'gender', 'website_url', 'website_title');
     }
     $possible_strings = array_diff($possible_strings, $exclude_fields);
     $possible_ints = array_diff($possible_ints, $exclude_fields);
     $possible_floats = array_diff($possible_floats, $exclude_fields);
     $possible_bools = array_diff($possible_bools, $exclude_fields);
     // Set the options needed for registration.
     $regOptions = array('interface' => 'guest', 'username' => !empty($_POST['user']) ? $_POST['user'] : '', 'email' => !empty($_POST['email']) ? $_POST['email'] : '', 'password' => !empty($_POST['passwrd1']) ? $_POST['passwrd1'] : '', 'password_check' => !empty($_POST['passwrd2']) ? $_POST['passwrd2'] : '', 'openid' => !empty($_POST['openid_identifier']) ? $_POST['openid_identifier'] : '', 'auth_method' => !empty($_POST['authenticate']) ? $_POST['authenticate'] : '', 'check_reserved_name' => true, 'check_password_strength' => true, 'check_email_ban' => true, 'send_welcome_email' => !empty($modSettings['send_welcomeEmail']), 'require' => !empty($modSettings['coppaAge']) && !$verifiedOpenID && empty($_SESSION['skip_coppa']) ? 'coppa' : (empty($modSettings['registration_method']) ? 'nothing' : ($modSettings['registration_method'] == 1 ? 'activation' : 'approval')), 'extra_register_vars' => array(), 'theme_vars' => array());
     // Include the additional options that might have been filled in.
     foreach ($possible_strings as $var) {
         if (isset($_POST[$var])) {
             $regOptions['extra_register_vars'][$var] = Util::htmlspecialchars($_POST[$var], ENT_QUOTES);
         }
     }
     foreach ($possible_ints as $var) {
         if (isset($_POST[$var])) {
             $regOptions['extra_register_vars'][$var] = (int) $_POST[$var];
         }
     }
     foreach ($possible_floats as $var) {
         if (isset($_POST[$var])) {
             $regOptions['extra_register_vars'][$var] = (double) $_POST[$var];
         }
     }
     foreach ($possible_bools as $var) {
         if (isset($_POST[$var])) {
             $regOptions['extra_register_vars'][$var] = empty($_POST[$var]) ? 0 : 1;
         }
     }
     // Registration options are always default options...
     if (isset($_POST['default_options'])) {
         $_POST['options'] = isset($_POST['options']) ? $_POST['options'] + $_POST['default_options'] : $_POST['default_options'];
     }
     $regOptions['theme_vars'] = isset($_POST['options']) && is_array($_POST['options']) ? $_POST['options'] : array();
     // Make sure they are clean, dammit!
     $regOptions['theme_vars'] = htmlspecialchars__recursive($regOptions['theme_vars']);
     // Check whether we have fields that simply MUST be displayed?
     require_once SUBSDIR . '/Profile.subs.php';
     loadCustomFields(0, 'register');
     foreach ($context['custom_fields'] as $row) {
         // Don't allow overriding of the theme variables.
         if (isset($regOptions['theme_vars'][$row['colname']])) {
             unset($regOptions['theme_vars'][$row['colname']]);
         }
         // Prepare the value!
         $value = isset($_POST['customfield'][$row['colname']]) ? trim($_POST['customfield'][$row['colname']]) : '';
         // We only care for text fields as the others are valid to be empty.
         if (!in_array($row['type'], array('check', 'select', 'radio'))) {
             // Is it too long?
             if ($row['field_length'] && $row['field_length'] < Util::strlen($value)) {
                 $reg_errors->addError(array('custom_field_too_long', array($row['name'], $row['field_length'])));
             }
             // Any masks to apply?
             if ($row['type'] == 'text' && !empty($row['mask']) && $row['mask'] != 'none') {
                 // @todo We never error on this - just ignore it at the moment...
                 if ($row['mask'] == 'email' && !isValidEmail($value)) {
                     $reg_errors->addError(array('custom_field_invalid_email', array($row['name'])));
                 } elseif ($row['mask'] == 'number' && preg_match('~[^\\d]~', $value)) {
                     $reg_errors->addError(array('custom_field_not_number', array($row['name'])));
                 } elseif (substr($row['mask'], 0, 5) == 'regex' && trim($value) !== '' && preg_match(substr($row['mask'], 5), $value) === 0) {
                     $reg_errors->addError(array('custom_field_inproper_format', array($row['name'])));
                 }
             }
         }
         // Is this required but not there?
         if (trim($value) == '' && $row['show_reg'] > 1) {
             $reg_errors->addError(array('custom_field_empty', array($row['name'])));
         }
     }
     // Lets check for other errors before trying to register the member.
     if ($reg_errors->hasErrors()) {
         $_REQUEST['step'] = 2;
         // If they've filled in some details but made an error then they need less time to finish
         $_SESSION['register']['limit'] = 4;
         return $this->action_register();
     }
     // If they're wanting to use OpenID we need to validate them first.
     if (empty($_SESSION['openid']['verified']) && !empty($_POST['authenticate']) && $_POST['authenticate'] == 'openid') {
         // What do we need to save?
         $save_variables = array();
         foreach ($_POST as $k => $v) {
             if (!in_array($k, array('sc', 'sesc', $context['session_var'], 'passwrd1', 'passwrd2', 'regSubmit'))) {
                 $save_variables[$k] = $v;
             }
         }
         require_once SUBSDIR . '/OpenID.subs.php';
         $openID = new OpenID();
         $openID->validate($_POST['openid_identifier'], false, $save_variables);
     } elseif ($verifiedOpenID || (!empty($_POST['openid_identifier']) || !empty($_SESSION['openid']['openid_uri'])) && $_POST['authenticate'] == 'openid') {
         $regOptions['username'] = !empty($_POST['user']) && trim($_POST['user']) != '' ? $_POST['user'] : $_SESSION['openid']['nickname'];
         $regOptions['email'] = !empty($_POST['email']) && trim($_POST['email']) != '' ? $_POST['email'] : $_SESSION['openid']['email'];
         $regOptions['auth_method'] = 'openid';
         $regOptions['openid'] = !empty($_SESSION['openid']['openid_uri']) ? $_SESSION['openid']['openid_uri'] : (!empty($_POST['openid_identifier']) ? $_POST['openid_identifier'] : '');
     }
     // Registration needs to know your IP
     $req = request();
     $regOptions['ip'] = $user_info['ip'];
     $regOptions['ip2'] = $req->ban_ip();
     $memberID = registerMember($regOptions, 'register');
     // If there are "important" errors and you are not an admin: log the first error
     // Otherwise grab all of them and don't log anything
     if ($reg_errors->hasErrors(1) && !$user_info['is_admin']) {
         foreach ($reg_errors->prepareErrors(1) as $error) {
             fatal_error($error, 'general');
         }
     }
     // Was there actually an error of some kind dear boy?
     if ($reg_errors->hasErrors()) {
         $_REQUEST['step'] = 2;
         return $this->action_register();
     }
     // Do our spam protection now.
     spamProtection('register');
     // We'll do custom fields after as then we get to use the helper function!
     if (!empty($_POST['customfield'])) {
         require_once SUBSDIR . '/Profile.subs.php';
         makeCustomFieldChanges($memberID, 'register');
     }
     // If COPPA has been selected then things get complicated, setup the template.
     if (!empty($modSettings['coppaAge']) && empty($_SESSION['skip_coppa'])) {
         redirectexit('action=coppa;member=' . $memberID);
     } elseif (!empty($modSettings['registration_method'])) {
         loadTemplate('Register');
         $context += array('page_title' => $txt['register'], 'title' => $txt['registration_successful'], 'sub_template' => 'after', 'description' => $modSettings['registration_method'] == 2 ? $txt['approval_after_registration'] : $txt['activate_after_registration']);
     } else {
         call_integration_hook('integrate_activate', array($regOptions['username']));
         setLoginCookie(60 * $modSettings['cookieTime'], $memberID, hash('sha256', Util::strtolower($regOptions['username']) . $regOptions['password'] . $regOptions['register_vars']['password_salt']));
         redirectexit('action=auth;sa=check;member=' . $memberID, $context['server']['needs_login_fix']);
     }
 }
Esempio n. 3
0
function validateUsername($memID, $username)
{
    global $sourcedir, $txt;
    // No name?!  How can you register with no name?
    if ($username == '') {
        fatal_lang_error('need_username', false);
    }
    // Only these characters are permitted.
    if (in_array($username, array('_', '|')) || preg_match('~[<>&"\'=\\\\]~', preg_replace('~&#(?:\\d{1,7}|x[0-9a-fA-F]{1,6});~', '', $username)) != 0 || strpos($username, '[code') !== false || strpos($username, '[/code') !== false) {
        fatal_lang_error('error_invalid_characters_username', false);
    }
    if (stristr($username, $txt['guest_title']) !== false) {
        fatal_lang_error('username_reserved', true, array($txt['guest_title']));
    }
    require_once $sourcedir . '/Subs-Members.php';
    if (isReservedName($username, $memID, false)) {
        fatal_error('(' . htmlspecialchars($username) . ') ' . $txt['name_in_use'], false);
    }
    return null;
}
Esempio n. 4
0
function RegisterCheckUsername()
{
    global $sourcedir, $context, $txt;
    // This is XML!
    loadTemplate('Xml');
    $context['sub_template'] = 'check_username';
    $context['checked_username'] = isset($_GET['username']) ? $_GET['username'] : '';
    $context['valid_username'] = true;
    // Clean it up like mother would.
    $context['checked_username'] = preg_replace('~[\\t\\n\\r\\x0B\\0' . ($context['server']['complex_preg_chars'] ? '\\x{A0}' : " ") . ']+~u', ' ', $context['checked_username']);
    if (commonAPI::strlen($context['checked_username']) > 25) {
        $context['checked_username'] = commonAPI::htmltrim(commonAPI::substr($context['checked_username'], 0, 25));
    }
    // Only these characters are permitted.
    if (preg_match('~[<>&"\'=\\\\]~', preg_replace('~&#(?:\\d{1,7}|x[0-9a-fA-F]{1,6});~', '', $context['checked_username'])) != 0 || $context['checked_username'] == '_' || $context['checked_username'] == '|' || strpos($context['checked_username'], '[code') !== false || strpos($context['checked_username'], '[/code') !== false) {
        $context['valid_username'] = false;
    }
    if (stristr($context['checked_username'], $txt['guest_title']) !== false) {
        $context['valid_username'] = false;
    }
    if (trim($context['checked_username']) == '') {
        $context['valid_username'] = false;
    } else {
        require_once $sourcedir . '/lib/Subs-Members.php';
        $context['valid_username'] &= isReservedName($context['checked_username'], 0, false, false) ? 0 : 1;
    }
}
Esempio n. 5
0
function Post2()
{
    global $board, $topic, $txt, $modSettings, $sourcedir, $context;
    global $user_info, $board_info, $options, $smcFunc;
    // Sneaking off, are we?
    if (empty($_POST) && empty($topic)) {
        redirectexit('action=post;board=' . $board . '.0');
    } elseif (empty($_POST) && !empty($topic)) {
        redirectexit('action=post;topic=' . $topic . '.0');
    }
    // No need!
    $context['robot_no_index'] = true;
    // If we came from WYSIWYG then turn it back into BBC regardless.
    if (!empty($_REQUEST['message_mode']) && isset($_REQUEST['message'])) {
        require_once $sourcedir . '/Subs-Editor.php';
        $_REQUEST['message'] = html_to_bbc($_REQUEST['message']);
        // We need to unhtml it now as it gets done shortly.
        $_REQUEST['message'] = un_htmlspecialchars($_REQUEST['message']);
        // We need this for everything else.
        $_POST['message'] = $_REQUEST['message'];
    }
    // Previewing? Go back to start.
    if (isset($_REQUEST['preview'])) {
        return Post();
    }
    // Prevent double submission of this form.
    checkSubmitOnce('check');
    // No errors as yet.
    $post_errors = array();
    // If the session has timed out, let the user re-submit their form.
    if (checkSession('post', '', false) != '') {
        $post_errors[] = 'session_timeout';
    }
    // Wrong verification code?
    if (!$user_info['is_admin'] && !$user_info['is_mod'] && !empty($modSettings['posts_require_captcha']) && ($user_info['posts'] < $modSettings['posts_require_captcha'] || $user_info['is_guest'] && $modSettings['posts_require_captcha'] == -1)) {
        require_once $sourcedir . '/Subs-Editor.php';
        $verificationOptions = array('id' => 'post');
        $context['require_verification'] = create_control_verification($verificationOptions, true);
        if (is_array($context['require_verification'])) {
            $post_errors = array_merge($post_errors, $context['require_verification']);
        }
    }
    require_once $sourcedir . '/Subs-Post.php';
    loadLanguage('Post');
    // If this isn't a new topic load the topic info that we need.
    if (!empty($topic)) {
        $request = $smcFunc['db_query']('', '
			SELECT locked, is_sticky, id_poll, approved, id_first_msg, id_last_msg, id_member_started, id_board
			FROM {db_prefix}topics
			WHERE id_topic = {int:current_topic}
			LIMIT 1', array('current_topic' => $topic));
        $topic_info = $smcFunc['db_fetch_assoc']($request);
        $smcFunc['db_free_result']($request);
        // Though the topic should be there, it might have vanished.
        if (!is_array($topic_info)) {
            fatal_lang_error('topic_doesnt_exist');
        }
        // Did this topic suddenly move? Just checking...
        if ($topic_info['id_board'] != $board) {
            fatal_lang_error('not_a_topic');
        }
    }
    // Replying to a topic?
    if (!empty($topic) && !isset($_REQUEST['msg'])) {
        // Don't allow a post if it's locked.
        if ($topic_info['locked'] != 0 && !allowedTo('moderate_board')) {
            fatal_lang_error('topic_locked', false);
        }
        // Sorry, multiple polls aren't allowed... yet.  You should stop giving me ideas :P.
        if (isset($_REQUEST['poll']) && $topic_info['id_poll'] > 0) {
            unset($_REQUEST['poll']);
        }
        // Do the permissions and approval stuff...
        $becomesApproved = true;
        if ($topic_info['id_member_started'] != $user_info['id']) {
            if ($modSettings['postmod_active'] && allowedTo('post_unapproved_replies_any') && !allowedTo('post_reply_any')) {
                $becomesApproved = false;
            } else {
                isAllowedTo('post_reply_any');
            }
        } elseif (!allowedTo('post_reply_any')) {
            if ($modSettings['postmod_active'] && allowedTo('post_unapproved_replies_own') && !allowedTo('post_reply_own')) {
                $becomesApproved = false;
            } else {
                isAllowedTo('post_reply_own');
            }
        }
        if (isset($_POST['lock'])) {
            // Nothing is changed to the lock.
            if (empty($topic_info['locked']) && empty($_POST['lock']) || !empty($_POST['lock']) && !empty($topic_info['locked'])) {
                unset($_POST['lock']);
            } elseif (!allowedTo(array('lock_any', 'lock_own')) || !allowedTo('lock_any') && $user_info['id'] != $topic_info['id_member_started']) {
                unset($_POST['lock']);
            } elseif (!allowedTo('lock_any')) {
                // You cannot override a moderator lock.
                if ($topic_info['locked'] == 1) {
                    unset($_POST['lock']);
                } else {
                    $_POST['lock'] = empty($_POST['lock']) ? 0 : 2;
                }
            } else {
                $_POST['lock'] = empty($_POST['lock']) ? 0 : 1;
            }
        }
        // So you wanna (un)sticky this...let's see.
        if (isset($_POST['sticky']) && (empty($modSettings['enableStickyTopics']) || $_POST['sticky'] == $topic_info['is_sticky'] || !allowedTo('make_sticky'))) {
            unset($_POST['sticky']);
        }
        // If the number of replies has changed, if the setting is enabled, go back to Post() - which handles the error.
        if (empty($options['no_new_reply_warning']) && isset($_POST['last_msg']) && $topic_info['id_last_msg'] > $_POST['last_msg']) {
            $_REQUEST['preview'] = true;
            return Post();
        }
        $posterIsGuest = $user_info['is_guest'];
    } elseif (empty($topic)) {
        // Now don't be silly, new topics will get their own id_msg soon enough.
        unset($_REQUEST['msg'], $_POST['msg'], $_GET['msg']);
        // Do like, the permissions, for safety and stuff...
        $becomesApproved = true;
        if ($modSettings['postmod_active'] && !allowedTo('post_new') && allowedTo('post_unapproved_topics')) {
            $becomesApproved = false;
        } else {
            isAllowedTo('post_new');
        }
        if (isset($_POST['lock'])) {
            // New topics are by default not locked.
            if (empty($_POST['lock'])) {
                unset($_POST['lock']);
            } elseif (!allowedTo(array('lock_any', 'lock_own'))) {
                unset($_POST['lock']);
            } else {
                $_POST['lock'] = allowedTo('lock_any') ? 1 : 2;
            }
        }
        if (isset($_POST['sticky']) && (empty($modSettings['enableStickyTopics']) || empty($_POST['sticky']) || !allowedTo('make_sticky'))) {
            unset($_POST['sticky']);
        }
        $posterIsGuest = $user_info['is_guest'];
    } elseif (isset($_REQUEST['msg']) && !empty($topic)) {
        $_REQUEST['msg'] = (int) $_REQUEST['msg'];
        $request = $smcFunc['db_query']('', '
			SELECT id_member, poster_name, poster_email, poster_time, approved
			FROM {db_prefix}messages
			WHERE id_msg = {int:id_msg}
			LIMIT 1', array('id_msg' => $_REQUEST['msg']));
        if ($smcFunc['db_num_rows']($request) == 0) {
            fatal_lang_error('cant_find_messages', false);
        }
        $row = $smcFunc['db_fetch_assoc']($request);
        $smcFunc['db_free_result']($request);
        if (!empty($topic_info['locked']) && !allowedTo('moderate_board')) {
            fatal_lang_error('topic_locked', false);
        }
        if (isset($_POST['lock'])) {
            // Nothing changes to the lock status.
            if (empty($_POST['lock']) && empty($topic_info['locked']) || !empty($_POST['lock']) && !empty($topic_info['locked'])) {
                unset($_POST['lock']);
            } elseif (!allowedTo(array('lock_any', 'lock_own')) || !allowedTo('lock_any') && $user_info['id'] != $topic_info['id_member_started']) {
                unset($_POST['lock']);
            } elseif (!allowedTo('lock_any')) {
                // You're not allowed to break a moderator's lock.
                if ($topic_info['locked'] == 1) {
                    unset($_POST['lock']);
                } else {
                    $_POST['lock'] = empty($_POST['lock']) ? 0 : 2;
                }
            } else {
                $_POST['lock'] = empty($_POST['lock']) ? 0 : 1;
            }
        }
        // Change the sticky status of this topic?
        if (isset($_POST['sticky']) && (!allowedTo('make_sticky') || $_POST['sticky'] == $topic_info['is_sticky'])) {
            unset($_POST['sticky']);
        }
        if ($row['id_member'] == $user_info['id'] && !allowedTo('modify_any')) {
            if ((!$modSettings['postmod_active'] || $row['approved']) && !empty($modSettings['edit_disable_time']) && $row['poster_time'] + ($modSettings['edit_disable_time'] + 5) * 60 < time()) {
                fatal_lang_error('modify_post_time_passed', false);
            } elseif ($topic_info['id_member_started'] == $user_info['id'] && !allowedTo('modify_own')) {
                isAllowedTo('modify_replies');
            } else {
                isAllowedTo('modify_own');
            }
        } elseif ($topic_info['id_member_started'] == $user_info['id'] && !allowedTo('modify_any')) {
            isAllowedTo('modify_replies');
            // If you're modifying a reply, I say it better be logged...
            $moderationAction = true;
        } else {
            isAllowedTo('modify_any');
            // Log it, assuming you're not modifying your own post.
            if ($row['id_member'] != $user_info['id']) {
                $moderationAction = true;
            }
        }
        $posterIsGuest = empty($row['id_member']);
        // Can they approve it?
        $can_approve = allowedTo('approve_posts');
        $becomesApproved = $modSettings['postmod_active'] ? $can_approve && !$row['approved'] ? !empty($_REQUEST['approve']) ? 1 : 0 : $row['approved'] : 1;
        $approve_has_changed = $row['approved'] != $becomesApproved;
        if (!allowedTo('moderate_forum') || !$posterIsGuest) {
            $_POST['guestname'] = $row['poster_name'];
            $_POST['email'] = $row['poster_email'];
        }
    }
    // If the poster is a guest evaluate the legality of name and email.
    if ($posterIsGuest) {
        $_POST['guestname'] = !isset($_POST['guestname']) ? '' : trim($_POST['guestname']);
        $_POST['email'] = !isset($_POST['email']) ? '' : trim($_POST['email']);
        if ($_POST['guestname'] == '' || $_POST['guestname'] == '_') {
            $post_errors[] = 'no_name';
        }
        if ($smcFunc['strlen']($_POST['guestname']) > 25) {
            $post_errors[] = 'long_name';
        }
        if (empty($modSettings['guest_post_no_email'])) {
            // Only check if they changed it!
            if (!isset($row) || $row['poster_email'] != $_POST['email']) {
                if (!allowedTo('moderate_forum') && (!isset($_POST['email']) || $_POST['email'] == '')) {
                    $post_errors[] = 'no_email';
                }
                if (!allowedTo('moderate_forum') && preg_match('~^[0-9A-Za-z=_+\\-/][0-9A-Za-z=_\'+\\-/\\.]*@[\\w\\-]+(\\.[\\w\\-]+)*(\\.[\\w]{2,6})$~', $_POST['email']) == 0) {
                    $post_errors[] = 'bad_email';
                }
            }
            // Now make sure this email address is not banned from posting.
            isBannedEmail($_POST['email'], 'cannot_post', sprintf($txt['you_are_post_banned'], $txt['guest_title']));
        }
        // In case they are making multiple posts this visit, help them along by storing their name.
        if (empty($post_errors)) {
            $_SESSION['guest_name'] = $_POST['guestname'];
            $_SESSION['guest_email'] = $_POST['email'];
        }
    }
    // Check the subject and message.
    if (!isset($_POST['subject']) || $smcFunc['htmltrim']($smcFunc['htmlspecialchars']($_POST['subject'])) === '') {
        $post_errors[] = 'no_subject';
    }
    if (!isset($_POST['message']) || $smcFunc['htmltrim']($smcFunc['htmlspecialchars']($_POST['message']), ENT_QUOTES) === '') {
        $post_errors[] = 'no_message';
    } elseif (!empty($modSettings['max_messageLength']) && $smcFunc['strlen']($_POST['message']) > $modSettings['max_messageLength']) {
        $post_errors[] = 'long_message';
    } else {
        // Prepare the message a bit for some additional testing.
        $_POST['message'] = $smcFunc['htmlspecialchars']($_POST['message'], ENT_QUOTES);
        // Preparse code. (Zef)
        if ($user_info['is_guest']) {
            $user_info['name'] = $_POST['guestname'];
        }
        preparsecode($_POST['message']);
        // Let's see if there's still some content left without the tags.
        if ($smcFunc['htmltrim'](strip_tags(parse_bbc($_POST['message'], false), '<img>')) === '' && (!allowedTo('admin_forum') || strpos($_POST['message'], '[html]') === false)) {
            $post_errors[] = 'no_message';
        }
    }
    if (isset($_POST['calendar']) && !isset($_REQUEST['deleteevent']) && $smcFunc['htmltrim']($_POST['evtitle']) === '') {
        $post_errors[] = 'no_event';
    }
    // You are not!
    if (isset($_POST['message']) && strtolower($_POST['message']) == 'i am the administrator.' && !$user_info['is_admin']) {
        fatal_error('Knave! Masquerader! Charlatan!', false);
    }
    // Validate the poll...
    if (isset($_REQUEST['poll']) && $modSettings['pollMode'] == '1') {
        if (!empty($topic) && !isset($_REQUEST['msg'])) {
            fatal_lang_error('no_access', false);
        }
        // This is a new topic... so it's a new poll.
        if (empty($topic)) {
            isAllowedTo('poll_post');
        } elseif ($user_info['id'] == $topic_info['id_member_started'] && !allowedTo('poll_add_any')) {
            isAllowedTo('poll_add_own');
        } else {
            isAllowedTo('poll_add_any');
        }
        if (!isset($_POST['question']) || trim($_POST['question']) == '') {
            $post_errors[] = 'no_question';
        }
        $_POST['options'] = empty($_POST['options']) ? array() : htmltrim__recursive($_POST['options']);
        // Get rid of empty ones.
        foreach ($_POST['options'] as $k => $option) {
            if ($option == '') {
                unset($_POST['options'][$k], $_POST['options'][$k]);
            }
        }
        // What are you going to vote between with one choice?!?
        if (count($_POST['options']) < 2) {
            $post_errors[] = 'poll_few';
        }
    }
    if ($posterIsGuest) {
        // If user is a guest, make sure the chosen name isn't taken.
        require_once $sourcedir . '/Subs-Members.php';
        if (isReservedName($_POST['guestname'], 0, true, false) && (!isset($row['poster_name']) || $_POST['guestname'] != $row['poster_name'])) {
            $post_errors[] = 'bad_name';
        }
    } elseif (!isset($_REQUEST['msg'])) {
        $_POST['guestname'] = $user_info['username'];
        $_POST['email'] = $user_info['email'];
    }
    // Any mistakes?
    if (!empty($post_errors)) {
        loadLanguage('Errors');
        // Previewing.
        $_REQUEST['preview'] = true;
        $context['post_error'] = array('messages' => array());
        foreach ($post_errors as $post_error) {
            $context['post_error'][$post_error] = true;
            if ($post_error == 'long_message') {
                $txt['error_' . $post_error] = sprintf($txt['error_' . $post_error], $modSettings['max_messageLength']);
            }
            $context['post_error']['messages'][] = $txt['error_' . $post_error];
        }
        return Post();
    }
    // Make sure the user isn't spamming the board.
    if (!isset($_REQUEST['msg'])) {
        spamProtection('post');
    }
    // At about this point, we're posting and that's that.
    ignore_user_abort(true);
    @set_time_limit(300);
    // Add special html entities to the subject, name, and email.
    $_POST['subject'] = strtr($smcFunc['htmlspecialchars']($_POST['subject']), array("\r" => '', "\n" => '', "\t" => ''));
    $_POST['guestname'] = htmlspecialchars($_POST['guestname']);
    $_POST['email'] = htmlspecialchars($_POST['email']);
    // At this point, we want to make sure the subject isn't too long.
    if ($smcFunc['strlen']($_POST['subject']) > 100) {
        $_POST['subject'] = $smcFunc['substr']($_POST['subject'], 0, 100);
    }
    // Make the poll...
    if (isset($_REQUEST['poll'])) {
        // Make sure that the user has not entered a ridiculous number of options..
        if (empty($_POST['poll_max_votes']) || $_POST['poll_max_votes'] <= 0) {
            $_POST['poll_max_votes'] = 1;
        } elseif ($_POST['poll_max_votes'] > count($_POST['options'])) {
            $_POST['poll_max_votes'] = count($_POST['options']);
        } else {
            $_POST['poll_max_votes'] = (int) $_POST['poll_max_votes'];
        }
        $_POST['poll_expire'] = (int) $_POST['poll_expire'];
        $_POST['poll_expire'] = $_POST['poll_expire'] > 9999 ? 9999 : ($_POST['poll_expire'] < 0 ? 0 : $_POST['poll_expire']);
        // Just set it to zero if it's not there..
        if (!isset($_POST['poll_hide'])) {
            $_POST['poll_hide'] = 0;
        } else {
            $_POST['poll_hide'] = (int) $_POST['poll_hide'];
        }
        $_POST['poll_change_vote'] = isset($_POST['poll_change_vote']) ? 1 : 0;
        $_POST['poll_guest_vote'] = isset($_POST['poll_guest_vote']) ? 1 : 0;
        // Make sure guests are actually allowed to vote generally.
        if ($_POST['poll_guest_vote']) {
            require_once $sourcedir . '/Subs-Members.php';
            $allowedVoteGroups = groupsAllowedTo('poll_vote', $board);
            if (!in_array(-1, $allowedVoteGroups['allowed'])) {
                $_POST['poll_guest_vote'] = 0;
            }
        }
        // If the user tries to set the poll too far in advance, don't let them.
        if (!empty($_POST['poll_expire']) && $_POST['poll_expire'] < 1) {
            fatal_lang_error('poll_range_error', false);
        } elseif (empty($_POST['poll_expire']) && $_POST['poll_hide'] == 2) {
            $_POST['poll_hide'] = 1;
        }
        // Clean up the question and answers.
        $_POST['question'] = htmlspecialchars($_POST['question']);
        $_POST['question'] = $smcFunc['truncate']($_POST['question'], 255);
        $_POST['question'] = preg_replace('~&amp;#(\\d{4,5}|[2-9]\\d{2,4}|1[2-9]\\d);~', '&#$1;', $_POST['question']);
        $_POST['options'] = htmlspecialchars__recursive($_POST['options']);
    }
    // Check if they are trying to delete any current attachments....
    if (isset($_REQUEST['msg'], $_POST['attach_del']) && (allowedTo('post_attachment') || $modSettings['postmod_active'] && allowedTo('post_unapproved_attachments'))) {
        $del_temp = array();
        foreach ($_POST['attach_del'] as $i => $dummy) {
            $del_temp[$i] = (int) $dummy;
        }
        require_once $sourcedir . '/ManageAttachments.php';
        $attachmentQuery = array('attachment_type' => 0, 'id_msg' => (int) $_REQUEST['msg'], 'not_id_attach' => $del_temp);
        removeAttachments($attachmentQuery);
    }
    // ...or attach a new file...
    if (isset($_FILES['attachment']['name']) || !empty($_SESSION['temp_attachments']) && empty($_POST['from_qr'])) {
        // Verify they can post them!
        if (!$modSettings['postmod_active'] || !allowedTo('post_unapproved_attachments')) {
            isAllowedTo('post_attachment');
        }
        // Make sure we're uploading to the right place.
        if (!empty($modSettings['currentAttachmentUploadDir'])) {
            if (!is_array($modSettings['attachmentUploadDir'])) {
                $modSettings['attachmentUploadDir'] = unserialize($modSettings['attachmentUploadDir']);
            }
            // The current directory, of course!
            $current_attach_dir = $modSettings['attachmentUploadDir'][$modSettings['currentAttachmentUploadDir']];
        } else {
            $current_attach_dir = $modSettings['attachmentUploadDir'];
        }
        // If this isn't a new post, check the current attachments.
        if (isset($_REQUEST['msg'])) {
            $request = $smcFunc['db_query']('', '
				SELECT COUNT(*), SUM(size)
				FROM {db_prefix}attachments
				WHERE id_msg = {int:id_msg}
					AND attachment_type = {int:attachment_type}', array('id_msg' => (int) $_REQUEST['msg'], 'attachment_type' => 0));
            list($quantity, $total_size) = $smcFunc['db_fetch_row']($request);
            $smcFunc['db_free_result']($request);
        } else {
            $quantity = 0;
            $total_size = 0;
        }
        if (!empty($_SESSION['temp_attachments'])) {
            foreach ($_SESSION['temp_attachments'] as $attachID => $name) {
                if (preg_match('~^post_tmp_' . $user_info['id'] . '_\\d+$~', $attachID) == 0) {
                    continue;
                }
                if (!empty($_POST['attach_del']) && !in_array($attachID, $_POST['attach_del'])) {
                    unset($_SESSION['temp_attachments'][$attachID]);
                    @unlink($current_attach_dir . '/' . $attachID);
                    continue;
                }
                $_FILES['attachment']['tmp_name'][] = $attachID;
                $_FILES['attachment']['name'][] = $name;
                $_FILES['attachment']['size'][] = filesize($current_attach_dir . '/' . $attachID);
                list($_FILES['attachment']['width'][], $_FILES['attachment']['height'][]) = @getimagesize($current_attach_dir . '/' . $attachID);
                unset($_SESSION['temp_attachments'][$attachID]);
            }
        }
        if (!isset($_FILES['attachment']['name'])) {
            $_FILES['attachment']['tmp_name'] = array();
        }
        $attachIDs = array();
        foreach ($_FILES['attachment']['tmp_name'] as $n => $dummy) {
            if ($_FILES['attachment']['name'][$n] == '') {
                continue;
            }
            // Have we reached the maximum number of files we are allowed?
            $quantity++;
            if (!empty($modSettings['attachmentNumPerPostLimit']) && $quantity > $modSettings['attachmentNumPerPostLimit']) {
                checkSubmitOnce('free');
                fatal_lang_error('attachments_limit_per_post', false, array($modSettings['attachmentNumPerPostLimit']));
            }
            // Check the total upload size for this post...
            $total_size += $_FILES['attachment']['size'][$n];
            if (!empty($modSettings['attachmentPostLimit']) && $total_size > $modSettings['attachmentPostLimit'] * 1024) {
                checkSubmitOnce('free');
                fatal_lang_error('file_too_big', false, array($modSettings['attachmentPostLimit']));
            }
            $attachmentOptions = array('post' => isset($_REQUEST['msg']) ? $_REQUEST['msg'] : 0, 'poster' => $user_info['id'], 'name' => $_FILES['attachment']['name'][$n], 'tmp_name' => $_FILES['attachment']['tmp_name'][$n], 'size' => $_FILES['attachment']['size'][$n], 'approved' => !$modSettings['postmod_active'] || allowedTo('post_attachment'));
            if (createAttachment($attachmentOptions)) {
                $attachIDs[] = $attachmentOptions['id'];
                if (!empty($attachmentOptions['thumb'])) {
                    $attachIDs[] = $attachmentOptions['thumb'];
                }
            } else {
                if (in_array('could_not_upload', $attachmentOptions['errors'])) {
                    checkSubmitOnce('free');
                    fatal_lang_error('attach_timeout', 'critical');
                }
                if (in_array('too_large', $attachmentOptions['errors'])) {
                    checkSubmitOnce('free');
                    fatal_lang_error('file_too_big', false, array($modSettings['attachmentSizeLimit']));
                }
                if (in_array('bad_extension', $attachmentOptions['errors'])) {
                    checkSubmitOnce('free');
                    fatal_error($attachmentOptions['name'] . '.<br />' . $txt['cant_upload_type'] . ' ' . $modSettings['attachmentExtensions'] . '.', false);
                }
                if (in_array('directory_full', $attachmentOptions['errors'])) {
                    checkSubmitOnce('free');
                    fatal_lang_error('ran_out_of_space', 'critical');
                }
                if (in_array('bad_filename', $attachmentOptions['errors'])) {
                    checkSubmitOnce('free');
                    fatal_error(basename($attachmentOptions['name']) . '.<br />' . $txt['restricted_filename'] . '.', 'critical');
                }
                if (in_array('taken_filename', $attachmentOptions['errors'])) {
                    checkSubmitOnce('free');
                    fatal_lang_error('filename_exists');
                }
                if (in_array('bad_attachment', $attachmentOptions['errors'])) {
                    checkSubmitOnce('free');
                    fatal_lang_error('bad_attachment');
                }
            }
        }
    }
    // Make the poll...
    if (isset($_REQUEST['poll'])) {
        // Create the poll.
        $smcFunc['db_insert']('', '{db_prefix}polls', array('question' => 'string-255', 'hide_results' => 'int', 'max_votes' => 'int', 'expire_time' => 'int', 'id_member' => 'int', 'poster_name' => 'string-255', 'change_vote' => 'int', 'guest_vote' => 'int'), array($_POST['question'], $_POST['poll_hide'], $_POST['poll_max_votes'], empty($_POST['poll_expire']) ? 0 : time() + $_POST['poll_expire'] * 3600 * 24, $user_info['id'], $_POST['guestname'], $_POST['poll_change_vote'], $_POST['poll_guest_vote']), array('id_poll'));
        $id_poll = $smcFunc['db_insert_id']('{db_prefix}polls', 'id_poll');
        // Create each answer choice.
        $i = 0;
        $pollOptions = array();
        foreach ($_POST['options'] as $option) {
            $pollOptions[] = array($id_poll, $i, $option);
            $i++;
        }
        $smcFunc['db_insert']('insert', '{db_prefix}poll_choices', array('id_poll' => 'int', 'id_choice' => 'int', 'label' => 'string-255'), $pollOptions, array('id_poll', 'id_choice'));
    } else {
        $id_poll = 0;
    }
    // Creating a new topic?
    $newTopic = empty($_REQUEST['msg']) && empty($topic);
    $_POST['icon'] = !empty($attachIDs) && $_POST['icon'] == 'xx' ? 'clip' : $_POST['icon'];
    // Collect all parameters for the creation or modification of a post.
    $msgOptions = array('id' => empty($_REQUEST['msg']) ? 0 : (int) $_REQUEST['msg'], 'subject' => $_POST['subject'], 'body' => $_POST['message'], 'icon' => preg_replace('~[\\./\\\\*:"\'<>]~', '', $_POST['icon']), 'smileys_enabled' => !isset($_POST['ns']), 'attachments' => empty($attachIDs) ? array() : $attachIDs, 'approved' => $becomesApproved);
    $topicOptions = array('id' => empty($topic) ? 0 : $topic, 'board' => $board, 'poll' => isset($_REQUEST['poll']) ? $id_poll : null, 'lock_mode' => isset($_POST['lock']) ? (int) $_POST['lock'] : null, 'sticky_mode' => isset($_POST['sticky']) && !empty($modSettings['enableStickyTopics']) ? (int) $_POST['sticky'] : null, 'mark_as_read' => true, 'is_approved' => !$modSettings['postmod_active'] || empty($topic) || !empty($board_info['cur_topic_approved']));
    $posterOptions = array('id' => $user_info['id'], 'name' => $_POST['guestname'], 'email' => $_POST['email'], 'update_post_count' => !$user_info['is_guest'] && !isset($_REQUEST['msg']) && $board_info['posts_count']);
    // This is an already existing message. Edit it.
    if (!empty($_REQUEST['msg'])) {
        // Have admins allowed people to hide their screwups?
        if (time() - $row['poster_time'] > $modSettings['edit_wait_time'] || $user_info['id'] != $row['id_member']) {
            $msgOptions['modify_time'] = time();
            $msgOptions['modify_name'] = $user_info['name'];
        }
        // This will save some time...
        if (empty($approve_has_changed)) {
            unset($msgOptions['approved']);
        }
        modifyPost($msgOptions, $topicOptions, $posterOptions);
    } else {
        createPost($msgOptions, $topicOptions, $posterOptions);
        if (isset($topicOptions['id'])) {
            $topic = $topicOptions['id'];
        }
    }
    // Editing or posting an event?
    if (isset($_POST['calendar']) && (!isset($_REQUEST['eventid']) || $_REQUEST['eventid'] == -1)) {
        require_once $sourcedir . '/Subs-Calendar.php';
        // Make sure they can link an event to this post.
        canLinkEvent();
        // Insert the event.
        $eventOptions = array('board' => $board, 'topic' => $topic, 'title' => $_POST['evtitle'], 'member' => $user_info['id'], 'start_date' => sprintf('%04d-%02d-%02d', $_POST['year'], $_POST['month'], $_POST['day']), 'span' => isset($_POST['span']) && $_POST['span'] > 0 ? min((int) $modSettings['cal_maxspan'], (int) $_POST['span'] - 1) : 0);
        insertEvent($eventOptions);
    } elseif (isset($_POST['calendar'])) {
        $_REQUEST['eventid'] = (int) $_REQUEST['eventid'];
        // Validate the post...
        require_once $sourcedir . '/Subs-Calendar.php';
        validateEventPost();
        // If you're not allowed to edit any events, you have to be the poster.
        if (!allowedTo('calendar_edit_any')) {
            // Get the event's poster.
            $request = $smcFunc['db_query']('', '
				SELECT id_member
				FROM {db_prefix}calendar
				WHERE id_event = {int:id_event}', array('id_event' => $_REQUEST['eventid']));
            $row2 = $smcFunc['db_fetch_assoc']($request);
            $smcFunc['db_free_result']($request);
            // Silly hacker, Trix are for kids. ...probably trademarked somewhere, this is FAIR USE! (parody...)
            isAllowedTo('calendar_edit_' . ($row2['id_member'] == $user_info['id'] ? 'own' : 'any'));
        }
        // Delete it?
        if (isset($_REQUEST['deleteevent'])) {
            $smcFunc['db_query']('', '
				DELETE FROM {db_prefix}calendar
				WHERE id_event = {int:id_event}', array('id_event' => $_REQUEST['eventid']));
        } else {
            $span = !empty($modSettings['cal_allowspan']) && !empty($_REQUEST['span']) ? min((int) $modSettings['cal_maxspan'], (int) $_REQUEST['span'] - 1) : 0;
            $start_time = mktime(0, 0, 0, (int) $_REQUEST['month'], (int) $_REQUEST['day'], (int) $_REQUEST['year']);
            $smcFunc['db_query']('', '
				UPDATE {db_prefix}calendar
				SET end_date = {date:end_date},
					start_date = {date:start_date},
					title = {string:title}
				WHERE id_event = {int:id_event}', array('end_date' => strftime('%Y-%m-%d', $start_time + $span * 86400), 'start_date' => strftime('%Y-%m-%d', $start_time), 'id_event' => $_REQUEST['eventid'], 'title' => $smcFunc['htmlspecialchars']($_REQUEST['evtitle'], ENT_QUOTES)));
        }
        updateSettings(array('calendar_updated' => time()));
    }
    // Marking read should be done even for editing messages....
    // Mark all the parents read.  (since you just posted and they will be unread.)
    if (!$user_info['is_guest'] && !empty($board_info['parent_boards'])) {
        $smcFunc['db_query']('', '
			UPDATE {db_prefix}log_boards
			SET id_msg = {int:id_msg}
			WHERE id_member = {int:current_member}
				AND id_board IN ({array_int:board_list})', array('current_member' => $user_info['id'], 'board_list' => array_keys($board_info['parent_boards']), 'id_msg' => $modSettings['maxMsgID']));
    }
    // Turn notification on or off.  (note this just blows smoke if it's already on or off.)
    if (!empty($_POST['notify']) && allowedTo('mark_any_notify')) {
        $smcFunc['db_insert']('ignore', '{db_prefix}log_notify', array('id_member' => 'int', 'id_topic' => 'int', 'id_board' => 'int'), array($user_info['id'], $topic, 0), array('id_member', 'id_topic', 'id_board'));
    } elseif (!$newTopic) {
        $smcFunc['db_query']('', '
			DELETE FROM {db_prefix}log_notify
			WHERE id_member = {int:current_member}
				AND id_topic = {int:current_topic}', array('current_member' => $user_info['id'], 'current_topic' => $topic));
    }
    // Log an act of moderation - modifying.
    if (!empty($moderationAction)) {
        logAction('modify', array('topic' => $topic, 'message' => (int) $_REQUEST['msg'], 'member' => $row['id_member'], 'board' => $board));
    }
    if (isset($_POST['lock']) && $_POST['lock'] != 2) {
        logAction('lock', array('topic' => $topicOptions['id'], 'board' => $topicOptions['board']));
    }
    if (isset($_POST['sticky']) && !empty($modSettings['enableStickyTopics'])) {
        logAction('sticky', array('topic' => $topicOptions['id'], 'board' => $topicOptions['board']));
    }
    // Notify any members who have notification turned on for this topic - only do this if it's going to be approved(!)
    if ($becomesApproved) {
        if ($newTopic) {
            $notifyData = array('body' => $_POST['message'], 'subject' => $_POST['subject'], 'name' => $user_info['name'], 'poster' => $user_info['id'], 'msg' => $msgOptions['id'], 'board' => $board, 'topic' => $topic);
            notifyMembersBoard($notifyData);
        } elseif (empty($_REQUEST['msg'])) {
            // Only send it to everyone if the topic is approved, otherwise just to the topic starter if they want it.
            if ($topic_info['approved']) {
                sendNotifications($topic, 'reply');
            } else {
                sendNotifications($topic, 'reply', array(), $topic_info['id_member_started']);
            }
        }
    }
    // Returning to the topic?
    if (!empty($_REQUEST['goback'])) {
        // Mark the board as read.... because it might get confusing otherwise.
        $smcFunc['db_query']('', '
			UPDATE {db_prefix}log_boards
			SET id_msg = {int:maxMsgID}
			WHERE id_member = {int:current_member}
				AND id_board = {int:current_board}', array('current_board' => $board, 'current_member' => $user_info['id'], 'maxMsgID' => $modSettings['maxMsgID']));
    }
    if ($board_info['num_topics'] == 0) {
        cache_put_data('board-' . $board, null, 120);
    }
    if (!empty($_POST['announce_topic'])) {
        redirectexit('action=announce;sa=selectgroup;topic=' . $topic . (!empty($_POST['move']) && allowedTo('move_any') ? ';move' : '') . (empty($_REQUEST['goback']) ? '' : ';goback'));
    }
    if (!empty($_POST['move']) && allowedTo('move_any')) {
        redirectexit('action=movetopic;topic=' . $topic . '.0' . (empty($_REQUEST['goback']) ? '' : ';goback'));
    }
    // Return to post if the mod is on.
    if (isset($_REQUEST['msg']) && !empty($_REQUEST['goback'])) {
        redirectexit('topic=' . $topic . '.msg' . $_REQUEST['msg'] . '#msg' . $_REQUEST['msg'], $context['browser']['is_ie']);
    } elseif (!empty($_REQUEST['goback'])) {
        redirectexit('topic=' . $topic . '.new#new', $context['browser']['is_ie']);
    } else {
        redirectexit('board=' . $board . '.0');
    }
}
Esempio n. 6
0
function ArcadeSave_Guest()
{
    global $scripturl, $txt, $db_prefix, $modSettings, $context, $func, $sourcedir, $smcFunc;
    if (!isset($_REQUEST['name']) && !isset($_SESSION['playerName'])) {
        $context['arcade']['submit'] = 'askname';
        return ArcadeHighscore();
    } elseif (isset($_REQUEST['name']) || isset($_SESSION['playerName'])) {
        $_REQUEST['game'] = $_SESSION['save_score'][0]['id'];
        if (isset($_REQUEST['name'])) {
            require_once $sourcedir . '/Subs-Members.php';
            checkSession('post');
            $name = htmlspecialchars($_REQUEST['name']);
            if (isReservedName($name, 0, true, false)) {
                $context['arcade']['submit'] = 'askname';
                $context['arcade']['error'] = 'bad_name';
                return ArcadeHighscore();
            }
            $_SESSION['playerName'] = $name;
            $_SESSION['save_score'][1]['name'] = $name;
        }
        SaveScore($_SESSION['save_score'][0], $_SESSION['save_score'][1], $_SESSION['save_score'][2]);
        unset($_SESSION['save_score']);
        redirectexit('action=arcade;sa=highscore;game=' . $_REQUEST['game']);
    }
}
Esempio n. 7
0
function Post2()
{
    global $board, $topic, $txt, $db_prefix, $modSettings, $sourcedir, $context;
    global $ID_MEMBER, $user_info, $board_info, $options, $func;
    // Previewing? Go back to start.
    if (isset($_REQUEST['preview'])) {
        return Post();
    }
    // Prevent double submission of this form.
    checkSubmitOnce('check');
    // No errors as yet.
    $post_errors = array();
    // If the session has timed out, let the user re-submit their form.
    if (checkSession('post', '', false) != '') {
        $post_errors[] = 'session_timeout';
    }
    require_once $sourcedir . '/Subs-Post.php';
    loadLanguage('Post');
    // Replying to a topic?
    if (!empty($topic) && !isset($_REQUEST['msg'])) {
        $request = db_query("\n\t\t\tSELECT t.locked, t.isSticky, t.ID_POLL, t.numReplies, m.ID_MEMBER\n\t\t\tFROM ({$db_prefix}topics AS t, {$db_prefix}messages AS m)\n\t\t\tWHERE t.ID_TOPIC = {$topic}\n\t\t\t\tAND m.ID_MSG = t.ID_FIRST_MSG\n\t\t\tLIMIT 1", __FILE__, __LINE__);
        list($tmplocked, $tmpstickied, $pollID, $numReplies, $ID_MEMBER_POSTER) = mysql_fetch_row($request);
        mysql_free_result($request);
        // Don't allow a post if it's locked.
        if ($tmplocked != 0 && !allowedTo('moderate_board')) {
            fatal_lang_error(90, false);
        }
        // Sorry, multiple polls aren't allowed... yet.  You should stop giving me ideas :P.
        if (isset($_REQUEST['poll']) && $pollID > 0) {
            unset($_REQUEST['poll']);
        }
        if ($ID_MEMBER_POSTER != $ID_MEMBER) {
            isAllowedTo('post_reply_any');
        } elseif (!allowedTo('post_reply_any')) {
            isAllowedTo('post_reply_own');
        }
        if (isset($_POST['lock'])) {
            // Nothing is changed to the lock.
            if (empty($tmplocked) && empty($_POST['lock']) || !empty($_POST['lock']) && !empty($tmplocked)) {
                unset($_POST['lock']);
            } elseif (!allowedTo(array('lock_any', 'lock_own')) || !allowedTo('lock_any') && $ID_MEMBER != $ID_MEMBER_POSTER) {
                unset($_POST['lock']);
            } elseif (!allowedTo('lock_any')) {
                // You cannot override a moderator lock.
                if ($tmplocked == 1) {
                    unset($_POST['lock']);
                } else {
                    $_POST['lock'] = empty($_POST['lock']) ? 0 : 2;
                }
            } else {
                $_POST['lock'] = empty($_POST['lock']) ? 0 : 1;
            }
        }
        // So you wanna (un)sticky this...let's see.
        if (isset($_POST['sticky']) && (empty($modSettings['enableStickyTopics']) || $_POST['sticky'] == $tmpstickied || !allowedTo('make_sticky'))) {
            unset($_POST['sticky']);
        }
        // If the number of replies has changed, if the setting is enabled, go back to Post() - which handles the error.
        $newReplies = isset($_POST['num_replies']) && $numReplies > $_POST['num_replies'] ? $numReplies - $_POST['num_replies'] : 0;
        if (empty($options['no_new_reply_warning']) && !empty($newReplies)) {
            $_REQUEST['preview'] = true;
            return Post();
        }
        $posterIsGuest = $user_info['is_guest'];
    } elseif (empty($topic)) {
        if (!isset($_REQUEST['poll']) || $modSettings['pollMode'] != '1') {
            isAllowedTo('post_new');
        }
        if (isset($_POST['lock'])) {
            // New topics are by default not locked.
            if (empty($_POST['lock'])) {
                unset($_POST['lock']);
            } elseif (!allowedTo(array('lock_any', 'lock_own'))) {
                unset($_POST['lock']);
            } else {
                $_POST['lock'] = allowedTo('lock_any') ? 1 : 2;
            }
        }
        if (isset($_POST['sticky']) && (empty($modSettings['enableStickyTopics']) || empty($_POST['sticky']) || !allowedTo('make_sticky'))) {
            unset($_POST['sticky']);
        }
        $posterIsGuest = $user_info['is_guest'];
    } elseif (isset($_REQUEST['msg']) && !empty($topic)) {
        $_REQUEST['msg'] = (int) $_REQUEST['msg'];
        $request = db_query("\n\t\t\tSELECT\n\t\t\t\tm.ID_MEMBER, m.posterName, m.posterEmail, m.posterTime, \n\t\t\t\tt.ID_FIRST_MSG, t.locked, t.isSticky, t.ID_MEMBER_STARTED AS ID_MEMBER_POSTER\n\t\t\tFROM ({$db_prefix}messages AS m, {$db_prefix}topics AS t)\n\t\t\tWHERE m.ID_MSG = {$_REQUEST['msg']}\n\t\t\t\tAND t.ID_TOPIC = {$topic}\n\t\t\tLIMIT 1", __FILE__, __LINE__);
        if (mysql_num_rows($request) == 0) {
            fatal_lang_error('smf272', false);
        }
        $row = mysql_fetch_assoc($request);
        mysql_free_result($request);
        if (!empty($row['locked']) && !allowedTo('moderate_board')) {
            fatal_lang_error(90, false);
        }
        if (isset($_POST['lock'])) {
            // Nothing changes to the lock status.
            if (empty($_POST['lock']) && empty($row['locked']) || !empty($_POST['lock']) && !empty($row['locked'])) {
                unset($_POST['lock']);
            } elseif (!allowedTo(array('lock_any', 'lock_own')) || !allowedTo('lock_any') && $ID_MEMBER != $row['ID_MEMBER_POSTER']) {
                unset($_POST['lock']);
            } elseif (!allowedTo('lock_any')) {
                // You're not allowed to break a moderator's lock.
                if ($row['locked'] == 1) {
                    unset($_POST['lock']);
                } else {
                    $_POST['lock'] = empty($_POST['lock']) ? 0 : 2;
                }
            } else {
                $_POST['lock'] = empty($_POST['lock']) ? 0 : 1;
            }
        }
        // Change the sticky status of this topic?
        if (isset($_POST['sticky']) && (!allowedTo('make_sticky') || $_POST['sticky'] == $row['isSticky'])) {
            unset($_POST['sticky']);
        }
        if ($row['ID_MEMBER'] == $ID_MEMBER && !allowedTo('modify_any')) {
            if (!empty($modSettings['edit_disable_time']) && $row['posterTime'] + ($modSettings['edit_disable_time'] + 5) * 60 < time()) {
                fatal_lang_error('modify_post_time_passed', false);
            } elseif ($row['ID_MEMBER_POSTER'] == $ID_MEMBER && !allowedTo('modify_own')) {
                isAllowedTo('modify_replies');
            } else {
                isAllowedTo('modify_own');
            }
        } elseif ($row['ID_MEMBER_POSTER'] == $ID_MEMBER && !allowedTo('modify_any')) {
            isAllowedTo('modify_replies');
            // If you're modifying a reply, I say it better be logged...
            $moderationAction = true;
        } else {
            isAllowedTo('modify_any');
            // Log it, assuming you're not modifying your own post.
            if ($row['ID_MEMBER'] != $ID_MEMBER) {
                $moderationAction = true;
            }
        }
        $posterIsGuest = empty($row['ID_MEMBER']);
        if (!allowedTo('moderate_forum') || !$posterIsGuest) {
            $_POST['guestname'] = addslashes($row['posterName']);
            $_POST['email'] = addslashes($row['posterEmail']);
        }
    }
    // If the poster is a guest evaluate the legality of name and email.
    if ($posterIsGuest) {
        $_POST['guestname'] = !isset($_POST['guestname']) ? '' : trim($_POST['guestname']);
        $_POST['email'] = !isset($_POST['email']) ? '' : trim($_POST['email']);
        if ($_POST['guestname'] == '' || $_POST['guestname'] == '_') {
            $post_errors[] = 'no_name';
        }
        if ($func['strlen']($_POST['guestname']) > 25) {
            $post_errors[] = 'long_name';
        }
        if (empty($modSettings['guest_post_no_email'])) {
            // Only check if they changed it!
            if (!isset($row) || $row['posterEmail'] != $_POST['email']) {
                if (!allowedTo('moderate_forum') && (!isset($_POST['email']) || $_POST['email'] == '')) {
                    $post_errors[] = 'no_email';
                }
                if (!allowedTo('moderate_forum') && preg_match('~^[0-9A-Za-z=_+\\-/][0-9A-Za-z=_\'+\\-/\\.]*@[\\w\\-]+(\\.[\\w\\-]+)*(\\.[\\w]{2,6})$~', stripslashes($_POST['email'])) == 0) {
                    $post_errors[] = 'bad_email';
                }
            }
            // Now make sure this email address is not banned from posting.
            isBannedEmail($_POST['email'], 'cannot_post', sprintf($txt['you_are_post_banned'], $txt[28]));
        }
    }
    // Check the subject and message.
    if (!isset($_POST['subject']) || $func['htmltrim']($_POST['subject']) === '') {
        $post_errors[] = 'no_subject';
    }
    if (!isset($_POST['message']) || $func['htmltrim']($_POST['message']) === '') {
        $post_errors[] = 'no_message';
    } elseif (!empty($modSettings['max_messageLength']) && $func['strlen']($_POST['message']) > $modSettings['max_messageLength']) {
        $post_errors[] = 'long_message';
    } else {
        // Prepare the message a bit for some additional testing.
        $_POST['message'] = $func['htmlspecialchars']($_POST['message'], ENT_QUOTES);
        // Preparse code. (Zef)
        if ($user_info['is_guest']) {
            $user_info['name'] = $_POST['guestname'];
        }
        preparsecode($_POST['message']);
        // Let's see if there's still some content left without the tags.
        if ($func['htmltrim'](strip_tags(parse_bbc($_POST['message'], false), '<img>')) === '') {
            $post_errors[] = 'no_message';
        }
    }
    if (isset($_POST['calendar']) && !isset($_REQUEST['deleteevent']) && $func['htmltrim']($_POST['evtitle']) === '') {
        $post_errors[] = 'no_event';
    }
    // You are not!
    if (isset($_POST['message']) && strtolower($_POST['message']) == 'i am the administrator.' && !$user_info['is_admin']) {
        fatal_error('Knave! Masquerader! Charlatan!', false);
    }
    // Validate the poll...
    if (isset($_REQUEST['poll']) && $modSettings['pollMode'] == '1') {
        if (!empty($topic) && !isset($_REQUEST['msg'])) {
            fatal_lang_error(1, false);
        }
        // This is a new topic... so it's a new poll.
        if (empty($topic)) {
            isAllowedTo('poll_post');
        } elseif ($ID_MEMBER == $row['ID_MEMBER_POSTER'] && !allowedTo('poll_add_any')) {
            isAllowedTo('poll_add_own');
        } else {
            isAllowedTo('poll_add_any');
        }
        if (!isset($_POST['question']) || trim($_POST['question']) == '') {
            $post_errors[] = 'no_question';
        }
        $_POST['options'] = empty($_POST['options']) ? array() : htmltrim__recursive($_POST['options']);
        // Get rid of empty ones.
        foreach ($_POST['options'] as $k => $option) {
            if ($option == '') {
                unset($_POST['options'][$k], $_POST['options'][$k]);
            }
        }
        // What are you going to vote between with one choice?!?
        if (count($_POST['options']) < 2) {
            $post_errors[] = 'poll_few';
        }
    }
    if ($posterIsGuest) {
        // If user is a guest, make sure the chosen name isn't taken.
        require_once $sourcedir . '/Subs-Members.php';
        if (isReservedName($_POST['guestname'], 0, true, false) && (!isset($row['posterName']) || $_POST['guestname'] != $row['posterName'])) {
            $post_errors[] = 'bad_name';
        }
    } elseif (!isset($_REQUEST['msg'])) {
        $_POST['guestname'] = addslashes($user_info['username']);
        $_POST['email'] = addslashes($user_info['email']);
    }
    // Any mistakes?
    if (!empty($post_errors)) {
        loadLanguage('Errors');
        // Previewing.
        $_REQUEST['preview'] = true;
        $context['post_error'] = array('messages' => array());
        foreach ($post_errors as $post_error) {
            $context['post_error'][$post_error] = true;
            $context['post_error']['messages'][] = $txt['error_' . $post_error];
        }
        return Post();
    }
    // Make sure the user isn't spamming the board.
    if (!isset($_REQUEST['msg'])) {
        spamProtection('spam');
    }
    // At about this point, we're posting and that's that.
    ignore_user_abort(true);
    @set_time_limit(300);
    // Add special html entities to the subject, name, and email.
    $_POST['subject'] = strtr($func['htmlspecialchars']($_POST['subject']), array("\r" => '', "\n" => '', "\t" => ''));
    $_POST['guestname'] = htmlspecialchars($_POST['guestname']);
    $_POST['email'] = htmlspecialchars($_POST['email']);
    // At this point, we want to make sure the subject isn't too long.
    if ($func['strlen']($_POST['subject']) > 100) {
        $_POST['subject'] = addslashes($func['substr'](stripslashes($_POST['subject']), 0, 100));
    }
    // Make the poll...
    if (isset($_REQUEST['poll'])) {
        // Make sure that the user has not entered a ridiculous number of options..
        if (empty($_POST['poll_max_votes']) || $_POST['poll_max_votes'] <= 0) {
            $_POST['poll_max_votes'] = 1;
        } elseif ($_POST['poll_max_votes'] > count($_POST['options'])) {
            $_POST['poll_max_votes'] = count($_POST['options']);
        } else {
            $_POST['poll_max_votes'] = (int) $_POST['poll_max_votes'];
        }
        // Just set it to zero if it's not there..
        if (!isset($_POST['poll_hide'])) {
            $_POST['poll_hide'] = 0;
        } else {
            $_POST['poll_hide'] = (int) $_POST['poll_hide'];
        }
        $_POST['poll_change_vote'] = isset($_POST['poll_change_vote']) ? 1 : 0;
        // If the user tries to set the poll too far in advance, don't let them.
        if (!empty($_POST['poll_expire']) && $_POST['poll_expire'] < 1) {
            fatal_lang_error('poll_range_error', false);
        } elseif (empty($_POST['poll_expire']) && $_POST['poll_hide'] == 2) {
            $_POST['poll_hide'] = 1;
        }
        // Clean up the question and answers.
        $_POST['question'] = $func['htmlspecialchars']($_POST['question']);
        $_POST['options'] = htmlspecialchars__recursive($_POST['options']);
    }
    // Check if they are trying to delete any current attachments....
    if (isset($_REQUEST['msg'], $_POST['attach_del']) && allowedTo('post_attachment')) {
        $del_temp = array();
        foreach ($_POST['attach_del'] as $i => $dummy) {
            $del_temp[$i] = (int) $dummy;
        }
        require_once $sourcedir . '/ManageAttachments.php';
        removeAttachments('a.attachmentType = 0 AND a.ID_MSG = ' . (int) $_REQUEST['msg'] . ' AND a.ID_ATTACH NOT IN (' . implode(', ', $del_temp) . ')');
    }
    // ...or attach a new file...
    if (isset($_FILES['attachment']['name']) || !empty($_SESSION['temp_attachments'])) {
        isAllowedTo('post_attachment');
        // If this isn't a new post, check the current attachments.
        if (isset($_REQUEST['msg'])) {
            $request = db_query("\n\t\t\t\tSELECT COUNT(*), SUM(size)\n\t\t\t\tFROM {$db_prefix}attachments\n\t\t\t\tWHERE ID_MSG = " . (int) $_REQUEST['msg'] . "\n\t\t\t\t\tAND attachmentType = 0", __FILE__, __LINE__);
            list($quantity, $total_size) = mysql_fetch_row($request);
            mysql_free_result($request);
        } else {
            $quantity = 0;
            $total_size = 0;
        }
        if (!empty($_SESSION['temp_attachments'])) {
            foreach ($_SESSION['temp_attachments'] as $attachID => $name) {
                if (preg_match('~^post_tmp_' . $ID_MEMBER . '_\\d+$~', $attachID) == 0) {
                    continue;
                }
                if (!empty($_POST['attach_del']) && !in_array($attachID, $_POST['attach_del'])) {
                    unset($_SESSION['temp_attachments'][$attachID]);
                    @unlink($modSettings['attachmentUploadDir'] . '/' . $attachID);
                    continue;
                }
                $_FILES['attachment']['tmp_name'][] = $attachID;
                $_FILES['attachment']['name'][] = addslashes($name);
                $_FILES['attachment']['size'][] = filesize($modSettings['attachmentUploadDir'] . '/' . $attachID);
                list($_FILES['attachment']['width'][], $_FILES['attachment']['height'][]) = @getimagesize($modSettings['attachmentUploadDir'] . '/' . $attachID);
                unset($_SESSION['temp_attachments'][$attachID]);
            }
        }
        if (!isset($_FILES['attachment']['name'])) {
            $_FILES['attachment']['tmp_name'] = array();
        }
        $attachIDs = array();
        foreach ($_FILES['attachment']['tmp_name'] as $n => $dummy) {
            if ($_FILES['attachment']['name'][$n] == '') {
                continue;
            }
            // Have we reached the maximum number of files we are allowed?
            $quantity++;
            if (!empty($modSettings['attachmentNumPerPostLimit']) && $quantity > $modSettings['attachmentNumPerPostLimit']) {
                fatal_lang_error('attachments_limit_per_post', false, array($modSettings['attachmentNumPerPostLimit']));
            }
            // Check the total upload size for this post...
            $total_size += $_FILES['attachment']['size'][$n];
            if (!empty($modSettings['attachmentPostLimit']) && $total_size > $modSettings['attachmentPostLimit'] * 1024) {
                fatal_lang_error('smf122', false, array($modSettings['attachmentPostLimit']));
            }
            $attachmentOptions = array('post' => isset($_REQUEST['msg']) ? $_REQUEST['msg'] : 0, 'poster' => $ID_MEMBER, 'name' => $_FILES['attachment']['name'][$n], 'tmp_name' => $_FILES['attachment']['tmp_name'][$n], 'size' => $_FILES['attachment']['size'][$n]);
            if (createAttachment($attachmentOptions)) {
                $attachIDs[] = $attachmentOptions['id'];
                if (!empty($attachmentOptions['thumb'])) {
                    $attachIDs[] = $attachmentOptions['thumb'];
                }
            } else {
                if (in_array('could_not_upload', $attachmentOptions['errors'])) {
                    fatal_lang_error('smf124');
                }
                if (in_array('too_large', $attachmentOptions['errors'])) {
                    fatal_lang_error('smf122', false, array($modSettings['attachmentSizeLimit']));
                }
                if (in_array('bad_extension', $attachmentOptions['errors'])) {
                    fatal_error($attachmentOptions['name'] . '.<br />' . $txt['smf123'] . ' ' . $modSettings['attachmentExtensions'] . '.', false);
                }
                if (in_array('directory_full', $attachmentOptions['errors'])) {
                    fatal_lang_error('smf126');
                }
                if (in_array('bad_filename', $attachmentOptions['errors'])) {
                    fatal_error(basename($attachmentOptions['name']) . '.<br />' . $txt['smf130b'] . '.');
                }
                if (in_array('taken_filename', $attachmentOptions['errors'])) {
                    fatal_lang_error('smf125');
                }
            }
        }
    }
    // Make the poll...
    if (isset($_REQUEST['poll'])) {
        // Create the poll.
        db_query("\n\t\t\tINSERT INTO {$db_prefix}polls\n\t\t\t\t(question, hideResults, maxVotes, expireTime, ID_MEMBER, posterName, changeVote)\n\t\t\tVALUES (SUBSTRING('{$_POST['question']}', 1, 255), {$_POST['poll_hide']}, {$_POST['poll_max_votes']},\n\t\t\t\t" . (empty($_POST['poll_expire']) ? '0' : time() + $_POST['poll_expire'] * 3600 * 24) . ", {$ID_MEMBER}, SUBSTRING('{$_POST['guestname']}', 1, 255), {$_POST['poll_change_vote']})", __FILE__, __LINE__);
        $ID_POLL = db_insert_id();
        // Create each answer choice.
        $i = 0;
        $setString = '';
        foreach ($_POST['options'] as $option) {
            $setString .= "\n\t\t\t\t\t({$ID_POLL}, {$i}, SUBSTRING('{$option}', 1, 255)),";
            $i++;
        }
        db_query("\n\t\t\tINSERT INTO {$db_prefix}poll_choices\n\t\t\t\t(ID_POLL, ID_CHOICE, label)\n\t\t\tVALUES" . substr($setString, 0, -1), __FILE__, __LINE__);
    } else {
        $ID_POLL = 0;
    }
    // Creating a new topic?
    $newTopic = empty($_REQUEST['msg']) && empty($topic);
    // Collect all parameters for the creation or modification of a post.
    $msgOptions = array('id' => empty($_REQUEST['msg']) ? 0 : (int) $_REQUEST['msg'], 'subject' => $_POST['subject'], 'body' => $_POST['message'], 'icon' => preg_replace('~[\\./\\\\*\':"<>]~', '', $_POST['icon']), 'smileys_enabled' => !isset($_POST['ns']), 'attachments' => empty($attachIDs) ? array() : $attachIDs);
    $topicOptions = array('id' => empty($topic) ? 0 : $topic, 'board' => $board, 'poll' => isset($_REQUEST['poll']) ? $ID_POLL : null, 'lock_mode' => isset($_POST['lock']) ? (int) $_POST['lock'] : null, 'sticky_mode' => isset($_POST['sticky']) && !empty($modSettings['enableStickyTopics']) ? (int) $_POST['sticky'] : null, 'mark_as_read' => true);
    $posterOptions = array('id' => $ID_MEMBER, 'name' => $_POST['guestname'], 'email' => $_POST['email'], 'update_post_count' => !$user_info['is_guest'] && !isset($_REQUEST['msg']) && $board_info['posts_count']);
    // This is an already existing message. Edit it.
    if (!empty($_REQUEST['msg'])) {
        // Have admins allowed people to hide their screwups?
        if (time() - $row['posterTime'] > $modSettings['edit_wait_time'] || $ID_MEMBER != $row['ID_MEMBER']) {
            $msgOptions['modify_time'] = time();
            $msgOptions['modify_name'] = addslashes($user_info['name']);
        }
        modifyPost($msgOptions, $topicOptions, $posterOptions);
    } else {
        createPost($msgOptions, $topicOptions, $posterOptions);
        if (isset($topicOptions['id'])) {
            $topic = $topicOptions['id'];
        }
    }
    // Editing or posting an event?
    if (isset($_POST['calendar']) && (!isset($_REQUEST['eventid']) || $_REQUEST['eventid'] == -1)) {
        require_once $sourcedir . '/Calendar.php';
        calendarCanLink();
        calendarInsertEvent($board, $topic, $_POST['evtitle'], $ID_MEMBER, $_POST['month'], $_POST['day'], $_POST['year'], isset($_POST['span']) ? $_POST['span'] : null);
    } elseif (isset($_POST['calendar'])) {
        $_REQUEST['eventid'] = (int) $_REQUEST['eventid'];
        // Validate the post...
        require_once $sourcedir . '/Subs-Post.php';
        calendarValidatePost();
        // If you're not allowed to edit any events, you have to be the poster.
        if (!allowedTo('calendar_edit_any')) {
            // Get the event's poster.
            $request = db_query("\n\t\t\t\tSELECT ID_MEMBER\n\t\t\t\tFROM {$db_prefix}calendar\n\t\t\t\tWHERE ID_EVENT = {$_REQUEST['eventid']}", __FILE__, __LINE__);
            $row2 = mysql_fetch_assoc($request);
            mysql_free_result($request);
            // Silly hacker, Trix are for kids. ...probably trademarked somewhere, this is FAIR USE! (parody...)
            isAllowedTo('calendar_edit_' . ($row2['ID_MEMBER'] == $ID_MEMBER ? 'own' : 'any'));
        }
        // Delete it?
        if (isset($_REQUEST['deleteevent'])) {
            db_query("\n\t\t\t\tDELETE FROM {$db_prefix}calendar\n\t\t\t\tWHERE ID_EVENT = {$_REQUEST['eventid']}\n\t\t\t\tLIMIT 1", __FILE__, __LINE__);
        } else {
            $span = !empty($modSettings['cal_allowspan']) && !empty($_REQUEST['span']) ? min((int) $modSettings['cal_maxspan'], (int) $_REQUEST['span'] - 1) : 0;
            $start_time = mktime(0, 0, 0, (int) $_REQUEST['month'], (int) $_REQUEST['day'], (int) $_REQUEST['year']);
            db_query("\n\t\t\t\tUPDATE {$db_prefix}calendar\n\t\t\t\tSET endDate = '" . strftime('%Y-%m-%d', $start_time + $span * 86400) . "',\n\t\t\t\t\tstartDate = '" . strftime('%Y-%m-%d', $start_time) . "',\n\t\t\t\t\ttitle = '" . $func['htmlspecialchars']($_REQUEST['evtitle'], ENT_QUOTES) . "'\n\t\t\t\tWHERE ID_EVENT = {$_REQUEST['eventid']}\n\t\t\t\tLIMIT 1", __FILE__, __LINE__);
        }
        updateStats('calendar');
    }
    // Marking read should be done even for editing messages....
    if (!$user_info['is_guest']) {
        // Mark all the parents read.  (since you just posted and they will be unread.)
        if (!empty($board_info['parent_boards'])) {
            db_query("\n\t\t\t\tUPDATE {$db_prefix}log_boards\n\t\t\t\tSET ID_MSG = {$modSettings['maxMsgID']}\n\t\t\t\tWHERE ID_MEMBER = {$ID_MEMBER}\n\t\t\t\t\tAND ID_BOARD IN (" . implode(',', array_keys($board_info['parent_boards'])) . ")", __FILE__, __LINE__);
        }
    }
    // Turn notification on or off.  (note this just blows smoke if it's already on or off.)
    if (!empty($_POST['notify'])) {
        if (allowedTo('mark_any_notify')) {
            db_query("\n\t\t\t\tINSERT IGNORE INTO {$db_prefix}log_notify\n\t\t\t\t\t(ID_MEMBER, ID_TOPIC, ID_BOARD)\n\t\t\t\tVALUES ({$ID_MEMBER}, {$topic}, 0)", __FILE__, __LINE__);
        }
    } elseif (!$newTopic) {
        db_query("\n\t\t\tDELETE FROM {$db_prefix}log_notify\n\t\t\tWHERE ID_MEMBER = {$ID_MEMBER}\n\t\t\t\tAND ID_TOPIC = {$topic}\n\t\t\tLIMIT 1", __FILE__, __LINE__);
    }
    // Log an act of moderation - modifying.
    if (!empty($moderationAction)) {
        logAction('modify', array('topic' => $topic, 'message' => (int) $_REQUEST['msg'], 'member' => $row['ID_MEMBER']));
    }
    if (isset($_POST['lock']) && $_POST['lock'] != 2) {
        logAction('lock', array('topic' => $topicOptions['id']));
    }
    if (isset($_POST['sticky']) && !empty($modSettings['enableStickyTopics'])) {
        logAction('sticky', array('topic' => $topicOptions['id']));
    }
    // Notify any members who have notification turned on for this topic.
    if ($newTopic) {
        notifyMembersBoard();
    } elseif (empty($_REQUEST['msg'])) {
        sendNotifications($topic, 'reply');
    }
    // Returning to the topic?
    if (!empty($_REQUEST['goback'])) {
        // Mark the board as read.... because it might get confusing otherwise.
        db_query("\n\t\t\tUPDATE {$db_prefix}log_boards\n\t\t\tSET ID_MSG = {$modSettings['maxMsgID']}\n\t\t\tWHERE ID_MEMBER = {$ID_MEMBER}\n\t\t\t\tAND ID_BOARD = {$board}", __FILE__, __LINE__);
    }
    if (!empty($_POST['announce_topic'])) {
        redirectexit('action=announce;sa=selectgroup;topic=' . $topic . (!empty($_POST['move']) && allowedTo('move_any') ? ';move' : '') . (empty($_REQUEST['goback']) ? '' : ';goback'));
    }
    if (!empty($_POST['move']) && allowedTo('move_any')) {
        redirectexit('action=movetopic;topic=' . $topic . '.0' . (empty($_REQUEST['goback']) ? '' : ';goback'));
    }
    // Return to post if the mod is on.
    if (isset($_REQUEST['msg']) && !empty($_REQUEST['goback'])) {
        redirectexit('topic=' . $topic . '.msg' . $_REQUEST['msg'] . '#msg' . $_REQUEST['msg'], $context['browser']['is_ie']);
    } elseif (!empty($_REQUEST['goback'])) {
        redirectexit('topic=' . $topic . '.new#new', $context['browser']['is_ie']);
    } else {
        redirectexit('board=' . $board . '.0');
    }
}
Esempio n. 8
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;
}
Esempio n. 9
0
function resetPassword($memID, $username = null)
{
    global $db_prefix, $scripturl, $context, $txt, $sourcedir, $modSettings;
    // Language... and a required file.
    loadLanguage('Login');
    require_once $sourcedir . '/Subs-Post.php';
    // Get some important details.
    $request = db_query("\n\t\tSELECT memberName, emailAddress\n\t\tFROM {$db_prefix}members\n\t\tWHERE ID_MEMBER = {$memID}", __FILE__, __LINE__);
    list($user, $email) = mysql_fetch_row($request);
    mysql_free_result($request);
    if ($username !== null) {
        $old_user = $user;
        $user = trim($username);
    }
    // Generate a random password.
    require_once $sourcedir . '/Subs-Members.php';
    $newPassword = generateValidationCode();
    $newPassword_sha1 = sha1(strtolower($user) . $newPassword);
    // Do some checks on the username if needed.
    if ($username !== null) {
        // No name?!  How can you register with no name?
        if ($user == '') {
            fatal_lang_error(37, false);
        }
        // Only these characters are permitted.
        if (in_array($user, array('_', '|')) || preg_match('~[<>&"\'=\\\\]~', $user) != 0 || strpos($user, '[code') !== false || strpos($user, '[/code') !== false) {
            fatal_lang_error(240, false);
        }
        if (stristr($user, $txt[28]) !== false) {
            fatal_lang_error(244, true, array($txt[28]));
        }
        require_once $sourcedir . '/Subs-Members.php';
        if (isReservedName($user, $memID, false)) {
            fatal_error('(' . htmlspecialchars($user) . ') ' . $txt[473], false);
        }
        // Update the database...
        updateMemberData($memID, array('memberName' => '\'' . $user . '\'', 'passwd' => '\'' . $newPassword_sha1 . '\''));
    } else {
        updateMemberData($memID, array('passwd' => '\'' . $newPassword_sha1 . '\''));
    }
    if (isset($modSettings['integrate_reset_pass']) && function_exists($modSettings['integrate_reset_pass'])) {
        call_user_func($modSettings['integrate_reset_pass'], $old_user, $user, $newPassword);
    }
    // Send them the email informing them of the change - then we're done!
    sendmail($email, $txt['change_password'], "{$txt['hello_member']} {$user}!\n\n" . "{$txt['change_password_1']} {$context['forum_name']} {$txt['change_password_2']}\n\n" . "{$txt['719']}{$user}, {$txt['492']} {$newPassword}\n\n" . "{$txt['701']}\n" . "{$scripturl}?action=profile\n\n" . $txt[130]);
}
Esempio n. 10
0
function Register2()
{
    global $scripturl, $txt, $modSettings, $db_prefix, $context, $sourcedir;
    global $user_info, $options, $settings, $func;
    // Well, if you don't agree, you can't register.
    if (!empty($modSettings['requireAgreement']) && (empty($_POST['regagree']) || $_POST['regagree'] == 'no')) {
        redirectexit();
    }
    // Make sure they came from *somewhere*, have a session.
    if (!isset($_SESSION['old_url'])) {
        redirectexit('action=register');
    }
    // You can't register if it's disabled.
    if (!empty($modSettings['registration_method']) && $modSettings['registration_method'] == 3) {
        fatal_lang_error('registration_disabled', false);
    }
    foreach ($_POST as $key => $value) {
        if (!is_array($_POST[$key])) {
            $_POST[$key] = htmltrim__recursive(str_replace(array("\n", "\r"), '', $_POST[$key]));
        }
    }
    // Did they answer the verification questions correctly?
    if (!empty($modSettings['anti_spam_ver_enable'])) {
        if (!empty($modSettings['anti_spam_ver_ques_1']) && strcmp(strtolower($modSettings['anti_spam_ver_ans_1']), isset($_POST['anti_spam_ver_resp_1']) ? strtolower($_POST['anti_spam_ver_resp_1']) : '') || !empty($modSettings['anti_spam_ver_ques_2']) && strcmp(strtolower($modSettings['anti_spam_ver_ans_2']), isset($_POST['anti_spam_ver_resp_2']) ? strtolower($_POST['anti_spam_ver_resp_2']) : '') || !empty($modSettings['anti_spam_ver_ques_3']) && strcmp(strtolower($modSettings['anti_spam_ver_ans_3']), isset($_POST['anti_spam_ver_resp_3']) ? strtolower($_POST['anti_spam_ver_resp_3']) : '') || !empty($modSettings['anti_spam_ver_ques_4']) && strcmp(strtolower($modSettings['anti_spam_ver_ans_4']), isset($_POST['anti_spam_ver_resp_4']) ? strtolower($_POST['anti_spam_ver_resp_4']) : '') || !empty($modSettings['anti_spam_ver_ques_5']) && strcmp(strtolower($modSettings['anti_spam_ver_ans_5']), isset($_POST['anti_spam_ver_resp_5']) ? strtolower($_POST['anti_spam_ver_resp_5']) : '')) {
            fatal_lang_error('anti_spam_ver_failed', false);
        }
    }
    // Are they under age, and under age users are banned?
    if (!empty($modSettings['coppaAge']) && empty($modSettings['coppaType']) && !isset($_POST['skip_coppa'])) {
        // !!! This should be put in Errors, imho.
        loadLanguage('Login');
        fatal_lang_error('under_age_registration_prohibited', false, array($modSettings['coppaAge']));
    }
    // Check whether the visual verification code was entered correctly.
    if ((empty($modSettings['disable_visual_verification']) || $modSettings['disable_visual_verification'] != 1) && (empty($_REQUEST['visual_verification_code']) || strtoupper($_REQUEST['visual_verification_code']) !== $_SESSION['visual_verification_code'])) {
        $_SESSION['visual_errors'] = isset($_SESSION['visual_errors']) ? $_SESSION['visual_errors'] + 1 : 1;
        if ($_SESSION['visual_errors'] > 3 && isset($_SESSION['visual_verification_code'])) {
            unset($_SESSION['visual_verification_code']);
        }
        fatal_lang_error('visual_verification_failed', false);
    } elseif (isset($_SESSION['visual_errors'])) {
        unset($_SESSION['visual_errors']);
    }
    // Collect all extra registration fields someone might have filled in.
    $possible_strings = array('websiteUrl', 'websiteTitle', 'AIM', 'YIM', 'location', 'birthdate', 'timeFormat', 'buddy_list', 'pm_ignore_list', 'smileySet', 'signature', 'personalText', 'avatar', 'lngfile', 'secretQuestion', 'secretAnswer');
    $possible_ints = array('pm_email_notify', 'notifyTypes', 'ICQ', 'gender', 'ID_THEME');
    $possible_floats = array('timeOffset');
    $possible_bools = array('notifyAnnouncements', 'notifyOnce', 'notifySendBody', 'hideEmail', 'showOnline');
    if (isset($_POST['secretAnswer']) && $_POST['secretAnswer'] != '') {
        $_POST['secretAnswer'] = md5($_POST['secretAnswer']);
    }
    // Needed for isReservedName() and registerMember().
    require_once $sourcedir . '/Subs-Members.php';
    // Validation... even if we're not a mall.
    if (isset($_POST['realName']) && (!empty($modSettings['allow_editDisplayName']) || allowedTo('moderate_forum'))) {
        $_POST['realName'] = trim(preg_replace('~[\\s]~' . ($context['utf8'] ? 'u' : ''), ' ', $_POST['realName']));
        if (trim($_POST['realName']) != '' && !isReservedName($_POST['realName']) && $func['strlen']($_POST['realName']) <= 60) {
            $possible_strings[] = 'realName';
        }
    }
    if (isset($_POST['MSN']) && preg_match('~^[0-9A-Za-z=_+\\-/][0-9A-Za-z=_\'+\\-/\\.]*@[\\w\\-]+(\\.[\\w\\-]+)*(\\.[\\w]{2,6})$~', $_POST['MSN']) != 0) {
        $profile_strings[] = 'MSN';
    }
    // Handle a string as a birthdate...
    if (isset($_POST['birthdate']) && $_POST['birthdate'] != '') {
        $_POST['birthdate'] = strftime('%Y-%m-%d', strtotime($_POST['birthdate']));
    } elseif (!empty($_POST['bday1']) && !empty($_POST['bday2'])) {
        $_POST['birthdate'] = sprintf('%04d-%02d-%02d', empty($_POST['bday3']) ? 0 : (int) $_POST['bday3'], (int) $_POST['bday1'], (int) $_POST['bday2']);
    }
    // Validate the passed langauge file.
    if (isset($_POST['lngfile']) && !empty($modSettings['userLanguage'])) {
        $language_directories = array($settings['default_theme_dir'] . '/languages', $settings['actual_theme_dir'] . '/languages');
        if (!empty($settings['base_theme_dir'])) {
            $language_directories[] = $settings['base_theme_dir'] . '/languages';
        }
        $language_directories = array_unique($language_directories);
        foreach ($language_directories as $language_dir) {
            if (!file_exists($language_dir)) {
                continue;
            }
            $dir = dir($language_dir);
            while ($entry = $dir->read()) {
                if (preg_match('~^index\\.(.+)\\.php$~', $entry, $matches) && $matches[1] == $_POST['lngfile']) {
                    // Got it!
                    $found = true;
                    $_SESSION['language'] = $_POST['lngfile'];
                    break 2;
                }
            }
            $dir->close();
        }
        if (empty($found)) {
            unset($_POST['lngfile']);
        }
    } else {
        unset($_POST['lngfile']);
    }
    // Set the options needed for registration.
    $regOptions = array('interface' => 'guest', 'username' => $_POST['user'], 'email' => $_POST['email'], 'password' => $_POST['passwrd1'], 'password_check' => $_POST['passwrd2'], 'check_reserved_name' => true, 'check_password_strength' => true, 'check_email_ban' => true, 'send_welcome_email' => !empty($modSettings['send_welcomeEmail']), 'require' => !empty($modSettings['coppaAge']) && !isset($_POST['skip_coppa']) ? 'coppa' : (empty($modSettings['registration_method']) ? 'nothing' : ($modSettings['registration_method'] == 1 ? 'activation' : 'approval')), 'extra_register_vars' => array(), 'theme_vars' => array());
    // Include the additional options that might have been filled in.
    foreach ($possible_strings as $var) {
        if (isset($_POST[$var])) {
            $regOptions['extra_register_vars'][$var] = '\'' . $func['htmlspecialchars']($_POST[$var]) . '\'';
        }
    }
    foreach ($possible_ints as $var) {
        if (isset($_POST[$var])) {
            $regOptions['extra_register_vars'][$var] = (int) $_POST[$var];
        }
    }
    foreach ($possible_floats as $var) {
        if (isset($_POST[$var])) {
            $regOptions['extra_register_vars'][$var] = (double) $_POST[$var];
        }
    }
    foreach ($possible_bools as $var) {
        if (isset($_POST[$var])) {
            $regOptions['extra_register_vars'][$var] = empty($_POST[$var]) ? 0 : 1;
        }
    }
    // Registration options are always default options...
    if (isset($_POST['default_options'])) {
        $_POST['options'] = isset($_POST['options']) ? $_POST['options'] + $_POST['default_options'] : $_POST['default_options'];
    }
    $regOptions['theme_vars'] = isset($_POST['options']) && is_array($_POST['options']) ? htmlspecialchars__recursive($_POST['options']) : array();
    $memberID = registerMember($regOptions);
    // If COPPA has been selected then things get complicated, setup the template.
    if (!empty($modSettings['coppaAge']) && !isset($_POST['skip_coppa'])) {
        redirectexit('action=coppa;member=' . $memberID);
    } elseif (!empty($modSettings['registration_method'])) {
        loadTemplate('Register');
        $context += array('page_title' => &$txt[97], 'sub_template' => 'after', 'description' => $modSettings['registration_method'] == 2 ? $txt['approval_after_registration'] : $txt['activate_after_registration']);
    } else {
        setLoginCookie(60 * $modSettings['cookieTime'], $memberID, sha1(sha1(strtolower($regOptions['username']) . $regOptions['password']) . substr($regOptions['register_vars']['passwordSalt'], 1, -1)));
        redirectexit('action=login2;sa=check;member=' . $memberID, $context['server']['needs_login_fix']);
    }
}
Esempio n. 11
0
function RegisterCheckUsername()
{
    global $sourcedir, $smcFunc, $context, $txt;
    // This is XML!
    loadTemplate('Xml');
    $context['sub_template'] = 'check_username';
    $context['checked_username'] = isset($_GET['username']) ? $_GET['username'] : '';
    $context['valid_username'] = true;
    // Clean it up like mother would.
    $context['checked_username'] = preg_replace('~[\\t\\n\\r \\x0B\\0' . ($context['utf8'] ? $context['server']['complex_preg_chars'] ? '\\x{A0}\\x{AD}\\x{2000}-\\x{200F}\\x{201F}\\x{202F}\\x{3000}\\x{FEFF}' : " ­ -‏‟ ‟ " : '\\x00-\\x08\\x0B\\x0C\\x0E-\\x19\\xA0') . ']+~' . ($context['utf8'] ? 'u' : ''), ' ', $context['checked_username']);
    if ($smcFunc['strlen']($context['checked_username']) > 25) {
        $context['checked_username'] = $smcFunc['htmltrim']($smcFunc['substr']($context['checked_username'], 0, 25));
    }
    //xxx only allow these characters
    if (!RegisterUserIsAllowed($context['checked_username'], "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ /-:.%0123456789_")) {
        $context['valid_username'] = false;
    }
    // Only these characters are permitted.
    if (preg_match('~[<>&"\'=\\\\]~', preg_replace('~&#(?:\\d{1,7}|x[0-9a-fA-F]{1,6});~', '', $context['checked_username'])) != 0 || $context['checked_username'] == '_' || $context['checked_username'] == '|' || strpos($context['checked_username'], '[code') !== false || strpos($context['checked_username'], '[/code') !== false) {
        $context['valid_username'] = false;
    }
    if (stristr($context['checked_username'], $txt['guest_title']) !== false) {
        $context['valid_username'] = false;
    }
    if (trim($context['checked_username']) == '') {
        $context['valid_username'] = false;
    } else {
        require_once $sourcedir . '/Subs-Members.php';
        $context['valid_username'] &= isReservedName($context['checked_username'], 0, false, false) ? 0 : 1;
    }
}
Esempio n. 12
0
function loadProfileFields($force_reload = false)
{
    global $context, $profile_fields, $txt, $scripturl, $modSettings, $user_info, $old_profile, $smcFunc, $cur_profile, $language;
    // Don't load this twice!
    if (!empty($profile_fields) && !$force_reload) {
        return;
    }
    /* This horrific array defines all the profile fields in the whole world!
    		In general each "field" has one array - the key of which is the database column name associated with said field. Each item
    		can have the following attributes:
    
    				string $type:			The type of field this is - valid types are:
    					- callback:		This is a field which has its own callback mechanism for templating.
    					- check:		A simple checkbox.
    					- hidden:		This doesn't have any visual aspects but may have some validity.
    					- password:		A password box.
    					- select:		A select box.
    					- text:			A string of some description.
    
    				string $label:			The label for this item - default will be $txt[$key] if this isn't set.
    				string $subtext:		The subtext (Small label) for this item.
    				int $size:			Optional size for a text area.
    				array $input_attr:		An array of text strings to be added to the input box for this item.
    				string $value:			The value of the item. If not set $cur_profile[$key] is assumed.
    				string $permission:		Permission required for this item (Excluded _any/_own subfix which is applied automatically).
    				function $input_validate:	A runtime function which validates the element before going to the database. It is passed
    								the relevant $_POST element if it exists and should be treated like a reference.
    
    								Return types:
    					- true:			Element can be stored.
    					- false:		Skip this element.
    					- a text string:	An error occured - this is the error message.
    
    				function $preload:		A function that is used to load data required for this element to be displayed. Must return
    								true to be displayed at all.
    
    				string $cast_type:		If set casts the element to a certain type. Valid types (bool, int, float).
    				string $save_key:		If the index of this element isn't the database column name it can be overriden
    								with this string.
    				bool $is_dummy:			If set then nothing is acted upon for this element.
    				bool $enabled:			A test to determine whether this is even available - if not is unset.
    				string $link_with:		Key which links this field to an overall set.
    
    		Note that all elements that have a custom input_validate must ensure they set the value of $cur_profile correct to enable
    		the changes to be displayed correctly on submit of the form.
    
    	*/
    $profile_fields = array('avatar_choice' => array('type' => 'callback_template', 'callback_name' => 'profile/avatar_select', 'preload' => 'profileLoadAvatarData', 'input_validate' => 'profileSaveAvatarData', 'save_key' => 'avatar'), 'bday1' => array('type' => 'callback_template', 'callback_name' => 'profile/birthdate_select', 'permission' => 'profile_extra', 'preload' => function () {
        global $cur_profile, $context;
        // Split up the birthdate....
        list($uyear, $umonth, $uday) = explode('-', empty($cur_profile['birthdate']) || $cur_profile['birthdate'] == '0001-01-01' ? '0000-00-00' : $cur_profile['birthdate']);
        $context['member']['birth_date'] = array('year' => $uyear == '0004' ? '0000' : $uyear, 'month' => $umonth, 'day' => $uday);
        return true;
    }, 'input_validate' => function (&$value) {
        global $profile_vars, $cur_profile;
        if (isset($_POST['bday2'], $_POST['bday3']) && $value > 0 && $_POST['bday2'] > 0) {
            // Set to blank?
            if ((int) $_POST['bday3'] == 1 && (int) $_POST['bday2'] == 1 && (int) $value == 1) {
                $value = '0001-01-01';
            } else {
                $value = checkdate($value, $_POST['bday2'], $_POST['bday3'] < 4 ? 4 : $_POST['bday3']) ? sprintf('%04d-%02d-%02d', $_POST['bday3'] < 4 ? 4 : $_POST['bday3'], $_POST['bday1'], $_POST['bday2']) : '0001-01-01';
            }
        } else {
            $value = '0001-01-01';
        }
        $profile_vars['birthdate'] = $value;
        $cur_profile['birthdate'] = $value;
        return false;
    }), 'birthdate' => array('type' => 'hidden', 'permission' => 'profile_extra', 'input_validate' => function (&$value) {
        global $cur_profile;
        // !!! Should we check for this year and tell them they made a mistake :P? (based on coppa at least?)
        if (preg_match('/(\\d{4})[\\-\\., ](\\d{2})[\\-\\., ](\\d{2})/', $value, $dates) === 1) {
            $value = checkdate($dates[2], $dates[3], $dates[1] < 4 ? 4 : $dates[1]) ? sprintf('%04d-%02d-%02d', $dates[1] < 4 ? 4 : $dates[1], $dates[2], $dates[3]) : '0001-01-01';
            return true;
        } else {
            $value = empty($cur_profile['birthdate']) ? '0001-01-01' : $cur_profile['birthdate'];
            return false;
        }
    }), 'date_registered' => array('type' => 'text', 'value' => empty($cur_profile['date_registered']) ? $txt['not_applicable'] : strftime('%Y-%m-%d', $cur_profile['date_registered'] + ($user_info['time_offset'] + $modSettings['time_offset']) * 3600), 'label' => $txt['date_registered'], 'log_change' => true, 'permission' => 'moderate_forum', 'input_validate' => function (&$value) {
        global $txt, $user_info, $modSettings, $cur_profile, $context;
        // Bad date!  Go try again - please?
        if (($value = strtotime($value)) === -1) {
            $value = $cur_profile['date_registered'];
            return $txt['invalid_registration'] . ' ' . strftime('%d %b %Y ' . (strpos($user_info['time_format'], '%H') !== false ? '%I:%M:%S %p' : '%H:%M:%S'), forum_time(false));
        } elseif ($value != $txt['not_applicable'] && $value != strtotime(strftime('%Y-%m-%d', $cur_profile['date_registered'] + ($user_info['time_offset'] + $modSettings['time_offset']) * 3600))) {
            $value = $value - ($user_info['time_offset'] + $modSettings['time_offset']) * 3600;
        } else {
            $value = $cur_profile['date_registered'];
        }
        return true;
    }), 'email_address' => array('type' => 'text', 'label' => $txt['email'], 'subtext' => $txt['valid_email'], 'log_change' => true, 'permission' => 'profile_identity', 'input_validate' => function (&$value) {
        global $context, $old_profile, $context, $profile_vars, $sourcedir, $modSettings;
        if (strtolower($value) == strtolower($old_profile['email_address'])) {
            return false;
        }
        $isValid = profileValidateEmail($value, $context['id_member']);
        // Do they need to revalidate? If so schedule the function!
        if ($isValid === true && !empty($modSettings['send_validation_onChange']) && !allowedTo('moderate_forum')) {
            require_once $sourcedir . '/lib/Subs-Members.php';
            $profile_vars['validation_code'] = generateValidationCode();
            $profile_vars['is_activated'] = 2;
            $context['profile_execute_on_save'][] = 'profileSendActivation';
            unset($context['profile_execute_on_save']['reload_user']);
        }
        return $isValid;
    }), 'gender' => array('type' => 'select', 'cast_type' => 'int', 'options' => 'return array(0 => \'\', 1 => $txt[\'male\'], 2 => $txt[\'female\']);', 'label' => $txt['gender'], 'permission' => 'profile_extra'), 'hide_email' => array('type' => 'check', 'value' => empty($cur_profile['hide_email']) ? true : false, 'label' => $txt['allow_user_email'], 'permission' => 'profile_identity', 'input_validate' => function (&$value) {
        $value = $value == 0 ? 1 : 0;
        return true;
    }), 'id_group' => array('type' => 'callback_template', 'callback_name' => 'profile/group_manage', 'permission' => 'manage_membergroups', 'preload' => 'profileLoadGroups', 'log_change' => true, 'input_validate' => 'profileSaveGroups'), 'id_theme' => array('type' => 'callback_template', 'callback_name' => 'profile/theme_pick', 'permission' => 'profile_extra', 'enabled' => $modSettings['theme_allow'] || allowedTo('admin_forum'), 'preload' => function () {
        global $context, $cur_profile, $txt;
        $request = smf_db_query('SELECT value
					FROM {db_prefix}themes
					WHERE id_theme = {int:id_theme}
						AND variable = {string:variable}
					LIMIT 1', array('id_theme' => $cur_profile['id_theme'], 'variable' => 'name'));
        list($name) = mysql_fetch_row($request);
        mysql_free_result($request);
        $context['member']['theme'] = array('id' => $cur_profile['id_theme'], 'name' => empty($cur_profile['id_theme']) ? $txt['theme_forum_default'] : $name);
        return true;
    }, 'input_validate' => function (&$value) {
        $value = (int) $value;
        return true;
    }), 'karma_good' => array('type' => 'callback_template', 'callback_name' => 'profile/reputation_display', 'permission' => 'admin_forum', 'input_validate' => function (&$value) {
        global $profile_vars, $cur_profile;
        $value = (int) $value;
        if (isset($_POST['karma_bad'])) {
            $profile_vars['karma_bad'] = $_POST['karma_bad'] != '' ? (int) $_POST['karma_bad'] : 0;
            $cur_profile['karma_bad'] = $_POST['karma_bad'] != '' ? (int) $_POST['karma_bad'] : 0;
        }
        return true;
    }, 'preload' => function () {
        global $context, $cur_profile;
        //$context['member']['karma']['good'] = $cur_profile['karma_good'];
        //$context['member']['karma']['bad'] = $cur_profile['karma_bad'];
        return true;
    }, 'enabled' => !empty($modSettings['karmaMode'])), 'lngfile' => array('type' => 'select', 'options' => 'return $context[\'profile_languages\'];', 'label' => $txt['preferred_language'], 'permission' => 'profile_identity', 'preload' => 'profileLoadLanguages', 'enabled' => !empty($modSettings['userLanguage']), 'value' => empty($cur_profile['lngfile']) ? $language : $cur_profile['lngfile'], 'input_validate' => function (&$value) {
        global $context, $cur_profile;
        // Load the languages.
        profileLoadLanguages();
        if (isset($context['profile_languages'][$value])) {
            if ($context['user']['is_owner']) {
                $_SESSION['language'] = $value;
            }
            return true;
        } else {
            $value = $cur_profile['lngfile'];
            return false;
        }
    }), 'location' => array('type' => 'text', 'label' => $txt['location'], 'log_change' => true, 'size' => 50, 'permission' => 'profile_extra'), 'member_name' => array('type' => allowedTo('admin_forum') && isset($_GET['changeusername']) ? 'text' : 'label', 'label' => $txt['username'], 'subtext' => allowedTo('admin_forum') && !isset($_GET['changeusername']) ? '(<a href="' . $scripturl . '?action=profile;u=' . $context['id_member'] . ';area=account;changeusername" style="font-style: italic;">' . $txt['username_change'] . '</a>)' : '', 'log_change' => true, 'permission' => 'profile_identity', 'prehtml' => allowedTo('admin_forum') && isset($_GET['changeusername']) ? '<div class="alert">' . $txt['username_warning'] . '</div>' : '', 'input_validate' => function (&$value) {
        global $sourcedir, $context, $user_info, $cur_profile;
        if (allowedTo('admin_forum')) {
            // We\'ll need this...
            require_once $sourcedir . '/lib/Subs-Auth.php';
            // Maybe they are trying to change their password as well?
            $resetPassword = true;
            if (isset($_POST['passwrd1']) && $_POST['passwrd1'] != '' && isset($_POST['passwrd2']) && $_POST['passwrd1'] == $_POST['passwrd2'] && validatePassword($_POST['passwrd1'], $value, array($cur_profile['real_name'], $user_info['username'], $user_info['name'], $user_info['email'])) == null) {
                $resetPassword = false;
            }
            // Do the reset... this will send them an email too.
            if ($resetPassword) {
                resetPassword($context['id_member'], $value);
            } elseif ($value !== null) {
                validateUsername($context['id_member'], $value);
                updateMemberData($context['id_member'], array('member_name' => $value));
            }
        }
        return false;
    }), 'passwrd1' => array('type' => 'password', 'label' => $txt['choose_pass'], 'subtext' => $txt['password_strength'], 'size' => 20, 'value' => '', 'enabled' => empty($cur_profile['openid_uri']), 'permission' => 'profile_identity', 'save_key' => 'passwd', 'input_validate' => function (&$value) {
        global $sourcedir, $user_info, $smcFunc, $cur_profile;
        // If we didn\'t try it then ignore it!
        if ($value == '') {
            return false;
        }
        // Do the two entries for the password even match?
        if (!isset($_POST['passwrd2']) || $value != $_POST['passwrd2']) {
            return 'bad_new_password';
        }
        // Let\'s get the validation function into play...
        require_once $sourcedir . '/lib/Subs-Auth.php';
        $passwordErrors = validatePassword($value, $cur_profile['member_name'], array($cur_profile['real_name'], $user_info['username'], $user_info['name'], $user_info['email']));
        // Were there errors?
        if ($passwordErrors != null) {
            return 'password_' . $passwordErrors;
        }
        // Set up the new password variable... ready for storage.
        $value = sha1(strtolower($cur_profile['member_name']) . un_htmlspecialchars($value));
        return true;
    }), 'passwrd2' => array('type' => 'password', 'label' => $txt['verify_pass'], 'enabled' => empty($cur_profile['openid_uri']), 'size' => 20, 'value' => '', 'permission' => 'profile_identity', 'is_dummy' => true), 'personal_text' => array('type' => 'text', 'label' => $txt['personal_text'], 'log_change' => true, 'input_attr' => array('maxlength="50"'), 'size' => 50, 'permission' => 'profile_extra'), 'pm_prefs' => array('type' => 'callback_template', 'callback_name' => 'pm/settings', 'permission' => 'pm_read', 'preload' => function () {
        global $context, $cur_profile;
        $context['display_mode'] = $cur_profile['pm_prefs'] & 3;
        $context['send_email'] = $cur_profile['pm_email_notify'];
        $context['receive_from'] = !empty($cur_profile['pm_receive_from']) ? $cur_profile['pm_receive_from'] : 0;
        return true;
    }, 'input_validate' => function (&$value) {
        global $cur_profile, $profile_vars;
        // Simple validate and apply the two "sub settings"
        $value = max(min($value, 2), 0);
        $cur_profile['pm_email_notify'] = $profile_vars['pm_email_notify'] = max(min((int) $_POST['pm_email_notify'], 2), 0);
        $cur_profile['pm_receive_from'] = $profile_vars['pm_receive_from'] = max(min((int) $_POST['pm_receive_from'], 4), 0);
        return true;
    }), 'posts' => array('type' => 'int', 'label' => $txt['profile_posts'], 'log_change' => true, 'size' => 7, 'permission' => 'moderate_forum', 'input_validate' => function (&$value) {
        $value = $value != '' ? strtr($value, array(',' => '', '.' => '', ' ' => '')) : 0;
        return true;
    }), 'real_name' => array('type' => !empty($modSettings['allow_editDisplayName']) || allowedTo('moderate_forum') ? 'text' : 'label', 'label' => $txt['name'], 'subtext' => $txt['display_name_desc'], 'log_change' => true, 'input_attr' => array('maxlength="60"'), 'permission' => 'profile_identity', 'enabled' => !empty($modSettings['allow_editDisplayName']) || allowedTo('moderate_forum'), 'input_validate' => function (&$value) {
        global $context, $smcFunc, $sourcedir, $cur_profile;
        $value = trim(preg_replace('~[\\s]~' . ($context['utf8'] ? 'u' : ''), ' ', $value));
        if (trim($value) == '') {
            return 'no_name';
        } elseif (CommonAPI::strlen($value) > 60) {
            return 'name_too_long';
        } elseif ($cur_profile['real_name'] != $value) {
            require_once $sourcedir . '/lib/Subs-Members.php';
            if (isReservedName($value, $context['id_member'])) {
                return 'name_taken';
            }
        }
        return true;
    }), 'secret_question' => array('type' => 'text', 'label' => $txt['secret_question'], 'subtext' => $txt['secret_desc'], 'size' => 50, 'permission' => 'profile_identity'), 'secret_answer' => array('type' => 'text', 'label' => $txt['secret_answer'], 'subtext' => $txt['secret_desc2'], 'size' => 20, 'postinput' => '<span class="smalltext" style="margin-left: 4ex;"><a href="' . $scripturl . '?action=helpadmin;help=secret_why_blank" onclick="return reqWin(this.href);">' . $txt['secret_why_blank'] . '</a></span>', 'value' => '', 'permission' => 'profile_identity', 'input_validate' => function (&$value) {
        $value = $value != '' ? md5($value) : '';
        return true;
    }), 'signature' => array('type' => 'callback_template', 'callback_name' => allowedTo('profile_signature') ? 'profile/signature_modify' : 'profile/signature_cannot_modify', 'permission' => 'profile_extra', 'enabled' => substr($modSettings['signature_settings'], 0, 1) == 1, 'preload' => 'profileLoadSignatureData', 'input_validate' => 'profileValidateSignature'), 'show_online' => array('type' => 'check', 'label' => $txt['show_online'], 'permission' => 'profile_identity', 'enabled' => !empty($modSettings['allow_hideOnline']) || allowedTo('moderate_forum')), 'smiley_set' => array('type' => 'callback_template', 'callback_name' => 'profile/smiley_pick', 'enabled' => !empty($modSettings['smiley_sets_enable']), 'permission' => 'profile_extra', 'preload' => function () {
        global $modSettings, $context, $txt, $cur_profile;
        $context['member']['smiley_set']['id'] = empty($cur_profile['smiley_set']) ? '' : $cur_profile['smiley_set'];
        $context['smiley_sets'] = explode(',', 'none,,' . $modSettings['smiley_sets_known']);
        $set_names = explode("\n", $txt['smileys_none'] . "\n" . $txt['smileys_forum_board_default'] . "\n" . $modSettings['smiley_sets_names']);
        foreach ($context['smiley_sets'] as $i => $set) {
            $context['smiley_sets'][$i] = array('id' => htmlspecialchars($set), 'name' => htmlspecialchars($set_names[$i]), 'selected' => $set == $context['member']['smiley_set']['id']);
            if ($context['smiley_sets'][$i]['selected']) {
                $context['member']['smiley_set']['name'] = $set_names[$i];
            }
        }
        return true;
    }, 'input_validate' => function (&$value) {
        global $modSettings;
        $smiley_sets = explode(',', $modSettings['smiley_sets_known']);
        if (!in_array($value, $smiley_sets) && $value != 'none') {
            $value = '';
        }
        return true;
    }), 'theme_settings' => array('type' => 'callback_template', 'callback_name' => 'profile/theme_settings', 'permission' => 'profile_extra', 'is_dummy' => true, 'preload' => function () {
        loadLanguage('Settings');
        return true;
    }), 'time_format' => array('type' => 'callback_template', 'callback_name' => 'profile/timeformat_modify', 'permission' => 'profile_extra', 'preload' => function () {
        global $context, $user_info, $txt, $cur_profile, $modSettings;
        $context['easy_timeformats'] = array(array('format' => '', 'title' => $txt['timeformat_default']), array('format' => '%B %d, %Y, %I:%M:%S %p', 'title' => $txt['timeformat_easy1']), array('format' => '%B %d, %Y, %H:%M:%S', 'title' => $txt['timeformat_easy2']), array('format' => '%Y-%m-%d, %H:%M:%S', 'title' => $txt['timeformat_easy3']), array('format' => '%d %B %Y, %H:%M:%S', 'title' => $txt['timeformat_easy4']), array('format' => '%d-%m-%Y, %H:%M:%S', 'title' => $txt['timeformat_easy5']));
        $context['member']['time_format'] = $cur_profile['time_format'];
        $context['current_forum_time'] = strftime($modSettings['time_format'], forum_time(false)) . ' ' . date_default_timezone_get();
        $context['current_forum_time_js'] = strftime('%Y,' . ((int) strftime('%m', time() + $modSettings['time_offset'] * 3600) - 1) . ',%d,%H,%M,%S', time() + $modSettings['time_offset'] * 3600);
        $context['current_forum_time_hour'] = (int) strftime('%H', forum_time(false));
        return true;
    }), 'time_offset' => array('type' => 'callback_template', 'callback_name' => 'profile/timeoffset_modify', 'permission' => 'profile_extra', 'preload' => function () {
        global $context, $cur_profile;
        $context['member']['time_offset'] = $cur_profile['time_offset'];
        return true;
    }, 'input_validate' => function (&$value) {
        // Validate the time_offset...
        $value = (double) strtr($value, ',', '.');
        if ($value < -23.5 || $value > 23.5) {
            return 'bad_offset';
        }
        return true;
    }), 'usertitle' => array('type' => 'text', 'label' => $txt['custom_title'], 'log_change' => true, 'size' => 50, 'permission' => 'profile_title', 'input_attr' => array('maxlength="50"'), 'enabled' => !empty($modSettings['titlesEnable'])));
    $disabled_fields = !empty($modSettings['disabled_profile_fields']) ? explode(',', $modSettings['disabled_profile_fields']) : array();
    // For each of the above let's take out the bits which don't apply - to save memory and security!
    foreach ($profile_fields as $key => $field) {
        // Do we have permission to do this?
        if (isset($field['permission']) && !allowedTo($context['user']['is_owner'] ? array($field['permission'] . '_own', $field['permission'] . '_any') : $field['permission'] . '_any') && !allowedTo($field['permission'])) {
            unset($profile_fields[$key]);
        }
        // Is it enabled?
        if (isset($field['enabled']) && !$field['enabled']) {
            unset($profile_fields[$key]);
        }
        // Is it specifically disabled?
        if (in_array($key, $disabled_fields) || isset($field['link_with']) && in_array($field['link_with'], $disabled_fields)) {
            unset($profile_fields[$key]);
        }
    }
}
Esempio n. 13
0
/**
 * Checks a username obeys a load of rules
 *
 * - Returns null if fine
 *
 * @package Authorization
 * @param int $memID
 * @param string $username
 * @param string $error_context
 * @param boolean $check_reserved_name
 * @param boolean $fatal pass through to isReservedName
 * @return string
 */
function validateUsername($memID, $username, $error_context = 'register', $check_reserved_name = true, $fatal = true)
{
    global $txt;
    $errors = Error_Context::context($error_context, 0);
    // Don't use too long a name.
    if (Util::strlen($username) > 25) {
        $errors->addError('error_long_name');
    }
    // No name?!  How can you register with no name?
    if ($username == '') {
        $errors->addError('need_username');
    }
    // Only these characters are permitted.
    if (in_array($username, array('_', '|')) || preg_match('~[<>&"\'=\\\\]~', preg_replace('~&#(?:\\d{1,7}|x[0-9a-fA-F]{1,6});~', '', $username)) != 0 || strpos($username, '[code') !== false || strpos($username, '[/code') !== false) {
        $errors->addError('error_invalid_characters_username');
    }
    if (stristr($username, $txt['guest_title']) !== false) {
        $errors->addError(array('username_reserved', array($txt['guest_title'])), 1);
    }
    if ($check_reserved_name) {
        require_once SUBSDIR . '/Members.subs.php';
        if (isReservedName($username, $memID, false, $fatal)) {
            $errors->addError(array('name_in_use', array(htmlspecialchars($username, ENT_COMPAT, 'UTF-8'))));
        }
    }
}
Esempio n. 14
0
    /**
     * Posts or saves the message composed with Post().
     *
     * requires various permissions depending on the action.
     * handles attachment, post, and calendar saving.
     * sends off notifications, and allows for announcements and moderation.
     * accessed from ?action=post2.
     */
    public function action_post2()
    {
        global $board, $topic, $txt, $modSettings, $context, $user_settings;
        global $user_info, $board_info, $options, $ignore_temp;
        // Sneaking off, are we?
        if (empty($_POST) && empty($topic)) {
            if (empty($_SERVER['CONTENT_LENGTH'])) {
                redirectexit('action=post;board=' . $board . '.0');
            } else {
                fatal_lang_error('post_upload_error', false);
            }
        } elseif (empty($_POST) && !empty($topic)) {
            redirectexit('action=post;topic=' . $topic . '.0');
        }
        // No need!
        $context['robot_no_index'] = true;
        // We are now in post2 action
        $context['current_action'] = 'post2';
        require_once SOURCEDIR . '/AttachmentErrorContext.class.php';
        // No errors as yet.
        $post_errors = Error_Context::context('post', 1);
        $attach_errors = Attachment_Error_Context::context();
        // If the session has timed out, let the user re-submit their form.
        if (checkSession('post', '', false) != '') {
            $post_errors->addError('session_timeout');
            // Disable the preview so that any potentially malicious code is not executed
            $_REQUEST['preview'] = false;
            return $this->action_post();
        }
        // Wrong verification code?
        if (!$user_info['is_admin'] && !$user_info['is_mod'] && !empty($modSettings['posts_require_captcha']) && ($user_info['posts'] < $modSettings['posts_require_captcha'] || $user_info['is_guest'] && $modSettings['posts_require_captcha'] == -1)) {
            require_once SUBSDIR . '/VerificationControls.class.php';
            $verificationOptions = array('id' => 'post');
            $context['require_verification'] = create_control_verification($verificationOptions, true);
            if (is_array($context['require_verification'])) {
                foreach ($context['require_verification'] as $verification_error) {
                    $post_errors->addError($verification_error);
                }
            }
        }
        require_once SUBSDIR . '/Boards.subs.php';
        require_once SUBSDIR . '/Post.subs.php';
        loadLanguage('Post');
        // Drafts enabled and needed?
        if (!empty($modSettings['drafts_enabled']) && (isset($_POST['save_draft']) || isset($_POST['id_draft']))) {
            require_once SUBSDIR . '/Drafts.subs.php';
        }
        // First check to see if they are trying to delete any current attachments.
        if (isset($_POST['attach_del'])) {
            $keep_temp = array();
            $keep_ids = array();
            foreach ($_POST['attach_del'] as $dummy) {
                if (strpos($dummy, 'post_tmp_' . $user_info['id']) !== false) {
                    $keep_temp[] = $dummy;
                } else {
                    $keep_ids[] = (int) $dummy;
                }
            }
            if (isset($_SESSION['temp_attachments'])) {
                foreach ($_SESSION['temp_attachments'] as $attachID => $attachment) {
                    if (isset($_SESSION['temp_attachments']['post']['files'], $attachment['name']) && in_array($attachment['name'], $_SESSION['temp_attachments']['post']['files']) || in_array($attachID, $keep_temp) || strpos($attachID, 'post_tmp_' . $user_info['id']) === false) {
                        continue;
                    }
                    unset($_SESSION['temp_attachments'][$attachID]);
                    @unlink($attachment['tmp_name']);
                }
            }
            if (!empty($_REQUEST['msg'])) {
                require_once SUBSDIR . '/ManageAttachments.subs.php';
                $attachmentQuery = array('attachment_type' => 0, 'id_msg' => (int) $_REQUEST['msg'], 'not_id_attach' => $keep_ids);
                removeAttachments($attachmentQuery);
            }
        }
        // Then try to upload any attachments.
        $context['attachments']['can']['post'] = !empty($modSettings['attachmentEnable']) && $modSettings['attachmentEnable'] == 1 && (allowedTo('post_attachment') || $modSettings['postmod_active'] && allowedTo('post_unapproved_attachments'));
        if ($context['attachments']['can']['post'] && empty($_POST['from_qr'])) {
            require_once SUBSDIR . '/Attachments.subs.php';
            if (isset($_REQUEST['msg'])) {
                processAttachments((int) $_REQUEST['msg']);
            } else {
                processAttachments();
            }
        }
        // Previewing? Go back to start.
        if (isset($_REQUEST['preview'])) {
            return $this->action_post();
        }
        // Prevent double submission of this form.
        checkSubmitOnce('check');
        // If this isn't a new topic load the topic info that we need.
        if (!empty($topic)) {
            require_once SUBSDIR . '/Topic.subs.php';
            $topic_info = getTopicInfo($topic);
            // Though the topic should be there, it might have vanished.
            if (empty($topic_info)) {
                fatal_lang_error('topic_doesnt_exist');
            }
            // Did this topic suddenly move? Just checking...
            if ($topic_info['id_board'] != $board) {
                fatal_lang_error('not_a_topic');
            }
        }
        // Replying to a topic?
        if (!empty($topic) && !isset($_REQUEST['msg'])) {
            // Don't allow a post if it's locked.
            if ($topic_info['locked'] != 0 && !allowedTo('moderate_board')) {
                fatal_lang_error('topic_locked', false);
            }
            // Sorry, multiple polls aren't allowed... yet.  You should stop giving me ideas :P.
            if (isset($_REQUEST['poll']) && $topic_info['id_poll'] > 0) {
                unset($_REQUEST['poll']);
            }
            // Do the permissions and approval stuff...
            $becomesApproved = true;
            if ($topic_info['id_member_started'] != $user_info['id']) {
                if ($modSettings['postmod_active'] && allowedTo('post_unapproved_replies_any') && !allowedTo('post_reply_any')) {
                    $becomesApproved = false;
                } else {
                    isAllowedTo('post_reply_any');
                }
            } elseif (!allowedTo('post_reply_any')) {
                if ($modSettings['postmod_active']) {
                    if (allowedTo('post_unapproved_replies_own') && !allowedTo('post_reply_own')) {
                        $becomesApproved = false;
                    } elseif ($user_info['is_guest'] && allowedTo('post_unapproved_replies_any')) {
                        $becomesApproved = false;
                    } else {
                        isAllowedTo('post_reply_own');
                    }
                }
            }
            if (isset($_POST['lock'])) {
                // Nothing is changed to the lock.
                if (empty($topic_info['locked']) && empty($_POST['lock']) || !empty($_POST['lock']) && !empty($topic_info['locked'])) {
                    unset($_POST['lock']);
                } elseif (!allowedTo(array('lock_any', 'lock_own')) || !allowedTo('lock_any') && $user_info['id'] != $topic_info['id_member_started']) {
                    unset($_POST['lock']);
                } elseif (!allowedTo('lock_any')) {
                    // You cannot override a moderator lock.
                    if ($topic_info['locked'] == 1) {
                        unset($_POST['lock']);
                    } else {
                        $_POST['lock'] = empty($_POST['lock']) ? 0 : 2;
                    }
                } else {
                    $_POST['lock'] = empty($_POST['lock']) ? 0 : 1;
                }
            }
            // So you wanna (un)sticky this...let's see.
            if (isset($_POST['sticky']) && (empty($modSettings['enableStickyTopics']) || $_POST['sticky'] == $topic_info['is_sticky'] || !allowedTo('make_sticky'))) {
                unset($_POST['sticky']);
            }
            // If drafts are enabled, then pass this off
            if (!empty($modSettings['drafts_enabled']) && isset($_POST['save_draft'])) {
                saveDraft();
                return $this->action_post();
            }
            // If the number of replies has changed, if the setting is enabled, go back to action_post() - which handles the error.
            if (empty($options['no_new_reply_warning']) && isset($_POST['last_msg']) && $topic_info['id_last_msg'] > $_POST['last_msg']) {
                addInlineJavascript('
					$(document).ready(function () {
						$("html,body").scrollTop($(\'.category_header:visible:first\').offset().top);
					});');
                return $this->action_post();
            }
            $posterIsGuest = $user_info['is_guest'];
        } elseif (empty($topic)) {
            // Now don't be silly, new topics will get their own id_msg soon enough.
            unset($_REQUEST['msg'], $_POST['msg'], $_GET['msg']);
            // Do like, the permissions, for safety and stuff...
            $becomesApproved = true;
            if ($modSettings['postmod_active'] && !allowedTo('post_new') && allowedTo('post_unapproved_topics')) {
                $becomesApproved = false;
            } else {
                isAllowedTo('post_new');
            }
            if (isset($_POST['lock'])) {
                // New topics are by default not locked.
                if (empty($_POST['lock'])) {
                    unset($_POST['lock']);
                } elseif (!allowedTo(array('lock_any', 'lock_own'))) {
                    unset($_POST['lock']);
                } else {
                    $_POST['lock'] = allowedTo('lock_any') ? 1 : 2;
                }
            }
            if (isset($_POST['sticky']) && (empty($modSettings['enableStickyTopics']) || empty($_POST['sticky']) || !allowedTo('make_sticky'))) {
                unset($_POST['sticky']);
            }
            // Saving your new topic as a draft first?
            if (!empty($modSettings['drafts_enabled']) && isset($_POST['save_draft'])) {
                saveDraft();
                return $this->action_post();
            }
            $posterIsGuest = $user_info['is_guest'];
        } elseif (isset($_REQUEST['msg']) && !empty($topic)) {
            $_REQUEST['msg'] = (int) $_REQUEST['msg'];
            require_once SUBSDIR . '/Messages.subs.php';
            $msgInfo = basicMessageInfo($_REQUEST['msg'], true);
            if (empty($msgInfo)) {
                fatal_lang_error('cant_find_messages', false);
            }
            if (!empty($topic_info['locked']) && !allowedTo('moderate_board')) {
                fatal_lang_error('topic_locked', false);
            }
            if (isset($_POST['lock'])) {
                // Nothing changes to the lock status.
                if (empty($_POST['lock']) && empty($topic_info['locked']) || !empty($_POST['lock']) && !empty($topic_info['locked'])) {
                    unset($_POST['lock']);
                } elseif (!allowedTo(array('lock_any', 'lock_own')) || !allowedTo('lock_any') && $user_info['id'] != $topic_info['id_member_started']) {
                    unset($_POST['lock']);
                } elseif (!allowedTo('lock_any')) {
                    // You're not allowed to break a moderator's lock.
                    if ($topic_info['locked'] == 1) {
                        unset($_POST['lock']);
                    } else {
                        $_POST['lock'] = empty($_POST['lock']) ? 0 : 2;
                    }
                } else {
                    $_POST['lock'] = empty($_POST['lock']) ? 0 : 1;
                }
            }
            // Change the sticky status of this topic?
            if (isset($_POST['sticky']) && (!allowedTo('make_sticky') || $_POST['sticky'] == $topic_info['is_sticky'])) {
                unset($_POST['sticky']);
            }
            if ($msgInfo['id_member'] == $user_info['id'] && !allowedTo('modify_any')) {
                if ((!$modSettings['postmod_active'] || $msgInfo['approved']) && !empty($modSettings['edit_disable_time']) && $msgInfo['poster_time'] + ($modSettings['edit_disable_time'] + 5) * 60 < time()) {
                    fatal_lang_error('modify_post_time_passed', false);
                } elseif ($topic_info['id_member_started'] == $user_info['id'] && !allowedTo('modify_own')) {
                    isAllowedTo('modify_replies');
                } else {
                    isAllowedTo('modify_own');
                }
            } elseif ($topic_info['id_member_started'] == $user_info['id'] && !allowedTo('modify_any')) {
                isAllowedTo('modify_replies');
                // If you're modifying a reply, I say it better be logged...
                $moderationAction = true;
            } else {
                isAllowedTo('modify_any');
                // Log it, assuming you're not modifying your own post.
                if ($msgInfo['id_member'] != $user_info['id']) {
                    $moderationAction = true;
                }
            }
            // If drafts are enabled, then lets send this off to save
            if (!empty($modSettings['drafts_enabled']) && isset($_POST['save_draft'])) {
                saveDraft();
                return $this->action_post();
            }
            $posterIsGuest = empty($msgInfo['id_member']);
            // Can they approve it?
            $can_approve = allowedTo('approve_posts');
            $becomesApproved = $modSettings['postmod_active'] ? $can_approve && !$msgInfo['approved'] ? !empty($_REQUEST['approve']) ? 1 : 0 : $msgInfo['approved'] : 1;
            $approve_has_changed = $msgInfo['approved'] != $becomesApproved;
            if (!allowedTo('moderate_forum') || !$posterIsGuest) {
                $_POST['guestname'] = $msgInfo['poster_name'];
                $_POST['email'] = $msgInfo['poster_email'];
            }
        }
        // In case we want to override
        if (allowedTo('approve_posts')) {
            $becomesApproved = !isset($_REQUEST['approve']) || !empty($_REQUEST['approve']) ? 1 : 0;
            $approve_has_changed = isset($msgInfo['approved']) ? $msgInfo['approved'] != $becomesApproved : false;
        }
        // If the poster is a guest evaluate the legality of name and email.
        if ($posterIsGuest) {
            $_POST['guestname'] = !isset($_POST['guestname']) ? '' : Util::htmlspecialchars(trim($_POST['guestname']));
            $_POST['email'] = !isset($_POST['email']) ? '' : Util::htmlspecialchars(trim($_POST['email']));
            if ($_POST['guestname'] == '' || $_POST['guestname'] == '_') {
                $post_errors->addError('no_name');
            }
            if (Util::strlen($_POST['guestname']) > 25) {
                $post_errors->addError('long_name');
            }
            if (empty($modSettings['guest_post_no_email'])) {
                // Only check if they changed it!
                if (!isset($msgInfo) || $msgInfo['poster_email'] != $_POST['email']) {
                    require_once SUBSDIR . '/DataValidator.class.php';
                    if (!allowedTo('moderate_forum') && !Data_Validator::is_valid($_POST, array('email' => 'valid_email|required'), array('email' => 'trim'))) {
                        empty($_POST['email']) ? $post_errors->addError('no_email') : $post_errors->addError('bad_email');
                    }
                }
                // Now make sure this email address is not banned from posting.
                isBannedEmail($_POST['email'], 'cannot_post', sprintf($txt['you_are_post_banned'], $txt['guest_title']));
            }
            // In case they are making multiple posts this visit, help them along by storing their name.
            if (!$post_errors->hasErrors()) {
                $_SESSION['guest_name'] = $_POST['guestname'];
                $_SESSION['guest_email'] = $_POST['email'];
            }
        }
        // Check the subject and message.
        if (!isset($_POST['subject']) || Util::htmltrim(Util::htmlspecialchars($_POST['subject'])) === '') {
            $post_errors->addError('no_subject');
        }
        if (!isset($_POST['message']) || Util::htmltrim(Util::htmlspecialchars($_POST['message'], ENT_QUOTES)) === '') {
            $post_errors->addError('no_message');
        } elseif (!empty($modSettings['max_messageLength']) && Util::strlen($_POST['message']) > $modSettings['max_messageLength']) {
            $post_errors->addError(array('long_message', array($modSettings['max_messageLength'])));
        } else {
            // Prepare the message a bit for some additional testing.
            $_POST['message'] = Util::htmlspecialchars($_POST['message'], ENT_QUOTES);
            // Preparse code. (Zef)
            if ($user_info['is_guest']) {
                $user_info['name'] = $_POST['guestname'];
            }
            preparsecode($_POST['message']);
            // Let's see if there's still some content left without the tags.
            if (Util::htmltrim(strip_tags(parse_bbc($_POST['message'], false), '<img>')) === '' && (!allowedTo('admin_forum') || strpos($_POST['message'], '[html]') === false)) {
                $post_errors->addError('no_message');
            }
        }
        if (isset($_POST['calendar']) && !isset($_REQUEST['deleteevent']) && Util::htmltrim($_POST['evtitle']) === '') {
            $post_errors->addError('no_event');
        }
        // Validate the poll...
        if (isset($_REQUEST['poll']) && !empty($modSettings['pollMode'])) {
            if (!empty($topic) && !isset($_REQUEST['msg'])) {
                fatal_lang_error('no_access', false);
            }
            // This is a new topic... so it's a new poll.
            if (empty($topic)) {
                isAllowedTo('poll_post');
            } elseif ($user_info['id'] == $topic_info['id_member_started'] && !allowedTo('poll_add_any')) {
                isAllowedTo('poll_add_own');
            } else {
                isAllowedTo('poll_add_any');
            }
            if (!isset($_POST['question']) || trim($_POST['question']) == '') {
                $post_errors->addError('no_question');
            }
            $_POST['options'] = empty($_POST['options']) ? array() : htmltrim__recursive($_POST['options']);
            // Get rid of empty ones.
            foreach ($_POST['options'] as $k => $option) {
                if ($option == '') {
                    unset($_POST['options'][$k], $_POST['options'][$k]);
                }
            }
            // What are you going to vote between with one choice?!?
            if (count($_POST['options']) < 2) {
                $post_errors->addError('poll_few');
            } elseif (count($_POST['options']) > 256) {
                $post_errors->addError('poll_many');
            }
        }
        if ($posterIsGuest) {
            // If user is a guest, make sure the chosen name isn't taken.
            require_once SUBSDIR . '/Members.subs.php';
            if (isReservedName($_POST['guestname'], 0, true, false) && (!isset($msgInfo['poster_name']) || $_POST['guestname'] != $msgInfo['poster_name'])) {
                $post_errors->addError('bad_name');
            }
        } elseif (!isset($_REQUEST['msg'])) {
            $_POST['guestname'] = $user_info['username'];
            $_POST['email'] = $user_info['email'];
        }
        // Posting somewhere else? Are we sure you can?
        if (!empty($_REQUEST['post_in_board'])) {
            $new_board = (int) $_REQUEST['post_in_board'];
            if (!allowedTo('post_new', $new_board)) {
                $post_in_board = boardInfo($new_board);
                if (!empty($post_in_board)) {
                    $post_errors->addError(array('post_new_board', array($post_in_board['name'])));
                } else {
                    $post_errors->addError('post_new');
                }
            }
        }
        // Any mistakes?
        if ($post_errors->hasErrors() || $attach_errors->hasErrors()) {
            addInlineJavascript('
				$(document).ready(function () {
					$("html,body").scrollTop($(\'.category_header:visible:first\').offset().top);
				});');
            return $this->action_post();
        }
        // Make sure the user isn't spamming the board.
        if (!isset($_REQUEST['msg'])) {
            spamProtection('post');
        }
        // At about this point, we're posting and that's that.
        ignore_user_abort(true);
        @set_time_limit(300);
        // Add special html entities to the subject, name, and email.
        $_POST['subject'] = strtr(Util::htmlspecialchars($_POST['subject']), array("\r" => '', "\n" => '', "\t" => ''));
        $_POST['guestname'] = htmlspecialchars($_POST['guestname'], ENT_COMPAT, 'UTF-8');
        $_POST['email'] = htmlspecialchars($_POST['email'], ENT_COMPAT, 'UTF-8');
        // At this point, we want to make sure the subject isn't too long.
        if (Util::strlen($_POST['subject']) > 100) {
            $_POST['subject'] = Util::substr($_POST['subject'], 0, 100);
        }
        if (!empty($modSettings['mentions_enabled']) && !empty($_REQUEST['uid'])) {
            $query_params = array();
            $query_params['member_ids'] = array_unique(array_map('intval', $_REQUEST['uid']));
            require_once SUBSDIR . '/Members.subs.php';
            $mentioned_members = membersBy('member_ids', $query_params, true);
            $replacements = 0;
            $actually_mentioned = array();
            foreach ($mentioned_members as $member) {
                $_POST['message'] = str_replace('@' . $member['real_name'], '[member=' . $member['id_member'] . ']' . $member['real_name'] . '[/member]', $_POST['message'], $replacements);
                if ($replacements > 0) {
                    $actually_mentioned[] = $member['id_member'];
                }
            }
        }
        // Make the poll...
        if (isset($_REQUEST['poll'])) {
            // Make sure that the user has not entered a ridiculous number of options..
            if (empty($_POST['poll_max_votes']) || $_POST['poll_max_votes'] <= 0) {
                $_POST['poll_max_votes'] = 1;
            } elseif ($_POST['poll_max_votes'] > count($_POST['options'])) {
                $_POST['poll_max_votes'] = count($_POST['options']);
            } else {
                $_POST['poll_max_votes'] = (int) $_POST['poll_max_votes'];
            }
            $_POST['poll_expire'] = (int) $_POST['poll_expire'];
            $_POST['poll_expire'] = $_POST['poll_expire'] > 9999 ? 9999 : ($_POST['poll_expire'] < 0 ? 0 : $_POST['poll_expire']);
            // Just set it to zero if it's not there..
            if (!isset($_POST['poll_hide'])) {
                $_POST['poll_hide'] = 0;
            } else {
                $_POST['poll_hide'] = (int) $_POST['poll_hide'];
            }
            $_POST['poll_change_vote'] = isset($_POST['poll_change_vote']) ? 1 : 0;
            $_POST['poll_guest_vote'] = isset($_POST['poll_guest_vote']) ? 1 : 0;
            // Make sure guests are actually allowed to vote generally.
            if ($_POST['poll_guest_vote']) {
                require_once SUBSDIR . '/Members.subs.php';
                $allowedVoteGroups = groupsAllowedTo('poll_vote', $board);
                if (!in_array(-1, $allowedVoteGroups['allowed'])) {
                    $_POST['poll_guest_vote'] = 0;
                }
            }
            // If the user tries to set the poll too far in advance, don't let them.
            if (!empty($_POST['poll_expire']) && $_POST['poll_expire'] < 1) {
                fatal_lang_error('poll_range_error', false);
            } elseif (empty($_POST['poll_expire']) && $_POST['poll_hide'] == 2) {
                $_POST['poll_hide'] = 1;
            }
            // Clean up the question and answers.
            $_POST['question'] = htmlspecialchars($_POST['question'], ENT_COMPAT, 'UTF-8');
            $_POST['question'] = Util::substr($_POST['question'], 0, 255);
            $_POST['question'] = preg_replace('~&amp;#(\\d{4,5}|[2-9]\\d{2,4}|1[2-9]\\d);~', '&#$1;', $_POST['question']);
            $_POST['options'] = htmlspecialchars__recursive($_POST['options']);
            // Finally, make the poll.
            require_once SUBSDIR . '/Poll.subs.php';
            $id_poll = createPoll($_POST['question'], $user_info['id'], $_POST['guestname'], $_POST['poll_max_votes'], $_POST['poll_hide'], $_POST['poll_expire'], $_POST['poll_change_vote'], $_POST['poll_guest_vote'], $_POST['options']);
        } else {
            $id_poll = 0;
        }
        // ...or attach a new file...
        if (empty($ignore_temp) && $context['attachments']['can']['post'] && !empty($_SESSION['temp_attachments']) && empty($_POST['from_qr'])) {
            $attachIDs = array();
            foreach ($_SESSION['temp_attachments'] as $attachID => $attachment) {
                if ($attachID != 'initial_error' && strpos($attachID, 'post_tmp_' . $user_info['id']) === false) {
                    continue;
                }
                // If there was an initial error just show that message.
                if ($attachID == 'initial_error') {
                    unset($_SESSION['temp_attachments']);
                    break;
                }
                // No errors, then try to create the attachment
                if (empty($attachment['errors'])) {
                    // Load the attachmentOptions array with the data needed to create an attachment
                    $attachmentOptions = array('post' => isset($_REQUEST['msg']) ? $_REQUEST['msg'] : 0, 'poster' => $user_info['id'], 'name' => $attachment['name'], 'tmp_name' => $attachment['tmp_name'], 'size' => isset($attachment['size']) ? $attachment['size'] : 0, 'mime_type' => isset($attachment['type']) ? $attachment['type'] : '', 'id_folder' => isset($attachment['id_folder']) ? $attachment['id_folder'] : 0, 'approved' => !$modSettings['postmod_active'] || allowedTo('post_attachment'), 'errors' => array());
                    if (createAttachment($attachmentOptions)) {
                        $attachIDs[] = $attachmentOptions['id'];
                        if (!empty($attachmentOptions['thumb'])) {
                            $attachIDs[] = $attachmentOptions['thumb'];
                        }
                    }
                } else {
                    @unlink($attachment['tmp_name']);
                }
            }
            unset($_SESSION['temp_attachments']);
        }
        // Creating a new topic?
        $newTopic = empty($_REQUEST['msg']) && empty($topic);
        $_POST['icon'] = !empty($attachIDs) && $_POST['icon'] == 'xx' ? 'clip' : $_POST['icon'];
        // Collect all parameters for the creation or modification of a post.
        $msgOptions = array('id' => empty($_REQUEST['msg']) ? 0 : (int) $_REQUEST['msg'], 'subject' => $_POST['subject'], 'body' => $_POST['message'], 'icon' => preg_replace('~[\\./\\\\*:"\'<>]~', '', $_POST['icon']), 'smileys_enabled' => !isset($_POST['ns']), 'attachments' => empty($attachIDs) ? array() : $attachIDs, 'approved' => $becomesApproved);
        $topicOptions = array('id' => empty($topic) ? 0 : $topic, 'board' => $board, 'poll' => isset($_REQUEST['poll']) ? $id_poll : null, 'lock_mode' => isset($_POST['lock']) ? (int) $_POST['lock'] : null, 'sticky_mode' => isset($_POST['sticky']) && !empty($modSettings['enableStickyTopics']) ? (int) $_POST['sticky'] : null, 'mark_as_read' => true, 'is_approved' => !$modSettings['postmod_active'] || empty($topic) || !empty($board_info['cur_topic_approved']));
        $posterOptions = array('id' => $user_info['id'], 'name' => $_POST['guestname'], 'email' => $_POST['email'], 'update_post_count' => !$user_info['is_guest'] && !isset($_REQUEST['msg']) && $board_info['posts_count']);
        // This is an already existing message. Edit it.
        if (!empty($_REQUEST['msg'])) {
            // Have admins allowed people to hide their screwups?
            if (time() - $msgInfo['poster_time'] > $modSettings['edit_wait_time'] || $user_info['id'] != $msgInfo['id_member']) {
                $msgOptions['modify_time'] = time();
                $msgOptions['modify_name'] = $user_info['name'];
            }
            // This will save some time...
            if (empty($approve_has_changed)) {
                unset($msgOptions['approved']);
            }
            modifyPost($msgOptions, $topicOptions, $posterOptions);
        } else {
            if (!empty($modSettings['enableFollowup']) && !empty($_REQUEST['followup'])) {
                $original_post = (int) $_REQUEST['followup'];
            }
            // We also have to fake the board:
            // if it's valid and it's not the current, let's forget about the "current" and load the new one
            if (!empty($new_board) && $board !== $new_board) {
                $board = $new_board;
                loadBoard();
                // Some details changed
                $topicOptions['board'] = $board;
                $topicOptions['is_approved'] = !$modSettings['postmod_active'] || empty($topic) || !empty($board_info['cur_topic_approved']);
                $posterOptions['update_post_count'] = !$user_info['is_guest'] && !isset($_REQUEST['msg']) && $board_info['posts_count'];
            }
            createPost($msgOptions, $topicOptions, $posterOptions);
            if (isset($topicOptions['id'])) {
                $topic = $topicOptions['id'];
            }
            if (!empty($modSettings['enableFollowup'])) {
                require_once SUBSDIR . '/FollowUps.subs.php';
                require_once SUBSDIR . '/Messages.subs.php';
                // Time to update the original message with a pointer to the new one
                if (!empty($original_post) && canAccessMessage($original_post)) {
                    linkMessages($original_post, $topic);
                }
            }
        }
        // If we had a draft for this, its time to remove it since it was just posted
        if (!empty($modSettings['drafts_enabled']) && !empty($_POST['id_draft'])) {
            deleteDrafts($_POST['id_draft'], $user_info['id']);
        }
        // Editing or posting an event?
        if (isset($_POST['calendar']) && (!isset($_REQUEST['eventid']) || $_REQUEST['eventid'] == -1)) {
            require_once SUBSDIR . '/Calendar.subs.php';
            // Make sure they can link an event to this post.
            canLinkEvent();
            // Insert the event.
            $eventOptions = array('id_board' => $board, 'id_topic' => $topic, 'title' => $_POST['evtitle'], 'member' => $user_info['id'], 'start_date' => sprintf('%04d-%02d-%02d', $_POST['year'], $_POST['month'], $_POST['day']), 'span' => isset($_POST['span']) && $_POST['span'] > 0 ? min((int) $modSettings['cal_maxspan'], (int) $_POST['span'] - 1) : 0);
            insertEvent($eventOptions);
        } elseif (isset($_POST['calendar'])) {
            $_REQUEST['eventid'] = (int) $_REQUEST['eventid'];
            // Validate the post...
            require_once SUBSDIR . '/Calendar.subs.php';
            validateEventPost();
            // If you're not allowed to edit any events, you have to be the poster.
            if (!allowedTo('calendar_edit_any')) {
                $event_poster = getEventPoster($_REQUEST['eventid']);
                // Silly hacker, Trix are for kids. ...probably trademarked somewhere, this is FAIR USE! (parody...)
                isAllowedTo('calendar_edit_' . ($event_poster == $user_info['id'] ? 'own' : 'any'));
            }
            // Delete it?
            if (isset($_REQUEST['deleteevent'])) {
                removeEvent($_REQUEST['eventid']);
            } else {
                $span = !empty($modSettings['cal_allowspan']) && !empty($_REQUEST['span']) ? min((int) $modSettings['cal_maxspan'], (int) $_REQUEST['span'] - 1) : 0;
                $start_time = mktime(0, 0, 0, (int) $_REQUEST['month'], (int) $_REQUEST['day'], (int) $_REQUEST['year']);
                $eventOptions = array('start_date' => strftime('%Y-%m-%d', $start_time), 'end_date' => strftime('%Y-%m-%d', $start_time + $span * 86400), 'title' => $_REQUEST['evtitle']);
                modifyEvent($_REQUEST['eventid'], $eventOptions);
            }
        }
        // Marking boards as read.
        // (You just posted and they will be unread.)
        if (!$user_info['is_guest']) {
            $board_list = !empty($board_info['parent_boards']) ? array_keys($board_info['parent_boards']) : array();
            // Returning to the topic?
            if (!empty($_REQUEST['goback'])) {
                $board_list[] = $board;
            }
            if (!empty($board_list)) {
                markBoardsRead($board_list, false, false);
            }
        }
        // Turn notification on or off.
        if (!empty($_POST['notify']) && allowedTo('mark_any_notify')) {
            setTopicNotification($user_info['id'], $topic, true);
        } elseif (!$newTopic) {
            setTopicNotification($user_info['id'], $topic, false);
        }
        // Log an act of moderation - modifying.
        if (!empty($moderationAction)) {
            logAction('modify', array('topic' => $topic, 'message' => (int) $_REQUEST['msg'], 'member' => $msgInfo['id_member'], 'board' => $board));
        }
        if (isset($_POST['lock']) && $_POST['lock'] != 2) {
            logAction(empty($_POST['lock']) ? 'unlock' : 'lock', array('topic' => $topicOptions['id'], 'board' => $topicOptions['board']));
        }
        if (isset($_POST['sticky']) && !empty($modSettings['enableStickyTopics'])) {
            logAction(empty($_POST['sticky']) ? 'unsticky' : 'sticky', array('topic' => $topicOptions['id'], 'board' => $topicOptions['board']));
        }
        // Notify any members who have notification turned on for this topic/board - only do this if it's going to be approved(!)
        if ($becomesApproved) {
            require_once SUBSDIR . '/Notification.subs.php';
            if ($newTopic) {
                $notifyData = array('body' => $_POST['message'], 'subject' => $_POST['subject'], 'name' => $user_info['name'], 'poster' => $user_info['id'], 'msg' => $msgOptions['id'], 'board' => $board, 'topic' => $topic, 'signature' => isset($user_settings['signature']) ? $user_settings['signature'] : '');
                sendBoardNotifications($notifyData);
            } elseif (empty($_REQUEST['msg'])) {
                // Only send it to everyone if the topic is approved, otherwise just to the topic starter if they want it.
                if ($topic_info['approved']) {
                    sendNotifications($topic, 'reply');
                } else {
                    sendNotifications($topic, 'reply', array(), $topic_info['id_member_started']);
                }
            }
        }
        if (!empty($modSettings['mentions_enabled']) && !empty($actually_mentioned)) {
            require_once CONTROLLERDIR . '/Mentions.controller.php';
            $mentions = new Mentions_Controller();
            $mentions->setData(array('id_member' => $actually_mentioned, 'type' => 'men', 'id_msg' => $msgOptions['id'], 'status' => $becomesApproved ? 'new' : 'unapproved'));
            $mentions->action_add();
        }
        if ($board_info['num_topics'] == 0) {
            cache_put_data('board-' . $board, null, 120);
        }
        if (!empty($_POST['announce_topic'])) {
            redirectexit('action=announce;sa=selectgroup;topic=' . $topic . (!empty($_POST['move']) && allowedTo('move_any') ? ';move' : '') . (empty($_REQUEST['goback']) ? '' : ';goback'));
        }
        if (!empty($_POST['move']) && allowedTo('move_any')) {
            redirectexit('action=movetopic;topic=' . $topic . '.0' . (empty($_REQUEST['goback']) ? '' : ';goback'));
        }
        // Return to post if the mod is on.
        if (isset($_REQUEST['msg']) && !empty($_REQUEST['goback'])) {
            redirectexit('topic=' . $topic . '.msg' . $_REQUEST['msg'] . '#msg' . $_REQUEST['msg'], isBrowser('ie'));
        } elseif (!empty($_REQUEST['goback'])) {
            redirectexit('topic=' . $topic . '.new#new', isBrowser('ie'));
        } else {
            redirectexit('board=' . $board . '.0');
        }
    }
Esempio n. 15
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;
}
Esempio n. 16
0
function saveProfileChanges(&$profile_vars, &$post_errors, $memID)
{
    global $db_prefix, $user_info, $txt, $modSettings, $user_profile;
    global $newpassemail, $validationCode, $context, $settings, $sourcedir;
    global $func;
    // These make life easier....
    $old_profile =& $user_profile[$memID];
    // Permissions...
    if ($context['user']['is_owner']) {
        $changeIdentity = allowedTo(array('profile_identity_any', 'profile_identity_own'));
        $changeOther = allowedTo(array('profile_extra_any', 'profile_extra_own'));
    } else {
        $changeIdentity = allowedTo('profile_identity_any');
        $changeOther = allowedTo('profile_extra_any');
    }
    // Arrays of all the changes - makes things easier.
    $profile_bools = array('notifyAnnouncements', 'notifyOnce', 'notifySendBody');
    $profile_ints = array('pm_email_notify', 'notifyTypes', 'ICQ', 'gender', 'ID_THEME');
    $profile_floats = array('timeOffset');
    $profile_strings = array('websiteUrl', 'websiteTitle', 'AIM', 'YIM', 'location', 'birthdate', 'timeFormat', 'buddy_list', 'pm_ignore_list', 'smileySet', 'signature', 'personalText', 'avatar');
    // Fix the spaces in messenger screennames...
    $fix_spaces = array('MSN', 'AIM', 'YIM');
    foreach ($fix_spaces as $var) {
        // !!! Why?
        if (isset($_POST[$var])) {
            $_POST[$var] = strtr($_POST[$var], ' ', '+');
        }
    }
    // Make sure the MSN one is an email address, not something like 'none' :P.
    if (isset($_POST['MSN']) && ($_POST['MSN'] == '' || preg_match('~^[0-9A-Za-z=_+\\-/][0-9A-Za-z=_\'+\\-/\\.]*@[\\w\\-]+(\\.[\\w\\-]+)*(\\.[\\w]{2,6})$~', $_POST['MSN']) != 0)) {
        $profile_strings[] = 'MSN';
    }
    // Validate the title...
    if (!empty($modSettings['titlesEnable']) && (allowedTo('profile_title_any') || allowedTo('profile_title_own') && $context['user']['is_owner'])) {
        $profile_strings[] = 'usertitle';
    }
    // Validate the timeOffset...
    if (isset($_POST['timeOffset'])) {
        $_POST['timeOffset'] = strtr($_POST['timeOffset'], ',', '.');
        if ($_POST['timeOffset'] < -23.5 || $_POST['timeOffset'] > 23.5) {
            $post_errors[] = 'bad_offset';
        }
    }
    // Fix the URL...
    if (isset($_POST['websiteUrl'])) {
        if (strlen(trim($_POST['websiteUrl'])) > 0 && strpos($_POST['websiteUrl'], '://') === false) {
            $_POST['websiteUrl'] = 'http://' . $_POST['websiteUrl'];
        }
        if (strlen($_POST['websiteUrl']) < 8) {
            $_POST['websiteUrl'] = '';
        }
    }
    // !!! Should we check for this year and tell them they made a mistake :P? (based on coppa at least?)
    if (isset($_POST['birthdate'])) {
        if (preg_match('/(\\d{4})[\\-\\., ](\\d{2})[\\-\\., ](\\d{2})/', $_POST['birthdate'], $dates) === 1) {
            $_POST['birthdate'] = checkdate($dates[2], $dates[3], $dates[1] < 4 ? 4 : $dates[1]) ? sprintf('%04d-%02d-%02d', $dates[1] < 4 ? 4 : $dates[1], $dates[2], $dates[3]) : '0001-01-01';
        } else {
            unset($_POST['birthdate']);
        }
    } elseif (isset($_POST['bday1'], $_POST['bday2'], $_POST['bday3']) && $_POST['bday1'] > 0 && $_POST['bday2'] > 0) {
        $_POST['birthdate'] = checkdate($_POST['bday1'], $_POST['bday2'], $_POST['bday3'] < 4 ? 4 : $_POST['bday3']) ? sprintf('%04d-%02d-%02d', $_POST['bday3'] < 4 ? 4 : $_POST['bday3'], $_POST['bday1'], $_POST['bday2']) : '0001-01-01';
    } elseif (isset($_POST['bday1']) || isset($_POST['bday2']) || isset($_POST['bday3'])) {
        $_POST['birthdate'] = '0001-01-01';
    }
    if (isset($_POST['im_email_notify'])) {
        $_POST['pm_email_notify'] = $_POST['im_email_notify'];
    }
    // Validate and set the ignorelist...
    if (isset($_POST['pm_ignore_list']) || isset($_POST['im_ignore_list'])) {
        if (!isset($_POST['pm_ignore_list'])) {
            $_POST['pm_ignore_list'] = $_POST['im_ignore_list'];
        }
        $_POST['pm_ignore_list'] = strtr($func['htmltrim']($_POST['pm_ignore_list']), array('\\\'' => '&#039;', "\n" => "', '", "\r" => '', '&quot;' => ''));
        if (preg_match('~(\\A|,)\\*(\\Z|,)~s', $_POST['pm_ignore_list']) == 0) {
            $result = db_query("\n\t\t\t\tSELECT ID_MEMBER\n\t\t\t\tFROM {$db_prefix}members\n\t\t\t\tWHERE memberName IN ('{$_POST['pm_ignore_list']}') OR realName IN ('{$_POST['pm_ignore_list']}')\n\t\t\t\tLIMIT " . (substr_count($_POST['pm_ignore_list'], '\', \'') + 1), __FILE__, __LINE__);
            $_POST['pm_ignore_list'] = '';
            while ($row = mysql_fetch_assoc($result)) {
                $_POST['pm_ignore_list'] .= $row['ID_MEMBER'] . ',';
            }
            mysql_free_result($result);
            // !!! Did we find all the members?
            $_POST['pm_ignore_list'] = substr($_POST['pm_ignore_list'], 0, -1);
        } else {
            $_POST['pm_ignore_list'] = '*';
        }
    }
    // Similarly, do the same for the buddy list
    if (isset($_POST['buddy_list'])) {
        $_POST['buddy_list'] = strtr(trim($_POST['buddy_list']), array('\\\'' => '&#039;', "\n" => "', '", "\r" => '', '&quot;' => ''));
        if (trim($_POST['buddy_list']) != '') {
            $result = db_query("\n\t\t\t\tSELECT ID_MEMBER\n\t\t\t\tFROM {$db_prefix}members\n\t\t\t\tWHERE memberName IN ('{$_POST['buddy_list']}') OR realName IN ('{$_POST['buddy_list']}')\n\t\t\t\tLIMIT " . (substr_count($_POST['buddy_list'], '\', \'') + 1), __FILE__, __LINE__);
            $_POST['buddy_list'] = '';
            while ($row = mysql_fetch_assoc($result)) {
                $_POST['buddy_list'] .= $row['ID_MEMBER'] . ',';
            }
            mysql_free_result($result);
            // !!! Did we find all the members?
            $_POST['buddy_list'] = substr($_POST['buddy_list'], 0, -1);
        }
    }
    // Validate the smiley set.
    if (isset($_POST['smileySet'])) {
        $smiley_sets = explode(',', $modSettings['smiley_sets_known']);
        if (!in_array($_POST['smileySet'], $smiley_sets) && $_POST['smileySet'] != 'none') {
            $_POST['smileySet'] = '';
        }
    }
    // Make sure the signature isn't too long.
    if (isset($_POST['signature'])) {
        require_once $sourcedir . '/Subs-Post.php';
        if (!empty($modSettings['max_signatureLength']) && $func['strlen']($_POST['signature']) > $modSettings['max_signatureLength']) {
            $_POST['signature'] = addslashes($func['substr'](stripslashes($_POST['signature']), 0, $modSettings['max_signatureLength']));
        }
        if (strlen($_POST['signature']) > 65534) {
            $_POST['signature'] = addslashes($func['truncate'](stripslashes($_POST['signature']), 65534));
        }
        $_POST['signature'] = strtr($_POST['signature'], array('&quot;' => '\\&quot;', '&#039;' => '\\&#39;', '&#39;' => '\\&#39;'));
        preparsecode($_POST['signature']);
    }
    // Identity-only changes...
    if ($changeIdentity) {
        // This block is only concerned with display name validation.
        if (isset($_POST['realName']) && (!empty($modSettings['allow_editDisplayName']) || allowedTo('moderate_forum')) && trim($_POST['realName']) != $old_profile['realName']) {
            $_POST['realName'] = trim(preg_replace('~[\\s]~' . ($context['utf8'] ? 'u' : ''), ' ', $_POST['realName']));
            if (trim($_POST['realName']) == '') {
                $post_errors[] = 'no_name';
            } elseif ($func['strlen']($_POST['realName']) > 60) {
                $post_errors[] = 'name_too_long';
            } else {
                require_once $sourcedir . '/Subs-Members.php';
                if (isReservedName($_POST['realName'], $memID)) {
                    $post_errors[] = 'name_taken';
                }
            }
            if (isset($_POST['realName'])) {
                $profile_vars['realName'] = '\'' . $_POST['realName'] . '\'';
            }
        }
        // Change the registration date.
        if (!empty($_POST['dateRegistered']) && allowedTo('admin_forum')) {
            // Bad date!  Go try again - please?
            if (($_POST['dateRegistered'] = strtotime($_POST['dateRegistered'])) === -1) {
                fatal_error($txt['smf233'] . ' ' . strftime('%d %b %Y ' . (strpos($user_info['time_format'], '%H') !== false ? '%I:%M:%S %p' : '%H:%M:%S'), forum_time(false)), false);
            } elseif ($_POST['dateRegistered'] != $txt[470] && $_POST['dateRegistered'] != strtotime(strftime('%Y-%m-%d', $user_profile[$memID]['dateRegistered'] + ($user_info['time_offset'] + $modSettings['time_offset']) * 3600))) {
                $profile_vars['dateRegistered'] = $_POST['dateRegistered'] - ($user_info['time_offset'] + $modSettings['time_offset']) * 3600;
            }
        }
        // Change the number of posts.
        if (isset($_POST['posts']) && allowedTo('moderate_forum')) {
            $profile_vars['posts'] = $_POST['posts'] != '' ? (int) strtr($_POST['posts'], array(',' => '', '.' => '', ' ' => '')) : '\'\'';
        }
        // This block is only concerned with email address validation..
        if (isset($_POST['emailAddress']) && strtolower($_POST['emailAddress']) != strtolower($old_profile['emailAddress'])) {
            $_POST['emailAddress'] = strtr($_POST['emailAddress'], array('&#039;' => '\\\''));
            // Prepare the new password, or check if they want to change their own.
            if (!empty($modSettings['send_validation_onChange']) && !allowedTo('moderate_forum')) {
                require_once $sourcedir . '/Subs-Members.php';
                $validationCode = generateValidationCode();
                $profile_vars['validation_code'] = '\'' . $validationCode . '\'';
                $profile_vars['is_activated'] = '2';
                $newpassemail = true;
            }
            // Check the name and email for validity.
            if (trim($_POST['emailAddress']) == '') {
                $post_errors[] = 'no_email';
            }
            if (preg_match('~^[0-9A-Za-z=_+\\-/][0-9A-Za-z=_\'+\\-/\\.]*@[\\w\\-]+(\\.[\\w\\-]+)*(\\.[\\w]{2,6})$~', stripslashes($_POST['emailAddress'])) == 0) {
                $post_errors[] = 'bad_email';
            }
            // Email addresses should be and stay unique.
            $request = db_query("\n\t\t\t\tSELECT ID_MEMBER\n\t\t\t\tFROM {$db_prefix}members\n\t\t\t\tWHERE ID_MEMBER != {$memID}\n\t\t\t\t\tAND emailAddress = '{$_POST['emailAddress']}'\n\t\t\t\tLIMIT 1", __FILE__, __LINE__);
            if (mysql_num_rows($request) > 0) {
                $post_errors[] = 'email_taken';
            }
            mysql_free_result($request);
            $profile_vars['emailAddress'] = '\'' . $_POST['emailAddress'] . '\'';
        }
        // Hide email address?
        if (isset($_POST['hideEmail']) && (!empty($modSettings['allow_hideEmail']) || allowedTo('moderate_forum'))) {
            $profile_vars['hideEmail'] = empty($_POST['hideEmail']) ? '0' : '1';
        }
        // Are they allowed to change their hide status?
        if (isset($_POST['showOnline']) && (!empty($modSettings['allow_hideOnline']) || allowedTo('moderate_forum'))) {
            $profile_vars['showOnline'] = empty($_POST['showOnline']) ? '0' : '1';
        }
        // If they're trying to change the password, let's check they pick a sensible one.
        if (isset($_POST['passwrd1']) && $_POST['passwrd1'] != '') {
            // Do the two entries for the password even match?
            if ($_POST['passwrd1'] != $_POST['passwrd2']) {
                $post_errors[] = 'bad_new_password';
            }
            // Let's get the validation function into play...
            require_once $sourcedir . '/Subs-Auth.php';
            $passwordErrors = validatePassword($_POST['passwrd1'], $user_info['username'], array($user_info['name'], $user_info['email']));
            // Were there errors?
            if ($passwordErrors != null) {
                $post_errors[] = 'password_' . $passwordErrors;
            }
            // Set up the new password variable... ready for storage.
            $profile_vars['passwd'] = '\'' . sha1(strtolower($old_profile['memberName']) . un_htmlspecialchars(stripslashes($_POST['passwrd1']))) . '\'';
        }
        if (isset($_POST['secretQuestion'])) {
            $profile_vars['secretQuestion'] = '\'' . $_POST['secretQuestion'] . '\'';
        }
        // Do you have a *secret* password?
        if (isset($_POST['secretAnswer']) && $_POST['secretAnswer'] != '') {
            $profile_vars['secretAnswer'] = '\'' . md5($_POST['secretAnswer']) . '\'';
        }
    }
    // Things they can do if they are a forum moderator.
    if (allowedTo('moderate_forum')) {
        if (($_REQUEST['sa'] == 'activateAccount' || !empty($_POST['is_activated'])) && isset($old_profile['is_activated']) && $old_profile['is_activated'] != 1) {
            // If we are approving the deletion of an account, we do something special ;)
            if ($old_profile['is_activated'] == 4) {
                require_once $sourcedir . '/Subs-Members.php';
                deleteMembers($memID);
                redirectexit();
            }
            if (isset($modSettings['integrate_activate']) && function_exists($modSettings['integrate_activate'])) {
                call_user_func($modSettings['integrate_activate'], $old_profile['memberName']);
            }
            // Actually update this member now, as it guarantees the unapproved count can't get corrupted.
            updateMemberData($memID, array('is_activated' => $old_profile['is_activated'] >= 10 ? '11' : '1', 'validation_code' => '\'\''));
            // If we are doing approval, update the stats for the member just incase.
            if (in_array($old_profile['is_activated'], array(3, 4, 13, 14))) {
                updateSettings(array('unapprovedMembers' => $modSettings['unapprovedMembers'] > 1 ? $modSettings['unapprovedMembers'] - 1 : 0));
            }
            // Make sure we update the stats too.
            updateStats('member', false);
        }
        if (isset($_POST['karmaGood'])) {
            $profile_vars['karmaGood'] = $_POST['karmaGood'] != '' ? (int) $_POST['karmaGood'] : '\'\'';
        }
        if (isset($_POST['karmaBad'])) {
            $profile_vars['karmaBad'] = $_POST['karmaBad'] != '' ? (int) $_POST['karmaBad'] : '\'\'';
        }
    }
    // Assigning membergroups (you need admin_forum permissions to change an admins' membergroups).
    if (allowedTo('manage_membergroups')) {
        // The account page allows the change of your ID_GROUP - but not to admin!.
        if (isset($_POST['ID_GROUP']) && (allowedTo('admin_forum') || (int) $_POST['ID_GROUP'] != 1 && $old_profile['ID_GROUP'] != 1)) {
            $profile_vars['ID_GROUP'] = (int) $_POST['ID_GROUP'];
        }
        // Find the additional membergroups (if any)
        if (isset($_POST['additionalGroups']) && is_array($_POST['additionalGroups'])) {
            foreach ($_POST['additionalGroups'] as $i => $group_id) {
                if ((int) $group_id == 0 || !allowedTo('admin_forum') && (int) $group_id == 1) {
                    unset($_POST['additionalGroups'][$i], $_POST['additionalGroups'][$i]);
                } else {
                    $_POST['additionalGroups'][$i] = (int) $group_id;
                }
            }
            // Put admin back in there if you don't have permission to take it away.
            if (!allowedTo('admin_forum') && in_array(1, explode(',', $old_profile['additionalGroups']))) {
                $_POST['additionalGroups'][] = 1;
            }
            $profile_vars['additionalGroups'] = '\'' . implode(',', $_POST['additionalGroups']) . '\'';
        }
        // Too often, people remove delete their own account, or something.
        if (in_array(1, explode(',', $old_profile['additionalGroups'])) || $old_profile['ID_GROUP'] == 1) {
            $stillAdmin = !isset($profile_vars['ID_GROUP']) || $profile_vars['ID_GROUP'] == 1 || isset($_POST['additionalGroups']) && in_array(1, $_POST['additionalGroups']);
            // If they would no longer be an admin, look for any other...
            if (!$stillAdmin) {
                $request = db_query("\n\t\t\t\t\tSELECT ID_MEMBER\n\t\t\t\t\tFROM {$db_prefix}members\n\t\t\t\t\tWHERE (ID_GROUP = 1 OR FIND_IN_SET(1, additionalGroups))\n\t\t\t\t\t\tAND ID_MEMBER != {$memID}\n\t\t\t\t\tLIMIT 1", __FILE__, __LINE__);
                list($another) = mysql_fetch_row($request);
                mysql_free_result($request);
                if (empty($another)) {
                    fatal_lang_error('at_least_one_admin');
                }
            }
        }
    }
    // Validate the language file...
    if (($changeIdentity || $changeOther) && isset($_POST['lngfile']) && !empty($modSettings['userLanguage'])) {
        $language_directories = array($settings['default_theme_dir'] . '/languages', $settings['actual_theme_dir'] . '/languages');
        if (!empty($settings['base_theme_dir'])) {
            $language_directories[] = $settings['base_theme_dir'] . '/languages';
        }
        $language_directories = array_unique($language_directories);
        foreach ($language_directories as $language_dir) {
            if (!file_exists($language_dir)) {
                continue;
            }
            $dir = dir($language_dir);
            while ($entry = $dir->read()) {
                if (preg_match('~^index\\.(.+)\\.php$~', $entry, $matches) && $matches[1] == $_POST['lngfile']) {
                    $profile_vars['lngfile'] = "'{$_POST['lngfile']}'";
                    // If they are the owner, make this persist even after they log out.
                    if ($context['user']['is_owner']) {
                        $_SESSION['language'] = $_POST['lngfile'];
                    }
                }
            }
            $dir->close();
        }
    }
    // Here's where we sort out all the 'other' values...
    if ($changeOther) {
        makeThemeChanges($memID, isset($_POST['ID_THEME']) ? (int) $_POST['ID_THEME'] : $old_profile['ID_THEME']);
        makeAvatarChanges($memID, $post_errors);
        makeNotificationChanges($memID);
        foreach ($profile_bools as $var) {
            if (isset($_POST[$var])) {
                $profile_vars[$var] = empty($_POST[$var]) ? '0' : '1';
            }
        }
        foreach ($profile_ints as $var) {
            if (isset($_POST[$var])) {
                $profile_vars[$var] = $_POST[$var] != '' ? (int) $_POST[$var] : '\'\'';
            }
        }
        foreach ($profile_floats as $var) {
            if (isset($_POST[$var])) {
                $profile_vars[$var] = (double) $_POST[$var];
            }
        }
        foreach ($profile_strings as $var) {
            if (isset($_POST[$var])) {
                $profile_vars[$var] = '\'' . $_POST[$var] . '\'';
            }
        }
    }
    if (isset($profile_vars['ICQ']) && $profile_vars['ICQ'] == '0') {
        $profile_vars['ICQ'] = '\'\'';
    }
}
Esempio n. 17
0
/**
 * Checks a username obeys a load of rules
 *
 * @param int $memID,
 * @param string $username
 * @return string Returns null if fine
 */
function validateUsername($memID, $username, $return_error = false, $check_reserved_name = true)
{
    global $sourcedir, $txt, $smcFunc, $user_info;
    $errors = array();
    // Don't use too long a name.
    if ($smcFunc['strlen']($username) > 25) {
        $errors[] = array('lang', 'error_long_name');
    }
    // No name?!  How can you register with no name?
    if ($username == '') {
        $errors[] = array('lang', 'need_username');
    }
    // Only these characters are permitted.
    if (in_array($username, array('_', '|')) || preg_match('~[<>&"\'=\\\\]~', preg_replace('~&#(?:\\d{1,7}|x[0-9a-fA-F]{1,6});~', '', $username)) != 0 || strpos($username, '[code') !== false || strpos($username, '[/code') !== false) {
        $errors[] = array('lang', 'error_invalid_characters_username');
    }
    if (stristr($username, $txt['guest_title']) !== false) {
        $errors[] = array('lang', 'username_reserved', 'general', array($txt['guest_title']));
    }
    if ($check_reserved_name) {
        require_once $sourcedir . '/Subs-Members.php';
        if (isReservedName($username, $memID, false)) {
            $errors[] = array('done', '(' . htmlspecialchars($username) . ') ' . $txt['name_in_use']);
        }
    }
    if ($return_error) {
        return $errors;
    } elseif (empty($errors)) {
        return null;
    }
    loadLanguage('Errors');
    $error = $errors[0];
    $message = $error[0] == 'lang' ? empty($error[3]) ? $txt[$error[1]] : vsprintf($txt[$error[1]], $error[3]) : $error[1];
    fatal_error($message, empty($error[2]) || $user_info['is_admin'] ? false : $error[2]);
}
Esempio n. 18
0
function method_sign_in()
{
    global $db_prefix, $context, $user_profile, $modSettings, $register, $sourcedir, $user_info, $boardurl, $txt;
    require_once $sourcedir . '/Register.php';
    require_once $sourcedir . '/Subs-Members.php';
    require_once $sourcedir . '/Subs-Auth.php';
    $token = $context['mob_request']['params'][0][0];
    $code = $context['mob_request']['params'][1][0];
    $email = isset($context['mob_request']['params'][2][0]) ? base64_decode($context['mob_request']['params'][2][0]) : '';
    $username = isset($context['mob_request']['params'][3][0]) ? base64_decode($context['mob_request']['params'][3][0]) : '';
    $password = isset($context['mob_request']['params'][4][0]) ? base64_decode($context['mob_request']['params'][4][0]) : '';
    // verify tapatalk token and code first
    $ttid = TapatalkSsoVerification($token, $code);
    if (empty($ttid)) {
        get_error('Tapatalk authorization verify failed, please login with your username and password.');
    }
    $tapatalk_id_email = $ttid->email;
    $result_status = true;
    $register = false;
    $result_text = '';
    if (!$ttid->result || empty($tapatalk_id_email)) {
        get_error($ttid->result_text ? $ttid->result_text : 'Tapatalk authorization verify failed, please login with your username and password');
    }
    // sign in with email or register an account
    $login_id = emailExists($tapatalk_id_email);
    if (empty($login_id)) {
        if (empty($username)) {
            get_error('Invalid Parameters', 2);
        } else {
            if (isReservedName($username, 0, true, false)) {
                get_error($txt[473], 1);
            } else {
                if (empty($password)) {
                    $password = tt_generatePassword();
                }
                $_POST['user'] = $username;
                $_POST['email'] = $tapatalk_id_email;
                $_POST['passwrd1'] = $password;
                $_POST['passwrd2'] = $password;
                $_POST['regagree'] = 'on';
                $_POST['regSubmit'] = 'Register';
                $_POST['skip_coppa'] = 1;
                $_SESSION['old_url'] = $boardurl;
                $modSettings['disable_visual_verification'] = 1;
                $modSettings['recaptcha_enabled'] = 0;
                $modSettings['recaptcha_enable'] = 0;
                $modSettings['captchaenable'] = 0;
                // compatibility with old CAPTCHA Mod
                $modSettings['anti_spam_ver_enable'] = false;
                if ($modSettings['registration_method'] == 1) {
                    $modSettings['registration_method'] = 0;
                }
                $login_id = Register2();
                $register = true;
                $result_status = $modSettings['registration_method'] == 2 ? false : true;
                $result_text = $modSettings['registration_method'] == 2 ? $txt['approval_after_registration'] : '';
                if (empty($login_id)) {
                    get_error('Register failed');
                }
            }
        }
    }
    // do login
    if ($login_id) {
        $request = db_query("\n            SELECT passwd, ID_MEMBER AS id_member, is_activated, ID_GROUP AS id_group, emailAddress AS email_address, additionalGroups AS additional_groups, memberName AS member_name,\n                passwordSalt AS password_salt, ID_POST_GROUP\n            FROM {$db_prefix}members\n            WHERE ID_MEMBER = '{$login_id}'\n            ", __FILE__, __LINE__);
        $user = mysql_fetch_assoc($request);
        if ($user['is_activated'] == 3 && !$register) {
            fatal_lang_error('still_awaiting_approval');
        }
        // Set the login cookie
        setLoginCookie(60 * $modSettings['cookieTime'], $login_id, sha1($user['passwd'] . $user['password_salt']));
        loadMemberData($user['id_member'], false, 'profile');
        $user_info = $user_profile[$user['id_member']];
        $user_info['is_guest'] = false;
        $user_info['is_admin'] = $user['id_group'] == 1 || in_array(1, explode(',', $user['additional_groups']));
        $user_info['id'] = $user['id_member'];
        if (empty($user_info['additionalGroups'])) {
            $user_info['groups'] = array($user_info['ID_GROUP'], $user_info['ID_POST_GROUP']);
        } else {
            $user_info['groups'] = array_merge(array($user_info['ID_GROUP'], $user_info['ID_POST_GROUP']), explode(',', $user_info['additionalGroups']));
        }
        $user_info['groups'] = array_unique(array_map('intval', $user_info['groups']));
        // Banned?
        is_not_banned(true);
        // Don't stick the language or theme after this point.
        unset($_SESSION['language']);
        unset($_SESSION['ID_THEME']);
        // You've logged in, haven't you?
        updateMemberData($user_info['id'], array('lastLogin' => time(), 'memberIP' => '\'' . $user_info['ip'] . '\'', 'memberIP2' => '\'' . $_SERVER['BAN_CHECK_IP'] . '\''));
        // Get rid of the online entry for that old guest....
        db_query("\n            DELETE FROM {$db_prefix}log_online\n            WHERE session = 'ip{$user_info['ip']}'\n            LIMIT 1", __FILE__, __LINE__);
        $_SESSION['log_time'] = 0;
        loadPermissions();
        update_push();
        // We got this far? return a positive response....
        outputRPCLogin($result_status, $result_text);
    } else {
        get_error('Sign In Failed');
    }
}