/**
 * Check to see if a member deserves promotion, and handle it.
 *
 * @param  ?MEMBER	The member (NULL: current member).
 */
function ocf_member_handle_promotion($member_id = NULL)
{
    if (!addon_installed('points')) {
        return;
    }
    if (get_page_name() == 'admin_import') {
        return;
    }
    if (is_null($member_id)) {
        $member_id = get_member();
    }
    require_code('ocf_members');
    if (ocf_is_ldap_member($member_id)) {
        return;
    }
    require_code('points');
    $total_points = total_points($member_id);
    $groups = $GLOBALS['OCF_DRIVER']->get_members_groups($member_id, false, true);
    $or_list = '';
    foreach ($groups as $id) {
        if ($or_list != '') {
            $or_list .= ' OR ';
        }
        $or_list .= 'id=' . strval($id);
    }
    $promotions = $GLOBALS['FORUM_DB']->query('SELECT id,g_promotion_target FROM ' . $GLOBALS['FORUM_DB']->get_table_prefix() . 'f_groups WHERE (' . $or_list . ') AND g_promotion_target IS NOT NULL AND g_promotion_threshold<=' . strval((int) $total_points) . ' ORDER BY g_promotion_threshold');
    $promotes_today = array();
    foreach ($promotions as $promotion) {
        $_p = $promotion['g_promotion_target'];
        if (!array_key_exists($_p, $groups) && !array_key_exists($_p, $promotes_today)) {
            // If it is our primary
            if ($GLOBALS['FORUM_DRIVER']->get_member_row_field($member_id, 'm_primary_group') == $promotion['id']) {
                $GLOBALS['FORUM_DB']->query_update('f_members', array('m_primary_group' => $_p), array('id' => $member_id), '', 1);
            } else {
                $GLOBALS['FORUM_DB']->query_delete('f_group_members', array('gm_member_id' => $member_id, 'gm_group_id' => $_p), '', 1);
                $GLOBALS['FORUM_DB']->query_insert('f_group_members', array('gm_validated' => 1, 'gm_member_id' => $member_id, 'gm_group_id' => $_p), false, true);
                $GLOBALS['FORUM_DB']->query_delete('f_group_members', array('gm_member_id' => $member_id, 'gm_group_id' => $promotion['id']), '', 1);
                // It's a transition, so remove old membership
            }
            // Carefully update run-time cacheing
            global $USERS_GROUPS_CACHE;
            foreach (array(true, false) as $a) {
                foreach (array(true, false) as $b) {
                    if (isset($USERS_GROUPS_CACHE[$member_id][$a][$b])) {
                        $groups = $USERS_GROUPS_CACHE[$member_id][$a][$b];
                        $pos = array_search($_p, $groups);
                        if ($pos !== false) {
                            unset($groups[$pos]);
                        }
                        $groups[] = $promotion['id'];
                        $USERS_GROUPS_CACHE[$member_id][$a][$b] = $groups;
                    }
                }
            }
            $promotes_today[$_p] = 1;
        }
    }
    if (count($promotes_today) != 0) {
        $name = $GLOBALS['OCF_DRIVER']->get_member_row_field($member_id, 'm_username');
        log_it('MEMBER_PROMOTED_AUTOMATICALLY', strval($member_id), $name);
    }
}
Exemple #2
0
 /**
  * Standard modular render function for profile tabs edit hooks.
  *
  * @param  MEMBER			The ID of the member who is being viewed
  * @param  MEMBER			The ID of the member who is doing the viewing
  * @param  boolean		Whether to leave the tab contents NULL, if tis hook supports it, so that AJAX can load it later
  * @return ?array			A tuple: The tab title, the tab body text (may be blank), the tab fields, extra Javascript (may be blank) the suggested tab order, hidden fields (optional) (NULL: if $leave_to_ajax_if_possible was set)
  */
 function render_tab($member_id_of, $member_id_viewing, $leave_to_ajax_if_possible = false)
 {
     $order = 0;
     // Actualiser
     if (post_param('submitting_settings_tab', NULL) !== NULL) {
         require_code('ocf_members_action2');
         $is_ldap = ocf_is_ldap_member($member_id_of);
         $is_httpauth = ocf_is_httpauth_member($member_id_of);
         $is_remote = $GLOBALS['FORUM_DRIVER']->get_member_row_field($member_id_of, 'm_password_compat_scheme') == 'remote';
         if ($is_ldap || $is_httpauth || $is_remote || $member_id_of != $member_id_viewing && !has_specific_permission($member_id_viewing, 'assume_any_member')) {
             $password = NULL;
         } else {
             $password = post_param('edit_password');
             if ($password == '') {
                 $password = NULL;
             } else {
                 $password_confirm = trim(post_param('password_confirm'));
                 if ($password != $password_confirm) {
                     warn_exit(make_string_tempcode(escape_html(do_lang('PASSWORD_MISMATCH'))));
                 }
             }
         }
         $custom_fields = ocf_get_all_custom_fields_match($GLOBALS['FORUM_DRIVER']->get_members_groups($member_id_of), $member_id_of != $member_id_viewing && !has_specific_permission($member_id_viewing, 'view_any_profile_field') ? 1 : NULL, $member_id_of != $member_id_viewing ? NULL : 1, $member_id_of != $member_id_viewing ? NULL : 1);
         $actual_custom_fields = ocf_read_in_custom_fields($custom_fields, $member_id_of);
         $pt_allow = array_key_exists('pt_allow', $_POST) ? implode(',', $_POST['pt_allow']) : '';
         $tmp_groups = $GLOBALS['OCF_DRIVER']->get_usergroup_list(true, true);
         $all_pt_allow = '';
         foreach (array_keys($tmp_groups) as $key) {
             if ($key != db_get_first_id()) {
                 if ($all_pt_allow != '') {
                     $all_pt_allow .= ',';
                 }
                 $all_pt_allow .= strval($key);
             }
         }
         if ($pt_allow == $all_pt_allow) {
             $pt_allow = '*';
         }
         $pt_rules_text = post_param('pt_rules_text', NULL);
         if (has_specific_permission($member_id_viewing, 'member_maintenance')) {
             $validated = post_param_integer('validated', 0);
             $primary_group = $is_ldap || !has_specific_permission($member_id_viewing, 'assume_any_member') ? NULL : post_param_integer('primary_group', NULL);
             $is_perm_banned = post_param_integer('is_perm_banned', 0);
             $old_is_perm_banned = $GLOBALS['FORUM_DRIVER']->get_member_row_field($member_id_of, 'm_is_perm_banned');
             if ($old_is_perm_banned != $is_perm_banned) {
                 if ($is_perm_banned == 1) {
                     ocf_ban_member($member_id_of);
                 } else {
                     ocf_unban_member($member_id_of);
                 }
             }
             $highlighted_name = post_param_integer('highlighted_name', 0);
             if (has_specific_permission($member_id_viewing, 'probate_members')) {
                 $on_probation_until = get_input_date('on_probation_until');
                 $current__on_probation_until = $GLOBALS['FORUM_DRIVER']->get_member_row_field($member_id_of, 'm_on_probation_until');
                 if ((is_null($on_probation_until) || $on_probation_until <= time()) && $current__on_probation_until > time()) {
                     log_it('STOP_PROBATION', strval($member_id_of), $GLOBALS['FORUM_DRIVER']->get_username($member_id_of));
                 } elseif (!is_null($on_probation_until) && $on_probation_until > time() && $current__on_probation_until <= time()) {
                     log_it('START_PROBATION', strval($member_id_of), $GLOBALS['FORUM_DRIVER']->get_username($member_id_of));
                 } elseif (!is_null($on_probation_until) && $current__on_probation_until > $on_probation_until && $on_probation_until > time() && $current__on_probation_until > time()) {
                     log_it('REDUCE_PROBATION', strval($member_id_of), $GLOBALS['FORUM_DRIVER']->get_username($member_id_of));
                 } elseif (!is_null($on_probation_until) && $current__on_probation_until < $on_probation_until && $on_probation_until > time() && $current__on_probation_until > time()) {
                     log_it('EXTEND_PROBATION', strval($member_id_of), $GLOBALS['FORUM_DRIVER']->get_username($member_id_of));
                 }
             } else {
                 $on_probation_until = NULL;
             }
         } else {
             $validated = NULL;
             $primary_group = NULL;
             $highlighted_name = NULL;
             $on_probation_until = NULL;
         }
         if (has_actual_page_access($member_id_viewing, 'admin_ocf_join') || has_specific_permission($member_id_of, 'rename_self')) {
             $username = $is_ldap || $is_remote ? NULL : post_param('edit_username', NULL);
         } else {
             $username = NULL;
         }
         $email = post_param('email_address', NULL);
         if (!is_null($email)) {
             $email = trim($email);
         }
         $theme = post_param('theme', NULL);
         if ($is_remote) {
             $preview_posts = NULL;
             $zone_wide = NULL;
             $auto_monitor_contrib_content = NULL;
             $views_signatures = NULL;
             $timezone = NULL;
         } else {
             $preview_posts = post_param_integer('preview_posts', 0);
             $zone_wide = post_param_integer('zone_wide', 0);
             $auto_monitor_contrib_content = NULL;
             //post_param_integer('auto_monitor_contrib_content',0);	Moved to notifications tab
             $views_signatures = post_param_integer('views_signatures', 0);
             $timezone = post_param('timezone', get_site_timezone());
         }
         ocf_edit_member($member_id_of, $email, $preview_posts, post_param_integer('dob_day', -1), post_param_integer('dob_month', -1), post_param_integer('dob_year', -1), $timezone, $primary_group, $actual_custom_fields, $theme, post_param_integer('reveal_age', 0), $views_signatures, $auto_monitor_contrib_content, post_param('language', NULL), post_param_integer('allow_emails', 0), post_param_integer('allow_emails_from_staff', 0), $validated, $username, $password, $zone_wide, $highlighted_name, $pt_allow, $pt_rules_text, $on_probation_until);
         if (!array_key_exists('secondary_groups', $_POST)) {
             $_POST['secondary_groups'] = array();
         }
         require_code('ocf_groups_action2');
         $members_groups = $GLOBALS['OCF_DRIVER']->get_members_groups($member_id_of);
         $group_count = $GLOBALS['FORUM_DB']->query_value('f_groups', 'COUNT(*)');
         $groups = list_to_map('id', $GLOBALS['FORUM_DB']->query_select('f_groups', array('*'), $group_count > 200 ? array('g_is_private_club' => 0) : NULL));
         foreach ($_POST['secondary_groups'] as $group_id) {
             $group = $groups[intval($group_id)];
             if ($group['g_hidden'] == 1 && !in_array($group['id'], $members_groups) && !has_specific_permission($member_id_viewing, 'see_hidden_groups')) {
                 continue;
             }
             if (!in_array($group['id'], $members_groups) && (has_specific_permission($member_id_viewing, 'assume_any_member') || $group['g_open_membership'] == 1)) {
                 ocf_add_member_to_group($member_id_of, $group['id']);
             }
         }
         foreach ($members_groups as $group_id) {
             if (!in_array(strval($group_id), $_POST['secondary_groups'])) {
                 ocf_member_leave_group($group_id, $member_id_of);
             }
         }
         $GLOBALS['FORUM_DB']->query('DELETE FROM ' . $GLOBALS['FORUM_DB']->get_table_prefix() . 'f_member_known_login_ips WHERE i_member_id=' . strval($member_id_of) . ' AND ' . db_string_not_equal_to('i_val_code', ''));
         // So any re-confirms can happen
         if (addon_installed('awards')) {
             require_code('awards');
             handle_award_setting('member', strval($member_id_of));
         }
         attach_message(do_lang_tempcode('SUCCESS_SAVE'), 'inform');
     }
     if ($leave_to_ajax_if_possible) {
         return NULL;
     }
     // UI
     $title = do_lang_tempcode('SETTINGS');
     $myrow = $GLOBALS['FORUM_DRIVER']->get_member_row($member_id_of);
     if (is_null($myrow)) {
         warn_exit(do_lang_tempcode('USER_NO_EXIST'));
     }
     require_code('ocf_members_action2');
     list($fields, $hidden) = ocf_get_member_fields_settings(false, $member_id_of, NULL, $myrow['m_email_address'], $myrow['m_preview_posts'], $myrow['m_dob_day'], $myrow['m_dob_month'], $myrow['m_dob_year'], get_users_timezone($member_id_of), $myrow['m_theme'], $myrow['m_reveal_age'], $myrow['m_views_signatures'], $myrow['m_auto_monitor_contrib_content'], $myrow['m_language'], $myrow['m_allow_emails'], $myrow['m_allow_emails_from_staff'], $myrow['m_validated'], $myrow['m_primary_group'], $myrow['m_username'], $myrow['m_is_perm_banned'], '', $myrow['m_zone_wide'], $myrow['m_highlighted_name'], $myrow['m_pt_allow'], get_translated_text($myrow['m_pt_rules_text'], $GLOBALS['FORUM_DB']), $myrow['m_on_probation_until']);
     // Awards?
     if (addon_installed('awards')) {
         require_code('awards');
         $fields->attach(get_award_fields('member', strval($member_id_of)));
     }
     $redirect = get_param('redirect', NULL);
     if (!is_null($redirect)) {
         $hidden->attach(form_input_hidden('redirect', $redirect));
     }
     $hidden->attach(form_input_hidden('submitting_settings_tab', '1'));
     $javascript = "\n\t\t\tvar form=document.getElementById('email_address').form;\n\t\t\tform.prior_profile_edit_submit=form.onsubmit;\n\t\t\tform.onsubmit=function()\n\t\t\t\t{\n\t\t\t\t\tif (typeof form.elements['edit_password']!='undefined')\n\t\t\t\t\t{\n\t\t\t\t\t\tif ((form.elements['password_confirm']) && (form.elements['password_confirm'].value!=form.elements['edit_password'].value))\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\twindow.fauxmodal_alert('" . php_addslashes(do_lang('PASSWORD_MISMATCH')) . "');\n\t\t\t\t\t\t\treturn false;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tif (typeof form.prior_profile_edit_submit!='undefined' && form.prior_profile_edit_submit) return form.prior_profile_edit_submit();\n\t\t\t\t\treturn true;\n\t\t\t\t};\n\t\t";
     $text = '';
     return array($title, $fields, $text, $javascript, $order, $hidden);
 }
