5c7e49b7f6e16c5b015c230a0f582b8515f301a5
[mailer.git] / inc / libs / wernis_functions.php
1 <?php
2 /************************************************************************
3  * Mailer v0.2.1-FINAL                                Start: 10/19/2003 *
4  * ===================                          Last change: 08/12/2004 *
5  *                                                                      *
6  * -------------------------------------------------------------------- *
7  * File              : what-points.php                                  *
8  * -------------------------------------------------------------------- *
9  * Short description : All your collected points...                     *
10  * -------------------------------------------------------------------- *
11  * Kurzbeschreibung  : Alle Ihrer gesammelten Punkte                    *
12  * -------------------------------------------------------------------- *
13  * $Revision::                                                        $ *
14  * $Date::                                                            $ *
15  * $Tag:: 0.2.1-FINAL                                                 $ *
16  * $Author::                                                          $ *
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                      *
21  *                                                                      *
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.                                  *
26  *                                                                      *
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.                         *
31  *                                                                      *
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,               *
35  * MA  02110-1301  USA                                                  *
36  ************************************************************************/
37
38 // Some security stuff...
39 if (!defined('__SECURITY')) {
40         die();
41 } // END - if
42
43 // Sets a status message and code
44 function setWernisStatusMessage ($message, $status) {
45         $GLOBALS['wernis_data']['message'] = $message;
46         $GLOBALS['wernis_data']['status']  = $status;
47 }
48
49 // Get the status message
50 function getWernisErrorMessage () {
51         if (isset($GLOBALS['wernis_data']['message'])) {
52                 // Use raw message
53                 return $GLOBALS['wernis_data']['message'];
54         } elseif (isset($GLOBALS['wernis_data']['status'])) {
55                 // Fall-back to status
56                 return '{%message,WERNIS_ERROR_STATUS=' . $GLOBALS['wernis_data']['status'] . '%}';
57         } else {
58                 // Something bad happend
59                 return '{--WERNIS_UNKNOWN_ERROR--}';
60         }
61 }
62
63 // Get the status code
64 function getWernisErrorCode () {
65         if (isset($GLOBALS['wernis_data']['status'])) {
66                 // Use raw message
67                 return $GLOBALS['wernis_data']['status'];
68         } else {
69                 // Something bad happend
70                 return '{--WERNIS_UNKNOWN_ERROR--}';
71         }
72 }
73
74 // Sends out a request to the API and returns it's result
75 function sendWernisApiRequest ($scriptName, $requestData = array()) {
76         // Is the requestData an array?
77         if (!is_array($requestData)) {
78                 // Then abort here!
79                 return array(
80                         'status'  => 'failed_general',
81                         'message' => '{--WERNIS_API_REQUEST_DATA_INVALID--}'
82                 );
83         } // END - if
84
85         // Is the API id and MD5 hash there?
86         if ((getWernisApiId() == '') || (getWernisApiMd5() == '')) {
87                 // Abort here...
88                 return array(
89                         'status'  => 'failed_general',
90                         'message' => '{--WERNIS_API_REQUEST_DATA_MISSING--}'
91                 );
92         } // END - if
93
94         // Add more request data
95         $requestData['api_id']  = getWernisApiId();
96         $requestData['api_key'] = getWernisApiMd5();
97
98         // Is a purpose there?
99         if (!empty($requestData['purpose'])) {
100                 // Eval the purpose
101                 eval('$purpose = "' . doFinalCompilation($requestData['purpose'], FALSE) . '";');
102
103                 // Prepare the purpose, it needs encoding
104                 $requestData['purpose'] = encodeString($purpose);
105         } // END - if
106
107         // Construct the request string
108         $requestString = getWernisApiUrl() . $scriptName;
109
110         // Get the raw response from the lower function
111         $response = sendHttpPostRequest($requestString, $requestData);
112
113         // Check the response header if all is fine
114         if (!isHttpStatusOkay($response[0])) {
115                 // Something bad happend... :(
116                 return array(
117                         'status'  => 'request_error',
118                         'message' => '{%message,WERNIS_API_REQUEST_ERROR=' . $response[0] . '%}'
119                 );
120         } // END - if
121
122         // All (maybe) fine so remove the response header from server
123         $responseLine = '*INVALID*';
124         for ($idx = (count($response) - 1); $idx > 1; $idx--) {
125                 $line = trim($response[$idx]);
126                 if (!empty($line)) {
127                         $responseLine = $line;
128                         break;
129                 } // END - if
130         } // END - for
131
132         // Is the response leaded by a & symbol?
133         if (substr($responseLine, 0, 1) != '&') {
134                 // Something badly happened on server-side
135                 return array(
136                         'status'  => 'request_problem',
137                         'message' => sprintf(getMessage('WERNIS_API_REQUEST_PROBLEM'), $response[0], secureString($responseLine))
138                 );
139         } // END - if
140
141         // Remove the leading & (which can be used in Flash)
142         $responseLine = substr($responseLine, 1);
143
144         // Bring back the response
145         $data = explode('=', $responseLine);
146
147         // Default return array (should not stay empty)
148         $return = array();
149
150         // We use only the first two entries (which shall be fine)
151         if ($data[0] === 'error') {
152                 // The request has failed... :(
153                 switch ($data[1]) {
154                         case '404': // Invalid API id
155                         case 'AUTH': // Authorization has failed
156                                 $return = array(
157                                         'status'  => 'auth_failed',
158                                         'message' => '{--WERNIS_API_REQUEST_FAILED_AUTH--}'
159                                 );
160                                 break;
161
162                         case 'LOCKED': // User account is locked!
163                         case 'PASS': // Bad passphrase entered
164                         case 'USER': // Missing account or invalid password
165                                 $return = array(
166                                         'status'  => 'user_failed',
167                                         'message' => '{--WERNIS_API_REQUEST_FAILED_USER--}'
168                                 );
169                                 break;
170
171                         case 'OWN': // Transfer to own account
172                                 $return = array(
173                                         'status'  => 'own_failed',
174                                         'message' => '{--WERNIS_API_REQUEST_FAILED_OWN--}'
175                                 );
176                                 break;
177
178                         case 'AMOUNT': // Amount is depleted
179                                 $return = array(
180                                         'status'  => 'amount_failed',
181                                         'message' => '{--WERNIS_API_REQUEST_FAILED_AMOUNT--}'
182                                 );
183                                 break;
184
185                         case 'AMOUNT-SEND': // API amount is depleted
186                                 $return = array(
187                                         'status'  => 'api_amount_failed',
188                                         'message' => '{--WERNIS_API_REQUEST_FAILED_API_AMOUNT--}'
189                                 );
190                                 break;
191
192                         default: // Unknown error (maybe new?)
193                                 logDebugMessage(__FUNCTION__, __LINE__, sprintf('Unknown error %s from WDS66 API received.', $data[1]));
194                                 $return = array(
195                                         'status'  => 'request_failed',
196                                         'message' => '{%message,WERNIS_API_REQUEST_FAILED=' . $data[1] . '%}'
197                                 );
198                                 break;
199                 }
200         } else {
201                 // All fine here
202                 $return = array(
203                         'status'   => 'OK',
204                         'response' => $responseLine
205                 );
206         }
207
208         // Return the result
209         return $return;
210 }
211
212 // Tests the function by calling balance.php on the API
213 function doAdminTestWernisApi () {
214         // Only as admin
215         assert(isAdmin());
216
217         // Result is always failed
218         $result = FALSE;
219
220         // Prepare the request data
221         $requestData = array(
222                 't_uid' => getWernisRefid(),
223                 't_md5' => getWernisPassMd5()
224         );
225
226         // Return the result from the lower functions
227         $return = sendWernisApiRequest('balance.php', $requestData);
228
229         // Did it went smoothly?
230         if (isHttpResponseStatusOkay($return)) {
231                 // All fine!
232                 $result = TRUE;
233         } else {
234                 // Status failure text
235                 setWernisStatusMessage($return['message'], $return['status']);
236         }
237
238         // Return result
239         return $result;
240 }
241
242 // Widthdraw this amount
243 function executeWernisApiWithdraw ($wdsId, $userMd5, $amount) {
244         // Is the sponsor extension installed?
245         if (!isWernisWithdrawActive()) {
246                 if (!isExtensionActive('sponsor')) {
247                         // No, abort here
248                         return FALSE;
249                 } elseif (!isSponsor()) {
250                         // No sponsor, not allowed to withdraw!
251                         return FALSE;
252                 }
253         } // END - if
254
255         // Default is failed attempt
256         $result = FALSE;
257
258         // Prepare the request data
259         $requestData = array(
260                 'sub_request' => 'receive',
261                 't_uid'       => bigintval($wdsId),
262                 't_md5'       => $userMd5,
263                 'r_uid'       => getWernisRefid(),
264                 'amount'      => bigintval($amount),
265                 'purpose'     => getMaskedMessage('WERNIS_API_PURPOSE_WITHDRAW', getMemberId())
266         );
267
268         // Return the result from the lower functions
269         $return = sendWernisApiRequest('book.php', $requestData);
270
271         // Did it went smoothly?
272         if (isHttpResponseStatusOkay($return)) {
273                 // All fine!
274                 $result = TRUE;
275
276                 // Log the transfer
277                 logWernisTransfer($wdsId, $amount, 'WITHDRAW');
278         } else {
279                 // Status failure text
280                 setWernisStatusMessage($return['message'], $return['status']);
281
282                 // Log the transfer
283                 logWernisTransfer($wdsId, $amount, 'FAILED', $return['message'], $return['status']);
284         }
285
286         // Return result
287         return $result;
288 }
289
290 // Payout this amount
291 function executeWernisApiPayout ($wdsId, $amount) {
292         // Default is failed attempt
293         $result = FALSE;
294
295         // Prepare the request data
296         $requestData = array(
297                 'sub_request' => 'send',
298                 't_uid'       => getWernisRefid(),
299                 't_md5'       => getWernisPassMd5(),
300                 'r_uid'       => bigintval($wdsId),
301                 'amount'      => bigintval($amount),
302                 'purpose'     => getMaskedMessage('WERNIS_API_PURPOSE_PAYOUT', getMemberId())
303         );
304
305         // Return the result from the lower functions
306         $return = sendWernisApiRequest('book.php', $requestData);
307
308         if (isHttpResponseStatusOkay($return)) {
309                 // All fine!
310                 $result = TRUE;
311
312                 // Log the transfer
313                 logWernisTransfer($wdsId, $amount, 'PAYOUT');
314         } else {
315                 // Status failure text
316                 setWernisStatusMessage($return['message'], $return['status']);
317
318                 // Log the transfer
319                 logWernisTransfer($wdsId, $amount, 'FAILED', $return['message'], $return['status']);
320         }
321
322         // Return result
323         return $result;
324 }
325
326 // Execute auth.php request
327 function executeWernisApiAuth ($wernisId, $wernisPassword) {
328         // Prepare request data
329         $requestData = array(
330                 't_uid'       => bigintval($wernisId),
331                 't_md5'       => hashSha256($wernisPassword),
332         );
333
334         // Call auth.php
335         $return = sendWernisApiRequest('auth.php', $requestData);
336
337         // Return full array
338         return $return;
339 }
340
341 // Execute get.php reguest with given auth data (not all are used)
342 function executeWernisApiGet ($authData, $subRequest, $fields) {
343         // It must be an array
344         assert(is_array($authData));
345
346         // Check required array elements
347         assert(isset($authData['wernis_userid']));
348         assert(isset($authData['api_auth_key']));
349         assert(isset($authData['api_redirect_challenge']));
350
351         // Then create request array
352         $requestData = array(
353                 'sub_request' => $subRequest,
354                 'fields'      => $fields,
355                 't_uid'       => bigintval($authData['wernis_userid']),
356                 'auth_key'    => $authData['api_auth_key'],
357                 'challenge'   => $authData['api_redirect_challenge']
358         );
359
360         // Call get.php
361         $return = sendWernisApiRequest('get.php', $requestData);
362
363         // Return full array
364         return $return;
365 }
366
367 // Translate the status IN/OUT
368 function translateWernisTransferStatus ($status) {
369         // Default status is unknown
370         $return = '{%message,WERNIS_STATUS_UNKNWOWN=' . $status . '%}';
371
372         // Construct message id
373         $messageId = 'WERNIS_STATUS_' . $status;
374
375         // Is it there?
376         if (isMessageIdValid($messageId)) {
377                 // Then use it as message string
378                 $return = '{--' . $messageId . '--}';
379         } // END - if
380
381         // Return the status
382         return $return;
383 }
384
385 // Log the transfer
386 function logWernisTransfer ($wdsId, $amount, $type = 'FAILED', $message = '', $status = '') {
387         // Register this wernis movement
388         sqlQueryEscaped("INSERT INTO `{?_MYSQL_PREFIX?}_user_wernis` (`userid`, `wernis_account`, `wernis_amount`, `wernis_timestamp`, `wernis_type`, `wernis_api_message`, `wernis_api_status`) VALUES (%s, %s, %s, UNIX_TIMESTAMP(), '%s', '%s', '%s')",
389                 array(
390                         getMemberId(),
391                         bigintval($wdsId),
392                         bigintval($amount),
393                         $type,
394                         $message,
395                         $status
396                 ), __FUNCTION__, __LINE__);
397 }
398
399 // Calulcate fees and factor
400 function calculateWernisFee ($points, $mode) {
401         // Payout or withdraw are allowed modes!
402         //* DEBUG: */ debugOutput('mode=' . $mode . ',points=' . $points);
403         if (!in_array($mode, array('payout', 'withdraw'))) {
404                 // Log error and abort
405                 logDebugMessage(__FUNCTION__, __LINE__, 'userid=' . getMemberId() . ',mode=' . $mode . ',points=' . $points . ' - unknown mode detected.');
406                 return FALSE;
407         } // END - if
408
409         // Is there a percentage or fixed fee?
410         if (getConfig('wernis_' . $mode . '_fee_percent') > 0) {
411                 // Percentage fee
412                 $points -= $points * getConfig('wernis_'.$mode.'_fee_percent') / 100;
413         } elseif (getConfig('wernis_' . $mode . '_fee_fix') > 0) {
414                 // Fixed fee
415                 $points -= getConfig('wernis_' . $mode . '_fee_fix');
416         }
417
418         // Divide/multiply the factor
419         if ($mode == 'payout') {
420                 // Divide for payout
421                 $points = $points / getWernisPayoutFactor();
422         } else {
423                 // Multiply for withdraw
424                 $points = $points * getWernisWithdrawFactor();
425         }
426
427         // Return value
428         //* DEBUG: */ debugOutput('mode=' . $mode . ',points=' . $points);
429         return $points;
430 }
431
432 // Add withdraw fees and factor
433 // @TODO Unused?
434 function calulcateWernisWithdrawFee ($points) {
435         // Is there a percentage or fixed fee?
436         if (getWernisWithdrawFeePercent() > 0) {
437                 // Percentage fee
438                 $points += $points * getWernisWithdrawFeePercent() / 100;
439         } elseif (getWernisWithdrawFeeFix() > 0) {
440                 // Fixed fee
441                 $points += getWernisWithdrawFeeFix();
442         }
443
444         // Return value
445         return $points;
446 }
447
448 // Displays registration form for WDS66 registration
449 function doDisplayWernisUserRegistrationForm () {
450         // Is the form sent?
451         if (isFormSent('register')) {
452                 // Is wernis_id set?
453                 if (!isPostRequestElementSet('wernis_id')) {
454                         // Id not set
455                         displayMessage('{--GUEST_WERNIS_REGISTRATION_ID_NOT_SET--}');
456                 } elseif (!isPostRequestElementSet('wernis_password')) {
457                         // Password not set
458                         displayMessage('{--GUEST_WERNIS_REGISTRATION_PASSWORD_NOT_SET--}');
459                 } else {
460                         // So far, all fine, then let's do the call-back on auth.php ...
461                         $response = executeWernisApiAuth(postRequestElement('wernis_id'), postRequestElement('wernis_password'));
462
463                         // Was the status okay?
464                         if (isHttpResponseStatusOkay($response)) {
465                                 // All fine, then analyze API response
466                                 $args = convertApiResponseToArray($response['response'], '&', '=');
467
468                                 // Is status set?
469                                 //* DEBUG-DIE */ die('response=<pre>' . print_r($response, TRUE) . '</pre>,args=' . '<pre>'.print_r($args, TRUE).'</pre>');
470                                 assert(isset($args['auth_status']));
471
472                                 // Add WDS66 userid
473                                 $args['wernis_userid'] = postRequestElement('wernis_id');
474
475                                 // "Detect" auth status
476                                 $callbackFunction = 'doWernisAuth' . capitalizeUnderscoreString($args['auth_status']);
477
478                                 // Is the call-back there?
479                                 if (!is_callable($callbackFunction, FALSE, $callableName)) {
480                                         // Not there, could be bad. :(
481                                         reportBug(__FUNCTION__, __LINE__, 'Unsupported auth_status=' . $args['auth_status'] . ',args()=' . count($args) . ',callbackFunction=' . $callbackFunction . ' detected.');
482                                 } // END - if
483
484                                 // Then call it
485                                 $status = call_user_func($callbackFunction, $args);
486
487                                 // @TODO Something more to do here?
488                                 die(__FUNCTION__ . ':' . __LINE__ . ': status[' . gettype($status) . ']=' . $status . ' - Unfinished.');
489                         } else {
490                                 // Something bad happened
491                                 displayMessage($response['message']);
492                         }
493                 }
494         } // END - if
495
496         // Is there a challenge + response?
497         if ((isGetRequestElementSet('status')) && (isGetRequestElementSet('challenge')) && (isGetRequestElementSet('__challenge_response'))) {
498                 // Redirect from modules.php?module=auth, so validate challenge response ...
499                 // 1) Get first 24 characters = salt
500                 $salt = substr(getRequestElement('__challenge_response'), 0, 24);
501
502                 // 2) Generate hash for challenge response
503                 $challengeResponse = $salt . hashSha256($salt . getWernisApiMd5() . getRequestElement('challenge'));
504
505                 // Is the response valid?
506                 if ($challengeResponse != getRequestElement('__challenge_response')) {
507                         // Not valid
508                         displayMessage('{--GUEST_WERNIS_REGISTRATION_INVALID_CHALLENGE_RESPONSE--}');
509                         return;
510                 } // END - if
511
512                 /*
513                  * Now, that the challenge-response is the same, the challenge itself
514                  * is also the same. Next get the data from wernis_regs table by
515                  * challenge. There is currently no other way to get the data as there
516                  * is no Wernis user id provided. Later on the stored challenge response
517                  * can be compared with provided.
518                  */
519                 $return = doWernisFinishUserRegistration(getRequestElement('challenge'), getRequestElement('__challenge_response'), getRequestElement('status'));
520
521                 // Is the registration finished?
522                 if ($return === FALSE) {
523                         // No, then abort here silently as the function should have already displayed a message
524                         return;
525                 } // END - if
526         } elseif (!isFormSent('register')) {
527                 // Form not send, so load form template
528                 loadTemplate('guest_wernis_registration_rpc_form');
529         }
530 }
531
532 // Finish user registration with WDS66 API
533 function doWernisFinishUserRegistration ($challenge, $challengeResponse, $status) {
534         // Is the status 1? (= all fine with API call)
535         if ($status == '1') {
536                 // Get mapped data based on challenge
537                 $return = getWernisMappedDataFromApiByChallenge($challenge, $status);
538
539                 // Is the array filled?
540                 if ((count($return['mapped_data']) > 0) && (empty($return['message']))) {
541                         // Set must-fillout fields
542                         $return['mapped_data'] = runFilterChain('register_must_fillout', $return['mapped_data']);
543
544                         // Add missing elements
545                         $return['mapped_data']['gender']               = NULL;
546                         $return['mapped_data']['birthday_selection']   = generateDayMonthYearSelectionBox($return['mapped_data']['birth_day'], $return['mapped_data']['birth_month'], $return['mapped_data']['birth_year']);
547                         $return['mapped_data']['challenge']            = getRequestElement('challenge');
548                         $return['mapped_data']['__challenge_response'] = getRequestElement('__challenge_response');
549
550                         // Display form
551                         loadTemplate('guest_wernis_registration_form', FALSE, $return['mapped_data']);
552
553                         // All fine
554                         return TRUE;
555                 } else {
556                         // Something unexpected happened (e.g. no API requests left)
557                         displayMessage($return['message']);
558                         return FALSE;
559                 }
560         } else {
561                 // Status does not need to be changed
562                 die(__FUNCTION__ . ':' . __LINE__ . ': Reached!');
563         }
564 }
565
566 // "Getter" for mapped data by calling the API and given challenge and status
567 function getWernisMappedDataFromApiByChallenge ($challenge, $status) {
568         // Get stored registration data
569         $rows = getWernisRegistrationDataByKey('api_redirect_challenge', $challenge);
570
571         // Zero result found?
572         if (count($rows) == 0) {
573                 // Nothing found
574                 displayMessage('{--GUEST_WERNIS_REGISTRATION_ZERO_ROWS_FOUND--}');
575
576                 // Display form
577                 loadTemplate('guest_wernis_registration_rpc_form');
578                 return array();
579         } // END - if
580
581         // Init array
582         $return = array(
583                 // Mapped data
584                 'mapped_data' => array(),
585                 // Any error message from API
586                 'message'     => ''
587         );
588
589         // Has the auth status changed?
590         if ($rows[0]['api_auth_status'] != 'ACCEPTED') {
591                 /*
592                  * The authorization of this application has been accepted, so
593                  * update it and ignore result from function because the update
594                  * will always run.
595                  */
596                 updateWernisRegistrationDataByKey('api_auth_status', 'api_redirect_challenge', $challenge, 'ACCEPTED');
597         } // END - if
598
599         // Now call "get.php"
600         $response = executeWernisApiGet($rows[0], 'data', 'vorname|name|strasse|plz|ort|birth_day|birth_month|birth_year|email|werber');
601
602         // Was the status okay?
603         if (isHttpResponseStatusOkay($response)) {
604                 // API returned non-errous response, 'data=' must be found
605                 assert(substr($response['response'], 0, 5) == 'data=');
606
607                 // And remove it, this is now BASE64-encoded
608                 $encodedData = urldecode(substr($response['response'], 5));
609
610                 // And decode it (all steps separated to later "easily" debug them)
611                 $decodedData = base64_decode($encodedData);
612
613                 /*
614                  * Do some checks on the decoded string, it should be a
615                  * serialized array with 10 entries (see above
616                  * executeWernisApiGet() call).
617                  */
618                 assert(substr($decodedData, 0, 6) == 'a:10:{');
619                 assert(substr($decodedData, -1, 1) == '}');
620
621                 // The array seems to be fine, unserialize it
622                 $userData = unserialize($decodedData);
623
624                 // All mappings WDS66->mailer
625                 $mappings = array(
626                         'vorname'     => 'surname',
627                         'name'        => 'family',
628                         'strasse'     => 'street_nr',
629                         'plz'         => 'zip',
630                         'ort'         => 'city',
631                         'email'       => 'email',
632                         'birth_day'   => 'birth_day',
633                         'birth_month' => 'birth_month',
634                         'birth_year'  => 'birth_year',
635                         'werber'      => 'wernis_refid'
636                 );
637
638                 // Map all WDS66 entries into mailer entries
639                 foreach ($mappings as $from => $to) {
640                         // All must exist
641                         if (!isset($userData[$from])) {
642                                 // Element $from does not exist
643                                 reportBug(__FUNCTION__, __LINE__, 'Cannot map from=' . $from . ' -> to=' . $to . ': element does not exist.');
644                         } // END - if
645
646                         // "Map" all
647                         $return['mapped_data'][$to] = convertEmptyToNull($userData[$from]);
648                 } // END - foreach
649
650                 // Both arrays must have same size
651                 assert(count($userData) == count($return['mapped_data']));
652
653                 // Now add userid from WDS66
654                 $return['mapped_data']['wernis_userid'] = bigintval($rows[0]['wernis_userid']);
655         } else {
656                 // Something bad happened so copy the message
657                 $return['message'] = $response['message'];
658         }
659
660         // Return mapped data array
661         return $return;
662 }
663
664 // Updates auth status by given key/value pair
665 function updateWernisRegistrationDataByKey ($updatedColumn, $key, $oldValue, $newValue) {
666         // Run the update
667         sqlQueryEscaped("UPDATE
668         `{?_MYSQL_PREFIX?}_wernis_regs`
669 SET
670         `%s` = '%s'
671 WHERE
672         `%s` = '%s' AND
673         `%s` != '%s'
674 LIMIT 1",
675                 array(
676                         $updatedColumn,
677                         $newValue,
678                         $key,
679                         $oldValue,
680                         $updatedColumn,
681                         $oldValue
682                 ), __FUNCTION__, __LINE__
683         );
684
685         // Check if rows as been affected
686         return ifSqlHasZeroAffectedRows();
687 }
688
689 // "Getter" for Wernis registration data by given key and value
690 function getWernisRegistrationDataByKey ($key, $value, $limit = 1) {
691         // Init array
692         $rows = array();
693
694         // Now search for it
695         $result = sqlQueryEscaped("SELECT
696         `local_userid`,
697         `wernis_userid`,
698         `api_auth_status`,
699         `api_auth_key`,
700         `api_redirect_challenge`,
701         UNIX_TIMESTAMP(`record_inserted`) AS `record_inserted`
702 FROM
703         `{?_MYSQL_PREFIX?}_wernis_regs`
704 WHERE
705         `%s`='%s'
706 ORDER BY
707         `id`
708 LIMIT %d",
709                 array(
710                         $key,
711                         $value,
712                         $limit
713                 ), __FUNCTION__, __LINE__
714         );
715
716         // Is there an entry?
717         if (sqlNumRows($result) > 0) {
718                 // At least one entry has been found, so loop through all
719                 while ($row = sqlFetchArray($result)) {
720                         // Add it
721                         array_push($rows, $row);
722                 } // END - while
723         } // END - if
724
725         // Free result
726         sqlFreeResult($result);
727
728         // Return found entries
729         return $rows;
730 }
731
732 // Do local user registration with data from WDS66 API
733 function doWernisUserRegistration () {
734         // Call generic registration function
735         $status = doGenericUserRegistration();
736
737         // Does this went fine?
738         if ($status === FALSE) {
739                 // No, then abort here silently
740                 return FALSE;
741         } // END - if
742
743         // Make sure the user id is valid
744         assert(isset($GLOBALS['register_userid']));
745         assert(isValidId($GLOBALS['register_userid']));
746
747         // Generic registration is finished, so add more data:
748 }
749
750 //-----------------------------------------------------------------------------
751 //                      Auth status callback functions
752 //-----------------------------------------------------------------------------
753
754 // Handler for auth_status=PENDING
755 function doWernisAuthPending ($args) {
756         // $args must always be an array
757         assert(is_array($args));
758
759         // auth_key and wernis_userid must be set
760         assert(isset($args['auth_key']));
761         assert(isset($args['wernis_userid']));
762
763         // Generate a challenge that will be added to the URL
764         $challenge = hashSha256(generatePassword(128));
765
766         // Search entry in database by auth_key
767         if (countSumTotalData($args['auth_key'], 'wernis_regs', 'id', 'api_auth_key', TRUE) == 0) {
768                 // "Register" this call
769                 sqlQueryEscaped("INSERT INTO `{?_MYSQL_PREFIX?}_wernis_regs` (
770         `wernis_userid`,
771         `api_auth_status`,
772         `api_auth_key`,
773         `api_redirect_challenge`
774 ) VALUES (
775         %s,
776         'PENDING',
777         '%s',
778         '%s'
779 )",
780                         array(
781                                 bigintval($args['wernis_userid']),
782                                 $args['auth_key'],
783                                 $challenge
784                         ), __FUNCTION__, __LINE__
785                 );
786         } else {
787                 // Update challenge
788                 sqlQueryEscaped("UPDATE
789         `{?_MYSQL_PREFIX?}_wernis_regs`
790 SET
791         `api_redirect_challenge`='%s'
792 WHERE
793         `api_auth_key`='%s' AND
794         `wernis_userid`=%s
795         `api_auth_status`='PENDING'
796 LIMIT 1",
797                         array(
798                                 $challenge,
799                                 $args['auth_key'],
800                                 bigintval($args['wernis_userid'])
801                         ), __FUNCTION__, __LINE__
802                 );
803         }
804
805         // Should always update/insert
806         assert(sqlAffectedRows() == 1);
807
808         // Redirect to WDS66 module=auth ...
809         redirectToUrl(getWernisBaseUrl() . '/modules.php?module=auth&amp;auth_key=' . $args['auth_key'] . '&amp;params=' . urlencode(base64_encode('&module=' . getModule() . '&what=' . getWhat())) . '&amp;challenge=' . $challenge);
810 }
811
812 // Handler for auth_status=ACCEPTED
813 function doWernisAuthAccepted ($args) {
814         // $args must always be an array
815         assert(is_array($args));
816
817         // auth_key and wernis_userid must be set
818         assert(isset($args['auth_key']));
819         assert(isset($args['wernis_userid']));
820         die(__FUNCTION__ . ':' . __LINE__ . '<pre>' . print_r($args, TRUE) . '</pre>');
821 }
822
823 //-----------------------------------------------------------------------------
824 //                             Wrapper functions
825 //-----------------------------------------------------------------------------
826
827 // Wrapper function for 'wernis_refid'
828 function getWernisRefid () {
829         // Is there cache?
830         if (!isset($GLOBALS[__FUNCTION__])) {
831                 // Get config entry
832                 $GLOBALS[__FUNCTION__] = getConfig('wernis_refid');
833         } // END - if
834
835         // Return cache
836         return $GLOBALS[__FUNCTION__];
837 }
838
839 // Wrapper function for 'wernis_pass_md5'
840 function getWernisPassMd5 () {
841         // Is there cache?
842         if (!isset($GLOBALS[__FUNCTION__])) {
843                 // Get config entry
844                 $GLOBALS[__FUNCTION__] = getConfig('wernis_pass_md5');
845         } // END - if
846
847         // Return cache
848         return $GLOBALS[__FUNCTION__];
849 }
850
851 // Wrapper function for 'wernis_api_id'
852 function getWernisApiId () {
853         // Is there cache?
854         if (!isset($GLOBALS[__FUNCTION__])) {
855                 // Get config entry
856                 $GLOBALS[__FUNCTION__] = getConfig('wernis_api_id');
857         } // END - if
858
859         // Return cache
860         return $GLOBALS[__FUNCTION__];
861 }
862
863 // Wrapper function for 'wernis_api_md5'
864 function getWernisApiMd5 () {
865         // Is there cache?
866         if (!isset($GLOBALS[__FUNCTION__])) {
867                 // Get config entry
868                 $GLOBALS[__FUNCTION__] = getConfig('wernis_api_md5');
869         } // END - if
870
871         // Return cache
872         return $GLOBALS[__FUNCTION__];
873 }
874
875 // Wrapper function for 'wernis_api_url'
876 function getWernisApiUrl () {
877         // Is there cache?
878         if (!isset($GLOBALS[__FUNCTION__])) {
879                 // Get config entry
880                 $GLOBALS[__FUNCTION__] = getConfig('wernis_api_url');
881         } // END - if
882
883         // Return cache
884         return $GLOBALS[__FUNCTION__];
885 }
886
887 // Wrapper function for 'wernis_withdraw_active'
888 function getWernisWithdrawActive () {
889         // Is there cache?
890         if (!isset($GLOBALS[__FUNCTION__])) {
891                 // Get config entry
892                 $GLOBALS[__FUNCTION__] = getConfig('wernis_withdraw_active');
893         } // END - if
894
895         // Return cache
896         return $GLOBALS[__FUNCTION__];
897 }
898
899 // Wrapper function for 'wernis_payout_active'
900 function getWernisPayoutActive () {
901         // Is there cache?
902         if (!isset($GLOBALS[__FUNCTION__])) {
903                 // Get config entry
904                 $GLOBALS[__FUNCTION__] = getConfig('wernis_payout_active');
905         } // END - if
906
907         // Return cache
908         return $GLOBALS[__FUNCTION__];
909 }
910
911 // Wrapper function for 'wernis_withdraw_active'
912 function isWernisWithdrawActive () {
913         // Is there cache?
914         if (!isset($GLOBALS[__FUNCTION__])) {
915                 // Get config entry
916                 $GLOBALS[__FUNCTION__] = (getConfig('wernis_withdraw_active') == 'Y');
917         } // END - if
918
919         // Return cache
920         return $GLOBALS[__FUNCTION__];
921 }
922
923 // Wrapper function for 'wernis_payout_active'
924 function isWernisPayoutActive () {
925         // Is there cache?
926         if (!isset($GLOBALS[__FUNCTION__])) {
927                 // Get config entry
928                 $GLOBALS[__FUNCTION__] = (getConfig('wernis_payout_active') == 'Y');
929         } // END - if
930
931         // Return cache
932         return $GLOBALS[__FUNCTION__];
933 }
934
935 // Wrapper function for 'wernis_withdraw_factor'
936 function getWernisWithdrawFactor () {
937         // Is there cache?
938         if (!isset($GLOBALS[__FUNCTION__])) {
939                 // Get config entry
940                 $GLOBALS[__FUNCTION__] = getConfig('wernis_withdraw_factor');
941         } // END - if
942
943         // Return cache
944         return $GLOBALS[__FUNCTION__];
945 }
946
947 // Wrapper function for 'wernis_payout_factor'
948 function getWernisPayoutFactor () {
949         // Is there cache?
950         if (!isset($GLOBALS[__FUNCTION__])) {
951                 // Get config entry
952                 $GLOBALS[__FUNCTION__] = getConfig('wernis_payout_factor');
953         } // END - if
954
955         // Return cache
956         return $GLOBALS[__FUNCTION__];
957 }
958
959 // Wrapper function for 'wernis_withdraw_fee_percent'
960 function getWernisWithdrawFeePercent () {
961         // Is there cache?
962         if (!isset($GLOBALS[__FUNCTION__])) {
963                 // Get config entry
964                 $GLOBALS[__FUNCTION__] = getConfig('wernis_withdraw_fee_percent');
965         } // END - if
966
967         // Return cache
968         return $GLOBALS[__FUNCTION__];
969 }
970
971 // Wrapper function for 'wernis_withdraw_fee_fix'
972 function getWernisWithdrawFeeFix () {
973         // Is there cache?
974         if (!isset($GLOBALS[__FUNCTION__])) {
975                 // Get config entry
976                 $GLOBALS[__FUNCTION__] = getConfig('wernis_withdraw_fee_fix');
977         } // END - if
978
979         // Return cache
980         return $GLOBALS[__FUNCTION__];
981 }
982
983 // Wrapper function for 'wernis_payout_fee_percent'
984 function getWernisPayoutFeePercent () {
985         // Is there cache?
986         if (!isset($GLOBALS[__FUNCTION__])) {
987                 // Get config entry
988                 $GLOBALS[__FUNCTION__] = getConfig('wernis_payout_fee_percent');
989         } // END - if
990
991         // Return cache
992         return $GLOBALS[__FUNCTION__];
993 }
994
995 // Wrapper function for 'wernis_payout_fee_fix'
996 function getWernisPayoutFeeFix () {
997         // Is there cache?
998         if (!isset($GLOBALS[__FUNCTION__])) {
999                 // Get config entry
1000                 $GLOBALS[__FUNCTION__] = getConfig('wernis_payout_fee_fix');
1001         } // END - if
1002
1003         // Return cache
1004         return $GLOBALS[__FUNCTION__];
1005 }
1006
1007 // Wrapper function for 'wernis_min_payout'
1008 function getWernisMinPayout () {
1009         // Is there cache?
1010         if (!isset($GLOBALS[__FUNCTION__])) {
1011                 // Get config entry
1012                 $GLOBALS[__FUNCTION__] = getConfig('wernis_min_payout');
1013         } // END - if
1014
1015         // Return cache
1016         return $GLOBALS[__FUNCTION__];
1017 }
1018
1019 // Wrapper function for 'wernis_min_withdraw'
1020 function getWernisMinWithdraw () {
1021         // Is there cache?
1022         if (!isset($GLOBALS[__FUNCTION__])) {
1023                 // Get config entry
1024                 $GLOBALS[__FUNCTION__] = getConfig('wernis_min_withdraw');
1025         } // END - if
1026
1027         // Return cache
1028         return $GLOBALS[__FUNCTION__];
1029 }
1030
1031 // Wrapper function for 'wernis_base_url'
1032 function getWernisBaseUrl () {
1033         // Is there cache?
1034         if (!isset($GLOBALS[__FUNCTION__])) {
1035                 // Get config entry
1036                 $GLOBALS[__FUNCTION__] = getConfig('wernis_base_url');
1037         } // END - if
1038
1039         // Return cache
1040         return $GLOBALS[__FUNCTION__];
1041 }
1042
1043 // [EOF]
1044 ?>