Im having a problem with the code of my Invite System.. Sometimes, the SAME KEY is used by more than 1 person, which it isn't supposed to happen
I was wondering if any programmer out there with some spare time could take a look at the code to see what is wrong with it? Since i can't really understand this..
Any help would be appreciated.
<?php
function InviteMain()
{
global $sourcedir, $context, $txt, $boardurl, $boarddir, $scripturl, $smcFunc, $modSettings;
// Load the invitation language and template
if (loadlanguage('Invite') == false)
loadLanguage('Invite','english');
loadtemplate('Invite');
// Load all the subactions
$subActions = array(
'generate' => 'invite_generate',
'settings' => 'invite_admin_settings',
'give' => 'invitations_give',
'send' => 'invitations_send',
'log' => 'invite_log',
'version' => 'invite_version',
'massive' => 'invite_massive_delete',
'invitees' => 'invite_invitees',
);
// Add the Linktree
if ($context['current_action'] !== 'admin')
$context['linktree'][] = array(
'name' => (!empty($modSettings['invitations_title'])) ? $modSettings['invitations_title'] : $txt['invitations'],
'url' => $scripturl.'?action=invite',
);
if (isset($_GET['sa']))
$sa = $_GET['sa'];
else
invite_index();
if (isset($sa) && !empty($subActions[$sa]))
$subActions[$sa]();
if (!function_exists('invite_vital'))
fatal_error('Something is soooooo wrong!', false);
}
function invite_index()
{
global $context, $user_info, $smcFunc, $modSettings, $user_profile, $txt, $scripturl;
isAllowedTo('invite');
if (isset($modSettings['invitations_state']) && ($modSettings['invitations_state'] == 'off'))
fatal_lang_error('invitations_are_off',false);
// Get the total amount of entries.
$request = $smcFunc['db_query']('', '
SELECT date, invite_key, email, registered
FROM {db_prefix}invitations
WHERE author = {int:id_member}',
array(
'id_member' => $user_info['id'],
)
);
$totalinvitations = $smcFunc['db_num_rows']($request);
$context['invitations_date'] = array();
while ($row = $smcFunc['db_fetch_assoc']($request))
$context['invitations_date'][] = $row;
$smcFunc['db_free_result']($request);
// Create the page index for comments
$limit = !empty($modSettings['invitations_per_page']) && is_numeric($modSettings['invitations_per_page']) ? $modSettings['invitations_per_page'] : 10;
$context['start'] = (isset($_REQUEST['start'])) ? $_REQUEST['start'] : 0;
$context['page_index'] = constructPageIndex($scripturl . '?action=invite', $context['start'], $totalinvitations, $limit);
$context['page_title'] = (!empty($modSettings['invitations_title'])) ? $modSettings['invitations_title'] : $txt['invitations'];
$context['sub_template'] = 'invitations_index';
$where = 'i.author = {int:id_member}';
if (!empty($_REQUEST['do']) && $_REQUEST['do'] == 'expired')
{
$where .= ' AND (i.registered != 0 ';
if (!empty($modSettings['invitations_expiration']))
$where .= 'OR {int:now} > ({int:exp_date} + date))';
else
$where .= ')';
}
else if (!empty($_REQUEST['do']) && $_REQUEST['do'] == 'active')
{
$where .= ' AND (i.registered = 0 ';
if (!empty($modSettings['invitations_expiration']))
$where .= 'AND {int:now} < ({int:exp_date} + date))';
else
$where .= ')';
}
$dbresult = $smcFunc['db_query']('', '
SELECT i.date, i.invite_key, i.email, i.registered, m.real_name
FROM {db_prefix}invitations AS i
LEFT JOIN {db_prefix}members AS m ON (m.id_member = i.registered)
WHERE ' . $where . '
ORDER BY i.id_invite
LIMIT {int:start}, {int:limit}',array(
'id_member' => $user_info['id'],
'start' => $context['start'],
'limit' => $limit,
'now' => time(),
'exp_date' => !empty($modSettings['invitations_expiration']) ? $modSettings['invitations_expiration'] * 60 * 60 * 24 : '',
)
);
$context['invitations'] = array();
while ($row = $smcFunc['db_fetch_assoc']($dbresult))
$context['invitations'][] = $row;
$smcFunc['db_free_result']($dbresult);
if (allowedTo('invitations_unlimited') || empty($modSettings['invitations_value']))
$context['credits'] = -1;
else
{
// By Days
if ((isset($modSettings['invitations_method']) && ($modSettings['invitations_method'] == 'days')) && !empty($modSettings['invitations_value']))
{
$period = 60 * 60 * 24 * $modSettings['invitations_value'];
if (!empty($modSettings['invitations_max_credits'])){
$context['credits'] = 0;
foreach ($context['invitations_date'] as $invite)
{
// Invite credits at this point in time.
$context['credits'] += ($invite['date'] - $user_profile[$user_info['id']]['date_registered']) / $period;
// Make sure it's never above the max.
if ($context['credits'] > $modSettings['invitations_max_credits'])
$context['credits'] = $modSettings['invitations_max_credits'];
// Remove the one just sent.
$context['credits']--;
// Prepare for next loop.
$user_profile[$user_info['id']]['date_registered'] = $invite['date'];
}
$context['credits'] += (time() - $user_profile[$user_info['id']]['date_registered']) / $period;
}
else
$context['credits'] = (time() - $user_profile[$user_info['id']]['date_registered']) / $period;
if (!empty($modSettings['invitations_max_credits']) && $modSettings['invitations_max_credits'] == $context['credits'])
$context['invite_next'] = '<i>(' . $txt['invitations_max_reached'] . ')</i>';
else
$context['invite_next'] = timeformat(time() - ($context['credits'] - intval($context['credits'])) * $period + $period, true);
}
// By Posts
elseif ((isset($modSettings['invitations_method']) && ($modSettings['invitations_method'] == 'posts')) && !empty($modSettings['invitations_value'])){
$context['credits'] = $user_info['posts'] / $modSettings['invitations_value'];
$context['invite_next'] = !empty($modSettings['invitations_max_credits']) && ($modSettings['invitations_max_credits'] == $context['credits']) ? '<i>(' . $txt['invitations_max_reached'] . ')</i>' : '';
}
// By Karma
else{
$context['credits'] = (($user_profile[$user_info['id']]['karma']['good'] - $user_profile[$user_info['id']]['karma']['bad']) / $modSettings['invitations_value']);
$context['invite_next'] = !empty($modSettings['invitations_max_credits']) && ($modSettings['invitations_max_credits'] == $context['credits']) ? '<i>(' . $txt['invitations_max_reached'] . ')</i>' : '';
}
// Now reduce the amount of credits based on created invitations
$dbrequest = $smcFunc['db_query']('', '
SELECT COUNT(*)
FROM {db_prefix}invitations
WHERE author = {int:id_member}
AND email = 0
'.(!empty($modSettings['invitations_expiration']) && !empty($modSettings['invitations_recount_expired']) ? 'AND {int:now} < ({int:exp_date} + date)' : '').'',
array(
'id_member' => $user_info['id'],
'now' => time(),
'exp_date' => !empty($modSettings['invitations_expiration']) ? $modSettings['invitations_expiration'] * 60 * 60 * 24 : '',
)
);
list ($totalinvitations) = $smcFunc['db_fetch_row']($dbrequest);
$smcFunc['db_free_result']($dbrequest);
$context['credits'] = $context['credits'] - $totalinvitations;
$sql = $smcFunc['db_query']('', '
SELECT additional_credits
FROM {db_prefix}members
WHERE id_member = {int:id_member}
LIMIT 1',
array(
'id_member' => $user_info['id']
)
);
list($additional_credits) = $smcFunc['db_fetch_row']($sql);
$smcFunc['db_free_result']($sql);
$context['credits'] = $context['credits'] + $additional_credits;
if (!empty($modSettings['invitations_max_credits']) && $context['credits'] > $modSettings['invitations_max_credits'])
$context['credits'] = $modSettings['invitations_max_credits'];
}
}
function invitations_send(){
global $txt, $smcFunc, $context, $scripturl, $user_info, $modSettings, $sourcedir;
isAllowedTo('invite');
if (isset($modSettings['invitations_state']) && ($modSettings['invitations_state'] == 'off'))
fatal_lang_error('invitations_are_off',false);
if (!empty($modSettings['invitations_disable_email']))
fatal_lang_error('invitations_email_disabled',false);
if (empty($_REQUEST['key']))
fatal_lang_error('invitations_key_no_selected',false);
// We Send the Form!
if (!empty($_POST['do']) && $_POST['do'] == 'send'){
// Check if the visual verification code was entered correctly.
if (!empty($modSettings['invitations_verification']) && !isset($modSettings['invitations_disable_custom']) && !$context['user']['is_admin']){
require_once($sourcedir . '/Subs-Editor.php');
$verificationOptions = array(
'id' => 'register',
);
$context['visual_verification'] = create_control_verification($verificationOptions, true);
if (is_array($context['visual_verification']))
{
loadLanguage('Errors');
foreach ($context['visual_verification'] as $error)
fatal_error($txt['error_' . $error], false);
}
}
if (!preg_match('/^[_a-z0-9-]+(\.[_a-z0-9-]+)*@[a-z0-9-]+(\.[a-z0-9-]+)*(\.[a-z]{2,3})$/', $_REQUEST['recipient_email']))
fatal_lang_error('invitations_no_email', false);
$subject = (empty($modSettings['invitations_email_subject'])) ? $txt['invitations_default_email_subject'] : $modSettings['invitations_email_subject'];
$subject = str_replace('{forum}', $context['forum_name'], $subject);
$subject = str_replace('{inviter}', $user_info['name'], $subject);
$message = (empty($modSettings['invitations_email_message'])) ? $txt['invitations_default_email_message'] : $modSettings['invitations_email_message'];
if (!isset($_REQUEST['message']) || $_REQUEST['message'] == '')
$message = str_replace('{custom_message}', '', $message);
else
$message = str_replace('{custom_message}', $_REQUEST['message'], $message);
$message = str_replace('{forum}', $context['forum_name'], $message);
$message = str_replace('{inviter}', $user_info['name'], $message);
$message = str_replace('{invited}', $_REQUEST['recipient_name'], $message);
$message = str_replace('{link}', $scripturl . '?action=register;invite_key=' . $_REQUEST['key'], $message);
// Send!
require_once($sourcedir . '/Subs-Post.php');
if (!sendmail($_REQUEST['recipient_email'], $subject, $message, $context['user']['email']))
fatal_lang_error('invitations_no_send');
// Update
$smcFunc['db_query']('', '
UPDATE {db_prefix}invitations
SET email = {string:email}
WHERE invite_key = {string:key}
LIMIT {int:limit}',
array(
'key' => $_REQUEST['key'],
'email' => $_REQUEST['recipient_email'],
'limit' => 1,
)
);
$smcFunc['db_insert']('replace',
'{db_prefix}invitations_log',
array(
'recipient_name' => 'text', 'recipient_email' => 'text', 'inviter' => 'int', 'recipient_key' => 'text', 'date' => 'int',
),
array(
$_REQUEST['recipient_name'], $_REQUEST['recipient_email'], $user_info['id'], $_REQUEST['key'], time()
),
array()
);
redirectexit('action=invite;sent');
}
// We're looking for the send form
else
{
// Now add the Verification for guests
if (!empty($modSettings['invitations_verification']) && !$context['user']['is_admin']){
require_once($sourcedir . '/Subs-Editor.php');
$verificationOptions = array(
'id' => 'register',
);
$context['visual_verification'] = create_control_verification($verificationOptions);
$context['visual_verification_id'] = $verificationOptions['id'];
}
else
$context['visual_verification'] = false;
$context['page_title'] = $txt['invitation_send_email'];
$context['sub_template'] = 'invitations_send';
//Add the Linktree
$context['linktree'][] = array(
'name' => $txt['invitation_send_email'],
'url' => $scripturl.'?action=invite;sa=send;key='.$_REQUEST['key'],
);
}
}
function invite_generate()
{
global $smcFunc, $user_info;
if (isset($modSettings['invitations_state']) && ($modSettings['invitations_state'] == 'off'))
fatal_lang_error('invitations_are_off',false);
isAllowedTo('invite');
if (!isset($_POST['is_form']))
fatal_lang_error('invitations_no_permission',false);
checkSession();
$smcFunc['db_insert']('replace',
'{db_prefix}invitations',
array(
'author' => 'int', 'registered' => 'int', 'invite_key' => 'text', 'date' => 'int',
),
array(
$user_info['id'], 0, md5(uniqid()), time()
),
array()
);
redirectexit('action=invite;created');
}
function invite_admin_settings($return_config = false)
{
global $txt, $scripturl, $context, $sourcedir, $modSettings, $db_prefix;
$context[$context['admin_menu_name']]['tab_data']['title'] = $txt['invitations_admin_settings'];
$context[$context['admin_menu_name']]['tab_data']['description'] = $txt['invitations_admin_settings_description'];
// Set title and default sub-action.
$context['sub_template'] = 'show_settings';
$context['page_title'] = $txt['invitations_admin_settings'];
// We need this
require_once($sourcedir.'/ManageServer.php');
$config_vars = array(
// The General Settings
array('select', 'invitations_state', array('off' => $txt['invitations_off'], 'passive' => $txt['invitations_passive'], 'forced' => $txt['invitations_forced']), 'subtext' => $txt['invitations_state2']),
array('select', 'invitations_method', array('posts' => $txt['posts'], 'karma' => $txt['karma'], 'days' => $txt['invitations_date_registered'])),
array('int', 'invitations_value', 'postinput' => $txt['invitations_value2']),
array('int', 'invitations_max_credits', 'subtext' => $txt['invitations_max_credits2']),
array('int', 'invitations_expiration', 'subtext' => $txt['invitations_expiration2']),
array('check', 'invitations_recount_expired', 'subtext' => $txt['invitations_recount_expired2']),
array('check', 'invitations_disable_email', 'subtext' => $txt['invitations_disable_email2']),
array('check', 'invitations_disable_custom', 'subtext' => $txt['invitations_disable_custom2']),
'',
array('text', 'invitations_email_subject', 38, 'invitations_email_subject'),
array('large_text', 'invitations_email_message', 10, 'invitations_email_message', 'subtext' => $txt['invitations_email_message2']),
'',
array('text', 'invitations_title'),
array('check', 'invitations_verification', 'subtext' => $txt['invitations_verification2']),
array('check', 'invitations_enable_log', 'subtext' => $txt['invitations_enable_log2']),
array('int', 'invitations_registration', 'subtext' => $txt['invitations_registration2']),
array('int', 'invitations_per_page', 'subtext' => $txt['invitations_per_page2']),
array('check', 'invitations_in_profile', 'subtext' => $txt['invitations_in_profile2']),
array('check', 'invitations_in_stats', 'subtext' => $txt['invitations_in_stats2']),
);
if (isset($_GET['save']))
{
saveDBSettings($config_vars);
redirectexit('action=admin;area=invitations;sa=settings');
}
$context['post_url'] = $scripturl .'?action=admin;area=invitations;sa=settings;save';
prepareDBSettingContext($config_vars);
}
function invite_version()
{
global $context, $txt, $scripturl;
$context[$context['admin_menu_name']]['tab_data']['title'] = $txt['invitations_version'];
$context[$context['admin_menu_name']]['tab_data']['description'] = $txt['invitations_version_description'];
// You aren't admin?? Please you can`t be here
if (!$context['user']['is_admin'])
fatal_lang_error('invitations_no_permission', false);
$context['page_title'] = $txt['invitations_version'];
$context['sub_template'] = 'invite_version';
}
function invite_log()
{
global $context, $txt, $scripturl, $smcFunc;
$context[$context['admin_menu_name']]['tab_data']['title'] = $txt['invitations_log'];
$context[$context['admin_menu_name']]['tab_data']['description'] = $txt['invitations_log_description'];
// You aren't admin?? Please you can`t be here
if (!$context['user']['is_admin'])
fatal_lang_error('invitations_no_permission', false);
$context['page_title'] = $txt['invitations_log'];
$context['sub_template'] = 'invite_log';
$request = $smcFunc['db_query']('', '
SELECT COUNT(*)
FROM {db_prefix}invitations_log');
list ($totalresults) = $smcFunc['db_fetch_row']($request);
$smcFunc['db_free_result']($request);
$limit = 10;
$context['start'] = (isset($_REQUEST['start'])) ? $_REQUEST['start'] : 0;
$context['page_index'] = constructPageIndex($scripturl . '?action=admin;area=invitations;sa=log;start=%1$d', $context['start'], $totalresults, $limit, true);
// This is information about which page is current, and which page we're on - in case you don't like the constructed page index. (again, wireles..)
$context['page_info'] = array(
'current_page' => $_REQUEST['start'] / $limit + 1,
'num_pages' => floor(($totalresults - 1) / $limit) + 1,
);
$dbresult = $smcFunc['db_query']('', '
SELECT l.recipient_name, l.recipient_email, l.id_log, l.inviter, m.real_name, l.recipient_key, l.date
FROM {db_prefix}invitations_log AS l
LEFT JOIN {db_prefix}members AS m ON (m.id_member = l.inviter)
LIMIT {int:start}, {int:limit}',array(
'start' => $context['start'],
'limit' => $limit,
)
);
$context['invitations'] = array();
while ($row = $smcFunc['db_fetch_assoc']($dbresult))
$context['invitations'][] = $row;
$smcFunc['db_free_result']($dbresult);
}
function invite_massive_delete()
{
global $txt, $context, $smcFunc;
if (!$context['user']['is_admin'])
fatal_lang_error('invitations_no_permission', false);
if (empty($_POST['remove_all_log']))
{
foreach ($_POST['remove_logs'] as $index => $id)
$logs_ids[$index] = (int) $id;
$smcFunc['db_query']('', '
DELETE FROM {db_prefix}invitations_log
WHERE
id_log IN({array_int:logs})',
array(
'logs' => $logs_ids,
)
);
}
else
$smcFunc['db_query']('', 'TRUNCATE TABLE {db_prefix}invitations_log');
// Redirect!
redirectexit('action=admin;area=invitations;sa=log;' . $context['session_var'] . '=' . $context['session_id']);
}
function invite_invitees()
{
global $context, $txt, $scripturl, $smcFunc;
if (($_REQUEST['member'] == $context['user']['id'] && !allowedTo('invitations_own')) || !allowedTo('invitations_any'))
fatal_lang_error('invitations_no_permission', false);
if (isset($_REQUEST['member']) && loadMemberData($_REQUEST['member']))
{
global $user_profile;
// Just to let the members know it's not really a search.
$context['page_title'] = $txt['invitations_by'] . ' ' . $user_profile[$_REQUEST['member']]['real_name'];
// Find the number of results.
$request = $smcFunc['db_query']('', "
SELECT COUNT(*)
FROM {db_prefix}members AS mem
LEFT JOIN {db_prefix}invitations AS inv ON (inv.registered = mem.id_member)
WHERE inv.author = $_REQUEST[member]
AND is_activated = 1");
list ($numResults) = $smcFunc['db_fetch_row']($request);
$smcFunc['db_free_result']($request);
$context['start'] = (!empty($_REQUEST['start'])) ? $_REQUEST['start'] : 0;
$context['page_index'] = constructPageIndex($scripturl . '?actioninvite;sa=invitees;member=' . $_REQUEST['member'], $_REQUEST['start'], $numResults, 10);
$dbresult = $smcFunc['db_query']('', "
SELECT mem.id_member, mem.posts, mem.date_registered, mem.real_name
FROM {db_prefix}members AS mem
LEFT JOIN {db_prefix}invitations AS inv ON (inv.registered = mem.id_member)
LEFT JOIN {db_prefix}log_online AS lo ON (lo.id_member = mem.id_member)
LEFT JOIN {db_prefix}membergroups AS mg ON (mg.ID_GROUP = IF(mem.ID_GROUP = 0, mem.ID_POST_GROUP, mem.ID_GROUP))
WHERE inv.author = $_REQUEST[member]
AND is_activated = 1
LIMIT {int:start}, 10",array(
'start' => $context['start'],
)
);
$context['invitations'] = array();
while ($row = $smcFunc['db_fetch_assoc']($dbresult))
$context['invitations'][] = $row;
$smcFunc['db_free_result']($dbresult);
}
$context['template_layers'] = array('invitees');
}
function invitations_give()
{
global $txt, $smcFunc, $context, $scripturl, $user_info, $modSettings, $sourcedir;
if (!$context['user']['is_admin'])
fatal_lang_error('invitations_no_permission', false);
// We Send the Form!
if (!empty($_REQUEST['do']) && $_REQUEST['do'] == 'send')
{
if (!empty($_POST['credits']) && is_numeric($_POST['credits']) && isset($_REQUEST['newowner']))
{
$newowner = str_replace('"','', $_REQUEST['newowner']);
$newowner = str_replace("'",'', $newowner);
$newowner = str_replace('\\','', $newowner);
$newowner = htmlspecialchars($newowner, ENT_QUOTES);
$memid = 0;
$dbresult = $smcFunc['db_query']('', "
SELECT
real_name, id_member
FROM {db_prefix}members
WHERE real_name = '$newowner' OR member_name = '$newowner' LIMIT 1");
$row = $smcFunc['db_fetch_assoc']($dbresult);
$smcFunc['db_free_result']($dbresult);
if ($smcFunc['db_affected_rows']() != 0)
{
// Update
$smcFunc['db_query']('', '
UPDATE {db_prefix}members
SET additional_credits = additional_credits + {int:credits}
WHERE id_member = {int:member}
LIMIT {int:limit}',
array(
'credits' => (int) $_POST['credits'],
'member' => $row['id_member'],
'limit' => 1,
)
);
redirectexit('action=admin;area=invitations;sa=give;sent');
}
}
redirectexit('action=admin;area=invitations;sa=give;notsent');
}
$context['page_title'] = $txt['invitation_give'];
$context['sub_template'] = 'invitations_give';
$context[$context['admin_menu_name']]['tab_data']['title'] = $txt['invitation_give'];
$context[$context['admin_menu_name']]['tab_data']['description'] = $txt['invitations_give_description'];
}
function invite_vital()
{
return;
}
?>