Exemple #3
0
/**
 * Mass-load details for a list of members into memory, to reduce queries when we access it later.
 *
 * @param  array			List of members.
 */
function ocf_cache_member_details($members)
{
    require_code('ocf_members');
    $member_or_list = '';
    foreach ($members as $member) {
        if ($member_or_list != '') {
            $member_or_list .= ' OR ';
        }
        $member_or_list .= 'm.id=' . strval((int) $member);
    }
    if ($member_or_list != '') {
        $member_rows = $GLOBALS['FORUM_DB']->query('SELECT m.*,text_parsed AS signature FROM ' . $GLOBALS['FORUM_DB']->get_table_prefix() . 'f_members m LEFT JOIN ' . $GLOBALS['FORUM_DB']->get_table_prefix() . 'translate t ON ' . db_string_equal_to('language', user_lang()) . ' AND m.m_signature=t.id WHERE ' . $member_or_list);
        global $TABLE_LANG_FIELDS;
        $member_rows_2 = $GLOBALS['FORUM_DB']->query('SELECT f.* FROM ' . $GLOBALS['FORUM_DB']->get_table_prefix() . 'f_member_custom_fields f WHERE ' . str_replace('m.id', 'mf_member_id', $member_or_list), NULL, NULL, false, false, array_key_exists('f_member_custom_fields', $TABLE_LANG_FIELDS) ? $TABLE_LANG_FIELDS['f_member_custom_fields'] : array());
        $member_rows_3 = $GLOBALS['FORUM_DB']->query('SELECT gm_group_id,gm_member_id FROM ' . $GLOBALS['FORUM_DB']->get_table_prefix() . 'f_group_members WHERE gm_validated=1 AND (' . str_replace('m.id', 'gm_member_id', $member_or_list) . ')');
        global $MEMBER_CACHE_FIELD_MAPPINGS, $GROUP_MEMBERS_CACHE, $SIGNATURES_CACHE;
        $found_groups = array();
        foreach ($member_rows as $row) {
            $GLOBALS['OCF_DRIVER']->MEMBER_ROWS_CACHED[$row['id']] = $row;
            if (!ocf_is_ldap_member($row['id'])) {
                // Primary
                $pg = $GLOBALS['OCF_DRIVER']->get_member_row_field($row['id'], 'm_primary_group');
                $found_groups[$pg] = 1;
                $GROUP_MEMBERS_CACHE[$row['id']][false][false] = array($pg => 1);
            }
            // Signature
            if (get_page_name() != 'search' && !is_null($row['signature']) && $row['signature'] != '' && $row['m_signature'] != 0) {
                $SIGNATURES_CACHE[$row['id']] = new ocp_tempcode();
                if (!$SIGNATURES_CACHE[$row['id']]->from_assembly($row['signature'], true)) {
                    unset($SIGNATURES_CACHE[$row['id']]);
                }
            }
        }
        foreach ($member_rows_2 as $row) {
            $MEMBER_CACHE_FIELD_MAPPINGS[$row['mf_member_id']] = $row;
        }
        foreach ($member_rows_3 as $row) {
            if (!ocf_is_ldap_member($row['gm_member_id'])) {
                $GROUP_MEMBERS_CACHE[$row['gm_member_id']][false][false][$row['gm_group_id']] = 1;
                $found_groups[$row['gm_group_id']] = 1;
            }
        }
        require_code('ocf_groups');
        ocf_ensure_groups_cached(array_keys($found_groups));
    }
}
Exemple #4
0
 /**
  * Find if the given member id and password is valid. If username is NULL, then the member id is used instead.
  * All authorisation, cookies, and form-logins, are passed through this function.
  * Some forums do cookie logins differently, so a Boolean is passed in to indicate whether it is a cookie login.
  *
  * @param  ?SHORT_TEXT	The member username (NULL: don't use this in the authentication - but look it up using the ID if needed)
  * @param  ?MEMBER		The member id (NULL: use member name)
  * @param  MD5				The md5-hashed password
  * @param  string			The raw password
  * @param  boolean		Whether this is a cookie login, determines how the hashed password is treated for the value passed in
  * @return array			A map of 'id' and 'error'. If 'id' is NULL, an error occurred and 'error' is set
  */
 function forum_authorise_login($username, $userid, $password_hashed, $password_raw, $cookie_login = false)
 {
     $out = array();
     $out['id'] = NULL;
     require_code('ocf_members');
     require_code('ocf_groups');
     if (!function_exists('require_lang')) {
         require_code('lang');
     }
     if (!function_exists('do_lang_tempcode')) {
         require_code('tempcode');
     }
     if (!function_exists('require_lang')) {
         return $out;
     }
     require_lang('ocf');
     require_code('mail');
     $skip_auth = false;
     if ($userid === NULL) {
         $rows = $this->connection->query('SELECT * FROM ' . $this->connection->get_table_prefix() . 'f_members WHERE ' . db_string_equal_to('m_username', $username), 1);
         if (!array_key_exists(0, $rows) && get_option('one_per_email_address') == '1') {
             $rows = $this->connection->query('SELECT * FROM ' . $this->connection->get_table_prefix() . 'f_members WHERE ' . db_string_equal_to('m_email_address', $username) . ' ORDER BY id ASC', 1);
         }
         if (array_key_exists(0, $rows)) {
             $this->MEMBER_ROWS_CACHED[$rows[0]['id']] = $rows[0];
             $userid = $rows[0]['id'];
         }
     } else {
         $rows[0] = $this->get_member_row($userid);
     }
     // LDAP to the rescue if we couldn't get a row
     global $LDAP_CONNECTION;
     if (!array_key_exists(0, $rows) && $LDAP_CONNECTION !== NULL && $userid === NULL) {
         // See if LDAP has it -- if so, we can add
         $test = ocf_is_on_ldap($username);
         if (!$test) {
             $out['error'] = is_null($username) ? do_lang_tempcode('USER_NO_EXIST') : do_lang_tempcode('_USER_NO_EXIST', escape_html($username));
             return $out;
         }
         $test_auth = ocf_ldap_authorise_login($username, $password_raw);
         if ($test_auth['m_pass_hash_salted'] == '!!!') {
             $out['error'] = do_lang_tempcode('USER_BAD_PASSWORD');
             return $out;
         }
         if ($test) {
             require_code('ocf_members_action');
             require_code('ocf_members_action2');
             $completion_form_submitted = trim(post_param('email_address', '')) != '';
             if (!$completion_form_submitted && get_value('no_finish_profile') !== '1') {
                 @ob_end_clean();
                 if (!function_exists('do_header')) {
                     require_code('site');
                 }
                 $middle = ocf_member_external_linker_ask($username, 'ldap', ocf_ldap_guess_email($username));
                 $tpl = globalise($middle, NULL, '', true);
                 $tpl->evaluate_echo();
                 exit;
             } else {
                 $userid = ocf_member_external_linker($username, uniqid('', true), 'ldap');
                 $row = $this->get_member_row($userid);
             }
         }
     }
     if (!array_key_exists(0, $rows) || $rows[0] === NULL) {
         $out['error'] = is_null($username) ? do_lang_tempcode('USER_NO_EXIST') : do_lang_tempcode('_USER_NO_EXIST', escape_html($username));
         return $out;
     }
     $row = $rows[0];
     // Now LDAP can kick in and get the correct hash
     if (ocf_is_ldap_member($userid)) {
         //$rows[0]['m_pass_hash_salted']=ocf_get_ldap_hash($userid);
         // Doesn't exist any more? This is a special case - the 'LDAP member' exists in our DB, but not LDAP. It has been deleted from LDAP or LDAP server has jumped
         /*if (is_null($rows[0]['m_pass_hash_salted']))
         		{
         			$out['error']=(do_lang_tempcode('_USER_NO_EXIST',$username));
         			return $out;
         		} No longer appropriate with new authentication mode - instead we just have to give an invalid password message  */
         $row = array_merge($row, ocf_ldap_authorise_login($username, $password_hashed));
     }
     if (addon_installed('unvalidated')) {
         if ($row['m_validated'] == 0) {
             $out['error'] = do_lang_tempcode('USER_NOT_VALIDATED_STAFF');
             return $out;
         }
     }
     if ($row['m_validated_email_confirm_code'] != '') {
         $out['error'] = do_lang_tempcode('USER_NOT_VALIDATED_EMAIL');
         return $out;
     }
     if ($this->is_banned($row['id'])) {
         $out['error'] = do_lang_tempcode('USER_BANNED');
         return $out;
     }
     // Check password
     if (!$skip_auth) {
         // Choose a compatibility screen.
         // Note that almost all cookie logins are the same. This is because the cookie logins use OCF cookies, regardless of compatibility scheme.
         $password_compatibility_scheme = $row['m_password_compat_scheme'];
         switch ($password_compatibility_scheme) {
             case 'remote':
                 // This will work too - we're logging in with the username of a remote profile, so no resynching will happen
             // This will work too - we're logging in with the username of a remote profile, so no resynching will happen
             case '':
                 // ocPortal style salted MD5 algorithm
                 if ($cookie_login) {
                     if ($password_hashed !== $row['m_pass_hash_salted']) {
                         require_code('tempcode');
                         // This can be incidental even in fast AJAX scripts, if an old invalid cookie is present, so we need tempcode for do_lang_tempcode
                         $out['error'] = do_lang_tempcode('USER_BAD_PASSWORD');
                         return $out;
                     }
                 } else {
                     if (md5($row['m_pass_salt'] . $password_hashed) !== $row['m_pass_hash_salted']) {
                         $out['error'] = do_lang_tempcode('USER_BAD_PASSWORD');
                         return $out;
                     }
                 }
                 break;
             case 'plain':
                 if ($password_hashed !== md5($row['m_pass_hash_salted'])) {
                     $out['error'] = do_lang_tempcode('USER_BAD_PASSWORD');
                     return $out;
                 }
                 break;
             case 'md5':
                 // Old style plain md5		(also works if both are unhashed: used for LDAP)
                 if ($password_hashed !== $row['m_pass_hash_salted'] && $password_hashed != '!!!') {
                     $out['error'] = do_lang_tempcode('USER_BAD_PASSWORD');
                     return $out;
                 }
                 break;
                 /*		case 'httpauth':
                 				// This is handled in get_member()  */
                 break;
             case 'ldap':
                 if ($password_hashed !== $row['m_pass_hash_salted']) {
                     $out['error'] = do_lang_tempcode('USER_BAD_PASSWORD');
                     return $out;
                 }
                 break;
             default:
                 $path = get_file_base() . '/sources_custom/hooks/systems/ocf_auth/' . $password_compatibility_scheme . '.php';
                 if (!file_exists($path)) {
                     $path = get_file_base() . '/sources/hooks/systems/ocf_auth/' . $password_compatibility_scheme . '.php';
                 }
                 if (!file_exists($path)) {
                     $out['error'] = do_lang_tempcode('UNKNOWN_AUTH_SCHEME_IN_DB');
                     return $out;
                 }
                 require_code('hooks/systems/ocf_auth/' . $password_compatibility_scheme);
                 $ob = object_factory('Hook_ocf_auth_' . $password_compatibility_scheme);
                 $error = $ob->auth($username, $userid, $password_hashed, $password_raw, $cookie_login, $row);
                 if (!is_null($error)) {
                     $out['error'] = $error;
                     return $out;
                 }
                 break;
         }
     }
     // Ok, authorised basically, but we need to see if this is a valid login IP
     if (ocf_get_best_group_property($this->get_members_groups($row['id']), 'enquire_on_new_ips') == 1) {
         global $SENT_OUT_VALIDATE_NOTICE;
         $ip = get_ip_address(3);
         $test2 = $this->connection->query_value_null_ok('f_member_known_login_ips', 'i_val_code', array('i_member_id' => $row['id'], 'i_ip' => $ip));
         if ((is_null($test2) || $test2 != '') && !compare_ip_address($ip, $row['m_ip_address'])) {
             if (!$SENT_OUT_VALIDATE_NOTICE) {
                 if (!is_null($test2)) {
                     $this->connection->query_delete('f_member_known_login_ips', array('i_member_id' => $row['id'], 'i_ip' => $ip), '', 1);
                 }
                 $code = !is_null($test2) ? $test2 : uniqid('', true);
                 $this->connection->query_insert('f_member_known_login_ips', array('i_val_code' => $code, 'i_member_id' => $row['id'], 'i_ip' => $ip));
                 $url = find_script('validateip') . '?code=' . $code;
                 $url_simple = find_script('validateip');
                 require_code('comcode');
                 $mail = do_lang('IP_VERIFY_MAIL', comcode_escape($url), comcode_escape(get_ip_address()), array($url_simple, $code), get_lang($row['id']));
                 $email_address = $row['m_email_address'];
                 if ($email_address == '') {
                     $email_address = get_option('staff_address');
                 }
                 if (running_script('index')) {
                     mail_wrap(do_lang('IP_VERIFY_MAIL_SUBJECT', NULL, NULL, NULL, get_lang($row['id'])), $mail, array($email_address), $row['m_username'], '', '', 1);
                 }
                 $SENT_OUT_VALIDATE_NOTICE = true;
             }
             $out['error'] = do_lang_tempcode('REQUIRES_IP_VALIDATION');
             return $out;
         }
     }
     $this->ocf_flood_control($row['id']);
     $out['id'] = $row['id'];
     return $out;
 }
