Skip to content

Commit 3f576e3

Browse files
committed
Merge pull request #2243 from MPOS/coin-address-table
[ADDED] coin_addresses table and support
2 parents a9bfc91 + a4e17e6 commit 3f576e3

File tree

12 files changed

+212
-61
lines changed

12 files changed

+212
-61
lines changed

include/autoloader.inc.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
// We need to load these first
1717
require_once(CLASS_DIR . '/base.class.php');
1818
require_once(CLASS_DIR . '/coins/coin_base.class.php');
19+
require_once(CLASS_DIR . '/coin_address.class.php');
1920
require_once(CLASS_DIR . '/setting.class.php');
2021
require_once(INCLUDE_DIR . '/version.inc.php');
2122
if (PHP_OS == 'WINNT') require_once(CLASS_DIR . '/memcached.class.php');

include/classes/base.class.php

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,9 @@ public function setDebug($debug) {
2222
public function setCoin($coin) {
2323
$this->coin = $coin;
2424
}
25+
public function setCoinAddress($coin_address) {
26+
$this->coin_address = $coin_address;
27+
}
2528
public function setLog($log) {
2629
$this->log = $log;
2730
}
Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,107 @@
1+
<?php
2+
$defflip = (!cfip()) ? exit(header('HTTP/1.1 401 Unauthorized')) : 1;
3+
4+
class CoinAddress extends Base {
5+
protected $table = 'coin_addresses';
6+
private $cache = array();
7+
8+
/**
9+
* Fetch users coin address for a currency
10+
* @param userID int UserID
11+
* @return data string Coin Address
12+
**/
13+
public function getCoinAddress($userID, $currency=NULL) {
14+
if ($currency === NULL) $currency = $this->config['currency'];
15+
$this->debug->append("STA " . __METHOD__, 4);
16+
$stmt = $this->mysqli->prepare("
17+
SELECT coin_address
18+
FROM " . $this->getTableName() . "
19+
WHERE account_id = ? AND currency = ?
20+
");
21+
if ( $this->checkStmt($stmt) && $stmt->bind_param('is', $userID, $currency) && $stmt->execute() && $result = $stmt->get_result()) {
22+
if ($result->num_rows == 1) {
23+
return $result->fetch_object()->coin_address;
24+
}
25+
}
26+
$this->debug->append("Unable to fetch users coin address for " . $currency);
27+
return $this->sqlError();
28+
}
29+
30+
/**
31+
* Check if a coin address is already set
32+
* @param address string Coin Address to check for
33+
* @return bool true or false
34+
**/
35+
public function existsCoinAddress($address) {
36+
$this->debug->append("STA " . __METHOD__, 4);
37+
return $this->getSingle($address, 'coin_address', 'coin_address', 's') === $address;
38+
}
39+
40+
/**
41+
* Add a new coin address record for a user
42+
* @param userID int Account ID
43+
* @param address string Coin Address
44+
* @param currency string Currency short handle, defaults to config option
45+
* @return bool true or false
46+
**/
47+
public function add($userID, $address, $currency=NULL) {
48+
if ($currency === NULL) $currency = $this->config['currency'];
49+
if ($address != $this->getCoinAddress($userID) && $this->existsCoinAddress($address)) {
50+
$this->setErrorMessage('Unable to update coin address, address already exists');
51+
return false;
52+
}
53+
$stmt = $this->mysqli->prepare("INSERT INTO " . $this->getTableName() . " (account_id, currency, coin_address) VALUES (?, ?, ?)");
54+
if ( $this->checkStmt($stmt) && $stmt->bind_param('iss', $userID, $currency, $address) && $stmt->execute()) {
55+
return true;
56+
}
57+
return $this->sqlError();
58+
}
59+
60+
/**
61+
* Remove a coin address record for a user
62+
* @param userID int Account ID
63+
* @param currency string Currency short handle, defaults to config option
64+
* @return bool true or false
65+
**/
66+
public function remove ($userID, $currency=NULL) {
67+
if ($currency === NULL) $currency = $this->config['currency'];
68+
$stmt = $this->mysqli->prepare("DELETE FROM " . $this->getTableName() . " WHERE account_id = ? AND currency = ?");
69+
if ( $this->checkStmt($stmt) && $stmt->bind_param('is', $userID, $currency) && $stmt->execute()) {
70+
return true;
71+
}
72+
return $this->sqlError();
73+
}
74+
75+
/**
76+
* Update a coin address record for a user and a currency
77+
* @param userID int Account ID
78+
* @param address string Coin Address
79+
* @param currency string Currency short handle, defaults to config option
80+
* @return bool true or false
81+
**/
82+
public function update($userID, $address, $currency=NULL) {
83+
if ($currency === NULL) $currency = $this->config['currency'];
84+
if ($address != $this->getCoinAddress($userID) && $this->existsCoinAddress($address)) {
85+
$this->setErrorMessage('Unable to update coin address, address already exists');
86+
return false;
87+
}
88+
if ($this->getCoinAddress($userID) != NULL) {
89+
$stmt = $this->mysqli->prepare("UPDATE " . $this->getTableName() . " SET coin_address = ? WHERE account_id = ? AND currency = ?");
90+
if ( $this->checkStmt($stmt) && $stmt->bind_param('sis', $address, $userID, $currency) && $stmt->execute()) {
91+
return true;
92+
}
93+
} else {
94+
$stmt = $this->mysqli->prepare("INSERT INTO " . $this->getTableName() . " (coin_address, account_id, currency) VALUES (?, ?, ?)");
95+
if ( $this->checkStmt($stmt) && $stmt->bind_param('sis', $address, $userID, $currency) && $stmt->execute()) {
96+
return true;
97+
}
98+
}
99+
return $this->sqlError();
100+
}
101+
}
102+
103+
$coin_address = new CoinAddress();
104+
$coin_address->setDebug($debug);
105+
$coin_address->setConfig($config);
106+
$coin_address->setMysql($mysqli);
107+
$coin_address->setErrorCodes($aErrorCodes);

include/classes/transaction.class.php

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -355,7 +355,7 @@ public function getAPQueue($limit=250) {
355355
a.id,
356356
a.username,
357357
a.ap_threshold,
358-
a.coin_address,
358+
ca.coin_address,
359359
IFNULL(
360360
ROUND(
361361
(
@@ -370,11 +370,13 @@ public function getAPQueue($limit=250) {
370370
ON t.block_id = b.id
371371
LEFT JOIN " . $this->user->getTableName() . " AS a
372372
ON t.account_id = a.id
373-
WHERE t.archived = 0 AND a.ap_threshold > 0 AND a.coin_address IS NOT NULL AND a.coin_address != ''
373+
LEFT JOIN " . $this->coin_address->getTableName() . " AS ca
374+
ON ca.account_id = a.id
375+
WHERE t.archived = 0 AND a.ap_threshold > 0 AND ca.coin_address IS NOT NULL AND ca.coin_address != '' AND ca.currency = ?
374376
GROUP BY t.account_id
375377
HAVING confirmed > a.ap_threshold AND confirmed > " . $this->config['txfee_auto'] . "
376378
LIMIT ?");
377-
if ($this->checkStmt($stmt) && $stmt->bind_param('i', $limit) && $stmt->execute() && $result = $stmt->get_result())
379+
if ($this->checkStmt($stmt) && $stmt->bind_param('si', $this->config['currency'], $limit) && $stmt->execute() && $result = $stmt->get_result())
378380
return $result->fetch_all(MYSQLI_ASSOC);
379381
return $this->sqlError();
380382
}
@@ -446,7 +448,7 @@ public function getMPQueue($limit=250) {
446448
a.id,
447449
a.username,
448450
a.ap_threshold,
449-
a.coin_address,
451+
ca.coin_address,
450452
p.id AS payout_id,
451453
IFNULL(
452454
ROUND(
@@ -464,11 +466,13 @@ public function getMPQueue($limit=250) {
464466
ON t.account_id = p.account_id
465467
LEFT JOIN " . $this->block->getTableName() . " AS b
466468
ON t.block_id = b.id
467-
WHERE p.completed = 0 AND t.archived = 0 AND a.coin_address IS NOT NULL AND a.coin_address != ''
469+
LEFT JOIN " . $this->coin_address->getTableName() . " AS ca
470+
ON ca.account_id = a.id
471+
WHERE p.completed = 0 AND t.archived = 0 AND ca.currency = ? AND ca.coin_address IS NOT NULL AND ca.coin_address != ''
468472
GROUP BY t.account_id
469473
HAVING confirmed > " . $this->config['txfee_manual'] . "
470474
LIMIT ?");
471-
if ($this->checkStmt($stmt) && $stmt->bind_param('i', $limit) && $stmt->execute() && $result = $stmt->get_result())
475+
if ($this->checkStmt($stmt) && $stmt->bind_param('si', $this->config['currency'], $limit) && $stmt->execute() && $result = $stmt->get_result())
472476
return $result->fetch_all(MYSQLI_ASSOC);
473477
return $this->sqlError('E0050');
474478
}
@@ -478,6 +482,7 @@ public function getMPQueue($limit=250) {
478482
$transaction->setMemcache($memcache);
479483
$transaction->setNotification($notification);
480484
$transaction->setDebug($debug);
485+
$transaction->setCoinAddress($coin_address);
481486
$transaction->setMysql($mysqli);
482487
$transaction->setConfig($config);
483488
$transaction->setBlock($block);

include/classes/user.class.php

Lines changed: 44 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -163,7 +163,7 @@ public function getTopInviters($limit=10,$start=0) {
163163
$invitation->setDebug($this->debug);
164164
$invitation->setLog($this->log);
165165
$stmt = $this->mysqli->prepare("
166-
SELECT COUNT(i.account_id) AS invitationcount,a.id,a.username,a.email,
166+
SELECT COUNT(i.account_id) AS invitationcount,a.id,a.username,a.email,
167167
(SELECT COUNT(account_id) FROM " . $invitation->getTableName() . " WHERE account_id = i.account_id AND is_activated = 1 GROUP BY account_id) AS activated
168168
FROM " . $invitation->getTableName() . " AS i
169169
LEFT JOIN " . $this->getTableName() . " AS a
@@ -340,38 +340,20 @@ public function getAllAutoPayout() {
340340
$this->debug->append("STA " . __METHOD__, 4);
341341
$stmt = $this->mysqli->prepare("
342342
SELECT
343-
id, username, coin_address, ap_threshold
344-
FROM " . $this->getTableName() . "
345-
WHERE ap_threshold > 0
346-
AND coin_address IS NOT NULL
343+
a.id, a.username, ca.coin_address AS coin_address, a.ap_threshold
344+
FROM " . $this->getTableName() . " AS a
345+
LEFT JOIN " . $this->coin_address->getTableName() . " AS ca
346+
ON a.id = ca.account_id
347+
WHERE ap_threshold > 0 AND ca.currency = ?
348+
AND ca.coin_address IS NOT NULL
347349
");
348-
if ( $this->checkStmt($stmt) && $stmt->execute() && $result = $stmt->get_result()) {
350+
if ( $this->checkStmt($stmt) && $stmt->bind_param('s', $this->config['currency']) && $stmt->execute() && $result = $stmt->get_result()) {
349351
return $result->fetch_all(MYSQLI_ASSOC);
350352
}
351353
$this->debug->append("Unable to fetch users with AP set");
352354
return false;
353355
}
354356

355-
/**
356-
* Fetch users coin address
357-
* @param userID int UserID
358-
* @return data string Coin Address
359-
**/
360-
public function getCoinAddress($userID) {
361-
$this->debug->append("STA " . __METHOD__, 4);
362-
return $this->getSingle($userID, 'coin_address', 'id');
363-
}
364-
365-
/**
366-
* Check if a coin address exists already
367-
* @param address string Coin Address
368-
* @return bool True of false
369-
**/
370-
public function existsCoinAddress($address) {
371-
$this->debug->append("STA " . __METHOD__, 4);
372-
return $this->getSingle($address, 'coin_address', 'coin_address', 's') === $address;
373-
}
374-
375357
/**
376358
* Fetch users donation value
377359
* @param userID int UserID
@@ -519,7 +501,7 @@ public function updateAccount($userID, $address, $threshold, $donate, $email, $t
519501
return false;
520502
}
521503
if (!empty($address)) {
522-
if ($address != $this->getCoinAddress($userID) && $this->existsCoinAddress($address)) {
504+
if ($address != $this->coin_address->getCoinAddress($userID) && $this->coin_address->existsCoinAddress($address)) {
523505
$this->setErrorMessage('Address is already in use');
524506
return false;
525507
}
@@ -559,10 +541,19 @@ public function updateAccount($userID, $address, $threshold, $donate, $email, $t
559541
}
560542

561543
// We passed all validation checks so update the account
562-
$stmt = $this->mysqli->prepare("UPDATE $this->table SET coin_address = ?, ap_threshold = ?, donate_percent = ?, email = ?, timezone = ?, is_anonymous = ? WHERE id = ?");
563-
if ($this->checkStmt($stmt) && $stmt->bind_param('sddssii', $address, $threshold, $donate, $email, $timezone, $is_anonymous, $userID) && $stmt->execute()) {
544+
$stmt = $this->mysqli->prepare("UPDATE $this->table SET ap_threshold = ?, donate_percent = ?, email = ?, timezone = ?, is_anonymous = ? WHERE id = ?");
545+
if ($this->checkStmt($stmt) && $stmt->bind_param('ddssii', $threshold, $donate, $email, $timezone, $is_anonymous, $userID) && $stmt->execute()) {
564546
$this->log->log("info", $this->getUserName($userID)." updated their account details");
565-
return true;
547+
// Update coin address too
548+
if ($address) {
549+
if ($this->coin_address->update($userID, $address)) {
550+
return true;
551+
}
552+
} else {
553+
if ($this->coin_address->remove($userID, $address)) {
554+
return true;
555+
}
556+
}
566557
}
567558
// Catchall
568559
$this->setErrorMessage('Failed to update your account');
@@ -703,22 +694,18 @@ public function getUserData($userID) {
703694
$this->debug->append("Fetching user information for user id: $userID");
704695
$stmt = $this->mysqli->prepare("
705696
SELECT
706-
id, username, pin, api_key, is_admin, is_anonymous, email, timezone, no_fees,
707-
IFNULL(donate_percent, '0') as donate_percent, coin_address, ap_threshold
708-
FROM $this->table
697+
id AS id, username, pin, api_key, is_admin, is_anonymous, email, timezone, no_fees,
698+
IFNULL(donate_percent, '0') as donate_percent, ap_threshold
699+
FROM " . $this->getTableName() . "
709700
WHERE id = ? LIMIT 0,1");
710-
if ($this->checkStmt($stmt)) {
711-
$stmt->bind_param('i', $userID);
712-
if (!$stmt->execute()) {
713-
$this->debug->append('Failed to execute statement');
714-
return false;
715-
}
716-
$result = $stmt->get_result();
701+
if ($this->checkStmt($stmt) && $stmt->bind_param('i', $userID) && $stmt->execute() && $result = $stmt->get_result()) {
702+
$aData = $result->fetch_assoc();
703+
$aData['coin_address'] = $this->coin_address->getCoinAddress($userID);
717704
$stmt->close();
718-
return $result->fetch_assoc();
705+
return $aData;
719706
}
720707
$this->debug->append("Failed to fetch user information for $userID");
721-
return false;
708+
return $this->sqlError();
722709
}
723710

724711
/**
@@ -742,6 +729,10 @@ public function register($username, $coinaddress, $password1, $password2, $pin,
742729
return false;
743730
}
744731
if (!is_null($coinaddress)) {
732+
if ($this->coin_address->existsCoinAddress($coinaddress)) {
733+
$this->setErrorMessage('Coin address is already taken');
734+
return false;
735+
}
745736
if (!$this->bitcoin->validateaddress($coinaddress)) {
746737
$this->setErrorMessage('Coin address is not valid');
747738
return false;
@@ -755,7 +746,7 @@ public function register($username, $coinaddress, $password1, $password2, $pin,
755746
$this->setErrorMessage( 'This e-mail address is already taken' );
756747
return false;
757748
}
758-
if (strlen($password1) < 8) {
749+
if (strlen($password1) < 8) {
759750
$this->setErrorMessage( 'Password is too short, minimum of 8 characters required' );
760751
return false;
761752
}
@@ -801,15 +792,15 @@ public function register($username, $coinaddress, $password1, $password2, $pin,
801792
! $this->setting->getValue('accounts_confirm_email_disabled') ? $is_locked = 1 : $is_locked = 0;
802793
$is_admin = 0;
803794
$stmt = $this->mysqli->prepare("
804-
INSERT INTO $this->table (username, pass, email, signup_timestamp, pin, api_key, is_locked, coin_address)
805-
VALUES (?, ?, ?, ?, ?, ?, ?, ?)
795+
INSERT INTO $this->table (username, pass, email, signup_timestamp, pin, api_key, is_locked)
796+
VALUES (?, ?, ?, ?, ?, ?, ?)
806797
");
807798
} else {
808799
$is_locked = 0;
809800
$is_admin = 1;
810801
$stmt = $this->mysqli->prepare("
811-
INSERT INTO $this->table (username, pass, email, signup_timestamp, pin, api_key, is_admin, is_locked, coin_address)
812-
VALUES (?, ?, ?, ?, ?, ?, 1, ?, ?)
802+
INSERT INTO $this->table (username, pass, email, signup_timestamp, pin, api_key, is_admin, is_locked)
803+
VALUES (?, ?, ?, ?, ?, ?, 1, ?)
813804
");
814805
}
815806

@@ -820,7 +811,9 @@ public function register($username, $coinaddress, $password1, $password2, $pin,
820811
$username_clean = strip_tags($username);
821812
$signup_time = time();
822813

823-
if ($this->checkStmt($stmt) && $stmt->bind_param('sssissis', $username_clean, $password_hash, $email1, $signup_time, $pin_hash, $apikey_hash, $is_locked, $coinaddress) && $stmt->execute()) {
814+
if ($this->checkStmt($stmt) && $stmt->bind_param('sssissi', $username_clean, $password_hash, $email1, $signup_time, $pin_hash, $apikey_hash, $is_locked) && $stmt->execute()) {
815+
$new_account_id = $this->mysqli->insert_id;
816+
if (!is_null($coinaddress)) $this->coin_address->add($new_account_id, $coinaddress);
824817
if (! $this->setting->getValue('accounts_confirm_email_disabled') && $is_admin != 1) {
825818
if ($token = $this->token->createToken('confirm_email', $stmt->insert_id)) {
826819
$aData['username'] = $username_clean;
@@ -843,7 +836,8 @@ public function register($username, $coinaddress, $password1, $password2, $pin,
843836
} else {
844837
$this->setErrorMessage( 'Unable to register' );
845838
$this->debug->append('Failed to insert user into DB: ' . $this->mysqli->error);
846-
if ($stmt->sqlstate == '23000') $this->setErrorMessage( 'Username, email or Coinaddress already registered' );
839+
echo $this->mysqli->error;
840+
if ($stmt->sqlstate == '23000') $this->setErrorMessage( 'Username or email already registered' );
847841
return false;
848842
}
849843
return false;
@@ -997,4 +991,5 @@ public function getCurrentIP($trustremote=false, $checkcloudflare=true, $checkcl
997991
$user->setToken($oToken);
998992
$user->setBitcoin($bitcoin);
999993
$user->setSetting($setting);
994+
$user->setCoinAddress($coin_address);
1000995
$user->setErrorCodes($aErrorCodes);

include/pages/account/edit.inc.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,7 @@
104104
$_SESSION['POPUP'][] = array('CONTENT' => 'You have not yet unlocked account withdrawls.', 'TYPE' => 'alert alert-danger');
105105
} else if ($aBalance['confirmed'] < $config['mp_threshold']) {
106106
$_SESSION['POPUP'][] = array('CONTENT' => 'Payout must be greater or equal than ' . $config['mp_threshold'] . '.', 'TYPE' => 'info');
107-
} else if (!$user->getCoinAddress($_SESSION['USERDATA']['id'])) {
107+
} else if (!$coin_address->getCoinAddress($_SESSION['USERDATA']['id'])) {
108108
$_SESSION['POPUP'][] = array('CONTENT' => 'You have no payout address set.', 'TYPE' => 'alert alert-danger');
109109
} else {
110110
$user->log->log("info", $_SESSION['USERDATA']['username']." requesting manual payout");

include/pages/account/workers.inc.php

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,10 @@
44
if ($user->isAuthenticated()) {
55

66

7-
if (!$user->getCoinAddress($_SESSION['USERDATA']['id']) AND $setting->getValue('disable_worker_edit')) {
8-
7+
if (!$coin_address->getCoinAddress($_SESSION['USERDATA']['id']) AND $setting->getValue('disable_worker_edit')) {
98
$_SESSION['POPUP'][] = array('CONTENT' => 'You have no payout address set.', 'TYPE' => 'alert alert-danger');
109
$_SESSION['POPUP'][] = array('CONTENT' => 'You can not add workers unless a valid Payout Address is set in your User Settings.', 'TYPE' => 'alert alert-danger');
1110
$smarty->assign('CONTENT', 'disabled.tpl');
12-
1311
} else {
1412
switch (@$_REQUEST['do']) {
1513
case 'delete':

0 commit comments

Comments
 (0)