} if ($Invites != $Cur['Invites'] && check_perms('users_edit_invites')) { $UpdateSet[] = "invites = '{$Invites}'"; $EditSummary[] = "number of invites changed to {$Invites}"; $HeavyUpdates['Invites'] = $Invites; } if ($Warned == 1 && $Cur['Warned'] == '0000-00-00 00:00:00' && check_perms('users_warn')) { $Weeks = 'week' . ($WarnLength === 1 ? '' : 's'); Misc::send_pm($UserID, 0, 'You have received a warning', "You have been [url=" . site_url() . "wiki.php?action=article&id=218]warned for {$WarnLength} {$Weeks}[/url] by [user]" . $LoggedUser['Username'] . "[/user]. The reason given was:\n[quote]{$WarnReason}[/quote]"); $UpdateSet[] = "Warned = '" . sqltime() . "' + INTERVAL {$WarnLength} WEEK"; $Msg = "warned for {$WarnLength} {$Weeks}"; if ($WarnReason) { $Msg .= " for \"{$WarnReason}\""; } $EditSummary[] = db_string($Msg); $LightUpdates['Warned'] = time_plus(3600 * 24 * 7 * $WarnLength); } elseif ($Warned == 0 && $Cur['Warned'] != '0000-00-00 00:00:00' && check_perms('users_warn')) { $UpdateSet[] = "Warned = '0000-00-00 00:00:00'"; $EditSummary[] = 'warning removed'; $LightUpdates['Warned'] = '0000-00-00 00:00:00'; } elseif ($Warned == 1 && $ExtendWarning != '---' && check_perms('users_warn')) { $Weeks = 'week' . ($ExtendWarning === 1 ? '' : 's'); Misc::send_pm($UserID, 0, 'Your warning has been extended', "Your warning has been extended by {$ExtendWarning} {$Weeks} by [user]" . $LoggedUser['Username'] . "[/user]. The reason given was:\n[quote]{$WarnReason}[/quote]"); $UpdateSet[] = "Warned = Warned + INTERVAL {$ExtendWarning} WEEK"; $DB->query("\n\t\tSELECT Warned + INTERVAL {$ExtendWarning} WEEK\n\t\tFROM users_info\n\t\tWHERE UserID = '{$UserID}'"); list($WarnedUntil) = $DB->next_record(); $Msg = "warning extended by {$ExtendWarning} {$Weeks} to {$WarnedUntil}"; if ($WarnReason) { $Msg .= " for \"{$WarnReason}\""; } $EditSummary[] = db_string($Msg);
function log_attempt($UserID) { global $DB, $Cache, $AttemptID, $Attempts, $Bans, $BannedUntil; $IPStr = $_SERVER['REMOTE_ADDR']; $IPA = substr($IPStr, 0, strcspn($IPStr, '.')); $IP = Tools::ip_to_unsigned($IPStr); if ($AttemptID) { // User has attempted to log in recently $Attempts++; if ($Attempts > 5) { // Only 6 allowed login attempts, ban user's IP $BannedUntil = time_plus(60 * 60 * 6); $DB->query("\n\t\t\t\t\tUPDATE login_attempts\n\t\t\t\t\tSET\n\t\t\t\t\t\tLastAttempt = '" . sqltime() . "',\n\t\t\t\t\t\tAttempts = '" . db_string($Attempts) . "',\n\t\t\t\t\t\tBannedUntil = '" . db_string($BannedUntil) . "',\n\t\t\t\t\t\tBans = Bans + 1\n\t\t\t\t\tWHERE ID = '" . db_string($AttemptID) . "'"); if ($Bans > 9) { // Automated bruteforce prevention $DB->query("\n\t\t\t\t\t\tSELECT Reason\n\t\t\t\t\t\tFROM ip_bans\n\t\t\t\t\t\tWHERE {$IP} BETWEEN FromIP AND ToIP"); if ($DB->has_results()) { //Ban exists already, only add new entry if not for same reason list($Reason) = $DB->next_record(MYSQLI_BOTH, false); if ($Reason != 'Automated ban per >60 failed login attempts') { $DB->query("\n\t\t\t\t\t\t\t\tUPDATE ip_bans\n\t\t\t\t\t\t\t\tSET Reason = CONCAT('Automated ban per >60 failed login attempts AND ', Reason)\n\t\t\t\t\t\t\t\tWHERE FromIP = {$IP}\n\t\t\t\t\t\t\t\t\tAND ToIP = {$IP}"); } } else { //No ban $DB->query("\n\t\t\t\t\t\t\tINSERT IGNORE INTO ip_bans\n\t\t\t\t\t\t\t\t(FromIP, ToIP, Reason)\n\t\t\t\t\t\t\tVALUES\n\t\t\t\t\t\t\t\t('{$IP}','{$IP}', 'Automated ban per >60 failed login attempts')"); $Cache->delete_value("ip_bans_{$IPA}"); } } } else { // User has attempted fewer than 6 logins $DB->query("\n\t\t\t\t\tUPDATE login_attempts\n\t\t\t\t\tSET\n\t\t\t\t\t\tLastAttempt = '" . sqltime() . "',\n\t\t\t\t\t\tAttempts = '" . db_string($Attempts) . "',\n\t\t\t\t\t\tBannedUntil = '0000-00-00 00:00:00'\n\t\t\t\t\tWHERE ID = '" . db_string($AttemptID) . "'"); } } else { // User has not attempted to log in recently $Attempts = 1; $DB->query("\n\t\t\t\tINSERT INTO login_attempts\n\t\t\t\t\t(UserID, IP, LastAttempt, Attempts)\n\t\t\t\tVALUES\n\t\t\t\t\t('" . db_string($UserID) . "', '" . db_string($IPStr) . "', '" . sqltime() . "', 1)"); } }
/** * Warn a user. * * @param int $UserID * @param int $Duration length of warning in seconds * @param string $reason */ public static function warn_user($UserID, $Duration, $Reason) { global $Time; $QueryID = G::$DB->get_query_id(); G::$DB->query("\n\t\t\tSELECT Warned\n\t\t\tFROM users_info\n\t\t\tWHERE UserID = {$UserID}\n\t\t\t\tAND Warned != '0000-00-00 00:00:00'"); if (G::$DB->has_results()) { //User was already warned, appending new warning to old. list($OldDate) = G::$DB->next_record(); $NewExpDate = date('Y-m-d H:i:s', strtotime($OldDate) + $Duration); Misc::send_pm($UserID, 0, 'You have received multiple warnings.', "When you received your latest warning (set to expire on " . date('Y-m-d', time() + $Duration) . '), you already had a different warning (set to expire on ' . date('Y-m-d', strtotime($OldDate)) . ").\n\n Due to this collision, your warning status will now expire at {$NewExpDate}."); $AdminComment = date('Y-m-d') . " - Warning (Clash) extended to expire at {$NewExpDate} by " . G::$LoggedUser['Username'] . "\nReason: {$Reason}\n\n"; G::$DB->query(' UPDATE users_info SET Warned = \'' . db_string($NewExpDate) . '\', WarnedTimes = WarnedTimes + 1, AdminComment = CONCAT(\'' . db_string($AdminComment) . '\', AdminComment) WHERE UserID = \'' . db_string($UserID) . '\''); } else { //Not changing, user was not already warned $WarnTime = time_plus($Duration); G::$Cache->begin_transaction("user_info_{$UserID}"); G::$Cache->update_row(false, array('Warned' => $WarnTime)); G::$Cache->commit_transaction(0); $AdminComment = date('Y-m-d') . " - Warned until {$WarnTime} by " . G::$LoggedUser['Username'] . "\nReason: {$Reason}\n\n"; G::$DB->query(' UPDATE users_info SET Warned = \'' . db_string($WarnTime) . '\', WarnedTimes = WarnedTimes + 1, AdminComment = CONCAT(\'' . db_string($AdminComment) . '\', AdminComment) WHERE UserID = \'' . db_string($UserID) . '\''); } G::$DB->set_query_id($QueryID); }
} $DB->set_query_id($UserQuery); $Passkeys = $DB->collect('torrent_pass'); foreach ($Passkeys as $Passkey) { Tracker::update_tracker('update_user', array('passkey' => $Passkey, 'can_leech' => '1')); } // Put user on ratio watch if he doesn't meet the standards sleep(10); $DB->query("\n\t\tSELECT m.ID, m.Downloaded\n\t\tFROM users_info AS i\n\t\t\tJOIN users_main AS m ON m.ID = i.UserID\n\t\tWHERE m.Uploaded / m.Downloaded < m.RequiredRatio\n\t\t\tAND i.RatioWatchEnds = '0000-00-00 00:00:00'\n\t\t\tAND m.Enabled = '1'\n\t\t\tAND m.can_leech = '1'"); $OnRatioWatch = $DB->collect('ID'); if (count($OnRatioWatch) > 0) { $DB->query("\n\t\t\tUPDATE users_info AS i\n\t\t\t\tJOIN users_main AS m ON m.ID = i.UserID\n\t\t\tSET i.RatioWatchEnds = '" . time_plus(60 * 60 * 24 * 14) . "',\n\t\t\t\ti.RatioWatchTimes = i.RatioWatchTimes + 1,\n\t\t\t\ti.RatioWatchDownload = m.Downloaded\n\t\t\tWHERE m.ID IN(" . implode(',', $OnRatioWatch) . ')'); } foreach ($OnRatioWatch as $UserID) { $Cache->begin_transaction("user_info_heavy_{$UserID}"); $Cache->update_row(false, array('RatioWatchEnds' => time_plus(60 * 60 * 24 * 14), 'RatioWatchDownload' => 0)); $Cache->commit_transaction(0); Misc::send_pm($UserID, 0, 'You have been put on Ratio Watch', "This happens when your ratio falls below the requirements we have outlined in the rules located [url=" . site_url() . "rules.php?p=ratio]here[/url].\n For information about ratio watch, click the link above."); echo "Ratio watch on: {$UserID}\n"; } sleep(5); //------------- Rescore 0.95 logs of disabled users $LogQuery = $DB->query("\n\t\t\tSELECT DISTINCT t.ID\n\t\t\tFROM torrents AS t\n\t\t\t\tJOIN users_main AS um ON t.UserID = um.ID\n\t\t\t\tJOIN torrents_logs_new AS tl ON tl.TorrentID = t.ID\n\t\t\tWHERE um.Enabled = '2'\n\t\t\t\tAND t.HasLog = '1'\n\t\t\t\tAND LogScore = 100\n\t\t\t\tAND Log LIKE 'EAC extraction logfile from%'"); $Details = array(); $Details[] = "Ripped with EAC v0.95, -1 point [1]"; $Details = serialize($Details); while (list($TorrentID) = $DB->next_record()) { $DB->query("\n\t\t\tUPDATE torrents\n\t\t\tSET LogScore = 99\n\t\t\tWHERE ID = {$TorrentID}"); $DB->query("\n\t\t\tUPDATE torrents_logs_new\n\t\t\tSET Score = 99, Details = '{$Details}'\n\t\t\tWHERE TorrentID = {$TorrentID}"); } sleep(5);
function warn_user($UserID, $Duration, $Reason) { global $LoggedUser, $DB, $Cache, $Time; $DB->query("SELECT Warned FROM users_info WHERE UserID=".$UserID." AND Warned <> '0000-00-00 00:00:00'"); if($DB->record_count() > 0) { //User was already warned, appending new warning to old. list($OldDate) = $DB->next_record(); $NewExpDate = date('Y-m-d H:i:s', strtotime($OldDate) + $Duration); send_pm($UserID, 0, db_string("You have received multiple warnings."), db_string("When you received your latest warning (Set to expire on ".date("Y-m-d", (time() + $Duration))."), you already had a different warning (Set to expire on ".date("Y-m-d", strtotime($OldDate)).").\n\n Due to this collision, your warning status will now expire at ".$NewExpDate.".")); $AdminComment = date("Y-m-d").' - Warning (Clash) extended to expire at '.$NewExpDate.' by '.$LoggedUser['Username']."\nReason: $Reason\n"; $DB->query('UPDATE users_info SET Warned=\''.db_string($NewExpDate).'\', WarnedTimes=WarnedTimes+1, AdminComment=CONCAT(\''.db_string($AdminComment).'\',AdminComment) WHERE UserID=\''.db_string($UserID).'\''); } else { //Not changing, user was not already warned $WarnTime = time_plus($Duration); $Cache->begin_transaction('user_info_'.$UserID); $Cache->update_row(false, array('Warned' => $WarnTime)); $Cache->commit_transaction(0); $AdminComment = "\n".date("Y-m-d").' - Warned until '.$WarnTime.' by '.$LoggedUser['Username']."\nReason: $Reason\n"; $DB->query('UPDATE users_info SET Warned=\''.db_string($WarnTime).'\', WarnedTimes=WarnedTimes+1, AdminComment=CONCAT(\''.db_string($AdminComment).'\',AdminComment) WHERE UserID=\''.db_string($UserID).'\''); } }
$WarningLength = $_POST['length']; $PostID = (int) $_POST['postid']; $UserID = (int) $_POST['userid']; $Key = (int) $_POST['key']; $SQLTime = sqltime(); $UserInfo = Users::user_info($UserID); if ($UserInfo['Class'] > $LoggedUser['Class']) { error(403); } $URL = site_url() . "forums.php?action=viewthread&postid={$PostID}#post{$PostID}"; if ($WarningLength !== 'verbal') { $Time = (int) $WarningLength * (7 * 24 * 60 * 60); Tools::warn_user($UserID, $Time, "{$URL} - {$Reason}"); $Subject = 'You have received a warning'; $PrivateMessage = "You have received a {$WarningLength} week warning for [url={$URL}]this post[/url].\n\n" . $PrivateMessage; $WarnTime = time_plus($Time); $AdminComment = date('Y-m-d') . " - Warned until {$WarnTime} by " . $LoggedUser['Username'] . " for {$URL}\nReason: {$Reason}\n\n"; } else { $Subject = 'You have received a verbal warning'; $PrivateMessage = "You have received a verbal warning for [url={$URL}]this post[/url].\n\n" . $PrivateMessage; $AdminComment = date('Y-m-d') . ' - Verbally warned by ' . $LoggedUser['Username'] . " for {$URL}\nReason: {$Reason}\n\n"; Tools::update_user_notes($UserID, $AdminComment); } $DB->query("\n\tINSERT INTO users_warnings_forums\n\t\t(UserID, Comment)\n\tVALUES\n\t\t('{$UserID}', '" . db_string($AdminComment) . "')\n\tON DUPLICATE KEY UPDATE\n\t\tComment = CONCAT('" . db_string($AdminComment) . "', Comment)"); Misc::send_pm($UserID, $LoggedUser['ID'], $Subject, $PrivateMessage); //edit the post $DB->query("\n\tSELECT\n\t\tp.Body,\n\t\tp.AuthorID,\n\t\tp.TopicID,\n\t\tt.ForumID,\n\t\tCEIL(\n\t\t\t(\n\t\t\t\tSELECT COUNT(p2.ID)\n\t\t\t\tFROM forums_posts AS p2\n\t\t\t\tWHERE p2.TopicID = p.TopicID\n\t\t\t\t\tAND p2.ID <= '{$PostID}'\n\t\t\t) / " . POSTS_PER_PAGE . "\n\t\t) AS Page\n\tFROM forums_posts AS p\n\t\tJOIN forums_topics AS t ON p.TopicID = t.ID\n\t\tJOIN forums AS f ON t.ForumID = f.ID\n\tWHERE p.ID = '{$PostID}'"); list($OldBody, $AuthorID, $TopicID, $ForumID, $Page) = $DB->next_record(); // Perform the update $DB->query("\n\tUPDATE forums_posts\n\tSET Body = '" . db_string($Body) . "',\n\t\tEditedUserID = '{$UserID}',\n\t\tEditedTime = '{$SQLTime}'\n\tWHERE ID = '{$PostID}'"); $CatalogueID = floor((POSTS_PER_PAGE * $Page - POSTS_PER_PAGE) / THREAD_CATALOGUE);
function time_df($TS1, $TS2, $Levels = 2, $Span = true) { $TimeStamp1 = strtotime($TS1); $TimeStamp2 = strtotime($TS2); $Time = $TimeStamp1 - $TimeStamp2; //If the time is negative, then we know that it expires in the future if ($Time < 0) { $Time = -$Time; $HideAgo = true; } $Years = floor($Time / 31556926); // seconds in a year $Remain = $Time - $Years * 31556926; $Months = floor($Remain / 2629744); // seconds in a month $Remain = $Remain - $Months * 2629744; $Weeks = floor($Remain / 604800); // seconds in a week $Remain = $Remain - $Weeks * 604800; $Days = floor($Remain / 86400); // seconds in a day $Remain = $Remain - $Days * 86400; $Hours = floor($Remain / 3600); $Remain = $Remain - $Hours * 3600; $Minutes = floor($Remain / 60); $Remain = $Remain - $Minutes * 60; $Seconds = $Remain; $Return = ''; if ($Years > 0 && $Levels > 0) { if ($Years > 1) { $Return .= $Years . ' years'; } else { $Return .= $Years . ' year'; } $Levels--; } if ($Months > 0 && $Levels > 0) { if ($Return != '') { $Return .= ', '; } if ($Months > 1) { $Return .= $Months . ' months'; } else { $Return .= $Months . ' month'; } $Levels--; } if ($Weeks > 0 && $Levels > 0) { if ($Return != "") { $Return .= ', '; } if ($Weeks > 1) { $Return .= $Weeks . ' weeks'; } else { $Return .= $Weeks . ' week'; } $Levels--; } if ($Days > 0 && $Levels > 0) { if ($Return != '') { $Return .= ', '; } if ($Days > 1) { $Return .= $Days . ' days'; } else { $Return .= $Days . ' day'; } $Levels--; } if ($Hours > 0 && $Levels > 0) { if ($Return != '') { $Return .= ', '; } if ($Hours > 1) { $Return .= $Hours . ' hours'; } else { $Return .= $Hours . ' hour'; } $Levels--; } if ($Minutes > 0 && $Levels > 0) { if ($Return != '') { $Return .= ' and '; } if ($Minutes > 1) { $Return .= $Minutes . ' mins'; } else { $Return .= $Minutes . ' min'; } $Levels--; } if ($Return == '') { $Return = 'Just now'; } elseif (!isset($HideAgo)) { $Return .= ' ago'; } if ($Span) { return '<span class="time" title="' . date('M d Y, H:i', strtotime(time_plus($Time))) . '">' . $Return . '</span>'; } else { return $Return; } }
function log_attempt($UserID) { global $DB, $AttemptID, $Attempts, $Bans, $BannedUntil, $Time; if ($AttemptID) { // User has attempted to log in recently $Attempts++; if ($Attempts > 5) { // Only 6 allowed login attempts, ban user's IP $BannedUntil = time_plus(60 * 60 * 6); $DB->query("UPDATE login_attempts SET\n\t\t\t\t\tLastAttempt='" . sqltime() . "',\n\t\t\t\t\tAttempts='" . db_string($Attempts) . "',\n\t\t\t\t\tBannedUntil='" . db_string($BannedUntil) . "',\n\t\t\t\t\tBans=Bans+1 \n\t\t\t\t\tWHERE ID='" . db_string($AttemptID) . "'"); if ($Bans > 9) { // Automated bruteforce prevention $IP = ip2unsigned($_SERVER['REMOTE_ADDR']); $DB->query("SELECT Reason FROM ip_bans WHERE " . $IP . " BETWEEN FromIP AND ToIP"); if ($DB->record_count() > 0) { //Ban exists already, only add new entry if not for same reason list($Reason) = $DB->next_record(MYSQLI_BOTH, false); if ($Reason != "Automated ban per >60 failed login attempts") { $DB->query("UPDATE ip_bans\n\t\t\t\t\t\t\t\tSET Reason = CONCAT('Automated ban per >60 failed login attempts AND ', Reason)\n\t\t\t\t\t\t\t\tWHERE FromIP = " . $IP . " AND ToIP = " . $IP); } } else { //No ban $DB->query("INSERT INTO ip_bans\n\t\t\t\t\t\t\t(FromIP, ToIP, Reason) VALUES\n\t\t\t\t\t\t\t('{$IP}','{$IP}', 'Automated ban per >60 failed login attempts')"); $Cache->delete_value('ip_bans'); } } } else { // User has attempted fewer than 6 logins $DB->query("UPDATE login_attempts SET\n\t\t\t\t\tLastAttempt='" . sqltime() . "',\n\t\t\t\t\tAttempts='" . db_string($Attempts) . "',\n\t\t\t\t\tBannedUntil='0000-00-00 00:00:00' \n\t\t\t\t\tWHERE ID='" . db_string($AttemptID) . "'"); } } else { // User has not attempted to log in recently $Attempts = 1; $DB->query("INSERT INTO login_attempts \n\t\t\t\t(UserID,IP,LastAttempt,Attempts) VALUES \n\t\t\t\t('" . db_string($UserID) . "','" . db_string($_SERVER['REMOTE_ADDR']) . "','" . sqltime() . "',1)"); } }
function log_attempt($UserID) { global $DB, $AttemptID, $Attempts, $Bans, $BannedUntil, $Time; if($AttemptID) { // User has attempted to log in recently $Attempts++; if ($Attempts>5) { // Only 6 allowed login attempts, ban user's IP $BannedUntil=time_plus(60*60*6); $DB->query("UPDATE login_attempts SET LastAttempt='".sqltime()."', Attempts='".db_string($Attempts)."', BannedUntil='".db_string($BannedUntil)."', Bans=Bans+1 WHERE ID='".db_string($AttemptID)."'"); if (!empty($UserID)) { $DB->query("UPDATE users_info SET AdminComment = CONCAT('".sqltime()." - 6 Failed login attempts from ".$_SERVER['REMOTE_ADDR']."\n\n', AdminComment) WHERE UserID = ".$UserID); } if ($Bans>9) { // Automated bruteforce prevention $IP = ip2long($_SERVER['REMOTE_ADDR']); $DB->query("SELECT Reason FROM ip_bans WHERE ".$IP." BETWEEN FromIP AND ToIP"); if($DB->record_count() > 0) { //Ban exists already, only add new entry if not for same reason list($Reason) = $DB->next_record(); if($Reason != "Automated ban per >60 failed login attempts") { $DB->query("INSERT INTO ip_bans (FromIP, ToIP, Reason) VALUES ('$IP','$IP', 'Automated ban per >60 failed login attempts')"); } } else { //No ban $DB->query("INSERT INTO ip_bans (FromIP, ToIP, Reason) VALUES ('$IP','$IP', 'Automated ban per >60 failed login attempts')"); } } } else { // User has attempted fewer than 6 logins $DB->query("UPDATE login_attempts SET LastAttempt='".sqltime()."', Attempts='".db_string($Attempts)."', BannedUntil='0000-00-00 00:00:00' WHERE ID='".db_string($AttemptID)."'"); } } else { // User has not attempted to log in recently $Attempts=1; $DB->query("INSERT INTO login_attempts (UserID,IP,LastAttempt,Attempts) VALUES ('".db_string($UserID)."','".db_string($_SERVER['REMOTE_ADDR'])."','".sqltime()."',1)"); } } // end log_attempt function
/** * Initiate a password reset * * @param int $UserID The user ID * @param string $Username The username * @param string $Email The email address */ public static function resetPassword($UserID, $Username, $Email) { $ResetKey = Users::make_secret(); G::$DB->query("\n\t\t\tUPDATE users_info\n\t\t\tSET\n\t\t\t\tResetKey = '" . db_string($ResetKey) . "',\n\t\t\t\tResetExpires = '" . time_plus(60 * 60) . "'\n\t\t\tWHERE UserID = '{$UserID}'"); require SERVER_ROOT . '/classes/templates.class.php'; $TPL = new TEMPLATE(); $TPL->open(SERVER_ROOT . '/templates/password_reset.tpl'); // Password reset template $TPL->set('Username', $Username); $TPL->set('ResetKey', $ResetKey); $TPL->set('IP', $_SERVER['REMOTE_ADDR']); $TPL->set('SITE_NAME', SITE_NAME); $TPL->set('SITE_URL', NONSSL_SITE_URL); Misc::send_email($Email, 'Password reset information for ' . SITE_NAME, $TPL->get(), 'noreply'); }
list($UserCount) = $DB->next_record(); $Cache->cache_value('stats_user_count', $UserCount, 0); } $UserID = $LoggedUser['ID']; //This is where we handle things passed to us authorize(); $DB->query("SELECT can_leech FROM users_main WHERE ID = " . $UserID); list($CanLeech) = $DB->next_record(); if ($LoggedUser['RatioWatch'] || !$CanLeech || $LoggedUser['DisableInvites'] == '1' || $LoggedUser['Invites'] == 0 && !check_perms('site_send_unlimited_invites') || $UserCount >= USER_LIMIT && USER_LIMIT != 0 && !check_perms('site_can_invite_always')) { error(403); } $Email = $_POST['email']; $Username = $LoggedUser['Username']; $SiteName = SITE_NAME; $SiteURL = NONSSL_SITE_URL; $InviteExpires = time_plus(60 * 60 * 24 * 3); // 3 days //MultiInvite if (strpos($Email, '|') && check_perms('site_send_unlimited_invites')) { $Emails = explode('|', $Email); } else { $Emails = array($Email); } foreach ($Emails as $CurEmail) { if (!preg_match("/^" . EMAIL_REGEX . "\$/i", $CurEmail)) { if (count($Emails) > 1) { continue; } else { error('Invalid email.'); header('Location: user.php?action=invite'); die;