Exemple #5
0
 /**
  * The UI and actualisation for sending out the confirm email.
  *
  * @return tempcode		The UI
  */
 function step2()
 {
     $title = get_page_title('RESET_PASSWORD');
     breadcrumb_set_parents(array(array('_SELF:_SELF:misc', do_lang_tempcode('RESET_PASSWORD'))));
     breadcrumb_set_self(do_lang_tempcode('START'));
     $username = trim(post_param('username', ''));
     $email_address = trim(post_param('email_address', ''));
     if ($username == '' && $email_address == '') {
         warn_exit(do_lang_tempcode('PASSWORD_RESET_ERROR'));
     }
     if ($username != '') {
         $member = $GLOBALS['FORUM_DRIVER']->get_member_from_username($username);
     } else {
         $member = $GLOBALS['FORUM_DRIVER']->get_member_from_email_address($email_address);
     }
     if (is_null($member)) {
         warn_exit(do_lang_tempcode('PASSWORD_RESET_ERROR_2'));
     }
     $username = $GLOBALS['FORUM_DRIVER']->get_username($member);
     if ($GLOBALS['FORUM_DRIVER']->get_member_row_field($member, 'm_password_compat_scheme') == '' && has_specific_permission($member, 'disable_lost_passwords') && !$GLOBALS['IS_ACTUALLY_ADMIN']) {
         warn_exit(do_lang_tempcode('NO_RESET_ACCESS'));
     }
     if ($GLOBALS['FORUM_DRIVER']->get_member_row_field($member, 'm_password_compat_scheme') == 'remote') {
         warn_exit(do_lang_tempcode('NO_PASSWORD_RESET_REMOTE', ocp_srv('HTTP_HOST')));
     }
     if ($GLOBALS['FORUM_DRIVER']->get_member_row_field($member, 'm_password_compat_scheme') == 'httpauth') {
         warn_exit(do_lang_tempcode('NO_PASSWORD_RESET_HTTPAUTH'));
     }
     $is_ldap = ocf_is_ldap_member($member);
     $is_httpauth = ocf_is_httpauth_member($member);
     if ($is_ldap) {
         warn_exit(do_lang_tempcode('EXT_NO_PASSWORD_CHANGE'));
     }
     $code = mt_rand(0, mt_getrandmax());
     $GLOBALS['FORUM_DB']->query_update('f_members', array('m_password_change_code' => strval($code)), array('id' => $member), '', 1);
     $email = $GLOBALS['FORUM_DRIVER']->get_member_row_field($member, 'm_email_address');
     if ($email == '') {
         warn_exit(do_lang_tempcode('MEMBER_NO_EMAIL_ADDRESS_RESET_TO'));
     }
     log_it('RESET_PASSWORD', strval($member), strval($code));
     // Send confirm mail
     $zone = get_module_zone('lostpassword');
     $_url = build_url(array('page' => 'lostpassword', 'type' => 'step3', 'code' => $code, 'member' => $member), $zone, NULL, false, false, true);
     $url = $_url->evaluate();
     $_url_simple = build_url(array('page' => 'lostpassword', 'type' => 'step3', 'code' => NULL, 'username' => NULL, 'member' => NULL), $zone, NULL, false, false, true);
     $url_simple = $_url_simple->evaluate();
     $message = do_lang('RESET_PASSWORD_TEXT', comcode_escape(get_site_name()), comcode_escape($username), array(comcode_escape($url), $url_simple, strval($member), strval($code)), get_lang($member));
     require_code('mail');
     mail_wrap(do_lang('RESET_PASSWORD', NULL, NULL, NULL, get_lang($member)), $message, array($email), $GLOBALS['FORUM_DRIVER']->get_username($member), '', '', 3, NULL, false, NULL, false, false, false, 'MAIL', true);
     breadcrumb_set_self(do_lang_tempcode('DONE'));
     return inform_screen($title, do_lang_tempcode('RESET_CODE_MAILED'));
 }
