2 /************************************************************************
3 * Mailer v0.2.1-FINAL Start: 06/22/2013 *
4 * =================== Last change: 06/22/2013 *
6 * -------------------------------------------------------------------- *
7 * File : transaction_functions.php *
8 * -------------------------------------------------------------------- *
9 * Short description : Functions for ext-transaction *
10 * -------------------------------------------------------------------- *
11 * Kurzbeschreibung : Funktionen fuer ext-transaction *
12 * -------------------------------------------------------------------- *
15 * $Tag:: 0.2.1-FINAL $ *
17 * -------------------------------------------------------------------- *
18 * Copyright (c) 2003 - 2009 by Roland Haeder *
19 * Copyright (c) 2009 - 2015 by Mailer Developer Team *
20 * For more information visit: http://mxchange.org *
22 * This program is free software; you can redistribute it and/or modify *
23 * it under the terms of the GNU General Public License as published by *
24 * the Free Software Foundation; either version 2 of the License, or *
25 * (at your option) any later version. *
27 * This program is distributed in the hope that it will be useful, *
28 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
29 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
30 * GNU General Public License for more details. *
32 * You should have received a copy of the GNU General Public License *
33 * along with this program; if not, write to the Free Software *
34 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, *
36 ************************************************************************/
38 // Some security stuff...
39 if (!defined('__SECURITY')) {
43 // Logs a transaction and "signs" it
44 function logTransaction ($sender, $receiver, $level, $valueAmount, $originalAmount, $transactionSubject) {
45 // Check all conditions
46 assert(((is_null($sender)) || (isValidId($sender))) && (isValidId($receiver)) && ((is_null($level)) || (isValidNumber($level))) && ($valueAmount > 0) && ($originalAmount > 0));
48 // Record the transaction for later fee collection
49 sqlQueryEscaped("INSERT INTO
50 `{?_MYSQL_PREFIX?}_transaction_log`
53 `transaction_receiver`,
56 `transaction_original`,
57 `transaction_fee_sender`,
58 `transaction_fee_sender_percents`,
59 `transaction_fee_receiver`,
60 `transaction_fee_receiver_percents`,
80 calculateSenderTransactionFee($originalAmount),
81 getConfig('transaction_fee_sender'),
82 calculateReceiverTransactionFee($valueAmount),
83 getConfig('transaction_fee_receiver'),
85 ), __FUNCTION__, __LINE__
89 assert(isValidId(getSqlInsertId()));
92 // Calculates transaction fee for sender amount
93 function calculateSenderTransactionFee ($amount) {
95 $fee = $amount * getConfig('transaction_fee_sender') / 100;
101 // Calculates transaction fee for receiver amount
102 function calculateReceiverTransactionFee ($amount) {
104 $fee = $amount * getConfig('transaction_fee_receiver') / 100;
110 // Hashes given transaction data
111 function generateHashFromTransactionData (array &$data, $oldHash = '') {
112 // Add CAPTCHA code, if missing
113 if (!isset($data['transaction_captcha'])) {
115 $data['transaction_captcha'] = generateId(
124 // Convert some possible NULL values
125 $data['transaction_sender'] = convertNull($data['transaction_sender']);
127 // Generate string to hash
128 $string = implode(':', $data);
131 $hash = hashString($string, $oldHash);
137 // "Getter" for CAPTCHA code from given transaction id
138 function getCaptchaCodeFromTransactionId ($transactionId) {
140 assert(isValidId($transactionId));
146 $result = sqlQueryEscaped("SELECT
147 `transaction_captcha`
149 `{?_MYSQL_PREFIX?}_transaction_log`
151 `transaction_id`=%s AND
152 `transaction_level` IS NULL AND
153 `transaction_captcha` IS NOT NULL
156 bigintval($transactionId)
157 ), __FUNCTION__, __LINE__
161 if (sqlNumRows($result) == 1) {
163 list($code) = sqlFetchRoww($result);
167 sqlFreeResult($result);
173 // Tries to confirm given transactions
174 function doTryConfirmTransactions (array $post) {
175 // Make sure only members can do this
176 assert((isMember()) && (isset($post['ok'])) && (ifPostHasSelection('transaction_id', $post)));
178 // Remove submit button
181 // Default is not working ;-)
184 // Init arrays/variables
185 $confirmedIds = array();
186 $failedIds = array();
189 // "Walk" through all transaction ids
190 foreach ($post['transaction_id'] as $transactionId => $code) {
191 // Process only valid ids/CAPTCHA codes
192 if ((isValidId($transactionId)) && (empty($code))) {
193 // Empty code found, no CAPTCHA entered
195 } elseif ((!isValidId($transactionId)) || (!isValidNumber($code))) {
196 // Better set it as "invalid" explicitly and abort here
204 // Try to load more transaction data
205 $result = sqlQueryEscaped("SELECT
208 `transaction_sender`,
209 `transaction_receiver`,
210 `transaction_fee_sender`,
211 `transaction_fee_receiver`,
212 `transaction_original`,
213 `transaction_subject`,
214 `transaction_timestamp`
216 `{?_MYSQL_PREFIX?}_transaction_log`
218 `transaction_id`=%s AND
219 `transaction_hash` != 'INVALID' AND
220 `transaction_sender` != %s AND
221 `transaction_sender` IS NOT NULL AND
222 `transaction_receiver` != %s AND
223 `transaction_receiver` IS NOT NULL AND
224 `transaction_confirmed`='N' AND
225 `transaction_level` IS NULL AND
226 `transaction_captcha` IS NOT NULL
229 bigintval($transactionId),
232 ), __FUNCTION__, __LINE__
235 // Is there one entry?
236 if (sqlNumRows($result) == 1) {
238 $data = sqlFetchArray($result);
241 * Save hash for later usage and remove it, so that the hasher
242 * function will calculate the same hash if same CAPTCHA code
245 $oldHash = $data['transaction_hash'];
246 unset($data['transaction_hash']);
248 // Set captcha code from POST data
249 $data['transaction_captcha'] = bigintval($code);
251 // Generate hash again
252 $hash = generateHashFromTransactionData($data, $oldHash);
255 $confirmed = ($hash == $oldHash);
256 if ($confirmed === TRUE) {
257 // Then mark it as confirmed and count all points
258 array_push($confirmedIds, $transactionId);
259 $points += $data['transaction_fee_sender'] + $data['transaction_fee_receiver'];
261 // Failed confirmation
262 array_push($failedIds, $transactionId);
267 sqlFreeResult($result);
269 // If it is not found, abort here
270 if (!isFilledArray($data)) {
271 // Is not valid, better explicitly set it here and abort
277 // Were all transaction ids valid?
278 if ($confirmed === TRUE) {
279 // Update all confirmed transactions
280 sqlQueryEscaped("UPDATE
281 `{?_MYSQL_PREFIX?}_transaction_log`
283 `transaction_confirmed`='Y'
285 `transaction_id` IN (" . implode(',', $confirmedIds) . ") AND
286 `transaction_hash` != 'INVALID' AND
287 `transaction_sender` != %s AND
288 `transaction_sender` IS NOT NULL AND
289 `transaction_receiver` != %s AND
290 `transaction_receiver` IS NOT NULL AND
291 `transaction_confirmed`='N'
297 ), __FUNCTION__, __LINE__
300 // Check if all has been updated
301 $confirmed = (sqlAffectedRows() == count($confirmedIds));
303 // Has all confirmed?
304 if ($confirmed === TRUE) {
308 'transaction_confirmed',
309 'transaction_confirmed_yearly',
313 // Add them user's "pot"
314 $updated = doUpdateMemberProfileData(array(
315 'transaction_fees' => getUserData('transaction_fees') + $points,
316 'transaction_confirmed' => getUserData('transaction_confirmed') + count($confirmedIds),
317 'transaction_confirmed_yearly' => getUserData('transaction_confirmed_yearly') + count($confirmedIds),
318 'transaction_count' => getUserData('transaction_count') + (count($confirmedIds) * getConfig('transaction_count_captcha_confirm'))
319 ), $allowed, '', FALSE);
321 // Should always work
322 assert($updated === TRUE);
326 // Are there some failed transactions?
327 if (count($failedIds) > 0) {
329 sqlQueryEscaped("UPDATE
330 `{?_MYSQL_PREFIX?}_transaction_log`
332 `transaction_captcha_failed`='Y'
334 `transaction_id` IN (" . implode(',', $failedIds) . ") AND
335 `transaction_hash` != 'INVALID' AND
336 `transaction_sender` != %s AND
337 `transaction_sender` IS NOT NULL AND
338 `transaction_receiver` != %s AND
339 `transaction_receiver` IS NOT NULL AND
340 `transaction_confirmed`='N'
346 ), __FUNCTION__, __LINE__
349 // Should always work
350 assert(sqlAffectedRows() == count($failedIds));
357 // Checks whether the given user has a fee exempt
358 function ifUserHasTransactionFeeExempt ($username) {
359 // Accept only valid ids
360 assert(isValidId($username));
363 if (!isset($GLOBALS[__FUNCTION__][$username])) {
364 // Default is the user has no excempt
365 $GLOBALS[__FUNCTION__][$username] = FALSE;
368 $GLOBALS[__FUNCTION__][$username] = (getTotalPoints($username) < getConfig('transaction_fee_exempt_amount'));
372 return $GLOBALS[__FUNCTION__][$username];