/** * Add to the newsletter, in the simplest way. * * @param EMAIL The email address of the subscriber * @param integer The interest level * @range 1 4 * @param ?LANGUAGE_NAME The language (NULL: users) * @param boolean Whether to require a confirmation mail * @param ?AUTO_LINK The newsletter to join (NULL: the first) * @param string Subscribers forename * @param string Subscribers surname * @return string Newsletter password */ function basic_newsletter_join($email, $interest_level = 4, $lang = NULL, $get_confirm_mail = false, $newsletter_id = NULL, $forename = '', $surname = '') { if (is_null($lang)) { $lang = user_lang(); } if (is_null($newsletter_id)) { $newsletter_id = db_get_first_id(); } $password = get_rand_password(); $code_confirm = $get_confirm_mail ? mt_rand(1, 9999999) : 0; $test = $GLOBALS['SITE_DB']->query_value_null_ok('newsletter_subscribe', 'the_level', array('newsletter_id' => $newsletter_id, 'email' => $email)); if ($test === 0) { $GLOBALS['SITE_DB']->query_delete('newsletter_subscribe', array('newsletter_id' => $newsletter_id, 'email' => $email), '', 1); $test = NULL; } if (is_null($test)) { require_lang('newsletter'); $test = $GLOBALS['SITE_DB']->query_value_null_ok('newsletter', 'email', array('email' => $email)); if (is_null($test)) { $salt = produce_salt(); $GLOBALS['SITE_DB']->query_insert('newsletter', array('n_forename' => $forename, 'n_surname' => $surname, 'join_time' => time(), 'email' => $email, 'code_confirm' => $code_confirm, 'pass_salt' => $salt, 'the_password' => md5($password . $salt), 'language' => $lang), false, true); // race condition if ($get_confirm_mail) { $_url = build_url(array('page' => 'newsletter', 'type' => 'confirm', 'email' => $email, 'confirm' => $code_confirm), get_module_zone('newsletter')); $url = $_url->evaluate(); $message = do_lang('NEWSLETTER_SIGNUP_TEXT', comcode_escape($url), comcode_escape($password), array($forename, $surname, $email, get_site_name()), $lang); require_code('mail'); mail_wrap(do_lang('NEWSLETTER_SIGNUP', NULL, NULL, NULL, $lang), $message, array($email)); } } else { $GLOBALS['SITE_DB']->query_update('newsletter', array('join_time' => time()), array('email' => $email), '', 1); $password = ''; } $GLOBALS['SITE_DB']->query_insert('newsletter_subscribe', array('newsletter_id' => $newsletter_id, 'the_level' => $interest_level, 'email' => $email), false, true); // race condition return $password; } return do_lang('NA'); }
/** * Get the site-wide salt. It should be something hard for a hacker to get, so we depend on data gathered both from the database and file-system. * * @return ID_TEXT The salt */ function get_site_salt() { $site_salt = get_value('site_salt'); if ($site_salt === NULL) { $site_salt = produce_salt(); set_value('site_salt', $site_salt); } //global $SITE_INFO; This is unstable on some sites, as the array can be prepopulated on the fly //$site_salt.=serialize($SITE_INFO); return md5($site_salt); }
/** * Add a member. * * @param SHORT_TEXT The username. * @param SHORT_TEXT The password. * @param SHORT_TEXT The e-mail address. * @param ?array A list of usergroups (NULL: default/current usergroups). * @param ?integer Day of date of birth (NULL: unknown). * @param ?integer Month of date of birth (NULL: unknown). * @param ?integer Year of date of birth (NULL: unknown). * @param array A map of custom field values (field-id=>value). * @param ?ID_TEXT The member timezone (NULL: auto-detect). * @param ?GROUP The member's primary (NULL: default). * @param BINARY Whether the profile has been validated. * @param ?TIME When the member joined (NULL: now). * @param ?TIME When the member last visited (NULL: now). * @param ID_TEXT The member's default theme. * @param ?URLPATH The URL to the member's avatar (blank: none) (NULL: choose one automatically). * @param LONG_TEXT The member's signature (blank: none). * @param BINARY Whether the member is permanently banned. * @param BINARY Whether posts are previewed before they are made. * @param BINARY Whether the member's age may be shown. * @param SHORT_TEXT The member's title (blank: get from primary). * @param URLPATH The URL to the member's photo (blank: none). * @param URLPATH The URL to the member's photo thumbnail (blank: none). * @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 member's 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 LONG_TEXT Personal notes of the member. * @param ?IP The member's IP address (NULL: IP address of current user). * @param SHORT_TEXT The code required before the account becomes active (blank: already entered). * @param boolean Whether to check details for correctness. * @param ?ID_TEXT The compatibility scheme that the password operates in (blank: none) (NULL: none [meaning normal ocPortal salted style] or plain, depending on whether passwords are encrypted). * @param SHORT_TEXT The password salt (blank: password compatibility scheme does not use a salt / auto-generate). * @param BINARY Whether the member likes to view zones without menus, when a choice is available. * @param ?TIME The time the member last made a submission (NULL: set to now). * @param ?AUTO_LINK Force an ID (NULL: don't force an ID) * @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. * @return AUTO_LINK The ID of the new member. */ function ocf_make_member($username, $password, $email_address, $secondary_groups, $dob_day, $dob_month, $dob_year, $custom_fields, $timezone = NULL, $primary_group = NULL, $validated = 1, $join_time = NULL, $last_visit_time = NULL, $theme = '', $avatar_url = NULL, $signature = '', $is_perm_banned = 0, $preview_posts = 0, $reveal_age = 1, $title = '', $photo_url = '', $photo_thumb_url = '', $views_signatures = 1, $auto_monitor_contrib_content = NULL, $language = NULL, $allow_emails = 1, $allow_emails_from_staff = 1, $personal_notes = '', $ip_address = NULL, $validated_email_confirm_code = '', $check_correctness = true, $password_compatibility_scheme = NULL, $salt = '', $zone_wide = 1, $last_submit_time = NULL, $id = NULL, $highlighted_name = 0, $pt_allow = '*', $pt_rules_text = '') { if (is_null($auto_monitor_contrib_content)) { $auto_monitor_contrib_content = get_value('no_auto_notifications') === '1' ? 0 : 1; } if (is_null($password_compatibility_scheme)) { if (get_value('no_password_hashing') === '1') { $password_compatibility_scheme = 'plain'; } else { $password_compatibility_scheme = ''; } } if (is_null($language)) { $language = ''; } if (is_null($signature)) { $signature = ''; } if (is_null($title)) { $title = ''; } if (is_null($timezone)) { $timezone = get_site_timezone(); } if (is_null($allow_emails)) { $allow_emails = 1; } if (is_null($allow_emails_from_staff)) { $allow_emails_from_staff = 1; } if (is_null($personal_notes)) { $personal_notes = ''; } if (is_null($avatar_url)) { if ($GLOBALS['IN_MINIKERNEL_VERSION'] == 1 || !addon_installed('ocf_member_avatars')) { $avatar_url = ''; } else { if (get_option('random_avatars') == '1' && !running_script('stress_test_loader')) { require_code('themes2'); $codes = get_all_image_ids_type('ocf_default_avatars/default_set', false, $GLOBALS['FORUM_DB']); shuffle($codes); $results = array(); foreach ($codes as $code) { if (strpos($code, 'ocp_fanatic') !== false) { continue; } $count = $GLOBALS['FORUM_DB']->query_value_null_ok_full('SELECT SUM(m_cache_num_posts) FROM ' . $GLOBALS['FORUM_DB']->get_table_prefix() . 'f_members WHERE ' . db_string_equal_to('m_avatar_url', find_theme_image($code, false, true))); if (is_null($count)) { $count = 0; } $results[$code] = $count; } @asort($results); // @'d as type checker fails for some odd reason $found_avatars = array_keys($results); $avatar_url = find_theme_image(array_shift($found_avatars), true, true); } if (is_null($avatar_url)) { $GLOBALS['SITE_DB']->query_delete('theme_images', array('id' => 'ocf_default_avatars/default', 'path' => '')); // In case failure cached, gets very confusing $avatar_url = find_theme_image('ocf_default_avatars/default', true, true); if (is_null($avatar_url)) { $avatar_url = ''; } } } } if ($check_correctness) { if (!in_array($password_compatibility_scheme, array('ldap', 'httpauth'))) { ocf_check_name_valid($username, NULL, $password_compatibility_scheme == '' ? $password : NULL); } if (!function_exists('has_actual_page_access') || !has_actual_page_access(get_member(), 'admin_ocf_join')) { require_code('type_validation'); if (!is_valid_email_address($email_address) && $email_address != '') { warn_exit(do_lang_tempcode('_INVALID_EMAIL_ADDRESS', escape_html($email_address))); } } } require_code('ocf_members'); require_code('ocf_groups'); if (is_null($last_submit_time)) { $last_submit_time = time(); } if (is_null($join_time)) { $join_time = time(); } if (is_null($last_visit_time)) { $last_visit_time = time(); } if (is_null($primary_group)) { $primary_group = get_first_default_group(); // This is members } if (is_null($secondary_groups)) { $secondary_groups = ocf_get_all_default_groups(false); } foreach ($secondary_groups as $_g_id => $g_id) { if ($g_id == $primary_group) { unset($secondary_groups[$_g_id]); } } if (is_null($ip_address)) { $ip_address = get_ip_address(); } if ($password_compatibility_scheme == '' && get_value('no_password_hashing') === '1') { $password_compatibility_scheme = 'plain'; $salt = ''; } if ($salt == '' && $password_compatibility_scheme == '') { $salt = produce_salt(); $password_salted = md5($salt . md5($password)); } else { $password_salted = $password; } // Supplement custom field values given with defaults, and check constraints $all_fields = list_to_map('id', ocf_get_all_custom_fields_match($secondary_groups)); require_code('fields'); foreach ($all_fields as $field) { $field_id = $field['id']; if (array_key_exists($field_id, $custom_fields)) { if ($check_correctness && $field[array_key_exists('cf_show_on_join_form', $field) ? 'cf_show_on_join_form' : 'cf_required'] == 0 && $field['cf_owner_set'] == 0 && !has_actual_page_access(get_member(), 'admin_ocf_join')) { access_denied('I_ERROR'); } } else { $custom_fields[$field_id] = ''; } } if (!addon_installed('unvalidated')) { $validated = 1; } $map = array('m_username' => $username, 'm_pass_hash_salted' => $password_salted, 'm_pass_salt' => $salt, 'm_theme' => $theme, 'm_avatar_url' => $avatar_url, 'm_validated' => $validated, 'm_validated_email_confirm_code' => $validated_email_confirm_code, 'm_cache_num_posts' => 0, 'm_cache_warnings' => 0, 'm_max_email_attach_size_mb' => 5, 'm_join_time' => $join_time, 'm_timezone_offset' => $timezone, 'm_primary_group' => $primary_group, 'm_last_visit_time' => $last_visit_time, 'm_last_submit_time' => $last_submit_time, 'm_signature' => insert_lang_comcode($signature, 4, $GLOBALS['FORUM_DB']), 'm_is_perm_banned' => $is_perm_banned, 'm_preview_posts' => $preview_posts, 'm_notes' => $personal_notes, 'm_dob_day' => $dob_day, 'm_dob_month' => $dob_month, 'm_dob_year' => $dob_year, 'm_reveal_age' => $reveal_age, 'm_email_address' => $email_address, 'm_title' => $title, 'm_photo_url' => $photo_url, 'm_photo_thumb_url' => $photo_thumb_url, 'm_views_signatures' => $views_signatures, 'm_auto_monitor_contrib_content' => $auto_monitor_contrib_content, 'm_highlighted_name' => $highlighted_name, 'm_pt_allow' => $pt_allow, 'm_pt_rules_text' => insert_lang_comcode($pt_rules_text, 4, $GLOBALS['FORUM_DB']), 'm_language' => $language, 'm_ip_address' => $ip_address, 'm_zone_wide' => $zone_wide, 'm_allow_emails' => $allow_emails, 'm_allow_emails_from_staff' => $allow_emails_from_staff, 'm_password_change_code' => '', 'm_password_compat_scheme' => $password_compatibility_scheme, 'm_on_probation_until' => NULL); if (!is_null($id)) { $map['id'] = $id; } $member_id = $GLOBALS['FORUM_DB']->query_insert('f_members', $map, true); if ($check_correctness) { // If it was an invite/recommendation, award the referrer if (addon_installed('recommend')) { $inviter = $GLOBALS['FORUM_DB']->query_value_null_ok('f_invites', 'i_inviter', array('i_email_address' => $email_address), 'ORDER BY i_time'); if (!is_null($inviter)) { if (addon_installed('points')) { require_code('points2'); require_lang('recommend'); system_gift_transfer(do_lang('RECOMMEND_SITE_TO', $username, get_site_name()), intval(get_option('points_RECOMMEND_SITE')), $inviter); } if (addon_installed('chat')) { require_code('chat2'); buddy_add($inviter, $member_id); buddy_add($member_id, $inviter); } } } } $value = mixed(); // Store custom fields $row = array('mf_member_id' => $member_id); $all_fields_types = collapse_2d_complexity('id', 'cf_type', $all_fields); foreach ($custom_fields as $field_num => $value) { if (!array_key_exists($field_num, $all_fields_types)) { continue; } // Trying to set a field we're not allowed to (doesn't apply to our group) $ob = get_fields_hook($all_fields_types[$field_num]); list(, , $storage_type) = $ob->get_field_value_row_bits($all_fields[$field_num]); if (strpos($storage_type, '_trans') !== false) { $value = insert_lang($value, 3, $GLOBALS['FORUM_DB']); } $row['field_' . strval($field_num)] = $value; } // Set custom field row $all_fields_regardless = $GLOBALS['FORUM_DB']->query_select('f_custom_fields', array('id', 'cf_type')); foreach ($all_fields_regardless as $field) { if (!array_key_exists('field_' . strval($field['id']), $row)) { $ob = get_fields_hook($field['cf_type']); list(, , $storage_type) = $ob->get_field_value_row_bits($field); $value = ''; if (strpos($storage_type, '_trans') !== false) { $value = insert_lang($value, 3, $GLOBALS['FORUM_DB']); } $row['field_' . strval($field['id'])] = $value; } } $GLOBALS['FORUM_DB']->query_insert('f_member_custom_fields', $row); // Any secondary work foreach ($secondary_groups as $g) { if ($g != $primary_group) { $GLOBALS['FORUM_DB']->query_delete('f_group_members', array('gm_member_id' => $member_id, 'gm_group_id' => $g), '', 1); $GLOBALS['FORUM_DB']->query_insert('f_group_members', array('gm_group_id' => $g, 'gm_member_id' => $member_id, 'gm_validated' => 1)); } } if ($check_correctness) { if (function_exists('decache')) { decache('side_stats'); } } return $member_id; }
/** * A custom random number seed generator. It returns a random number seed. * * @return integer A random seed */ function make_seed() { list($usec, $sec) = explode(' ', microtime(false)); $u = produce_salt(); return intval(floatval($sec) * floatval($usec)) + ord(substr($u, 0, 1)) + (ord(substr($u, 1, 2)) << 8); }
/** * The actualiser for newsletter subscription maintenance (adding, updating, deleting). * * @return tempcode The UI */ function newsletter_maintenance() { require_code('type_validation'); breadcrumb_set_parents(array(array('_SELF:_SELF:misc', get_option('newsletter_title')))); $title = get_page_title('_NEWSLETTER_JOIN', true, array(escape_html(get_option('newsletter_title')))); // Add $email = trim(post_param('email')); $password = trim(post_param('password')); $forename = trim(post_param('forename')); $surname = trim(post_param('surname')); if ($password != trim(post_param('password_confirm'))) { warn_exit(make_string_tempcode(escape_html(do_lang('PASSWORD_MISMATCH')))); } $lang = post_param('lang', user_lang()); if (!is_valid_email_address($email) || $password == '') { return warn_screen($title, do_lang_tempcode('IMPROPERLY_FILLED_IN')); } $message = do_lang_tempcode('NEWSLETTER_UPDATE'); $old_confirm = $GLOBALS['SITE_DB']->query_value_null_ok('newsletter', 'code_confirm', array('email' => $email)); if (is_null($old_confirm)) { $newsletters = $GLOBALS['SITE_DB']->query_select('newsletters', array('id')); $found_level = false; foreach ($newsletters as $newsletter) { if (get_option('interest_levels') == '1') { $level = post_param_integer('level' . strval($newsletter['id'])); } else { $level = post_param_integer('level' . strval($newsletter['id']), 0); if ($level == 1) { $level = 4; } } if ($level != 0) { $found_level = true; } } if (!$found_level) { warn_exit(do_lang_tempcode('NOT_NEWSLETTER_SUBSCRIBER')); } $code_confirm = mt_rand(1, 32000); $salt = produce_salt(); $GLOBALS['SITE_DB']->query_insert('newsletter', array('n_forename' => $forename, 'n_surname' => $surname, 'join_time' => time(), 'language' => $lang, 'email' => $email, 'code_confirm' => $code_confirm, 'pass_salt' => $salt, 'the_password' => md5($password . $salt))); $this->send_confirmation($email, $code_confirm, NULL, $forename, $surname); $message = do_lang_tempcode('NEWSLETTER_CONFIRM', escape_html($email)); } elseif ($old_confirm != 0) { $this->send_confirmation($email, $old_confirm, NULL, $forename, $surname); return inform_screen($title, do_lang_tempcode('NEWSLETTER_CONFIRM', escape_html($email))); } // Change/make settings $old_password = $GLOBALS['SITE_DB']->query_value('newsletter', 'the_password', array('email' => $email)); $old_salt = $GLOBALS['SITE_DB']->query_value('newsletter', 'pass_salt', array('email' => $email)); if (!has_specific_permission(get_member(), 'change_newsletter_subscriptions') && $old_password != '' && $old_password != md5($password . $old_salt)) { $_reset_url = build_url(array('page' => '_SELF', 'type' => 'reset', 'email' => $email), '_SELF'); $reset_url = $_reset_url->evaluate(); return warn_screen($title, do_lang_tempcode('NEWSLETTER_PASSWORD_RESET', escape_html($reset_url))); } else { $newsletters = $GLOBALS['SITE_DB']->query_select('newsletters', array('id')); foreach ($newsletters as $newsletter) { if (get_option('interest_levels') == '1') { $level = post_param_integer('level' . strval($newsletter['id'])); } else { $level = post_param_integer('level' . strval($newsletter['id']), 0); if ($level == 1) { $level = 4; } } // First we delete $GLOBALS['SITE_DB']->query_delete('newsletter_subscribe', array('newsletter_id' => $newsletter['id'], 'email' => $email), '', 1); if ($level != 0) { $GLOBALS['SITE_DB']->query_insert('newsletter_subscribe', array('newsletter_id' => $newsletter['id'], 'email' => $email, 'the_level' => $level)); } // Update name $GLOBALS['SITE_DB']->query_update('newsletter', array('n_forename' => $forename, 'n_surname' => $surname), array('email' => $email), '', 1); } } return inform_screen($title, $message); }