Exemple #6
0
/**
 * Get a list of the usergroups a member is in (keys say the usergroups, values are irrelevant).
 *
 * @param  ?MEMBER	The member to find the usergroups of (NULL: current member).
 * @param  boolean	Whether to skip looking at secret usergroups.
 * @param  boolean	Whether to take probation into account
 * @return array		Reverse list (e.g. array(1=>1,2=>1,3=>1) for someone in (1,2,3)).
 */
function ocf_get_members_groups($member_id = NULL, $skip_secret = false, $handle_probation = true)
{
    if (is_guest($member_id)) {
        $ret = array();
        $ret[db_get_first_id()] = 1;
        return $ret;
    }
    if (is_null($member_id)) {
        $member_id = get_member();
    }
    if ($handle_probation) {
        $opt = $GLOBALS['FORUM_DRIVER']->get_member_row_field($member_id, 'm_on_probation_until');
        if (!is_null($opt) && $opt > time()) {
            global $PROBATION_GROUP;
            if (is_null($PROBATION_GROUP)) {
                $probation_group = get_option('probation_usergroup');
                $PROBATION_GROUP = $GLOBALS['FORUM_DB']->query_value_null_ok('f_groups g LEFT JOIN ' . $GLOBALS['FORUM_DB']->get_table_prefix() . 'translate t ON t.id=g.g_name', 'g.id', array('text_original' => $probation_group));
                if (is_null($PROBATION_GROUP)) {
                    $PROBATION_GROUP = false;
                }
            }
            if ($PROBATION_GROUP !== false) {
                return array($PROBATION_GROUP => 1);
            }
        }
    }
    $skip_secret = $skip_secret && (!function_exists('get_member') || $member_id != get_member()) && (!function_exists('has_specific_permission') || !has_specific_permission(get_member(), 'see_hidden_groups'));
    global $GROUP_MEMBERS_CACHE;
    if (isset($GROUP_MEMBERS_CACHE[$member_id][$skip_secret][$handle_probation])) {
        return $GROUP_MEMBERS_CACHE[$member_id][$skip_secret][$handle_probation];
    }
    $groups = array();
    // Now implicit usergroup hooks
    $hooks = find_all_hooks('systems', 'ocf_implicit_usergroups');
    foreach (array_keys($hooks) as $hook) {
        require_code('hooks/systems/ocf_implicit_usergroups/' . $hook);
        $ob = object_factory('Hook_implicit_usergroups_' . $hook);
        if ($ob->is_member_within($member_id)) {
            $groups[$ob->get_bound_group_id()] = 1;
        }
    }
    require_code('ocf_members');
    if (!function_exists('ocf_is_ldap_member') || !ocf_is_ldap_member($member_id)) {
        $_groups = $GLOBALS['FORUM_DB']->query_select('f_group_members m LEFT JOIN ' . $GLOBALS['FORUM_DB']->get_table_prefix() . 'f_groups g ON g.id=m.gm_group_id', array('gm_group_id', 'g_hidden'), array('gm_member_id' => $member_id, 'gm_validated' => 1), 'ORDER BY g.g_order');
        foreach ($_groups as $group) {
            $groups[$group['gm_group_id']] = 1;
        }
        if (!isset($GLOBALS['OCF_DRIVER'])) {
            if (method_exists($GLOBALS['FORUM_DRIVER'], 'forum_layer_initialise')) {
                $GLOBALS['FORUM_DRIVER']->forum_layer_initialise();
            }
        }
        $primary_group = $GLOBALS['OCF_DRIVER']->get_member_row_field($member_id, 'm_primary_group');
        if (is_null($primary_group)) {
            $primary_group = db_get_first_id();
        }
        $groups[$primary_group] = 1;
        foreach (array_keys($groups) as $group_id) {
            $groups[$group_id] = 1;
        }
        $GROUP_MEMBERS_CACHE[$member_id][false][$handle_probation] = $groups;
        $groups2 = $groups;
        foreach ($_groups as $group) {
            if ($group['g_hidden'] == 1) {
                unset($groups2[$group['gm_group_id']]);
            }
        }
        $GROUP_MEMBERS_CACHE[$member_id][true][$handle_probation] = $groups2;
        if ($skip_secret) {
            $groups = $groups2;
        }
    } else {
        $groups = ocf_get_members_groups_ldap($member_id);
        $GROUP_MEMBERS_CACHE[$member_id][false][$handle_probation] = $groups;
        $GROUP_MEMBERS_CACHE[$member_id][true][$handle_probation] = $groups;
        // Mirror to f_group_members table, so direct queries will also get it (we need to do listings of group members, for instance)
        $GLOBALS['FORUM_DB']->query_delete('f_group_members', array('gm_member_id' => $member_id));
        foreach (array_keys($groups) as $group_id) {
            $GLOBALS['FORUM_DB']->query_delete('f_group_members', array('gm_member_id' => $member_id, 'gm_group_id' => $group_id), '', 1);
            $GLOBALS['FORUM_DB']->query_insert('f_group_members', array('gm_group_id' => $group_id, 'gm_member_id' => $member_id, 'gm_validated' => 1));
        }
    }
    return $groups;
}
Exemple #7
0
/**
 * Get the primary of a member (supports consulting of LDAP).
 *
 * @param  MEMBER	The member.
 * @return GROUP	The primary.
 */
