0) && ($originalAmount > 0)); // Record the transaction for later fee collection sqlQueryEscaped("INSERT INTO `{?_MYSQL_PREFIX?}_transaction_log` ( `transaction_sender`, `transaction_receiver`, `transaction_level`, `transaction_value`, `transaction_original`, `transaction_fee_sender`, `transaction_fee_sender_percents`, `transaction_fee_receiver`, `transaction_fee_receiver_percents`, `transaction_subject` ) VALUES ( %s, %s, %s, %01.5f, %01.5f, %01.5f, %01.5f, %01.5f, %01.5f, '%s' )", array( convertNull($sender), bigintval($receiver), convertNull($level), $valueAmount, $originalAmount, calculateSenderTransactionFee($originalAmount), getConfig('transaction_fee_sender'), calculateReceiverTransactionFee($valueAmount), getConfig('transaction_fee_receiver'), $transactionSubject ), __FUNCTION__, __LINE__ ); // Should work assert(isValidId(getSqlInsertId()), 'getSqlInsertId() is not valid id number.'); } // Calculates transaction fee for sender amount function calculateSenderTransactionFee ($amount) { // Calculate it $fee = $amount * getConfig('transaction_fee_sender') / 100; // Return fee return $fee; } // Calculates transaction fee for receiver amount function calculateReceiverTransactionFee ($amount) { // Calculate it $fee = $amount * getConfig('transaction_fee_receiver') / 100; // Return fee return $fee; } // Hashes given transaction data function generateHashFromTransactionData (array &$data, $oldHash = '') { // Add CAPTCHA code, if missing if (!isset($data['transaction_captcha'])) { // Add it $data['transaction_captcha'] = generateId( 5, implode( ':', $data ) ); } // END - if // Convert some possible NULL values $data['transaction_sender'] = convertNull($data['transaction_sender']); // Generate string to hash $string = implode(':', $data); // Hash it then $hash = hashString($string, $oldHash); // Return it return $hash; } // "Getter" for CAPTCHA code from given transaction id function getCaptchaCodeFromTransactionId ($transactionId) { // Must be valid assert(isValidId($transactionId), 'transactionId=' . $transactionId . ' is not valid id number.'); // Default is NULL $code = NULL; // Search for it $result = sqlQueryEscaped("SELECT `transaction_captcha` FROM `{?_MYSQL_PREFIX?}_transaction_log` WHERE `transaction_id`=%s AND `transaction_level` IS NULL AND `transaction_captcha` IS NOT NULL LIMIT 1", array( bigintval($transactionId) ), __FUNCTION__, __LINE__ ); // Is it there? if (sqlNumRows($result) == 1) { // Load it list($code) = sqlFetchRoww($result); } // END - if // Free result sqlFreeResult($result); // Return it return $code; } // Tries to confirm given transactions function doTryConfirmTransactions (array $post) { // Make sure only members can do this assert((isMember()) && (isset($post['ok'])) && (ifPostHasSelection('transaction_id', $post))); // Remove submit button unset($post['ok']); // Default is not working ;-) $confirmed = FALSE; // Init arrays/variables $confirmedIds = array(); $failedIds = array(); $points = 0; // "Walk" through all transaction ids foreach ($post['transaction_id'] as $transactionId => $code) { // Process only valid ids/CAPTCHA codes if ((isValidId($transactionId)) && (empty($code))) { // Empty code found, no CAPTCHA entered continue; } elseif ((!isValidId($transactionId)) || (!isValidNumber($code))) { // Better set it as "invalid" explicitly and abort here $confirmed = FALSE; break; } // Init data array $data = array(); // Try to load more transaction data $result = sqlQueryEscaped("SELECT `transaction_id`, `transaction_hash`, `transaction_sender`, `transaction_receiver`, `transaction_fee_sender`, `transaction_fee_receiver`, `transaction_original`, `transaction_subject`, `transaction_timestamp` FROM `{?_MYSQL_PREFIX?}_transaction_log` WHERE `transaction_id`=%s AND `transaction_hash` != 'INVALID' AND `transaction_sender` != %s AND `transaction_sender` IS NOT NULL AND `transaction_receiver` != %s AND `transaction_receiver` IS NOT NULL AND `transaction_confirmed`='N' AND `transaction_level` IS NULL AND `transaction_captcha` IS NOT NULL LIMIT 1", array( bigintval($transactionId), getCurrentUserId(), getCurrentUserId() ), __FUNCTION__, __LINE__ ); // Is there one entry? if (sqlNumRows($result) == 1) { // Then load it $data = sqlFetchArray($result); /* * Save hash for later usage and remove it, so that the hasher * function will calculate the same hash if same CAPTCHA code * has been entered. */ $oldHash = $data['transaction_hash']; unset($data['transaction_hash']); // Set captcha code from POST data $data['transaction_captcha'] = bigintval($code); // Generate hash again $hash = generateHashFromTransactionData($data, $oldHash); // Is it the same? $confirmed = ($hash == $oldHash); if ($confirmed === TRUE) { // Then mark it as confirmed and count all points array_push($confirmedIds, $transactionId); $points += $data['transaction_fee_sender'] + $data['transaction_fee_receiver']; } else { // Failed confirmation array_push($failedIds, $transactionId); } } // END - if // Free result sqlFreeResult($result); // If it is not found, abort here if (!isFilledArray($data)) { // Is not valid, better explicitly set it here and abort $confirmed = FALSE; break; } // END - if } // END - foreach // Were all transaction ids valid? if ($confirmed === TRUE) { // Update all confirmed transactions sqlQueryEscaped("UPDATE `{?_MYSQL_PREFIX?}_transaction_log` SET `transaction_confirmed`='Y' WHERE `transaction_id` IN (" . implode(',', $confirmedIds) . ") AND `transaction_hash` != 'INVALID' AND `transaction_sender` != %s AND `transaction_sender` IS NOT NULL AND `transaction_receiver` != %s AND `transaction_receiver` IS NOT NULL AND `transaction_confirmed`='N' LIMIT %s", array( getCurrentUserId(), getCurrentUserId(), count($confirmedIds) ), __FUNCTION__, __LINE__ ); // Check if all has been updated $confirmed = (sqlAffectedRows() == count($confirmedIds)); // Has all confirmed? if ($confirmed === TRUE) { // Allowed fields $allowed = array( 'transaction_fees', 'transaction_confirmed', 'transaction_confirmed_yearly', 'transaction_count' ); // Add them user's "pot" $updated = doUpdateMemberProfileData(array( 'transaction_fees' => getUserData('transaction_fees') + $points, 'transaction_confirmed' => getUserData('transaction_confirmed') + count($confirmedIds), 'transaction_confirmed_yearly' => getUserData('transaction_confirmed_yearly') + count($confirmedIds), 'transaction_count' => getUserData('transaction_count') + (count($confirmedIds) * getConfig('transaction_count_captcha_confirm')) ), $allowed, '', FALSE); // Should always work assert($updated === TRUE, 'Nothing has been updated which is not expected.'); } // END - if } // END - if // Are there some failed transactions? if (count($failedIds) > 0) { // Then update all sqlQueryEscaped("UPDATE `{?_MYSQL_PREFIX?}_transaction_log` SET `transaction_captcha_failed`='Y' WHERE `transaction_id` IN (" . implode(',', $failedIds) . ") AND `transaction_hash` != 'INVALID' AND `transaction_sender` != %s AND `transaction_sender` IS NOT NULL AND `transaction_receiver` != %s AND `transaction_receiver` IS NOT NULL AND `transaction_confirmed`='N' LIMIT %s", array( getCurrentUserId(), getCurrentUserId(), count($failedIds) ), __FUNCTION__, __LINE__ ); // Should always work assert(sqlAffectedRows() == count($failedIds), 'sqlAffectedRows()=' . sqlAffectedRows() . ',failedIds()=' . count($failedIds)); } // END - if // Return status return $confirmed; } // Checks whether the given user has a fee exempt function ifUserHasTransactionFeeExempt ($username) { // Accept only valid ids assert(isValidId($username), 'username=' . $username . ' which is not a valid id number.'); // Is there "cache"? if (!isset($GLOBALS[__FUNCTION__][$username])) { // Default is the user has no excempt $GLOBALS[__FUNCTION__][$username] = FALSE; // "Determine" it $GLOBALS[__FUNCTION__][$username] = (getTotalPoints($username) < getConfig('transaction_fee_exempt_amount')); } // END - if // Return cache return $GLOBALS[__FUNCTION__][$username]; } // [EOF] ?>