function ocf_get_member_primary_group($member_id)
{
    global $PRIMARY_GROUP_MEMBERS;
    if (array_key_exists($member_id, $PRIMARY_GROUP_MEMBERS)) {
        return $PRIMARY_GROUP_MEMBERS[$member_id];
    }
    if (ocf_is_ldap_member($member_id)) {
        ocf_ldap_get_member_primary_group($member_id);
    } else {
        $PRIMARY_GROUP_MEMBERS[$member_id] = $GLOBALS['OCF_DRIVER']->get_member_row_field($member_id, 'm_primary_group');
    }
    return $PRIMARY_GROUP_MEMBERS[$member_id];
}
/**
 * Set whether a member that has applied to be in a, may be in it, and inform them of the decision.
 *
 * @param  GROUP		The usergroup.
 * @param  MEMBER		The prospective member.
 * @param  boolean	Whether the member is being declined membership.
 * @param  string		The reason given for declining.
 */
function ocf_member_validate_into_group($group_id, $prospective_member_id, $decline = false, $reason = '')
{
    if (ocf_is_ldap_member($prospective_member_id)) {
        return;
    }
    require_code('notifications');
    $GLOBALS['FORUM_DB']->query_delete('f_group_members', array('gm_member_id' => $prospective_member_id, 'gm_group_id' => $group_id), '', 1);
    $name = ocf_get_group_name($group_id);
    if (!$decline) {
        $GLOBALS['FORUM_DB']->query_insert('f_group_members', array('gm_group_id' => $group_id, 'gm_member_id' => $prospective_member_id, 'gm_validated' => 1));
        $mail = do_lang('GROUP_ACCEPTED_MAIL', get_site_name(), $name, NULL, get_lang($prospective_member_id));
        $subject = do_lang('GROUP_ACCEPTED_MAIL_SUBJECT', $name, NULL, NULL, get_lang($prospective_member_id));
    } else {
        if ($reason != '') {
            $mail = do_lang('GROUP_DECLINED_MAIL_REASON', comcode_escape(get_site_name()), comcode_escape($name), comcode_escape($reason), get_lang($prospective_member_id));
        } else {
            $mail = do_lang('GROUP_DECLINED_MAIL', comcode_escape(get_site_name()), comcode_escape($name), NULL, get_lang($prospective_member_id));
        }
        $subject = do_lang('GROUP_DECLINED_MAIL_SUBJECT', $name, NULL, NULL, get_lang($prospective_member_id));
    }
    dispatch_notification('ocf_group_declined', NULL, $subject, $mail, array($prospective_member_id));
}
/**
 * Get form fields for adding/editing/finishing a member profile.
 *
 * @param  boolean			Whether we are only handling the essential details of a profile.
 * @param  ?MEMBER			The ID of the member we are handling (NULL: new member).
 * @param  ?array				A list of usergroups (NULL: default/current usergroups).
 * @param  SHORT_TEXT		The e-mail address.
 * @param  BINARY				Whether posts are previewed before they are made.
 * @param  ?integer			Day of date of birth (NULL: not known).
 * @param  ?integer			Month of date of birth (NULL: not known).
 * @param  ?integer			Year of date of birth (NULL: not known).
 * @param  ?ID_TEXT			The member timezone (NULL: site default).
 * @param  ?ID_TEXT			The members default theme (NULL: not known).
 * @param  BINARY				Whether the members age may be shown.
 * @param  BINARY				Whether the member sees signatures in posts.
 * @param  ?BINARY			Whether the member automatically is enabled for notifications for content they contribute to (NULL: get default from config).
 * @param  ?LANGUAGE_NAME	The members language (NULL: auto detect).
 * @param  BINARY				Whether the member allows e-mails via the site.
 * @param  BINARY				Whether the member allows e-mails from staff via the site.
 * @param  BINARY				Whether the profile has been validated.
 * @param  ?GROUP				The members primary (NULL: not known).
 * @param  SHORT_TEXT		The username.
 * @param  BINARY				Whether the member is permanently banned.
 * @param  ID_TEXT			The special type of profile this is (blank: not a special type).
 * @param  BINARY				Whether the member likes to view zones without menus, when a choice is available.
 * @param  BINARY				Whether the member username will be highlighted.
 * @param  SHORT_TEXT		Usergroups that may PT the member.
 * @param  LONG_TEXT			Rules that other members must agree to before they may start a PT with the member.
 * @param  ?TIME				When the member is on probation until (NULL: just finished probation / or effectively was never on it)
 * @return array				A pair: The form fields, Hidden fields (both Tempcode).
 */
function ocf_get_member_fields_settings($mini_mode = true, $member_id = NULL, $groups = NULL, $email_address = '', $preview_posts = 0, $dob_day = NULL, $dob_month = NULL, $dob_year = NULL, $timezone = NULL, $theme = NULL, $reveal_age = 1, $views_signatures = 1, $auto_monitor_contrib_content = NULL, $language = NULL, $allow_emails = 1, $allow_emails_from_staff = 1, $validated = 1, $primary_group = NULL, $username = '', $is_perm_banned = 0, $special_type = '', $zone_wide = 1, $highlighted_name = 0, $pt_allow = '*', $pt_rules_text = '', $on_probation_until = NULL)
{
    if (is_null($auto_monitor_contrib_content)) {
        $auto_monitor_contrib_content = get_value('no_auto_notifications') === '1' ? 0 : 1;
    }
    $hidden = new ocp_tempcode();
    if (has_actual_page_access(get_member(), 'admin_ocf_join')) {
        $dob_optional = true;
    } else {
        $dob_optional = get_option('no_dob_ask') == '2';
    }
    if ($member_id === $GLOBALS['OCF_DRIVER']->get_guest_id()) {
        fatal_exit(do_lang_tempcode('INTERNAL_ERROR'));
    }
    require_code('form_templates');
    require_code('encryption');
    if ($special_type == '' && !is_null($member_id)) {
        if (ocf_is_ldap_member($member_id)) {
            $special_type = 'ldap';
        }
        if (ocf_is_httpauth_member($member_id)) {
            $special_type = 'httpauth';
        }
        if ($GLOBALS['FORUM_DRIVER']->get_member_row_field($member_id, 'm_password_compat_scheme') == 'remote') {
            $special_type = 'remote';
        }
    }
    if (is_null($groups)) {
        $groups = is_null($member_id) ? ocf_get_all_default_groups(true) : $GLOBALS['OCF_DRIVER']->get_members_groups($member_id);
    }
    $fields = new ocp_tempcode();
    // Human name / Username
    if ($special_type != 'ldap' && $special_type != 'remote' && $GLOBALS['FORUM_DRIVER']->get_member_row_field($member_id, 'm_password_compat_scheme') != 'facebook') {
        if (is_null($member_id) || has_actual_page_access(get_member(), 'admin_ocf_join') || has_specific_permission($member_id, 'rename_self')) {
            if (get_option('signup_fullname') == '1') {
                $fields->attach(form_input_line(do_lang_tempcode('NAME'), do_lang_tempcode('_DESCRIPTION_NAME'), is_null($member_id) ? 'username' : 'edit_username', $username, true));
            } else {
                $prohibit_username_whitespace = get_option('prohibit_username_whitespace', true);
                if ($prohibit_username_whitespace == '1') {
                    $fields->attach(form_input_codename(do_lang_tempcode('USERNAME'), do_lang_tempcode('DESCRIPTION_USERNAME'), is_null($member_id) ? 'username' : 'edit_username', $username, true));
                } else {
                    $fields->attach(form_input_line(do_lang_tempcode('USERNAME'), do_lang_tempcode('DESCRIPTION_USERNAME'), is_null($member_id) ? 'username' : 'edit_username', $username, true));
                }
            }
        }
    }
    // Password
    if ($special_type == '') {
        if (is_null($member_id) || $member_id == get_member() || has_specific_permission(get_member(), 'assume_any_member')) {
            $fields->attach(form_input_password(do_lang_tempcode('PASSWORD'), do_lang_tempcode('DESCRIPTION_PASSWORD' . (!is_null($member_id) ? '_EDIT' : '')), is_null($member_id) ? 'password' : 'edit_password', $mini_mode));
            $fields->attach(form_input_password(do_lang_tempcode('CONFIRM_PASSWORD'), '', 'password_confirm', $mini_mode));
        }
    }
    // E-mail address
    if ($email_address == '') {
        $email_address = trim(get_param('email_address', ''));
    }
    if ($special_type != 'remote') {
        $fields->attach(form_input_email(do_lang_tempcode('EMAIL_ADDRESS'), get_option('skip_email_confirm_join') == '1' ? new ocp_tempcode() : do_lang_tempcode('MUST_BE_REAL_ADDRESS'), 'email_address', $email_address, !has_specific_permission(get_member(), 'member_maintenance')));
        if (is_null($member_id) && $email_address == '' && get_option('skip_email_confirm_join') == '0') {
            $fields->attach(form_input_email(do_lang_tempcode('CONFIRM_EMAIL_ADDRESS'), '', 'email_address_confirm', '', !has_specific_permission(get_member(), 'member_maintenance')));
        }
    }
    // DOB
    $default_time = is_null($dob_month) ? NULL : usertime_to_utctime(mktime(0, 0, 0, $dob_month, $dob_day, $dob_year));
    if (get_option('no_dob_ask') != '1') {
        $fields->attach(form_input_date(do_lang_tempcode(get_option('no_dob_ask') == '2' ? 'BIRTHDAY' : 'DATE_OF_BIRTH'), '', 'dob', $dob_optional, false, false, $default_time, -130));
        if (addon_installed('ocf_forum')) {
            $fields->attach(form_input_tick(do_lang_tempcode('RELATED_FIELD', do_lang_tempcode('REVEAL_AGE')), do_lang_tempcode('DESCRIPTION_REVEAL_AGE'), 'reveal_age', $reveal_age == 1));
        }
    }
    // Work out what options we need to present
    $doing_international = get_option('allow_international') == '1' && $special_type != 'remote';
    $_langs = find_all_langs();
    $doing_langs = multi_lang() && $special_type != 'remote';
    $doing_email_option = get_option('allow_email_disable') == '1';
    $doing_email_from_staff_option = get_option('allow_email_from_staff_disable') == '1';
    $unspecced_width_zone_exists = $GLOBALS['SITE_DB']->query_value_null_ok('zones', 'zone_name', array('zone_wide' => NULL));
    $unspecced_theme_zone_exists = $GLOBALS['SITE_DB']->query_value_null_ok_full('SELECT COUNT(*) FROM ' . get_table_prefix() . 'zones WHERE ' . db_string_equal_to('zone_theme', '') . ' OR ' . db_string_equal_to('zone_theme', '-1'));
    $doing_wide_option = $special_type != 'remote' && !is_null($unspecced_width_zone_exists) && !$mini_mode;
    $doing_theme_option = $unspecced_theme_zone_exists != 0 && !$mini_mode;
    $doing_local_forum_options = addon_installed('ocf_forum') && $special_type != 'remote' && !$mini_mode;
    if ($doing_international || $doing_langs || $doing_email_option || $doing_wide_option || $doing_theme_option || $doing_local_forum_options) {
        $fields->attach(do_template('FORM_SCREEN_FIELD_SPACER', array('FORCE_OPEN' => is_null($member_id) ? true : NULL, 'TITLE' => do_lang_tempcode('SETTINGS'))));
    }
    require_lang('config');
    // Timezones, if enabled
    if ($doing_international) {
        $timezone_list = nice_get_timezone_list($timezone);
        $fields->attach(form_input_list(do_lang_tempcode('TIME_ZONE'), do_lang_tempcode('DESCRIPTION_TIMEZONE_MEMBER'), 'timezone', $timezone_list));
    }
    // Language choice, if we have multiple languages on site
    if ($doing_langs) {
        $lang_list = new ocp_tempcode();
        $no_lang_set = is_null($language) || $language == '';
        $allow_no_lang_set = get_value('allow_no_lang_selection') === '1';
        if ($allow_no_lang_set) {
            $lang_list->attach(form_input_list_entry('', $no_lang_set, do_lang_tempcode('UNSET')));
        } else {
            if ($no_lang_set) {
                $language = user_lang();
            }
        }
        $lang_list->attach(nice_get_langs($language));
        $fields->attach(form_input_list(do_lang_tempcode('LANGUAGE'), '', 'language', $lang_list, NULL, false, !$allow_no_lang_set));
    }
    // Email privacy
    if ($doing_email_option) {
        $fields->attach(form_input_tick(do_lang_tempcode('ALLOW_EMAILS'), do_lang_tempcode('DESCRIPTION_ALLOW_EMAILS'), 'allow_emails', $allow_emails == 1));
    }
    if ($doing_email_from_staff_option) {
        $fields->attach(form_input_tick(do_lang_tempcode('ALLOW_EMAILS_FROM_STAFF'), do_lang_tempcode('DESCRIPTION_ALLOW_EMAILS_FROM_STAFF'), 'allow_emails_from_staff', $allow_emails_from_staff == 1));
    }
    if (!$mini_mode) {
        // Wide-option, if we have any zones giving a choice
        require_lang('zones');
        if ($doing_wide_option) {
            $fields->attach(form_input_tick(do_lang_tempcode('WIDE'), do_lang_tempcode('DESCRIPTION_MEMBER_ZONE_WIDE'), 'zone_wide', $zone_wide == 1));
        }
        // Theme, if we have any zones giving a choice
        require_code('themes2');
        $entries = nice_get_themes($theme, false, false, 'RELY_SITE_DEFAULT');
        require_lang('themes');
        if ($doing_theme_option) {
            $fields->attach(form_input_list(do_lang_tempcode('THEME'), do_lang_tempcode('DESCRIPTION_THEME'), 'theme', $entries));
        }
        // Various forum options
        if (addon_installed('ocf_forum')) {
            if ($special_type != 'remote') {
                if (get_option('forced_preview_option') == '1') {
                    $fields->attach(form_input_tick(do_lang_tempcode('PREVIEW_POSTS'), do_lang_tempcode('DESCRIPTION_PREVIEW_POSTS'), 'preview_posts', $preview_posts == 1));
                }
                if (get_value('disable_views_sigs_option') !== '1') {
                    if (addon_installed('ocf_signatures')) {
                        $fields->attach(form_input_tick(do_lang_tempcode('VIEWS_SIGNATURES'), do_lang_tempcode('DESCRIPTION_VIEWS_SIGNATURES'), 'views_signatures', $views_signatures == 1));
                    }
                } else {
                    $hidden->attach(form_input_hidden('views_signatures', '1'));
                }
                //$fields->attach(form_input_tick(do_lang_tempcode('AUTO_NOTIFICATION_CONTRIB_CONTENT'),do_lang_tempcode('DESCRIPTION_AUTO_NOTIFICATION_CONTRIB_CONTENT'),'auto_monitor_contrib_content',$auto_monitor_contrib_content==1));
                $usergroup_list = new ocp_tempcode();
                $lgroups = $GLOBALS['OCF_DRIVER']->get_usergroup_list(true, true);
                foreach ($lgroups as $key => $val) {
                    if ($key != db_get_first_id()) {
                        $usergroup_list->attach(form_input_list_entry(strval($key), $pt_allow == '*' || count(array_intersect(array(strval($key)), explode(',', $pt_allow))) != 0, $val));
                    }
                }
                if (get_value('disable_pt_restrict') !== '1') {
                    $fields->attach(form_input_multi_list(do_lang_tempcode('PT_ALLOW'), addon_installed('chat') ? do_lang_tempcode('PT_ALLOW_DESCRIPTION_CHAT') : do_lang_tempcode('PT_ALLOW_DESCRIPTION'), 'pt_allow', $usergroup_list));
                    $fields->attach(form_input_text_comcode(do_lang_tempcode('PT_RULES_TEXT'), do_lang_tempcode('PT_RULES_TEXT_DESCRIPTION'), 'pt_rules_text', $pt_rules_text, false));
                }
            }
        }
        // Prepare list of usergroups, if maybe we are gonna let (a) usergroup-change field(s)
        $group_count = $GLOBALS['FORUM_DB']->query_value('f_groups', 'COUNT(*)');
        $rows = $GLOBALS['FORUM_DB']->query_select('f_groups', array('id', 'g_name', 'g_hidden', 'g_open_membership'), $group_count > 200 ? array('g_is_private_club' => 0) : NULL, 'ORDER BY g_order');
        $_groups = new ocp_tempcode();
        $default_primary_group = get_first_default_group();
        $current_primary_group = NULL;
        foreach ($rows as $group) {
            if ($group['id'] != db_get_first_id()) {
                $selected = $group['id'] == $primary_group || is_null($primary_group) && $group['id'] == $default_primary_group;
                if ($selected) {
                    $current_primary_group = $group['id'];
                }
                $_groups->attach(form_input_list_entry(strval($group['id']), $selected, get_translated_text($group['g_name'], $GLOBALS['FORUM_DB'])));
            }
        }
        // Some admin options...
        if (has_specific_permission(get_member(), 'member_maintenance')) {
            $fields->attach(do_template('FORM_SCREEN_FIELD_SPACER', array('TITLE' => do_lang_tempcode('MEMBER_ACCESS'))));
            // Probation
            if (has_specific_permission(get_member(), 'probate_members')) {
                $fields->attach(form_input_date(do_lang_tempcode('ON_PROBATION_UNTIL'), do_lang_tempcode('DESCRIPTION_ON_PROBATION_UNTIL'), 'on_probation_until', true, is_null($on_probation_until) || $on_probation_until <= time(), true, $on_probation_until, 2));
            }
            // Primary usergroup
            if ($special_type != 'ldap') {
                if (has_specific_permission(get_member(), 'assume_any_member')) {
                    if (is_null($member_id) || !$GLOBALS['FORUM_DRIVER']->is_super_admin($member_id) || count($GLOBALS['FORUM_DRIVER']->member_group_query($GLOBALS['FORUM_DRIVER']->get_super_admin_groups(), 2)) > 1) {
                        $fields->attach(form_input_list(do_lang_tempcode('PRIMARY_GROUP'), do_lang_tempcode('DESCRIPTION_PRIMARY_GROUP'), 'primary_group', $_groups));
                    }
                }
            }
        }
        // Secondary usergroups
        if ($special_type != 'ldap') {
            $_groups2 = new ocp_tempcode();
            $members_groups = is_null($member_id) ? array() : $GLOBALS['OCF_DRIVER']->get_members_groups($member_id, false, false);
            foreach ($rows as $group) {
                if ($group['g_hidden'] == 1 && !array_key_exists($group['id'], $members_groups) && !has_specific_permission(get_member(), 'see_hidden_groups')) {
                    continue;
                }
                if ($group['id'] != db_get_first_id() && $group['id'] != $current_primary_group && (array_key_exists($group['id'], $members_groups) || has_specific_permission(get_member(), 'assume_any_member') || $group['g_open_membership'] == 1)) {
                    $selected = array_key_exists($group['id'], $members_groups);
                    $_groups2->attach(form_input_list_entry(strval($group['id']), $selected, get_translated_text($group['g_name'], $GLOBALS['FORUM_DB'])));
                }
            }
            $sec_url = build_url(array('page' => 'groups', 'type' => 'misc'), get_module_zone('groups'));
            if (!$_groups2->is_empty()) {
                $fields->attach(form_input_multi_list(do_lang_tempcode('SECONDARY_GROUP_MEMBERSHIP'), do_lang_tempcode('DESCRIPTION_SECONDARY_GROUP', escape_html($sec_url->evaluate())), 'secondary_groups', $_groups2));
            }
        }
        // Special admin options
        if (has_specific_permission(get_member(), 'member_maintenance')) {
            if ($validated == 0) {
                $validated = get_param_integer('validated', 0);
                if ($validated == 1) {
                    attach_message(do_lang_tempcode('WILL_BE_VALIDATED_WHEN_SAVING'));
                }
            }
            if (addon_installed('unvalidated')) {
                $fields->attach(form_input_tick(do_lang_tempcode('VALIDATED'), do_lang_tempcode('DESCRIPTION_MEMBER_VALIDATED'), 'validated', $validated == 1));
            }
            if (get_value('disable_highlight_name') !== '1') {
                $fields->attach(form_input_tick(do_lang_tempcode('HIGHLIGHTED_NAME'), do_lang_tempcode(addon_installed('pointstore') ? 'DESCRIPTION_HIGHLIGHTED_NAME_P' : 'DESCRIPTION_HIGHLIGHTED_NAME'), 'highlighted_name', $highlighted_name == 1));
            }
            if (!is_null($member_id) && $member_id != get_member()) {
                // Can't ban someone new, and can't ban yourself
                $fields->attach(form_input_tick(do_lang_tempcode('_BANNED'), do_lang_tempcode('DESCRIPTION_MEMBER_BANNED'), 'is_perm_banned', $is_perm_banned == 1));
            }
        }
    }
    return array($fields, $hidden);
}