Merge pull request #2274 from MPOS/development
UPDATE : Development to Master
This commit is contained in:
commit
86df6d1e3e
4
.gitignore
vendored
4
.gitignore
vendored
@ -18,6 +18,10 @@
|
||||
/include/config/global.inc.scrypt.php
|
||||
/include/config/global.inc.sha.php
|
||||
|
||||
# Test files
|
||||
/scripts/test.php
|
||||
/cronjobs/test.php
|
||||
|
||||
# IDE Settings
|
||||
/.idea/*
|
||||
.buildpath
|
||||
|
||||
@ -59,7 +59,7 @@ if (empty($aTransactions['transactions'])) {
|
||||
$config['reward_type'] == 'block' ? $aData['amount'] = $aData['amount'] : $aData['amount'] = $config['reward'];
|
||||
$aData['height'] = $aBlockRPCInfo['height'];
|
||||
$aTxDetails = $bitcoin->gettransaction($aBlockRPCInfo['tx'][0]);
|
||||
if (!isset($aBlockRPCInfo['confirmations'])) {
|
||||
if (isset($aBlockRPCInfo['confirmations'])) {
|
||||
$aData['confirmations'] = $aBlockRPCInfo['confirmations'];
|
||||
} else if (isset($aTxDetails['confirmations'])) {
|
||||
$aData['confirmations'] = $aTxDetails['confirmations'];
|
||||
|
||||
@ -27,7 +27,7 @@ require_once('shared.inc.php');
|
||||
|
||||
// Header
|
||||
$log->logInfo('Running statistical queries, errors may just mean no shares were available');
|
||||
$strLogMask = "| %-26.26s | %8.8s | %-6.6s |";
|
||||
$strLogMask = "| %-33.33s | %8.8s | %-6.6s |";
|
||||
$log->logInfo(sprintf($strLogMask, 'Method', 'Runtime', 'Status'));
|
||||
|
||||
// Per user share statistics based on all shares submitted
|
||||
@ -37,9 +37,15 @@ $log->logInfo(sprintf($strLogMask, 'getAllUserShares', number_format(microtime(t
|
||||
|
||||
// Get all user hashrate statistics for caching
|
||||
$start = microtime(true);
|
||||
$statistics->getAllUserMiningStats() ? $status = 'OK' : $status = 'ERROR';
|
||||
$log->logInfo(sprintf($strLogMask, 'getAllUserMiningStats', number_format(microtime(true) - $start, 3), $status));
|
||||
$statistics->fetchAllUserMiningStats() ? $status = 'OK' : $status = 'ERROR';
|
||||
$log->logInfo(sprintf($strLogMask, 'fetchAllUserMiningStats', number_format(microtime(true) - $start, 3), $status));
|
||||
|
||||
// Store our statistical data into our `statistics_users` table
|
||||
$start = microtime(true);
|
||||
$statistics->storeAllUserMiningStatsSnapshot($statistics->getAllUserMiningStats()) ? $status = 'OK' : $status = 'ERROR';
|
||||
$log->logInfo(sprintf($strLogMask, 'storeAllUserMiningStatsSnapshot', number_format(microtime(true) - $start, 3), $status));
|
||||
|
||||
// Get stats for pool overview
|
||||
$start = microtime(true);
|
||||
$statistics->getTopContributors('hashes') ? $status = 'OK' : $status = 'ERROR';
|
||||
$log->logInfo(sprintf($strLogMask, 'getTopContributors(hashes)', number_format(microtime(true) - $start, 3), $status));
|
||||
|
||||
@ -65,7 +65,7 @@ $status = 'OK';
|
||||
$message = '';
|
||||
$affected = $share->purgeArchive();
|
||||
if ($affected === false) {
|
||||
$message = 'Failed to delete notifications: ' . $oToken->getCronError();
|
||||
$message = 'Failed to delete shares: ' . $share->getCronError();
|
||||
$status = 'ERROR';
|
||||
$monitoring->endCronjob($cron_name, 'E0008', 0, false, false);
|
||||
} else {
|
||||
@ -73,6 +73,19 @@ if ($affected === false) {
|
||||
}
|
||||
$log->logInfo(sprintf($strLogMask, 'purgeArchive', $affected, number_format(microtime(true) - $start, 3), $status, $message));
|
||||
|
||||
// Clenaup shares archive
|
||||
$start = microtime(true);
|
||||
$status = 'OK';
|
||||
$message = '';
|
||||
$affected = $statistics->purgeUserStats($setting->getValue('statistics_graphing_days', 1));
|
||||
if ($affected === false) {
|
||||
$message = 'Failed to delete entries: ' . $statistics->getCronError();
|
||||
$status = 'ERROR';
|
||||
$monitoring->endCronjob($cron_name, 'E0008', 0, false, false);
|
||||
} else {
|
||||
$affected == 0 ? $message = 'No entries deleted' : $message = 'Deleted old entries';
|
||||
}
|
||||
$log->logInfo(sprintf($strLogMask, 'purgeUserStats', $affected, number_format(microtime(true) - $start, 3), $status, $message));
|
||||
|
||||
// Cron cleanup and monitoring
|
||||
require_once('cron_end.inc.php');
|
||||
|
||||
@ -16,6 +16,7 @@ require_once(INCLUDE_DIR . '/config/error_codes.inc.php');
|
||||
// We need to load these first
|
||||
require_once(CLASS_DIR . '/base.class.php');
|
||||
require_once(CLASS_DIR . '/coins/coin_base.class.php');
|
||||
require_once(CLASS_DIR . '/coin_address.class.php');
|
||||
require_once(CLASS_DIR . '/setting.class.php');
|
||||
require_once(INCLUDE_DIR . '/version.inc.php');
|
||||
if (PHP_OS == 'WINNT') require_once(CLASS_DIR . '/memcached.class.php');
|
||||
|
||||
@ -22,6 +22,9 @@ class Base {
|
||||
public function setCoin($coin) {
|
||||
$this->coin = $coin;
|
||||
}
|
||||
public function setCoinAddress($coin_address) {
|
||||
$this->coin_address = $coin_address;
|
||||
}
|
||||
public function setLog($log) {
|
||||
$this->log = $log;
|
||||
}
|
||||
|
||||
107
include/classes/coin_address.class.php
Normal file
107
include/classes/coin_address.class.php
Normal file
@ -0,0 +1,107 @@
|
||||
<?php
|
||||
$defflip = (!cfip()) ? exit(header('HTTP/1.1 401 Unauthorized')) : 1;
|
||||
|
||||
class CoinAddress extends Base {
|
||||
protected $table = 'coin_addresses';
|
||||
private $cache = array();
|
||||
|
||||
/**
|
||||
* Fetch users coin address for a currency
|
||||
* @param userID int UserID
|
||||
* @return data string Coin Address
|
||||
**/
|
||||
public function getCoinAddress($userID, $currency=NULL) {
|
||||
if ($currency === NULL) $currency = $this->config['currency'];
|
||||
$this->debug->append("STA " . __METHOD__, 4);
|
||||
$stmt = $this->mysqli->prepare("
|
||||
SELECT coin_address
|
||||
FROM " . $this->getTableName() . "
|
||||
WHERE account_id = ? AND currency = ?
|
||||
");
|
||||
if ( $this->checkStmt($stmt) && $stmt->bind_param('is', $userID, $currency) && $stmt->execute() && $result = $stmt->get_result()) {
|
||||
if ($result->num_rows == 1) {
|
||||
return $result->fetch_object()->coin_address;
|
||||
}
|
||||
}
|
||||
$this->debug->append("Unable to fetch users coin address for " . $currency);
|
||||
return $this->sqlError();
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if a coin address is already set
|
||||
* @param address string Coin Address to check for
|
||||
* @return bool true or false
|
||||
**/
|
||||
public function existsCoinAddress($address) {
|
||||
$this->debug->append("STA " . __METHOD__, 4);
|
||||
return $this->getSingle($address, 'coin_address', 'coin_address', 's') === $address;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a new coin address record for a user
|
||||
* @param userID int Account ID
|
||||
* @param address string Coin Address
|
||||
* @param currency string Currency short handle, defaults to config option
|
||||
* @return bool true or false
|
||||
**/
|
||||
public function add($userID, $address, $currency=NULL) {
|
||||
if ($currency === NULL) $currency = $this->config['currency'];
|
||||
if ($address != $this->getCoinAddress($userID) && $this->existsCoinAddress($address)) {
|
||||
$this->setErrorMessage('Unable to update coin address, address already exists');
|
||||
return false;
|
||||
}
|
||||
$stmt = $this->mysqli->prepare("INSERT INTO " . $this->getTableName() . " (account_id, currency, coin_address) VALUES (?, ?, ?)");
|
||||
if ( $this->checkStmt($stmt) && $stmt->bind_param('iss', $userID, $currency, $address) && $stmt->execute()) {
|
||||
return true;
|
||||
}
|
||||
return $this->sqlError();
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove a coin address record for a user
|
||||
* @param userID int Account ID
|
||||
* @param currency string Currency short handle, defaults to config option
|
||||
* @return bool true or false
|
||||
**/
|
||||
public function remove ($userID, $currency=NULL) {
|
||||
if ($currency === NULL) $currency = $this->config['currency'];
|
||||
$stmt = $this->mysqli->prepare("DELETE FROM " . $this->getTableName() . " WHERE account_id = ? AND currency = ?");
|
||||
if ( $this->checkStmt($stmt) && $stmt->bind_param('is', $userID, $currency) && $stmt->execute()) {
|
||||
return true;
|
||||
}
|
||||
return $this->sqlError();
|
||||
}
|
||||
|
||||
/**
|
||||
* Update a coin address record for a user and a currency
|
||||
* @param userID int Account ID
|
||||
* @param address string Coin Address
|
||||
* @param currency string Currency short handle, defaults to config option
|
||||
* @return bool true or false
|
||||
**/
|
||||
public function update($userID, $address, $currency=NULL) {
|
||||
if ($currency === NULL) $currency = $this->config['currency'];
|
||||
if ($address != $this->getCoinAddress($userID) && $this->existsCoinAddress($address)) {
|
||||
$this->setErrorMessage('Unable to update coin address, address already exists');
|
||||
return false;
|
||||
}
|
||||
if ($this->getCoinAddress($userID) != NULL) {
|
||||
$stmt = $this->mysqli->prepare("UPDATE " . $this->getTableName() . " SET coin_address = ? WHERE account_id = ? AND currency = ?");
|
||||
if ( $this->checkStmt($stmt) && $stmt->bind_param('sis', $address, $userID, $currency) && $stmt->execute()) {
|
||||
return true;
|
||||
}
|
||||
} else {
|
||||
$stmt = $this->mysqli->prepare("INSERT INTO " . $this->getTableName() . " (coin_address, account_id, currency) VALUES (?, ?, ?)");
|
||||
if ( $this->checkStmt($stmt) && $stmt->bind_param('sis', $address, $userID, $currency) && $stmt->execute()) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return $this->sqlError();
|
||||
}
|
||||
}
|
||||
|
||||
$coin_address = new CoinAddress();
|
||||
$coin_address->setDebug($debug);
|
||||
$coin_address->setConfig($config);
|
||||
$coin_address->setMysql($mysqli);
|
||||
$coin_address->setErrorCodes($aErrorCodes);
|
||||
@ -12,6 +12,9 @@ class CoinBase extends Base {
|
||||
// Our coins target bits
|
||||
protected $target_bits = NULL;
|
||||
|
||||
// Our coins share difficulty precision
|
||||
protected $share_difficulty_precision = 0;
|
||||
|
||||
/**
|
||||
* Read our target bits
|
||||
**/
|
||||
@ -19,6 +22,13 @@ class CoinBase extends Base {
|
||||
return $this->target_bits;
|
||||
}
|
||||
|
||||
/**
|
||||
* Read our share difficulty precision
|
||||
**/
|
||||
public function getShareDifficultyPrecision() {
|
||||
return $this->share_difficulty_precision;
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculate the PPS value for this coin
|
||||
* WARNING: Get this wrong and you will over- or underpay your miners!
|
||||
|
||||
@ -8,6 +8,7 @@ $defflip = (!cfip()) ? exit(header('HTTP/1.1 401 Unauthorized')) : 1;
|
||||
**/
|
||||
class Coin extends CoinBase {
|
||||
protected $target_bits = 24;
|
||||
protected $share_difficulty_precision = 4;
|
||||
}
|
||||
|
||||
?>
|
||||
|
||||
@ -9,6 +9,7 @@ $defflip = (!cfip()) ? exit(header('HTTP/1.1 401 Unauthorized')) : 1;
|
||||
**/
|
||||
class Statistics extends Base {
|
||||
protected $table = 'statistics_shares';
|
||||
protected $table_user_stats = 'statistics_users';
|
||||
private $getcache = true;
|
||||
|
||||
// Disable fetching values from cache
|
||||
@ -18,6 +19,12 @@ class Statistics extends Base {
|
||||
public function getGetCache() {
|
||||
return $this->getcache;
|
||||
}
|
||||
public function getAllUserMiningStats() {
|
||||
return $this->allUserMiningStats;
|
||||
}
|
||||
public function getUserStatsTableName() {
|
||||
return $this->table_user_stats;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get our first block found
|
||||
@ -45,37 +52,37 @@ class Statistics extends Base {
|
||||
IFNULL(SUM(IF(confirmations > 0, 1, 0)), 0) AS TotalValid,
|
||||
IFNULL(SUM(IF(confirmations = -1, 1, 0)), 0) AS TotalOrphan,
|
||||
IFNULL(SUM(IF(confirmations > 0, difficulty, 0)), 0) AS TotalDifficulty,
|
||||
IFNULL(ROUND(SUM(IF(confirmations > -1, shares, 0))), 0) AS TotalShares,
|
||||
IFNULL(SUM(IF(confirmations > -1, shares, 0)), 0) AS TotalShares,
|
||||
IFNULL(SUM(IF(confirmations > -1, amount, 0)), 0) AS TotalAmount,
|
||||
IFNULL(SUM(IF(FROM_UNIXTIME(time) >= DATE_SUB(now(), INTERVAL 3600 SECOND), 1, 0)), 0) AS 1HourTotal,
|
||||
IFNULL(SUM(IF(confirmations > 0 AND FROM_UNIXTIME(time) >= DATE_SUB(now(), INTERVAL 3600 SECOND), 1, 0)), 0) AS 1HourValid,
|
||||
IFNULL(SUM(IF(confirmations = -1 AND FROM_UNIXTIME(time) >= DATE_SUB(now(), INTERVAL 3600 SECOND), 1, 0)), 0) AS 1HourOrphan,
|
||||
IFNULL(SUM(IF(confirmations > 0 AND FROM_UNIXTIME(time) >= DATE_SUB(now(), INTERVAL 3600 SECOND), difficulty, 0)), 0) AS 1HourDifficulty,
|
||||
IFNULL(ROUND(SUM(IF(confirmations > -1 AND FROM_UNIXTIME(time) >= DATE_SUB(now(), INTERVAL 3600 SECOND), shares, 0))), 0) AS 1HourShares,
|
||||
IFNULL(SUM(IF(confirmations > -1 AND FROM_UNIXTIME(time) >= DATE_SUB(now(), INTERVAL 3600 SECOND), shares, 0)), 0) AS 1HourShares,
|
||||
IFNULL(SUM(IF(confirmations > -1 AND FROM_UNIXTIME(time) >= DATE_SUB(now(), INTERVAL 3600 SECOND), amount, 0)), 0) AS 1HourAmount,
|
||||
IFNULL(SUM(IF(FROM_UNIXTIME(time) >= DATE_SUB(now(), INTERVAL 86400 SECOND), 1, 0)), 0) AS 24HourTotal,
|
||||
IFNULL(SUM(IF(confirmations > 0 AND FROM_UNIXTIME(time) >= DATE_SUB(now(), INTERVAL 86400 SECOND), 1, 0)), 0) AS 24HourValid,
|
||||
IFNULL(SUM(IF(confirmations = -1 AND FROM_UNIXTIME(time) >= DATE_SUB(now(), INTERVAL 86400 SECOND), 1, 0)), 0) AS 24HourOrphan,
|
||||
IFNULL(SUM(IF(confirmations > 0 AND FROM_UNIXTIME(time) >= DATE_SUB(now(), INTERVAL 86400 SECOND), difficulty, 0)), 0) AS 24HourDifficulty,
|
||||
IFNULL(ROUND(SUM(IF(confirmations > -1 AND FROM_UNIXTIME(time) >= DATE_SUB(now(), INTERVAL 86400 SECOND), shares, 0))), 0) AS 24HourShares,
|
||||
IFNULL(SUM(IF(confirmations > -1 AND FROM_UNIXTIME(time) >= DATE_SUB(now(), INTERVAL 86400 SECOND), shares, 0)), 0) AS 24HourShares,
|
||||
IFNULL(SUM(IF(confirmations > -1 AND FROM_UNIXTIME(time) >= DATE_SUB(now(), INTERVAL 86400 SECOND), amount, 0)), 0) AS 24HourAmount,
|
||||
IFNULL(SUM(IF(FROM_UNIXTIME(time) >= DATE_SUB(now(), INTERVAL 604800 SECOND), 1, 0)), 0) AS 7DaysTotal,
|
||||
IFNULL(SUM(IF(confirmations > 0 AND FROM_UNIXTIME(time) >= DATE_SUB(now(), INTERVAL 604800 SECOND), 1, 0)), 0) AS 7DaysValid,
|
||||
IFNULL(SUM(IF(confirmations = -1 AND FROM_UNIXTIME(time) >= DATE_SUB(now(), INTERVAL 604800 SECOND), 1, 0)), 0) AS 7DaysOrphan,
|
||||
IFNULL(SUM(IF(confirmations > 0 AND FROM_UNIXTIME(time) >= DATE_SUB(now(), INTERVAL 604800 SECOND), difficulty, 0)), 0) AS 7DaysDifficulty,
|
||||
IFNULL(ROUND(SUM(IF(confirmations > -1 AND FROM_UNIXTIME(time) >= DATE_SUB(now(), INTERVAL 604800 SECOND), shares, 0))), 0) AS 7DaysShares,
|
||||
IFNULL(SUM(IF(confirmations > -1 AND FROM_UNIXTIME(time) >= DATE_SUB(now(), INTERVAL 604800 SECOND), shares, 0)), 0) AS 7DaysShares,
|
||||
IFNULL(SUM(IF(confirmations > -1 AND FROM_UNIXTIME(time) >= DATE_SUB(now(), INTERVAL 604800 SECOND), amount, 0)), 0) AS 7DaysAmount,
|
||||
IFNULL(SUM(IF(FROM_UNIXTIME(time) >= DATE_SUB(now(), INTERVAL 2419200 SECOND), 1, 0)), 0) AS 4WeeksTotal,
|
||||
IFNULL(SUM(IF(confirmations > 0 AND FROM_UNIXTIME(time) >= DATE_SUB(now(), INTERVAL 2419200 SECOND), 1, 0)), 0) AS 4WeeksValid,
|
||||
IFNULL(SUM(IF(confirmations = -1 AND FROM_UNIXTIME(time) >= DATE_SUB(now(), INTERVAL 2419200 SECOND), 1, 0)), 0) AS 4WeeksOrphan,
|
||||
IFNULL(SUM(IF(confirmations > 0 AND FROM_UNIXTIME(time) >= DATE_SUB(now(), INTERVAL 2419200 SECOND), difficulty, 0)), 0) AS 4WeeksDifficulty,
|
||||
IFNULL(ROUND(SUM(IF(confirmations > -1 AND FROM_UNIXTIME(time) >= DATE_SUB(now(), INTERVAL 2419200 SECOND), shares, 0))), 0) AS 4WeeksShares,
|
||||
IFNULL(SUM(IF(confirmations > -1 AND FROM_UNIXTIME(time) >= DATE_SUB(now(), INTERVAL 2419200 SECOND), shares, 0)), 0) AS 4WeeksShares,
|
||||
IFNULL(SUM(IF(confirmations > -1 AND FROM_UNIXTIME(time) >= DATE_SUB(now(), INTERVAL 2419200 SECOND), amount, 0)), 0) AS 4WeeksAmount,
|
||||
IFNULL(SUM(IF(FROM_UNIXTIME(time) >= DATE_SUB(now(), INTERVAL 29030400 SECOND), 1, 0)), 0) AS 12MonthTotal,
|
||||
IFNULL(SUM(IF(confirmations > 0 AND FROM_UNIXTIME(time) >= DATE_SUB(now(), INTERVAL 29030400 SECOND), 1, 0)), 0) AS 12MonthValid,
|
||||
IFNULL(SUM(IF(confirmations = -1 AND FROM_UNIXTIME(time) >= DATE_SUB(now(), INTERVAL 29030400 SECOND), 1, 0)), 0) AS 12MonthOrphan,
|
||||
IFNULL(SUM(IF(confirmations > 0 AND FROM_UNIXTIME(time) >= DATE_SUB(now(), INTERVAL 29030400 SECOND), difficulty, 0)), 0) AS 12MonthDifficulty,
|
||||
IFNULL(ROUND(SUM(IF(confirmations > -1 AND FROM_UNIXTIME(time) >= DATE_SUB(now(), INTERVAL 29030400 SECOND), shares, 0))), 0) AS 12MonthShares,
|
||||
IFNULL(SUM(IF(confirmations > -1 AND FROM_UNIXTIME(time) >= DATE_SUB(now(), INTERVAL 29030400 SECOND), shares, 0)), 0) AS 12MonthShares,
|
||||
IFNULL(SUM(IF(confirmations > -1 AND FROM_UNIXTIME(time) >= DATE_SUB(now(), INTERVAL 29030400 SECOND), amount, 0)), 0) AS 12MonthAmount
|
||||
FROM " . $this->block->getTableName());
|
||||
if ($this->checkStmt($stmt) && $stmt->execute() && $result = $stmt->get_result()) {
|
||||
@ -127,7 +134,7 @@ class Statistics extends Base {
|
||||
b.*,
|
||||
a.username AS finder,
|
||||
a.is_anonymous AS is_anonymous,
|
||||
ROUND(difficulty * POW(2, 32 - " . $this->coin->getTargetBits() . "), 0) AS estshares
|
||||
ROUND(difficulty * POW(2, 32 - " . $this->coin->getTargetBits() . "), 4) AS estshares
|
||||
FROM " . $this->block->getTableName() . " AS b
|
||||
LEFT JOIN " . $this->user->getTableName() . " AS a
|
||||
ON b.account_id = a.id
|
||||
@ -163,7 +170,7 @@ class Statistics extends Base {
|
||||
return $this->memcache->setCache(__FUNCTION__ . $limit, $result->fetch_all(MYSQLI_ASSOC), 5);
|
||||
return $this->sqlError();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get SUM of blocks found and generated Coins for each worker
|
||||
* @param limit int Last limit blocks
|
||||
@ -185,7 +192,7 @@ class Statistics extends Base {
|
||||
return $this->memcache->setCache(__FUNCTION__ . $account_id . $limit, $result->fetch_all(MYSQLI_ASSOC), 5);
|
||||
return $this->sqlError();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Currently the only function writing to the database
|
||||
* Stored per block user statistics of valid and invalid shares
|
||||
@ -223,12 +230,12 @@ class Statistics extends Base {
|
||||
SELECT
|
||||
(
|
||||
(
|
||||
SELECT IFNULL(ROUND(SUM(IF(difficulty=0, POW(2, (" . $this->config['difficulty'] . " - 16)), difficulty))), 0) AS shares
|
||||
SELECT IFNULL(SUM(IF(difficulty=0, POW(2, (" . $this->config['difficulty'] . " - 16)), difficulty)), 0) AS shares
|
||||
FROM " . $this->share->getTableName() . "
|
||||
WHERE time > DATE_SUB(now(), INTERVAL ? SECOND)
|
||||
AND our_result = 'Y'
|
||||
) + (
|
||||
SELECT IFNULL(ROUND(SUM(IF(difficulty=0, POW(2, (" . $this->config['difficulty'] . " - 16)), difficulty))), 0) AS shares
|
||||
SELECT IFNULL(SUM(IF(difficulty=0, POW(2, (" . $this->config['difficulty'] . " - 16)), difficulty)), 0) AS shares
|
||||
FROM " . $this->share->getArchiveTableName() . "
|
||||
WHERE time > DATE_SUB(now(), INTERVAL ? SECOND)
|
||||
AND our_result = 'Y'
|
||||
@ -254,12 +261,12 @@ class Statistics extends Base {
|
||||
SELECT
|
||||
(
|
||||
(
|
||||
SELECT ROUND(COUNT(id) / ?, 2) AS sharerate
|
||||
SELECT ROUND(SUM(difficulty) / ?, 2) AS sharerate
|
||||
FROM " . $this->share->getTableName() . "
|
||||
WHERE time > DATE_SUB(now(), INTERVAL ? SECOND)
|
||||
AND our_result = 'Y'
|
||||
) + (
|
||||
SELECT ROUND(COUNT(id) / ?, 2) AS sharerate
|
||||
SELECT ROUND(SUM(difficulty) / ?, 2) AS sharerate
|
||||
FROM " . $this->share->getArchiveTableName() . "
|
||||
WHERE time > DATE_SUB(now(), INTERVAL ? SECOND)
|
||||
AND our_result = 'Y'
|
||||
@ -293,8 +300,8 @@ class Statistics extends Base {
|
||||
}
|
||||
$stmt = $this->mysqli->prepare("
|
||||
SELECT
|
||||
ROUND(IFNULL(SUM(IF(our_result='Y', IF(difficulty=0, POW(2, (" . $this->config['difficulty'] . " - 16)), difficulty), 0)), 0), 0) AS valid,
|
||||
ROUND(IFNULL(SUM(IF(our_result='N', IF(difficulty=0, POW(2, (" . $this->config['difficulty'] . " - 16)), difficulty), 0)), 0), 0) AS invalid
|
||||
IFNULL(SUM(IF(our_result='Y', IF(difficulty=0, POW(2, (" . $this->config['difficulty'] . " - 16)), difficulty), 0)), 0) AS valid,
|
||||
IFNULL(SUM(IF(our_result='N', IF(difficulty=0, POW(2, (" . $this->config['difficulty'] . " - 16)), difficulty), 0)), 0) AS invalid
|
||||
FROM " . $this->share->getTableName() . "
|
||||
WHERE UNIX_TIMESTAMP(time) > IFNULL((SELECT MAX(time) FROM " . $this->block->getTableName() . "), 0)");
|
||||
if ( $this->checkStmt($stmt) && $stmt->execute() && $result = $stmt->get_result() )
|
||||
@ -316,8 +323,8 @@ class Statistics extends Base {
|
||||
}
|
||||
$stmt = $this->mysqli->prepare("
|
||||
SELECT
|
||||
ROUND(IFNULL(SUM(IF(our_result='Y', IF(s.difficulty=0, POW(2, (" . $this->config['difficulty'] . " - 16)), s.difficulty), 0)), 0), 0) AS valid,
|
||||
ROUND(IFNULL(SUM(IF(our_result='N', IF(s.difficulty=0, POW(2, (" . $this->config['difficulty'] . " - 16)), s.difficulty), 0)), 0), 0) AS invalid,
|
||||
IFNULL(SUM(IF(our_result='Y', IF(s.difficulty=0, POW(2, (" . $this->config['difficulty'] . " - 16)), s.difficulty), 0)), 0) AS valid,
|
||||
IFNULL(SUM(IF(our_result='N', IF(s.difficulty=0, POW(2, (" . $this->config['difficulty'] . " - 16)), s.difficulty), 0)), 0) AS invalid,
|
||||
u.id AS id,
|
||||
u.donate_percent AS donate_percent,
|
||||
u.is_anonymous AS is_anonymous,
|
||||
@ -368,11 +375,11 @@ class Statistics extends Base {
|
||||
if ($data = $this->memcache->get(__FUNCTION__ . $account_id)) return $data;
|
||||
$stmt = $this->mysqli->prepare("
|
||||
SELECT
|
||||
ROUND(IFNULL(SUM(IF(our_result='Y', IF(difficulty=0, POW(2, (" . $this->config['difficulty'] . " - 16)), difficulty), 0)), 0), 0) AS valid,
|
||||
ROUND(IFNULL(SUM(IF(our_result='N', IF(difficulty=0, POW(2, (" . $this->config['difficulty'] . " - 16)), difficulty), 0)), 0), 0) AS invalid
|
||||
IFNULL(SUM(IF(our_result='Y', IF(difficulty=0, POW(2, (" . $this->config['difficulty'] . " - 16)), difficulty), 0)), 0) AS valid,
|
||||
IFNULL(SUM(IF(our_result='N', IF(difficulty=0, POW(2, (" . $this->config['difficulty'] . " - 16)), difficulty), 0)), 0) AS invalid
|
||||
FROM " . $this->share->getTableName() . "
|
||||
WHERE username LIKE ?
|
||||
AND UNIX_TIMESTAMP(time) >IFNULL((SELECT MAX(b.time) FROM " . $this->block->getTableName() . " AS b),0)");
|
||||
AND UNIX_TIMESTAMP(time) >IFNULL((SELECT MAX(b.time) FROM " . $this->block->getTableName() . " AS b),0)");
|
||||
$username = $username . ".%";
|
||||
if ($stmt && $stmt->bind_param("s", $username) && $stmt->execute() && $result = $stmt->get_result())
|
||||
return $this->memcache->setCache(__FUNCTION__ . $account_id, $result->fetch_assoc());
|
||||
@ -451,16 +458,19 @@ class Statistics extends Base {
|
||||
|
||||
/**
|
||||
* Fetch all user hashrates based on shares and archived shares
|
||||
* Store it in cache, also keep a copy of the data internally to
|
||||
* return it for further processing
|
||||
* @return data array Set of all user stats
|
||||
**/
|
||||
public function getAllUserMiningStats($interval=180) {
|
||||
public function fetchAllUserMiningStats($interval=180) {
|
||||
$this->debug->append("STA " . __METHOD__, 4);
|
||||
$stmt = $this->mysqli->prepare("
|
||||
SELECT
|
||||
a.id AS id,
|
||||
a.username AS account,
|
||||
COUNT(DISTINCT t1.username) AS workers,
|
||||
IFNULL(SUM(t1.difficulty), 0) AS shares,
|
||||
ROUND(COUNT(t1.id) / ?, 2) AS sharerate,
|
||||
ROUND(SUM(t1.difficulty) / ?, 2) AS sharerate,
|
||||
IFNULL(AVG(IF(difficulty=0, pow(2, (" . $this->config['difficulty'] . " - 16)), difficulty)), 0) AS avgsharediff
|
||||
FROM (
|
||||
SELECT
|
||||
@ -489,18 +499,51 @@ class Statistics extends Base {
|
||||
$aData['data'][$row['id']] = $row;
|
||||
$aData['data'][$row['id']]['hashrate'] = $this->coin->calcHashrate($row['shares'], $interval);
|
||||
}
|
||||
$this->allUserMiningStats = $aData;
|
||||
return $this->memcache->setStaticCache(STATISTICS_ALL_USER_HASHRATES, $aData, 600);
|
||||
} else {
|
||||
return $this->sqlError();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Store our gathered data into our statistic table for users
|
||||
* @param aData array Data created by fetchAllUserMiningStats
|
||||
* @return bool true or false
|
||||
**/
|
||||
public function storeAllUserMiningStatsSnapshot($aData) {
|
||||
$this->debug->append("STA " . __METHOD__, 4);
|
||||
if (!isset($aData['data'])) return false;
|
||||
// initilize
|
||||
$timestamp = time(); // Store all entries with the same timestamp to reduce cardinality
|
||||
$ok = 0;
|
||||
$failed = 0;
|
||||
foreach ($aData['data'] as $key => $aUserData) {
|
||||
$stmt = $this->mysqli->prepare("
|
||||
INSERT INTO " . $this->getUserStatsTableName() . "
|
||||
( account_id, hashrate, workers, sharerate, timestamp ) VALUES ( ?, ?, ?, ?, ?)");
|
||||
if ($this->checkStmt($stmt) && $stmt->bind_param("ididi", $aUserData['id'], $aUserData['hashrate'], $aUserData['workers'], $aUserData['sharerate'], $timestamp) && $stmt->execute() ) {
|
||||
$ok++;
|
||||
} else {
|
||||
$failed++;
|
||||
}
|
||||
}
|
||||
return array('ok' => $ok, 'failed' => $failed);
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetch unpaid PPS shares for an account
|
||||
* @param username string Username
|
||||
* @param account_id int User ID
|
||||
* @param last_paid_pps_id int Last paid out share by pps_payout cron
|
||||
* @return data int Sum of unpaid diff1 shares
|
||||
**/
|
||||
public function getUserUnpaidPPSShares($username, $account_id=NULL, $last_paid_pps_id) {
|
||||
$this->debug->append("STA " . __METHOD__, 4);
|
||||
if ($this->getGetCache() && $data = $this->memcache->get(__FUNCTION__ . $account_id)) return $data;
|
||||
$stmt = $this->mysqli->prepare("
|
||||
SELECT
|
||||
ROUND(IFNULL(SUM(IF(difficulty=0, POW(2, (" . $this->config['difficulty'] . " - 16)), difficulty)), 0), 0) AS total
|
||||
IFNULL(SUM(IF(difficulty=0, POW(2, (" . $this->config['difficulty'] . " - 16)), difficulty)), 0) AS total
|
||||
FROM " . $this->share->getTableName() . "
|
||||
WHERE username LIKE ?
|
||||
AND id > ?
|
||||
@ -515,7 +558,7 @@ class Statistics extends Base {
|
||||
* Get Shares per x interval by user
|
||||
* @param username string username
|
||||
* @param $account_id int account id
|
||||
* @return data integer Current Sharerate in shares/s
|
||||
* @return data integer Current Sharerate in diff1 shares/s
|
||||
**/
|
||||
public function getUserMiningStats($username, $account_id=NULL, $interval=180) {
|
||||
$this->debug->append("STA " . __METHOD__, 4);
|
||||
@ -532,7 +575,7 @@ class Statistics extends Base {
|
||||
if ($this->getGetCache() && $data = $this->memcache->get(__FUNCTION__ . $account_id)) return $data;
|
||||
$stmt = $this->mysqli->prepare("
|
||||
SELECT
|
||||
IFNULL(COUNT(*) / ?, 0) AS sharerate,
|
||||
IFNULL(SUM(difficulty) / ?, 0) AS sharerate,
|
||||
IFNULL(SUM(difficulty), 0) AS shares,
|
||||
IFNULL(AVG(difficulty), 0) AS avgsharediff
|
||||
FROM (
|
||||
@ -603,7 +646,7 @@ class Statistics extends Base {
|
||||
a.username AS account,
|
||||
a.donate_percent AS donate_percent,
|
||||
a.is_anonymous AS is_anonymous,
|
||||
ROUND(IFNULL(SUM(IF(s.difficulty=0, POW(2, (" . $this->config['difficulty'] . " - 16)), s.difficulty)), 0), 0) AS shares
|
||||
IFNULL(SUM(IF(s.difficulty=0, POW(2, (" . $this->config['difficulty'] . " - 16)), s.difficulty)), 0) AS shares
|
||||
FROM " . $this->share->getTableName() . " AS s
|
||||
LEFT JOIN " . $this->user->getTableName() . " AS a
|
||||
ON SUBSTRING_INDEX( s.username, '.', 1 ) = a.username
|
||||
@ -655,78 +698,24 @@ class Statistics extends Base {
|
||||
* @param $account_id int account id
|
||||
* @return data array NOT FINISHED YET
|
||||
**/
|
||||
public function getHourlyHashrateByAccount($username, $account_id=NULL) {
|
||||
public function getHourlyMiningStatsByAccount($account_id, $format='array', $days = 1) {
|
||||
$this->debug->append("STA " . __METHOD__, 4);
|
||||
if ($data = $this->memcache->get(__FUNCTION__ . $account_id)) return $data;
|
||||
$stmt = $this->mysqli->prepare("
|
||||
SELECT
|
||||
id,
|
||||
IFNULL(SUM(IF(difficulty=0, pow(2, (" . $this->config['difficulty'] . " - 16)), difficulty)), 0) AS shares,
|
||||
HOUR(time) AS hour
|
||||
FROM " . $this->share->getTableName() . "
|
||||
WHERE time <= FROM_UNIXTIME(FLOOR(UNIX_TIMESTAMP(NOW())/(60*60))*(60*60))
|
||||
AND time >= FROM_UNIXTIME(FLOOR(UNIX_TIMESTAMP(NOW())/(60*60))*(60*60)) - INTERVAL 24 HOUR
|
||||
AND our_result = 'Y'
|
||||
AND username LIKE ?
|
||||
GROUP BY HOUR(time)
|
||||
UNION
|
||||
SELECT
|
||||
share_id,
|
||||
IFNULL(SUM(IF(difficulty=0, pow(2, (" . $this->config['difficulty'] . " - 16)), difficulty)), 0) AS shares,
|
||||
HOUR(time) AS hour
|
||||
FROM " . $this->share->getArchiveTableName() . "
|
||||
WHERE time <= FROM_UNIXTIME(FLOOR(UNIX_TIMESTAMP(NOW())/(60*60))*(60*60))
|
||||
AND time >= FROM_UNIXTIME(FLOOR(UNIX_TIMESTAMP(NOW())/(60*60))*(60*60)) - INTERVAL 24 HOUR
|
||||
AND our_result = 'Y'
|
||||
AND username LIKE ?
|
||||
GROUP BY HOUR(time)");
|
||||
$username = $username . ".%";
|
||||
if ($this->checkStmt($stmt) && $stmt->bind_param('ss', $username, $username) && $stmt->execute() && $result = $stmt->get_result()) {
|
||||
$iStartHour = date('G');
|
||||
// Initilize array
|
||||
for ($i = 0; $i < 24; $i++) $aData[($iStartHour + $i) % 24] = 0;
|
||||
// Fill data
|
||||
while ($row = $result->fetch_assoc()) $aData[$row['hour']] += (int) $this->coin->calcHashrate($row['shares'], 3600);
|
||||
return $this->memcache->setCache(__FUNCTION__ . $account_id, $aData);
|
||||
}
|
||||
return $this->sqlError();
|
||||
}
|
||||
|
||||
/**
|
||||
* get Hourly hashrate for the pool
|
||||
* @param none
|
||||
* @return data array NOT FINISHED YET
|
||||
**/
|
||||
public function getHourlyHashrateByPool() {
|
||||
$this->debug->append("STA " . __METHOD__, 4);
|
||||
if ($this->getGetCache() && $data = $this->memcache->get(__FUNCTION__)) return $data;
|
||||
$stmt = $this->mysqli->prepare("
|
||||
SELECT
|
||||
id,
|
||||
IFNULL(SUM(IF(s.difficulty=0, pow(2, (" . $this->config['difficulty'] . " - 16)), s.difficulty)), 0) AS shares,
|
||||
HOUR(s.time) AS hour
|
||||
FROM " . $this->share->getTableName() . " AS s
|
||||
WHERE time <= FROM_UNIXTIME(FLOOR(UNIX_TIMESTAMP(NOW())/(60*60))*(60*60))
|
||||
AND time >= FROM_UNIXTIME(FLOOR(UNIX_TIMESTAMP(NOW())/(60*60))*(60*60)) - INTERVAL 24 HOUR
|
||||
AND our_result = 'Y'
|
||||
GROUP BY HOUR(time)
|
||||
UNION
|
||||
SELECT
|
||||
share_id,
|
||||
IFNULL(SUM(IF(s.difficulty=0, pow(2, (" . $this->config['difficulty'] . " - 16)), s.difficulty)), 0) AS shares,
|
||||
HOUR(s.time) AS hour
|
||||
FROM " . $this->share->getArchiveTableName() . " AS s
|
||||
WHERE time <= FROM_UNIXTIME(FLOOR(UNIX_TIMESTAMP(NOW())/(60*60))*(60*60))
|
||||
AND time >= FROM_UNIXTIME(FLOOR(UNIX_TIMESTAMP(NOW())/(60*60))*(60*60)) - INTERVAL 24 HOUR
|
||||
AND our_result = 'Y'
|
||||
GROUP BY HOUR(time)");
|
||||
if ($this->checkStmt($stmt) && $stmt->execute() && $result = $stmt->get_result()) {
|
||||
$iStartHour = date('G');
|
||||
// Initilize array
|
||||
for ($i = 0; $i < 24; $i++) $aData[($iStartHour + $i) % 24] = 0;
|
||||
// Fill data
|
||||
while ($row = $result->fetch_assoc()) $aData[$row['hour']] += (int) $this->coin->calcHashrate($row['shares'], 3600);
|
||||
return $this->memcache->setCache(__FUNCTION__, $aData);
|
||||
timestamp,
|
||||
FROM_UNIXTIME(timestamp, '%Y-%m-%d %H:%i') AS time,
|
||||
AVG(hashrate) AS hashrate,
|
||||
AVG(workers) AS workers,
|
||||
AVG(sharerate) AS sharerate
|
||||
FROM " . $this->getUserStatsTableName() . "
|
||||
WHERE FROM_UNIXTIME(timestamp) >= DATE_SUB(NOW(), INTERVAL $days DAY)
|
||||
AND account_id = ?
|
||||
GROUP BY DAY(FROM_UNIXTIME(timestamp)), HOUR(FROM_UNIXTIME(timestamp))");
|
||||
if ($this->checkStmt($stmt) && $stmt->bind_param('i', $account_id) && $stmt->execute() && $result = $stmt->get_result()) {
|
||||
$aData = $result->fetch_all(MYSQLI_ASSOC);
|
||||
if ($format == 'json') $aData = json_encode($aData);
|
||||
return $this->memcache->setCache(__FUNCTION__ . $account_id . $format, $aData);
|
||||
}
|
||||
return $this->sqlError();
|
||||
}
|
||||
@ -744,7 +733,7 @@ class Statistics extends Base {
|
||||
if ($this->config['payout_system'] != 'pps') {
|
||||
if (@$value1['valid'] > 0 && @$value2['valid'] > 0) {
|
||||
$this->config['reward_type'] == 'fixed' ? $reward = $this->config['reward'] : $reward = $this->block->getAverageAmount();
|
||||
$aEstimates['block'] = round(( (int)$value2['valid'] / (int)$value1['valid'] ) * (float)$reward, 8);
|
||||
$aEstimates['block'] = round(( (float)$value2['valid'] / (float)$value1['valid'] ) * (float)$reward, 8);
|
||||
$bNoFees == 0 ? $aEstimates['fee'] = round(((float)$this->config['fees'] / 100) * (float)$aEstimates['block'], 8) : $aEstimates['fee'] = 0;
|
||||
$aEstimates['donation'] = round((( (float)$dDonate / 100) * ((float)$aEstimates['block'] - (float)$aEstimates['fee'])), 8);
|
||||
$aEstimates['payout'] = round((float)$aEstimates['block'] - (float)$aEstimates['donation'] - (float)$aEstimates['fee'], 8);
|
||||
@ -789,7 +778,7 @@ class Statistics extends Base {
|
||||
SELECT
|
||||
IFNULL(COUNT(id), 0) as count,
|
||||
IFNULL(AVG(difficulty), 0) as average,
|
||||
IFNULL(ROUND(SUM(shares)), 0) as shares,
|
||||
IFNULL(SUM(shares), 0) as shares,
|
||||
IFNULL(SUM(amount), 0) as rewards
|
||||
FROM " . $this->block->getTableName() . "
|
||||
WHERE FROM_UNIXTIME(time) > DATE_SUB(now(), INTERVAL ? HOUR)
|
||||
@ -914,6 +903,17 @@ class Statistics extends Base {
|
||||
return $this->memcache->setCache(__FUNCTION__, $result->fetch_object()->total);
|
||||
return $this->sqlError();
|
||||
}
|
||||
|
||||
/**
|
||||
* Purge older entries from our statistics_users table
|
||||
**/
|
||||
public function purgeUserStats($days = 1) {
|
||||
// Fallbacks if unset
|
||||
$stmt = $this->mysqli->prepare("DELETE FROM " . $this->getUserStatsTableName() . " WHERE FROM_UNIXTIME(timestamp) <= DATE_SUB(NOW(), INTERVAL ? DAY)");
|
||||
if ($this->checkStmt($stmt) && $stmt->bind_param('i', $days) && $stmt->execute())
|
||||
return $stmt->affected_rows;
|
||||
return $this->sqlError();
|
||||
}
|
||||
}
|
||||
|
||||
$statistics = new Statistics();
|
||||
|
||||
@ -81,6 +81,8 @@ class Tools extends Base {
|
||||
return 'cryptorush';
|
||||
} else if (preg_match('/mintpal.com/', $url)) {
|
||||
return 'mintpal';
|
||||
} else if (preg_match('/bittrex.com/', $url)) {
|
||||
return 'bittrex';
|
||||
}
|
||||
$this->setErrorMessage("API URL unknown");
|
||||
return false;
|
||||
@ -116,6 +118,9 @@ class Tools extends Base {
|
||||
case 'mintpal':
|
||||
return @$aData['0']['last_price'];
|
||||
break;
|
||||
case 'bittrex':
|
||||
return @$aData['result']['Last'];
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
$this->setErrorMessage("Got an invalid response from ticker API");
|
||||
|
||||
@ -355,7 +355,7 @@ class Transaction extends Base {
|
||||
a.id,
|
||||
a.username,
|
||||
a.ap_threshold,
|
||||
a.coin_address,
|
||||
ca.coin_address,
|
||||
IFNULL(
|
||||
ROUND(
|
||||
(
|
||||
@ -370,11 +370,13 @@ class Transaction extends Base {
|
||||
ON t.block_id = b.id
|
||||
LEFT JOIN " . $this->user->getTableName() . " AS a
|
||||
ON t.account_id = a.id
|
||||
WHERE t.archived = 0 AND a.ap_threshold > 0 AND a.coin_address IS NOT NULL AND a.coin_address != ''
|
||||
LEFT JOIN " . $this->coin_address->getTableName() . " AS ca
|
||||
ON ca.account_id = a.id
|
||||
WHERE t.archived = 0 AND a.ap_threshold > 0 AND ca.coin_address IS NOT NULL AND ca.coin_address != '' AND ca.currency = ?
|
||||
GROUP BY t.account_id
|
||||
HAVING confirmed > a.ap_threshold AND confirmed > " . $this->config['txfee_auto'] . "
|
||||
LIMIT ?");
|
||||
if ($this->checkStmt($stmt) && $stmt->bind_param('i', $limit) && $stmt->execute() && $result = $stmt->get_result())
|
||||
if ($this->checkStmt($stmt) && $stmt->bind_param('si', $this->config['currency'], $limit) && $stmt->execute() && $result = $stmt->get_result())
|
||||
return $result->fetch_all(MYSQLI_ASSOC);
|
||||
return $this->sqlError();
|
||||
}
|
||||
@ -446,7 +448,7 @@ class Transaction extends Base {
|
||||
a.id,
|
||||
a.username,
|
||||
a.ap_threshold,
|
||||
a.coin_address,
|
||||
ca.coin_address,
|
||||
p.id AS payout_id,
|
||||
IFNULL(
|
||||
ROUND(
|
||||
@ -464,11 +466,13 @@ class Transaction extends Base {
|
||||
ON t.account_id = p.account_id
|
||||
LEFT JOIN " . $this->block->getTableName() . " AS b
|
||||
ON t.block_id = b.id
|
||||
WHERE p.completed = 0 AND t.archived = 0 AND a.coin_address IS NOT NULL AND a.coin_address != ''
|
||||
LEFT JOIN " . $this->coin_address->getTableName() . " AS ca
|
||||
ON ca.account_id = a.id
|
||||
WHERE p.completed = 0 AND t.archived = 0 AND ca.currency = ? AND ca.coin_address IS NOT NULL AND ca.coin_address != ''
|
||||
GROUP BY t.account_id
|
||||
HAVING confirmed > " . $this->config['txfee_manual'] . "
|
||||
LIMIT ?");
|
||||
if ($this->checkStmt($stmt) && $stmt->bind_param('i', $limit) && $stmt->execute() && $result = $stmt->get_result())
|
||||
if ($this->checkStmt($stmt) && $stmt->bind_param('si', $this->config['currency'], $limit) && $stmt->execute() && $result = $stmt->get_result())
|
||||
return $result->fetch_all(MYSQLI_ASSOC);
|
||||
return $this->sqlError('E0050');
|
||||
}
|
||||
@ -478,6 +482,7 @@ $transaction = new Transaction();
|
||||
$transaction->setMemcache($memcache);
|
||||
$transaction->setNotification($notification);
|
||||
$transaction->setDebug($debug);
|
||||
$transaction->setCoinAddress($coin_address);
|
||||
$transaction->setMysql($mysqli);
|
||||
$transaction->setConfig($config);
|
||||
$transaction->setBlock($block);
|
||||
|
||||
@ -163,7 +163,7 @@ class User extends Base {
|
||||
$invitation->setDebug($this->debug);
|
||||
$invitation->setLog($this->log);
|
||||
$stmt = $this->mysqli->prepare("
|
||||
SELECT COUNT(i.account_id) AS invitationcount,a.id,a.username,a.email,
|
||||
SELECT COUNT(i.account_id) AS invitationcount,a.id,a.username,a.email,
|
||||
(SELECT COUNT(account_id) FROM " . $invitation->getTableName() . " WHERE account_id = i.account_id AND is_activated = 1 GROUP BY account_id) AS activated
|
||||
FROM " . $invitation->getTableName() . " AS i
|
||||
LEFT JOIN " . $this->getTableName() . " AS a
|
||||
@ -340,38 +340,20 @@ class User extends Base {
|
||||
$this->debug->append("STA " . __METHOD__, 4);
|
||||
$stmt = $this->mysqli->prepare("
|
||||
SELECT
|
||||
id, username, coin_address, ap_threshold
|
||||
FROM " . $this->getTableName() . "
|
||||
WHERE ap_threshold > 0
|
||||
AND coin_address IS NOT NULL
|
||||
a.id, a.username, ca.coin_address AS coin_address, a.ap_threshold
|
||||
FROM " . $this->getTableName() . " AS a
|
||||
LEFT JOIN " . $this->coin_address->getTableName() . " AS ca
|
||||
ON a.id = ca.account_id
|
||||
WHERE ap_threshold > 0 AND ca.currency = ?
|
||||
AND ca.coin_address IS NOT NULL
|
||||
");
|
||||
if ( $this->checkStmt($stmt) && $stmt->execute() && $result = $stmt->get_result()) {
|
||||
if ( $this->checkStmt($stmt) && $stmt->bind_param('s', $this->config['currency']) && $stmt->execute() && $result = $stmt->get_result()) {
|
||||
return $result->fetch_all(MYSQLI_ASSOC);
|
||||
}
|
||||
$this->debug->append("Unable to fetch users with AP set");
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetch users coin address
|
||||
* @param userID int UserID
|
||||
* @return data string Coin Address
|
||||
**/
|
||||
public function getCoinAddress($userID) {
|
||||
$this->debug->append("STA " . __METHOD__, 4);
|
||||
return $this->getSingle($userID, 'coin_address', 'id');
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if a coin address exists already
|
||||
* @param address string Coin Address
|
||||
* @return bool True of false
|
||||
**/
|
||||
public function existsCoinAddress($address) {
|
||||
$this->debug->append("STA " . __METHOD__, 4);
|
||||
return $this->getSingle($address, 'coin_address', 'coin_address', 's') === $address;
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetch users donation value
|
||||
* @param userID int UserID
|
||||
@ -514,12 +496,12 @@ class User extends Base {
|
||||
$this->setErrorMessage('Donation above allowed 100% limit');
|
||||
return false;
|
||||
}
|
||||
if (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
|
||||
if ($email != 'hidden' && $email != NULL && !filter_var($email, FILTER_VALIDATE_EMAIL)) {
|
||||
$this->setErrorMessage('Invalid email address');
|
||||
return false;
|
||||
}
|
||||
if (!empty($address)) {
|
||||
if ($address != $this->getCoinAddress($userID) && $this->existsCoinAddress($address)) {
|
||||
if ($address != $this->coin_address->getCoinAddress($userID) && $this->coin_address->existsCoinAddress($address)) {
|
||||
$this->setErrorMessage('Address is already in use');
|
||||
return false;
|
||||
}
|
||||
@ -558,11 +540,23 @@ class User extends Base {
|
||||
}
|
||||
}
|
||||
|
||||
// If we hide our email or it's not set, fetch current one to update
|
||||
if ($email == 'hidden' || $email == NULL)
|
||||
$email = $this->getUserEmailById($userID);
|
||||
// We passed all validation checks so update the account
|
||||
$stmt = $this->mysqli->prepare("UPDATE $this->table SET coin_address = ?, ap_threshold = ?, donate_percent = ?, email = ?, timezone = ?, is_anonymous = ? WHERE id = ?");
|
||||
if ($this->checkStmt($stmt) && $stmt->bind_param('sddssii', $address, $threshold, $donate, $email, $timezone, $is_anonymous, $userID) && $stmt->execute()) {
|
||||
$stmt = $this->mysqli->prepare("UPDATE $this->table SET ap_threshold = ?, donate_percent = ?, email = ?, timezone = ?, is_anonymous = ? WHERE id = ?");
|
||||
if ($this->checkStmt($stmt) && $stmt->bind_param('ddssii', $threshold, $donate, $email, $timezone, $is_anonymous, $userID) && $stmt->execute()) {
|
||||
$this->log->log("info", $this->getUserName($userID)." updated their account details");
|
||||
return true;
|
||||
// Update coin address too
|
||||
if ($address) {
|
||||
if ($this->coin_address->update($userID, $address)) {
|
||||
return true;
|
||||
}
|
||||
} else {
|
||||
if ($this->coin_address->remove($userID, $address)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
// Catchall
|
||||
$this->setErrorMessage('Failed to update your account');
|
||||
@ -703,22 +697,18 @@ class User extends Base {
|
||||
$this->debug->append("Fetching user information for user id: $userID");
|
||||
$stmt = $this->mysqli->prepare("
|
||||
SELECT
|
||||
id, username, pin, api_key, is_admin, is_anonymous, email, timezone, no_fees,
|
||||
IFNULL(donate_percent, '0') as donate_percent, coin_address, ap_threshold
|
||||
FROM $this->table
|
||||
id AS id, username, pin, api_key, is_admin, is_anonymous, email, timezone, no_fees,
|
||||
IFNULL(donate_percent, '0') as donate_percent, ap_threshold
|
||||
FROM " . $this->getTableName() . "
|
||||
WHERE id = ? LIMIT 0,1");
|
||||
if ($this->checkStmt($stmt)) {
|
||||
$stmt->bind_param('i', $userID);
|
||||
if (!$stmt->execute()) {
|
||||
$this->debug->append('Failed to execute statement');
|
||||
return false;
|
||||
}
|
||||
$result = $stmt->get_result();
|
||||
if ($this->checkStmt($stmt) && $stmt->bind_param('i', $userID) && $stmt->execute() && $result = $stmt->get_result()) {
|
||||
$aData = $result->fetch_assoc();
|
||||
$aData['coin_address'] = $this->coin_address->getCoinAddress($userID);
|
||||
$stmt->close();
|
||||
return $result->fetch_assoc();
|
||||
return $aData;
|
||||
}
|
||||
$this->debug->append("Failed to fetch user information for $userID");
|
||||
return false;
|
||||
return $this->sqlError();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -742,6 +732,10 @@ class User extends Base {
|
||||
return false;
|
||||
}
|
||||
if (!is_null($coinaddress)) {
|
||||
if ($this->coin_address->existsCoinAddress($coinaddress)) {
|
||||
$this->setErrorMessage('Coin address is already taken');
|
||||
return false;
|
||||
}
|
||||
if (!$this->bitcoin->validateaddress($coinaddress)) {
|
||||
$this->setErrorMessage('Coin address is not valid');
|
||||
return false;
|
||||
@ -755,7 +749,7 @@ class User extends Base {
|
||||
$this->setErrorMessage( 'This e-mail address is already taken' );
|
||||
return false;
|
||||
}
|
||||
if (strlen($password1) < 8) {
|
||||
if (strlen($password1) < 8) {
|
||||
$this->setErrorMessage( 'Password is too short, minimum of 8 characters required' );
|
||||
return false;
|
||||
}
|
||||
@ -801,15 +795,15 @@ class User extends Base {
|
||||
! $this->setting->getValue('accounts_confirm_email_disabled') ? $is_locked = 1 : $is_locked = 0;
|
||||
$is_admin = 0;
|
||||
$stmt = $this->mysqli->prepare("
|
||||
INSERT INTO $this->table (username, pass, email, signup_timestamp, pin, api_key, is_locked, coin_address)
|
||||
VALUES (?, ?, ?, ?, ?, ?, ?, ?)
|
||||
INSERT INTO $this->table (username, pass, email, signup_timestamp, pin, api_key, is_locked)
|
||||
VALUES (?, ?, ?, ?, ?, ?, ?)
|
||||
");
|
||||
} else {
|
||||
$is_locked = 0;
|
||||
$is_admin = 1;
|
||||
$stmt = $this->mysqli->prepare("
|
||||
INSERT INTO $this->table (username, pass, email, signup_timestamp, pin, api_key, is_admin, is_locked, coin_address)
|
||||
VALUES (?, ?, ?, ?, ?, ?, 1, ?, ?)
|
||||
INSERT INTO $this->table (username, pass, email, signup_timestamp, pin, api_key, is_admin, is_locked)
|
||||
VALUES (?, ?, ?, ?, ?, ?, 1, ?)
|
||||
");
|
||||
}
|
||||
|
||||
@ -820,7 +814,9 @@ class User extends Base {
|
||||
$username_clean = strip_tags($username);
|
||||
$signup_time = time();
|
||||
|
||||
if ($this->checkStmt($stmt) && $stmt->bind_param('sssissis', $username_clean, $password_hash, $email1, $signup_time, $pin_hash, $apikey_hash, $is_locked, $coinaddress) && $stmt->execute()) {
|
||||
if ($this->checkStmt($stmt) && $stmt->bind_param('sssissi', $username_clean, $password_hash, $email1, $signup_time, $pin_hash, $apikey_hash, $is_locked) && $stmt->execute()) {
|
||||
$new_account_id = $this->mysqli->insert_id;
|
||||
if (!is_null($coinaddress)) $this->coin_address->add($new_account_id, $coinaddress);
|
||||
if (! $this->setting->getValue('accounts_confirm_email_disabled') && $is_admin != 1) {
|
||||
if ($token = $this->token->createToken('confirm_email', $stmt->insert_id)) {
|
||||
$aData['username'] = $username_clean;
|
||||
@ -843,7 +839,8 @@ class User extends Base {
|
||||
} else {
|
||||
$this->setErrorMessage( 'Unable to register' );
|
||||
$this->debug->append('Failed to insert user into DB: ' . $this->mysqli->error);
|
||||
if ($stmt->sqlstate == '23000') $this->setErrorMessage( 'Username, email or Coinaddress already registered' );
|
||||
echo $this->mysqli->error;
|
||||
if ($stmt->sqlstate == '23000') $this->setErrorMessage( 'Username or email already registered' );
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
@ -997,4 +994,5 @@ $user->setMail($mail);
|
||||
$user->setToken($oToken);
|
||||
$user->setBitcoin($bitcoin);
|
||||
$user->setSetting($setting);
|
||||
$user->setCoinAddress($coin_address);
|
||||
$user->setErrorCodes($aErrorCodes);
|
||||
|
||||
@ -160,6 +160,13 @@ $aSettings['statistics'][] = array(
|
||||
'name' => 'statistics_ajax_data_interval', 'value' => $setting->getValue('statistics_ajax_data_interval'),
|
||||
'tooltip' => 'Time in minutes, interval for hashrate and sharerate calculations. Higher intervals allow for better accuracy at a higer server load.'
|
||||
);
|
||||
$aSettings['statistics'][] = array(
|
||||
'display' => 'Graphing Days', 'type' => 'text',
|
||||
'size' => 25,
|
||||
'default' => 1,
|
||||
'name' => 'statistics_graphing_days', 'value' => $setting->getValue('statistics_graphing_days'),
|
||||
'tooltip' => 'How many days to graph out on the statistics -> graphs page.'
|
||||
);
|
||||
$aSettings['statistics'][] = array(
|
||||
'display' => 'Block Statistics Count', 'type' => 'text',
|
||||
'size' => 25,
|
||||
|
||||
@ -3,15 +3,13 @@
|
||||
// Small helper array that may be used on some page controllers to
|
||||
// fetch the crons we wish to monitor
|
||||
switch ($config['payout_system']) {
|
||||
case 'pplns':
|
||||
$sPayoutSystem = $config['payout_system'] . '_payout';
|
||||
break;
|
||||
case 'pps':
|
||||
$sPayoutSystem = $config['payout_system'] . '_payout';
|
||||
break;
|
||||
case 'prop':
|
||||
$sPayoutSystem = 'proportional_payout';
|
||||
break;
|
||||
default: // pps && pplns land here
|
||||
$sPayoutSystem = $config['payout_system'] . '_payout';
|
||||
}
|
||||
|
||||
$aMonitorCrons = array('statistics','tickerupdate','notifications','tables_cleanup','findblock',$sPayoutSystem,'blockupdate','payouts');
|
||||
|
||||
?>
|
||||
|
||||
@ -108,7 +108,10 @@ class jsonRPCClient {
|
||||
curl_setopt($ch, CURLOPT_USERPWD, $url['user'] . ":" . $url['pass']);
|
||||
curl_setopt($ch, CURLOPT_POST, true);
|
||||
curl_setopt($ch, CURLOPT_POSTFIELDS, $request);
|
||||
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
|
||||
// curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
|
||||
$response = curl_exec($ch);
|
||||
if (curl_errno($ch)) throw new Exception('RPC call failed: ' . curl_error($ch));
|
||||
if ($this->debug) $this->debug_output[] = 'Response: ' . $response;
|
||||
$response = json_decode($response, true);
|
||||
$resultStatus = curl_getinfo($ch);
|
||||
@ -116,7 +119,6 @@ class jsonRPCClient {
|
||||
if ($resultStatus['http_code'] == '401') throw new Exception('RPC call did not return 200: Authentication failed');
|
||||
throw new Exception('RPC call did not return 200: HTTP error: ' . $resultStatus['http_code'] . ' - JSON Response: [' . @$response['error']['code'] . '] ' . @$response['error']['message']);
|
||||
}
|
||||
if (curl_errno($ch)) throw new Exception('RPC call failed: ' . curl_error($ch));
|
||||
curl_close($ch);
|
||||
|
||||
// final checks and return
|
||||
|
||||
@ -104,7 +104,7 @@ if ($user->isAuthenticated()) {
|
||||
$_SESSION['POPUP'][] = array('CONTENT' => 'You have not yet unlocked account withdrawls.', 'TYPE' => 'alert alert-danger');
|
||||
} else if ($aBalance['confirmed'] < $config['mp_threshold']) {
|
||||
$_SESSION['POPUP'][] = array('CONTENT' => 'Payout must be greater or equal than ' . $config['mp_threshold'] . '.', 'TYPE' => 'info');
|
||||
} else if (!$user->getCoinAddress($_SESSION['USERDATA']['id'])) {
|
||||
} else if (!$coin_address->getCoinAddress($_SESSION['USERDATA']['id'])) {
|
||||
$_SESSION['POPUP'][] = array('CONTENT' => 'You have no payout address set.', 'TYPE' => 'alert alert-danger');
|
||||
} else {
|
||||
$user->log->log("info", $_SESSION['USERDATA']['username']." requesting manual payout");
|
||||
|
||||
@ -4,12 +4,10 @@ $defflip = (!cfip()) ? exit(header('HTTP/1.1 401 Unauthorized')) : 1;
|
||||
if ($user->isAuthenticated()) {
|
||||
|
||||
|
||||
if (!$user->getCoinAddress($_SESSION['USERDATA']['id']) AND $setting->getValue('disable_worker_edit')) {
|
||||
|
||||
if (!$coin_address->getCoinAddress($_SESSION['USERDATA']['id']) AND $setting->getValue('disable_worker_edit')) {
|
||||
$_SESSION['POPUP'][] = array('CONTENT' => 'You have no payout address set.', 'TYPE' => 'alert alert-danger');
|
||||
$_SESSION['POPUP'][] = array('CONTENT' => 'You can not add workers unless a valid Payout Address is set in your User Settings.', 'TYPE' => 'alert alert-danger');
|
||||
$smarty->assign('CONTENT', 'disabled.tpl');
|
||||
|
||||
} else {
|
||||
switch (@$_REQUEST['do']) {
|
||||
case 'delete':
|
||||
|
||||
@ -20,7 +20,7 @@ if ($setting->getValue('notifications_disable_pool_newsletter', 0) == 1) {
|
||||
$iSuccess = 0;
|
||||
foreach ($user->getAllAssoc() as $aData) {
|
||||
$aUserNotificationSettings = $notification->getNotificationSettings($aData['id']);
|
||||
if ($aData['is_locked'] != 0 || $aUserNotificationSettings['newsletter'] != 1) continue;
|
||||
if ($aData['is_locked'] != 0 || $aUserNotificationSettings['newsletter'] != 1 || empty($aData['email'])) continue;
|
||||
$aData['subject'] = $_REQUEST['data']['subject'];
|
||||
$aData['CONTENT'] = $_REQUEST['data']['content'];
|
||||
if (!$mail->sendMail('newsletter/body', $aData, true)) {
|
||||
|
||||
@ -5,7 +5,7 @@ $defflip = (!cfip()) ? exit(header('HTTP/1.1 401 Unauthorized')) : 1;
|
||||
$api->isActive();
|
||||
|
||||
// Check for valid API key
|
||||
$id = $user->checkApiKey($_REQUEST['api_key']);
|
||||
$id = $user->checkApiKey(@$_REQUEST['api_key']);
|
||||
|
||||
header('HTTP/1.1 400 Bad Request');
|
||||
die('400 Bad Request');
|
||||
|
||||
@ -19,7 +19,9 @@ echo json_encode(
|
||||
'workers' => $worker->getCountAllActiveWorkers(),
|
||||
'shares_this_round' => $aShares['valid'],
|
||||
'last_block' => $aLastBlock['height'],
|
||||
'network_hashrate' => $dNetworkHashrate
|
||||
'network_hashrate' => $dNetworkHashrate,
|
||||
'fee' => $config['fees'],
|
||||
'payout' => $config['payout_system']
|
||||
)
|
||||
);
|
||||
|
||||
|
||||
@ -52,6 +52,7 @@ if ($user->isAuthenticated()) {
|
||||
$smarty->assign('BLOCKSFOUND', $aLastBlocks);
|
||||
$smarty->assign('DISABLED_DASHBOARD', $setting->getValue('disable_dashboard'));
|
||||
$smarty->assign('DISABLED_DASHBOARD_API', $setting->getValue('disable_dashboard_api'));
|
||||
$smarty->assign('DISABLED_API', $setting->getValue('disable_api'));
|
||||
$smarty->assign('ESTIMATES', array('shares' => $iEstShares, 'percent' => $dEstPercent));
|
||||
$smarty->assign('NETWORK', array('difficulty' => $dDifficulty, 'block' => $iBlock, 'EstNextDifficulty' => $dEstNextDifficulty, 'EstTimePerBlock' => $dExpectedTimePerBlock, 'BlocksUntilDiffChange' => $iBlocksUntilDiffChange));
|
||||
$smarty->assign('INTERVAL', $interval / 60);
|
||||
|
||||
@ -18,28 +18,30 @@ if ($setting->getValue('recaptcha_enabled') && $setting->getValue('recaptcha_ena
|
||||
}
|
||||
}
|
||||
|
||||
if ($setting->getValue('maintenance') && !$user->isAdmin($user->getUserIdByEmail($_POST['username']))) {
|
||||
$_SESSION['POPUP'][] = array('CONTENT' => 'You are not allowed to login during maintenace.', 'TYPE' => 'info');
|
||||
} else if (!empty($_POST['username']) && !empty($_POST['password'])) {
|
||||
// Check if recaptcha is enabled, process form data if valid
|
||||
if (!$setting->getValue('recaptcha_enabled') || !$setting->getValue('recaptcha_enabled_logins') || ($setting->getValue('recaptcha_enabled') && $setting->getValue('recaptcha_enabled_logins') && $rsp->is_valid)) {
|
||||
if (!$config['csrf']['enabled'] || $config['csrf']['enabled'] && $csrftoken->valid) {
|
||||
// check if login is correct
|
||||
if ($user->checkLogin(@$_POST['username'], @$_POST['password']) ) {
|
||||
$port = ($_SERVER["SERVER_PORT"] == "80" || $_SERVER["SERVER_PORT"] == "443") ? "" : (":".$_SERVER["SERVER_PORT"]);
|
||||
$location = (@$_SERVER['HTTPS'] == "on") ? 'https://' : 'http://';
|
||||
$location .= $_SERVER['SERVER_NAME'] . $port . $_SERVER['SCRIPT_NAME'];
|
||||
$location.= '?page=dashboard';
|
||||
if (!headers_sent()) header('Location: ' . $location);
|
||||
exit('<meta http-equiv="refresh" content="0; url=' . htmlspecialchars($location) . '"/>');
|
||||
if (!empty($_POST['username']) && !empty($_POST['password'])) {
|
||||
if ($setting->getValue('maintenance') && !$user->isAdmin($user->getUserIdByEmail($_POST['username']))) {
|
||||
$_SESSION['POPUP'][] = array('CONTENT' => 'You are not allowed to login during maintenace.', 'TYPE' => 'alert alert-info');
|
||||
} else {
|
||||
// Check if recaptcha is enabled, process form data if valid
|
||||
if (!$setting->getValue('recaptcha_enabled') || !$setting->getValue('recaptcha_enabled_logins') || ($setting->getValue('recaptcha_enabled') && $setting->getValue('recaptcha_enabled_logins') && $rsp->is_valid)) {
|
||||
if (!$config['csrf']['enabled'] || $config['csrf']['enabled'] && $csrftoken->valid) {
|
||||
// check if login is correct
|
||||
if ($user->checkLogin(@$_POST['username'], @$_POST['password']) ) {
|
||||
$port = ($_SERVER["SERVER_PORT"] == "80" || $_SERVER["SERVER_PORT"] == "443") ? "" : (":".$_SERVER["SERVER_PORT"]);
|
||||
$location = (@$_SERVER['HTTPS'] == "on") ? 'https://' : 'http://';
|
||||
$location .= $_SERVER['SERVER_NAME'] . $port . $_SERVER['SCRIPT_NAME'];
|
||||
$location.= '?page=dashboard';
|
||||
if (!headers_sent()) header('Location: ' . $location);
|
||||
exit('<meta http-equiv="refresh" content="0; url=' . htmlspecialchars($location) . '"/>');
|
||||
} else {
|
||||
$_SESSION['POPUP'][] = array('CONTENT' => 'Unable to login: '.$user->getError(), 'TYPE' => 'alert alert-danger');
|
||||
}
|
||||
} else {
|
||||
$_SESSION['POPUP'][] = array('CONTENT' => 'Unable to login: '.$user->getError(), 'TYPE' => 'alert alert-danger');
|
||||
$_SESSION['POPUP'][] = array('CONTENT' => $csrftoken->getErrorWithDescriptionHTML(), 'TYPE' => 'alert alert-warning');
|
||||
}
|
||||
} else {
|
||||
$_SESSION['POPUP'][] = array('CONTENT' => $csrftoken->getErrorWithDescriptionHTML(), 'TYPE' => 'alert alert-warning');
|
||||
$_SESSION['POPUP'][] = array('CONTENT' => 'Invalid Captcha, please try again.', 'TYPE' => 'alert alert-danger');
|
||||
}
|
||||
} else {
|
||||
$_SESSION['POPUP'][] = array('CONTENT' => 'Invalid Captcha, please try again.', 'TYPE' => 'alert alert-danger');
|
||||
}
|
||||
}
|
||||
// Load login template
|
||||
|
||||
@ -4,11 +4,9 @@ $defflip = (!cfip()) ? exit(header('HTTP/1.1 401 Unauthorized')) : 1;
|
||||
if (!$smarty->isCached('master.tpl', $smarty_cache_key)) {
|
||||
$debug->append('No cached version available, fetching from backend', 3);
|
||||
if ($user->isAuthenticated()) {
|
||||
$aHourlyHashRates = $statistics->getHourlyHashrateByAccount($_SESSION['USERDATA']['username'], $_SESSION['USERDATA']['id']);
|
||||
$aPoolHourlyHashRates = $statistics->getHourlyHashrateByPool();
|
||||
$aHourlyMiningStats = $statistics->getHourlyMiningStatsByAccount($_SESSION['USERDATA']['id'], 'json', $setting->getValue('statistics_graphing_days', 1));
|
||||
}
|
||||
$smarty->assign("YOURHASHRATES", @$aHourlyHashRates);
|
||||
$smarty->assign("POOLHASHRATES", @$aPoolHourlyHashRates);
|
||||
$smarty->assign('YOURMININGSTATS', @$aHourlyMiningStats);
|
||||
} else {
|
||||
$debug->append('Using cached page', 3);
|
||||
}
|
||||
|
||||
@ -66,6 +66,7 @@ $aGlobal = array(
|
||||
'coinaddresscheck' => $config['check_valid_coinaddress'],
|
||||
'csrf' => $config['csrf'],
|
||||
'config' => array(
|
||||
'sharediffprecision' => $coin->getShareDifficultyPrecision(),
|
||||
'date' => $setting->getValue('system_date_format', '%m/%d/%Y %H:%M:%S'),
|
||||
'website_design' => $setting->getValue('website_design'),
|
||||
'poolnav_enabled' => $setting->getValue('poolnav_enabled'),
|
||||
|
||||
@ -2,7 +2,7 @@
|
||||
$defflip = (!cfip()) ? exit(header('HTTP/1.1 401 Unauthorized')) : 1;
|
||||
|
||||
define('MPOS_VERSION', '0.0.4');
|
||||
define('DB_VERSION', '0.0.11');
|
||||
define('DB_VERSION', '0.0.14');
|
||||
define('CONFIG_VERSION', '0.0.8');
|
||||
define('HASH_VERSION', 1);
|
||||
|
||||
|
||||
19
scripts/test_email.php
Executable file
19
scripts/test_email.php
Executable file
@ -0,0 +1,19 @@
|
||||
<?php
|
||||
|
||||
// Change to working directory
|
||||
chdir(dirname(__FILE__));
|
||||
|
||||
// Include all settings and classes
|
||||
require_once('shared.inc.php');
|
||||
|
||||
// Send email
|
||||
$aMailData = array(
|
||||
'email' => $setting->getValue('system_error_email'),
|
||||
'subject' => 'Test email from mining pool',
|
||||
'coinname' => $config['gettingstarted']['coinname'],
|
||||
'stratumurl' => $config['gettingstarted']['stratumurl'],
|
||||
'stratumport' => $config['gettingstarted']['stratumport']
|
||||
);
|
||||
|
||||
if (!$mail->sendMail('notifications/test_email', $aMailData))
|
||||
echo "Failed to send test email" . PHP_EOL;
|
||||
@ -42,6 +42,7 @@ echo 'Validating all coin addresses. This may take some time.' . PHP_EOL . PHP_E
|
||||
|
||||
printf($mask, 'Username', 'E-Mail', 'Address', 'Status');
|
||||
foreach ($users as $aData) {
|
||||
$aData['coin_address'] = $coin_address->getCoinAddress($aData['id']);
|
||||
if (empty($aData['coin_address']) && $aData['is_locked'] == 0) {
|
||||
$status = 'UNSET';
|
||||
} else if ($aData['is_locked'] == 1) {
|
||||
|
||||
@ -36,7 +36,6 @@
|
||||
$username = $user['username'];
|
||||
$loggedIp = $user['loggedIp'];
|
||||
$lastLogin = $user['last_login'];
|
||||
$coinAddress = $user['coin_address'];
|
||||
$mailAddress = $user['email'];
|
||||
|
||||
$everLoggedIn = !empty($lastLogin);
|
||||
|
||||
@ -53,6 +53,16 @@ CREATE TABLE IF NOT EXISTS `blocks` (
|
||||
KEY `time` (`time`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='Discovered blocks persisted from Litecoin Service';
|
||||
|
||||
CREATE TABLE IF NOT EXISTS `coin_addresses` (
|
||||
`id` int(11) NOT NULL AUTO_INCREMENT,
|
||||
`account_id` int(11) NOT NULL,
|
||||
`currency` varchar(5) NOT NULL,
|
||||
`coin_address` varchar(255) NOT NULL,
|
||||
PRIMARY KEY (`id`),
|
||||
UNIQUE KEY `coin_address` (`coin_address`),
|
||||
KEY `account_id` (`account_id`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
|
||||
|
||||
CREATE TABLE IF NOT EXISTS `invitations` (
|
||||
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
|
||||
`account_id` int(11) unsigned NOT NULL,
|
||||
@ -134,7 +144,7 @@ CREATE TABLE IF NOT EXISTS `settings` (
|
||||
UNIQUE KEY `setting` (`name`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
|
||||
|
||||
INSERT INTO `settings` (`name`, `value`) VALUES ('DB_VERSION', '0.0.11');
|
||||
INSERT INTO `settings` (`name`, `value`) VALUES ('DB_VERSION', '0.0.13');
|
||||
|
||||
CREATE TABLE IF NOT EXISTS `shares` (
|
||||
`id` bigint(30) NOT NULL AUTO_INCREMENT,
|
||||
@ -229,12 +239,15 @@ CREATE TABLE IF NOT EXISTS `transactions` (
|
||||
KEY `account_id_archived` (`account_id`,`archived`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
|
||||
|
||||
CREATE TABLE IF NOT EXISTS `templates` (
|
||||
`template` varchar(255) NOT NULL,
|
||||
`active` tinyint(1) NOT NULL DEFAULT 0,
|
||||
`content` mediumtext,
|
||||
`modified_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||||
PRIMARY KEY (`template`)
|
||||
CREATE TABLE `statistics_users` (
|
||||
`id` int(11) NOT NULL AUTO_INCREMENT,
|
||||
`account_id` int(11) NOT NULL,
|
||||
`hashrate` int(11) NOT NULL,
|
||||
`workers` int(11) NOT NULL,
|
||||
`sharerate` float NOT NULL,
|
||||
`timestamp` int(11) NOT NULL,
|
||||
PRIMARY KEY (`id`),
|
||||
KEY `account_id_timestamp` (`account_id`,`timestamp`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
|
||||
|
||||
/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
|
||||
|
||||
@ -7,7 +7,7 @@
|
||||
<div class="panel-body">
|
||||
<ul>
|
||||
<li><b><i>Q: When will I get paid?</b></i></li>
|
||||
<b>A:</b> This pool uses the follwing payout system.<br>
|
||||
<b>A:</b> This pool uses the following payout system.<br>
|
||||
{if $GLOBAL.config.payout_system == 'prop'}
|
||||
<br>
|
||||
<b>Proportional (Prop)</b> - The block reward is distributed among miners in proportion to the number of shares they submitted in a round. The expected reward per share depends on the number of shares already submitted in the round.
|
||||
|
||||
@ -28,7 +28,7 @@
|
||||
{/if}
|
||||
<div class="form-group">
|
||||
<label>E-Mail</label>
|
||||
{nocache}<input class="form-control" type="text" name="email" value="{$GLOBAL.userdata.email|escape}" size="20" {if $GLOBAL.twofactor.enabled && $GLOBAL.twofactor.options.details && !$DETAILSUNLOCKED}id="disabledInput" disabled{/if}/>{/nocache}
|
||||
{nocache}<input class="form-control" type="text" name="email" value="hidden" size="20" {if $GLOBAL.twofactor.enabled && $GLOBAL.twofactor.options.details && !$DETAILSUNLOCKED}id="disabledInput" disabled{/if}/>{/nocache}
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label>Timezone</label>
|
||||
|
||||
@ -4,7 +4,7 @@
|
||||
{literal}
|
||||
$(document).ready(function(){
|
||||
$('#qrcodeholder').qrcode({
|
||||
text : "{/literal}|http{if $smarty.server.HTTPS|default:"0" eq 'on'}s{/if}://{$smarty.server.SERVER_NAME}{$smarty.server.SCRIPT_NAME}?page=api|{$GLOBAL.userdata.api_key}|{$GLOBAL.userdata.id}|{$GLOBAL.config.currency|upper}|{literal}",
|
||||
text : "{/literal}|http{if $smarty.server.HTTPS|default:"0" eq 'on'}s{/if}://{$smarty.server.SERVER_NAME}{if $smarty.server.SERVER_PORT != "443" && $smarty.server.SERVER_PORT != "80"}:{$smarty.server.SERVER_PORT}{/if}{$smarty.server.SCRIPT_NAME}?page=api|{$GLOBAL.userdata.api_key}|{$GLOBAL.userdata.id}|{$GLOBAL.config.currency|upper}|{literal}",
|
||||
render : "canvas", // 'canvas' or 'table'. Default value is 'canvas'
|
||||
background : "#ffffff",
|
||||
foreground : "#000000",
|
||||
|
||||
@ -16,7 +16,9 @@
|
||||
{include file="dashboard/overview/default.tpl"}
|
||||
{include file="dashboard/round_statistics/$PAYOUT_SYSTEM/default.tpl"}
|
||||
{include file="dashboard/account_data/default.tpl"}
|
||||
{if !$DISABLED_API}
|
||||
{include file="dashboard/worker_information/default.tpl"}
|
||||
{/if}
|
||||
{include file="dashboard/blocks/default.tpl"}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@ -108,15 +108,15 @@ $(document).ready(function(){
|
||||
$('#b-nethashrate').html('n/a');
|
||||
}
|
||||
$('#b-sharerate').html((parseFloat(data.getdashboarddata.data.personal.sharerate).toFixed(2)));
|
||||
$('#b-yvalid').html(number_format(data.getdashboarddata.data.personal.shares.valid));
|
||||
$('#b-yivalid').html(number_format(data.getdashboarddata.data.personal.shares.invalid));
|
||||
$('#b-yvalid').html(number_format(data.getdashboarddata.data.personal.shares.valid, {/literal}{$GLOBAL.config.sharediffprecision}{literal}));
|
||||
$('#b-yivalid').html(number_format(data.getdashboarddata.data.personal.shares.invalid, {/literal}{$GLOBAL.config.sharediffprecision}{literal}));
|
||||
if ( data.getdashboarddata.data.personal.shares.valid > 0 ) {
|
||||
$('#b-yefficiency').html(number_format(100 - data.getdashboarddata.data.personal.shares.invalid_percent, 2) + "%");
|
||||
} else {
|
||||
$('#b-yefficiency').html(number_format(0, 2) + "%");
|
||||
}
|
||||
$('#b-pvalid').html(number_format(data.getdashboarddata.data.pool.shares.valid));
|
||||
$('#b-pivalid').html(number_format(data.getdashboarddata.data.pool.shares.invalid));
|
||||
$('#b-pvalid').html(number_format(data.getdashboarddata.data.pool.shares.valid, {/literal}{$GLOBAL.config.sharediffprecision}{literal}));
|
||||
$('#b-pivalid').html(number_format(data.getdashboarddata.data.pool.shares.invalid, {/literal}{$GLOBAL.config.sharediffprecision}{literal}));
|
||||
if ( data.getdashboarddata.data.pool.shares.valid > 0 ) {
|
||||
$('#b-pefficiency').html(number_format(100 - data.getdashboarddata.data.pool.shares.invalid_percent, 2) + "%");
|
||||
} else {
|
||||
@ -178,7 +178,7 @@ $(document).ready(function(){
|
||||
return;
|
||||
}
|
||||
if (blocks[0].height > lastBlock) {
|
||||
if(canCreateSoundJS) {
|
||||
if(canCreateSoundJS) {
|
||||
createjs.Sound.play('ding');
|
||||
}
|
||||
lastBlock = blocks[0].height;
|
||||
@ -234,6 +234,7 @@ $(document).ready(function(){
|
||||
});
|
||||
})();
|
||||
|
||||
{/literal}{if !$DISABLED_API}{literal}
|
||||
// Worker process to update active workers in the account details table
|
||||
(function worker2() {
|
||||
$.ajax({
|
||||
@ -250,7 +251,9 @@ $(document).ready(function(){
|
||||
}
|
||||
});
|
||||
})();
|
||||
{/literal}{/if}{literal}
|
||||
|
||||
{/literal}{if !$DISABLED_API}{literal}
|
||||
// Worker process to update user account balances
|
||||
// Our worker process to keep worker information updated
|
||||
(function worker3() {
|
||||
@ -265,7 +268,8 @@ $(document).ready(function(){
|
||||
}
|
||||
});
|
||||
})();
|
||||
|
||||
{/literal}{/if}{literal}
|
||||
|
||||
// Mute Button
|
||||
$('#muteButton').click(function(){
|
||||
if(muteFlag == 2) {
|
||||
@ -280,8 +284,6 @@ $(document).ready(function(){
|
||||
$(this).find($(".fa")).removeClass('fa-volume-up').addClass('fa-volume-off');
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
});
|
||||
{/literal}
|
||||
</script>
|
||||
|
||||
@ -9,12 +9,12 @@
|
||||
<th><h5><i class="fa fa-smile-o fa-fw"></i> Valid</h5></th>
|
||||
<th>
|
||||
<div class="progress progress-striped progress-fix">
|
||||
<div id="b-yvalid" class="progress-bar progress-bar-success black" style="width: 100%" aria-valuemax="100" aria-valuemin="0" aria-valuenow="{$GLOBAL.userdata.shares.valid|number_format}" role="progressbar">{$GLOBAL.userdata.shares.valid|number_format}</div>
|
||||
<div id="b-yvalid" class="progress-bar progress-bar-success black" style="width: 100%" aria-valuemax="100" aria-valuemin="0" aria-valuenow="{$GLOBAL.userdata.shares.valid|number_format}" role="progressbar">{$GLOBAL.userdata.shares.valid|number_format:$GLOBAL.config.sharediffprecision}</div>
|
||||
</div>
|
||||
</th>
|
||||
<th>
|
||||
<div class="progress progress-striped progress-fix">
|
||||
<div id="b-pvalid" class="progress-bar progress-bar-success black" style="width: 100%" aria-valuemax="100" aria-valuemin="0" aria-valuenow="{$GLOBAL.roundshares.valid|number_format}" role="progressbar">{$GLOBAL.roundshares.valid|number_format}</div>
|
||||
<div id="b-pvalid" class="progress-bar progress-bar-success black" style="width: 100%" aria-valuemax="100" aria-valuemin="0" aria-valuenow="{$GLOBAL.roundshares.valid|number_format}" role="progressbar">{$GLOBAL.roundshares.valid|number_format:$GLOBAL.config.sharediffprecision}</div>
|
||||
</div>
|
||||
</th>
|
||||
</tr>
|
||||
@ -22,12 +22,12 @@
|
||||
<th><h5><i class="fa fa-frown-o fa-fw"></i> Invalid</h5></th>
|
||||
<th>
|
||||
<div class="progress progress-striped progress-fix">
|
||||
<div id="b-yivalid" class="progress-bar progress-bar-danger black" style="width: 100%" aria-valuemax="100" aria-valuemin="0" aria-valuenow="{$GLOBAL.userdata.shares.invalid|number_format}" role="progressbar">{$GLOBAL.userdata.shares.invalid|number_format}</div>
|
||||
<div id="b-yivalid" class="progress-bar progress-bar-danger black" style="width: 100%" aria-valuemax="100" aria-valuemin="0" aria-valuenow="{$GLOBAL.userdata.shares.invalid|number_format}" role="progressbar">{$GLOBAL.userdata.shares.invalid|number_format:$GLOBAL.config.sharediffprecision}</div>
|
||||
</div>
|
||||
</th>
|
||||
<th>
|
||||
<div class="progress progress-striped progress-fix">
|
||||
<div id="b-pivalid" class="progress-bar progress-bar-danger black" style="width: 100%" aria-valuemax="100" aria-valuemin="0" aria-valuenow="{$GLOBAL.roundshares.invalid|number_format}" role="progressbar">{$GLOBAL.roundshares.invalid|number_format}</div>
|
||||
<div id="b-pivalid" class="progress-bar progress-bar-danger black" style="width: 100%" aria-valuemax="100" aria-valuemin="0" aria-valuenow="{$GLOBAL.roundshares.invalid|number_format}" role="progressbar">{$GLOBAL.roundshares.invalid|number_format:$GLOBAL.config.sharediffprecision}</div>
|
||||
</div>
|
||||
</th>
|
||||
</tr>
|
||||
|
||||
@ -9,12 +9,12 @@
|
||||
<th><h5><i class="fa fa-smile-o fa-fw"></i> Valid</h6></th>
|
||||
<th>
|
||||
<div class="progress progress-striped progress-fix">
|
||||
<div id="b-yvalid" class="progress-bar progress-bar-success black" style="width: 100%" aria-valuemax="100" aria-valuemin="0" aria-valuenow="{$GLOBAL.userdata.shares.valid|number_format}" role="progressbar">{$GLOBAL.userdata.shares.valid|number_format}</div>
|
||||
<div id="b-yvalid" class="progress-bar progress-bar-success black" style="width: 100%" aria-valuemax="100" aria-valuemin="0" aria-valuenow="{$GLOBAL.userdata.shares.valid|number_format}" role="progressbar">{$GLOBAL.userdata.shares.valid|number_format:$GLOBAL.config.sharediffprecision}</div>
|
||||
</div>
|
||||
</th>
|
||||
<th>
|
||||
<div class="progress progress-striped progress-fix">
|
||||
<div id="b-pvalid" class="progress-bar progress-bar-success black" style="width: 100%" aria-valuemax="100" aria-valuemin="0" aria-valuenow="{$GLOBAL.roundshares.valid|number_format}" role="progressbar">{$GLOBAL.roundshares.valid|number_format}</div>
|
||||
<div id="b-pvalid" class="progress-bar progress-bar-success black" style="width: 100%" aria-valuemax="100" aria-valuemin="0" aria-valuenow="{$GLOBAL.roundshares.valid|number_format}" role="progressbar">{$GLOBAL.roundshares.valid|number_format:$GLOBAL.config.sharediffprecision}</div>
|
||||
</div>
|
||||
</th>
|
||||
</tr>
|
||||
@ -22,12 +22,12 @@
|
||||
<th><h5><i class="fa fa-frown-o fa-fw"></i> Invalid</h6></th>
|
||||
<th>
|
||||
<div class="progress progress-striped progress-fix">
|
||||
<div id="b-yivalid" class="progress-bar progress-bar-danger black" style="width: 100%" aria-valuemax="100" aria-valuemin="0" aria-valuenow="{$GLOBAL.userdata.shares.invalid|number_format}" role="progressbar">{$GLOBAL.userdata.shares.invalid|number_format}</div>
|
||||
<div id="b-yivalid" class="progress-bar progress-bar-danger black" style="width: 100%" aria-valuemax="100" aria-valuemin="0" aria-valuenow="{$GLOBAL.userdata.shares.invalid|number_format}" role="progressbar">{$GLOBAL.userdata.shares.invalid|number_format:$GLOBAL.config.sharediffprecision}</div>
|
||||
</div>
|
||||
</th>
|
||||
<th>
|
||||
<div class="progress progress-striped progress-fix">
|
||||
<div id="b-pivalid" class="progress-bar progress-bar-danger black" style="width: 100%" aria-valuemax="100" aria-valuemin="0" aria-valuenow="{$GLOBAL.roundshares.invalid|number_format}" role="progressbar">{$GLOBAL.roundshares.invalid|number_format}</div>
|
||||
<div id="b-pivalid" class="progress-bar progress-bar-danger black" style="width: 100%" aria-valuemax="100" aria-valuemin="0" aria-valuenow="{$GLOBAL.roundshares.invalid|number_format}" role="progressbar">{$GLOBAL.roundshares.invalid|number_format:$GLOBAL.config.sharediffprecision}</div>
|
||||
</div>
|
||||
</th>
|
||||
</tr>
|
||||
|
||||
@ -9,12 +9,12 @@
|
||||
<th><h5><i class="fa fa-smile-o fa-fw"></i> Valid</h5></th>
|
||||
<th>
|
||||
<div class="progress progress-striped progress-fix">
|
||||
<div id="b-yvalid" class="progress-bar progress-bar-success black" style="width: 100%" aria-valuemax="100" aria-valuemin="0" aria-valuenow="{$GLOBAL.userdata.shares.valid|number_format}" role="progressbar">{$GLOBAL.userdata.shares.valid|number_format}</div>
|
||||
<div id="b-yvalid" class="progress-bar progress-bar-success black" style="width: 100%" aria-valuemax="100" aria-valuemin="0" aria-valuenow="{$GLOBAL.userdata.shares.valid|number_format}" role="progressbar">{$GLOBAL.userdata.shares.valid|number_format:$GLOBAL.config.sharediffprecision}</div>
|
||||
</div>
|
||||
</th>
|
||||
<th>
|
||||
<div class="progress progress-striped progress-fix">
|
||||
<div id="b-pvalid" class="progress-bar progress-bar-success black" style="width: 100%" aria-valuemax="100" aria-valuemin="0" aria-valuenow="{$GLOBAL.roundshares.valid|number_format}" role="progressbar">{$GLOBAL.roundshares.valid|number_format}</div>
|
||||
<div id="b-pvalid" class="progress-bar progress-bar-success black" style="width: 100%" aria-valuemax="100" aria-valuemin="0" aria-valuenow="{$GLOBAL.roundshares.valid|number_format}" role="progressbar">{$GLOBAL.roundshares.valid|number_format:$GLOBAL.config.sharediffprecision}</div>
|
||||
</div>
|
||||
</th>
|
||||
</tr>
|
||||
@ -22,12 +22,12 @@
|
||||
<th><h5><i class="fa fa-frown-o fa-fw"></i> Invalid</h5></th>
|
||||
<th>
|
||||
<div class="progress progress-striped progress-fix">
|
||||
<div id="b-yivalid" class="progress-bar progress-bar-danger black" style="width: 100%" aria-valuemax="100" aria-valuemin="0" aria-valuenow="{$GLOBAL.userdata.shares.invalid|number_format}" role="progressbar">{$GLOBAL.userdata.shares.invalid|number_format}</div>
|
||||
<div id="b-yivalid" class="progress-bar progress-bar-danger black" style="width: 100%" aria-valuemax="100" aria-valuemin="0" aria-valuenow="{$GLOBAL.userdata.shares.invalid|number_format}" role="progressbar">{$GLOBAL.userdata.shares.invalid|number_format:$GLOBAL.config.sharediffprecision}</div>
|
||||
</div>
|
||||
</th>
|
||||
<th>
|
||||
<div class="progress progress-striped progress-fix">
|
||||
<div id="b-pivalid" class="progress-bar progress-bar-danger black" style="width: 100%" aria-valuemax="100" aria-valuemin="0" aria-valuenow="{$GLOBAL.roundshares.invalid|number_format}" role="progressbar">{$GLOBAL.roundshares.invalid|number_format}</div>
|
||||
<div id="b-pivalid" class="progress-bar progress-bar-danger black" style="width: 100%" aria-valuemax="100" aria-valuemin="0" aria-valuenow="{$GLOBAL.roundshares.invalid|number_format}" role="progressbar">{$GLOBAL.roundshares.invalid|number_format:$GLOBAL.config.sharediffprecision}</div>
|
||||
</div>
|
||||
</th>
|
||||
</tr>
|
||||
|
||||
@ -1,39 +1,46 @@
|
||||
<article class="module width_half">
|
||||
<form action="{$smarty.server.SCRIPT_NAME}" method="post">
|
||||
<div class="row">
|
||||
<form class="col-md-4" role="form" method="POST">
|
||||
<input type="hidden" name="token" value="{$smarty.request.token|escape}">
|
||||
<input type="hidden" name="page" value="{$smarty.request.page|escape}">
|
||||
<input type="hidden" name="action" value="{$smarty.request.action|escape}">
|
||||
<input type="hidden" name="ctoken" value="{$CTOKEN|escape|default:""}" />
|
||||
|
||||
|
||||
<input type="hidden" name="do" value="resetPassword">
|
||||
<header><h3>Password reset</h3></header>
|
||||
<div class="module_content">
|
||||
<fieldset>
|
||||
<label>New Password</label>
|
||||
<input type="password" name="newPassword" required>
|
||||
</fieldset>
|
||||
<fieldset>
|
||||
<label>Repeat New Password</label>
|
||||
<input type="password" name="newPassword2" required>
|
||||
</fieldset>
|
||||
<div class="clear"></div>
|
||||
</div>
|
||||
<footer>
|
||||
{nocache}
|
||||
<input type="hidden" name="cp_token" value="{$smarty.request.cp_token|escape|default:""}">
|
||||
<input type="hidden" name="utype" value="change_pw">
|
||||
{if $GLOBAL.twofactor.enabled && $GLOBAL.twofactor.options.changepw}
|
||||
{if $CHANGEPASSSENT == 1 && $CHANGEPASSUNLOCKED == 1}
|
||||
<input type="submit" value="Change Password" class="btn btn-warning btn-sm">
|
||||
{elseif $CHANGEPASSSENT == 0 && $CHANGEPASSUNLOCKED == 1 || $CHANGEPASSSENT == 1 && $CHANGEPASSUNLOCKED == 0}
|
||||
<input type="submit" value="Change Password" class="btn btn-warning btn-sm" disabled="disabled">
|
||||
{elseif $CHANGEPASSSENT == 0 && $CHANGEPASSUNLOCKED == 0}
|
||||
<input type="submit" value="Unlock" class="btn btn-warning btn-sm" name="unlock">
|
||||
<div class="panel panel-default">
|
||||
<div class="panel-heading">
|
||||
<h3 class="panel-title">Password reset</h3>
|
||||
</div>
|
||||
<div class="panel-body">
|
||||
<div class="form-group">
|
||||
<fieldset>
|
||||
<label>New Password</label>
|
||||
<input class="form-control" type="password" name="newPassword" required>
|
||||
</fieldset>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<fieldset>
|
||||
<label>Repeat New Password</label>
|
||||
<input class="form-control" type="password" name="newPassword2" required>
|
||||
</fieldset>
|
||||
</div>
|
||||
</div>
|
||||
<div class="panel-footer">
|
||||
{nocache}
|
||||
<input type="hidden" name="cp_token" value="{$smarty.request.cp_token|escape|default:""}">
|
||||
<input type="hidden" name="utype" value="change_pw">
|
||||
{if $GLOBAL.twofactor.enabled && $GLOBAL.twofactor.options.changepw}
|
||||
{if $CHANGEPASSSENT == 1 && $CHANGEPASSUNLOCKED == 1}
|
||||
<input type="submit" value="Change Password" class="btn btn-warning btn-sm">
|
||||
{elseif $CHANGEPASSSENT == 0 && $CHANGEPASSUNLOCKED == 1 || $CHANGEPASSSENT == 1 && $CHANGEPASSUNLOCKED == 0}
|
||||
<input type="submit" value="Change Password" class="btn btn-warning btn-sm" disabled="disabled">
|
||||
{elseif $CHANGEPASSSENT == 0 && $CHANGEPASSUNLOCKED == 0}
|
||||
<input type="submit" value="Unlock" class="btn btn-warning btn-sm" name="unlock">
|
||||
{/if}
|
||||
{else}
|
||||
<input type="submit" value="Change Password" class="btn btn-warning btn-sm">
|
||||
{/if}
|
||||
{else}
|
||||
<input type="submit" value="Change Password" class="btn btn-warning btn-sm">
|
||||
{/if}
|
||||
{/nocache}
|
||||
</footer>
|
||||
{/nocache}
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</article>
|
||||
</div>
|
||||
|
||||
@ -1,10 +0,0 @@
|
||||
{if is_array($YOURHASHRATES) && is_array($POOLHASHRATES)}
|
||||
<div class="tab-pane fade in" id="both">
|
||||
<div class="panel-heading">
|
||||
Your vs. Pool Hashrate
|
||||
</div>
|
||||
<div class="panel-body">
|
||||
<div id="both-area-chart"></div>
|
||||
</div>
|
||||
</div>
|
||||
{/if}
|
||||
@ -1,95 +1,48 @@
|
||||
<script>
|
||||
$(function () {
|
||||
var hashChart = Morris.Line({
|
||||
element: 'hashrate-area-chart',
|
||||
data: {$YOURMININGSTATS},
|
||||
xkey: 'time',
|
||||
ykeys: ['hashrate'],
|
||||
labels: ['Hashrate'],
|
||||
pointSize: 1,
|
||||
hideHover: 'auto',
|
||||
resize: true,
|
||||
fillOpacity: 1.00,
|
||||
lineColors: ['#24A665'],
|
||||
pointFillColors: ['#24A665'],
|
||||
pointStrokeColors: ['#24A665']
|
||||
});
|
||||
|
||||
// needed for automatic activation of first tab
|
||||
$(function () {
|
||||
$('#hashrategraph a:first').tab('show')
|
||||
})
|
||||
var workersChart = Morris.Line({
|
||||
element: 'workers-area-chart',
|
||||
data: {$YOURMININGSTATS},
|
||||
xkey: 'time',
|
||||
ykeys: ['workers'],
|
||||
labels: ['Workers'],
|
||||
pointSize: 1,
|
||||
hideHover: 'auto',
|
||||
resize: true,
|
||||
fillOpacity: 1.00,
|
||||
lineColors: ['#24A665'],
|
||||
pointFillColors: ['#24A665'],
|
||||
pointStrokeColors: ['#24A665']
|
||||
});
|
||||
|
||||
// You can't draw here chart directly, because it's on hidden tab, instead let's do the workaround
|
||||
$('a[data-toggle="tab"]').on('shown.bs.tab', function (e) {
|
||||
// this ain't pretty, but you should get the idea
|
||||
if ($(e.target).attr('href') == '#pool' && $('#pool-area-chart').html().length == 0) {
|
||||
Morris.Area({
|
||||
element: 'pool-area-chart',
|
||||
data: [
|
||||
{foreach $POOLHASHRATES as $hour=>$hashrate}
|
||||
{
|
||||
period: '{$hour|default:"0"}:00',
|
||||
Pool: '{$hashrate|default:"0"}',
|
||||
},
|
||||
{/foreach}
|
||||
],
|
||||
parseTime: false,
|
||||
behaveLikeLine: true,
|
||||
xkey: 'period',
|
||||
ykeys: ['Pool'],
|
||||
labels: ['Hashrate'],
|
||||
pointSize: 2,
|
||||
hideHover: 'auto',
|
||||
lineColors: ['#0b62a4'],
|
||||
pointFillColors: ['#FFFFFF'],
|
||||
resize: true,
|
||||
fillOpacity: 1.00,
|
||||
postUnits: ' KH/s'
|
||||
});
|
||||
}
|
||||
|
||||
if ($(e.target).attr('href') == '#mine' && $('#mine-area-chart').html().length == 0) {
|
||||
Morris.Area({
|
||||
element: 'mine-area-chart',
|
||||
data: [
|
||||
{foreach $YOURHASHRATES as $yourhour=>$yourhashrate}
|
||||
{
|
||||
period: '{$yourhour|default:"0"}:00',
|
||||
Mine: '{$yourhashrate|default:"0"}',
|
||||
},
|
||||
{/foreach}
|
||||
],
|
||||
parseTime: false,
|
||||
behaveLikeLine: true,
|
||||
xkey: 'period',
|
||||
ykeys: ['Mine'],
|
||||
labels: ['Hashrate'],
|
||||
pointSize: 2,
|
||||
hideHover: 'auto',
|
||||
lineColors: ['#24A665'],
|
||||
pointFillColors: ['#FFFFFF'],
|
||||
resize: true,
|
||||
fillOpacity: 1.00,
|
||||
postUnits: ' KH/s'
|
||||
});
|
||||
}
|
||||
|
||||
if ($(e.target).attr('href') == '#both' && $('#both-area-chart').html().length == 0) {
|
||||
Morris.Area({
|
||||
element: 'both-area-chart',
|
||||
data: [
|
||||
{foreach $YOURHASHRATES as $yourhour=>$yourhashrate}
|
||||
{
|
||||
period: '{$yourhour|default:"0"}:00',
|
||||
Mine: '{$yourhashrate|default:"0"}',
|
||||
{foreach $POOLHASHRATES as $poolhour=>$poolhashrate}
|
||||
{if $yourhour eq $poolhour}
|
||||
Pool: '{$poolhashrate|default:"0"}',
|
||||
{/if}
|
||||
{/foreach}
|
||||
},
|
||||
{/foreach}
|
||||
],
|
||||
parseTime: false,
|
||||
behaveLikeLine: true,
|
||||
xkey: 'period',
|
||||
ykeys: ['Mine', 'Pool'],
|
||||
labels: ['Your Hashrate', 'Pool Hashrate'],
|
||||
pointSize: 2,
|
||||
hideHover: 'auto',
|
||||
resize: true,
|
||||
fillOpacity: 0.1,
|
||||
postUnits: ' KH/s'
|
||||
});
|
||||
}
|
||||
|
||||
var shareCharts= Morris.Line({
|
||||
element: 'sharerate-area-chart',
|
||||
data: {$YOURMININGSTATS},
|
||||
xkey: 'time',
|
||||
ykeys: ['sharerate'],
|
||||
labels: ['Sharerate'],
|
||||
pointSize: 1,
|
||||
hideHover: 'auto',
|
||||
resize: true,
|
||||
fillOpacity: 1.00,
|
||||
lineColors: ['#24A665'],
|
||||
pointFillColors: ['#24A665'],
|
||||
pointStrokeColors: ['#24A665']
|
||||
});
|
||||
});
|
||||
</script>
|
||||
@ -98,19 +51,45 @@ $(function () {
|
||||
<div class="col-lg-12">
|
||||
<div class="panel panel-info">
|
||||
<div class="panel-heading">
|
||||
<i class="fa fa-signal fa-fw"></i> Stats
|
||||
</div>
|
||||
<i class="fa fa-signal fa-fw"></i> Average Hashrate past 24h
|
||||
</div>
|
||||
<div class="panel-body">
|
||||
<ul class="nav nav-pills" id="hashrategraph">
|
||||
<li><a href="#mine" data-toggle="tab">Mine</a></li>
|
||||
<li><a href="#pool" data-toggle="tab">Pool</a></li>
|
||||
<li><a href="#both" data-toggle="tab">Both</a></li>
|
||||
</ul>
|
||||
<div class="tab-content">
|
||||
{include file="{$smarty.request.page|escape}/{$smarty.request.action|escape}/mine.tpl"}
|
||||
{include file="{$smarty.request.page|escape}/{$smarty.request.action|escape}/pool.tpl"}
|
||||
{include file="{$smarty.request.page|escape}/{$smarty.request.action|escape}/both.tpl"}
|
||||
</div>
|
||||
<div id="hashrate-area-chart"></div>
|
||||
</div>
|
||||
<div class="panel-footer">
|
||||
Your average hashrate per hour, updated every backend cron run.
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-lg-12">
|
||||
<div class="panel panel-info">
|
||||
<div class="panel-heading">
|
||||
<i class="fa fa-signal fa-fw"></i> Average Workers past 24h
|
||||
</div>
|
||||
<div class="panel-body">
|
||||
<div id="workers-area-chart"></div>
|
||||
</div>
|
||||
<div class="panel-footer">
|
||||
Your average active workers per hour, updated every backend cron run.
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-lg-12">
|
||||
<div class="panel panel-info">
|
||||
<div class="panel-heading">
|
||||
<i class="fa fa-signal fa-fw"></i> Average Sharerate past 24h
|
||||
</div>
|
||||
<div class="panel-body">
|
||||
<div id="sharerate-area-chart"></div>
|
||||
</div>
|
||||
<div class="panel-footer">
|
||||
Your share rate per hour, updated every backend cron run.
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@ -1,10 +0,0 @@
|
||||
{if is_array($YOURHASHRATES)}
|
||||
<div class="tab-pane fade in" id="mine">
|
||||
<div class="panel-heading">
|
||||
Your Hashrate
|
||||
</div>
|
||||
<div class="panel-body">
|
||||
<div id="mine-area-chart"></div>
|
||||
</div>
|
||||
</div>
|
||||
{/if}
|
||||
@ -1,10 +0,0 @@
|
||||
{if is_array($POOLHASHRATES)}
|
||||
<div class="tab-pane fade in" id="pool">
|
||||
<div class="panel-heading">
|
||||
Pool Hashrate
|
||||
</div>
|
||||
<div class="panel-body">
|
||||
<div id="pool-area-chart"></div>
|
||||
</div>
|
||||
</div>
|
||||
{/if}
|
||||
@ -2,7 +2,7 @@
|
||||
<body>
|
||||
<p>Hello valued miner,</p><br />
|
||||
<p>{nocache}{$DATA.username}{/nocache} invited you to participate on this pool:
|
||||
<p><a href="http{if $smarty.server.HTTPS|default:"" eq "on"}s{/if}://{$smarty.server.SERVER_NAME}{$smarty.server.SCRIPT_NAME}?page=register&token={nocache}{$DATA.token}{/nocache}">http{if $smarty.server.HTTPS|default:"" eq "on"}s{/if}://{$smarty.server.SERVER_NAME}{$smarty.server.SCRIPT_NAME}?page=register&token={nocache}{$DATA.token}{/nocache}</a></p>
|
||||
<p><a href="http{if $smarty.server.HTTPS|default:"" eq "on"}s{/if}://{$smarty.server.SERVER_NAME}{if $smarty.server.SERVER_PORT != "443" && $smarty.server.SERVER_PORT != "80"}:{$smarty.server.SERVER_PORT}{/if}{$smarty.server.SCRIPT_NAME}?page=register&token={nocache}{$DATA.token}{/nocache}">http{if $smarty.server.HTTPS|default:"" eq "on"}s{/if}://{$smarty.server.SERVER_NAME}{$smarty.server.SCRIPT_NAME}?page=register&token={nocache}{$DATA.token}{/nocache}</a></p>
|
||||
{if $DATA.message}<p>Personal message:</p><p>{nocache}{$DATA.message}{/nocache}</p>{/if}
|
||||
<p></p>
|
||||
<p>Cheers,</p>
|
||||
|
||||
@ -2,7 +2,7 @@
|
||||
<body>
|
||||
<p>You have a pending request to change your account details.</p>
|
||||
<p>If you initiated this request, please follow the link below to confirm your changes. If you did NOT, please notify an administrator.</p>
|
||||
<p><a href="http{if $smarty.server.HTTPS|default:"" eq "on"}s{/if}://{$smarty.server.SERVER_NAME}{$smarty.server.SCRIPT_NAME}?page=account&action=edit&ea_token={nocache}{$DATA.token}{/nocache}">http{if $smarty.server.HTTPS|default:"" eq "on"}s{/if}://{$smarty.server.SERVER_NAME}{$smarty.server.SCRIPT_NAME}?page=account&action=edit&ea_token={nocache}{$DATA.token}{/nocache}</a></p>
|
||||
<p><a href="http{if $smarty.server.HTTPS|default:"" eq "on"}s{/if}://{$smarty.server.SERVER_NAME}{if $smarty.server.SERVER_PORT != "443" && $smarty.server.SERVER_PORT != "80"}:{$smarty.server.SERVER_PORT}{/if}{$smarty.server.SCRIPT_NAME}?page=account&action=edit&ea_token={nocache}{$DATA.token}{/nocache}">http{if $smarty.server.HTTPS|default:"" eq "on"}s{/if}://{$smarty.server.SERVER_NAME}{$smarty.server.SCRIPT_NAME}?page=account&action=edit&ea_token={nocache}{$DATA.token}{/nocache}</a></p>
|
||||
<br/>
|
||||
<br/>
|
||||
</body>
|
||||
|
||||
@ -2,7 +2,7 @@
|
||||
<body>
|
||||
<p>You have a pending request to change your password.</p>
|
||||
<p>If you initiated this request, please follow the link below to confirm your changes. If you did NOT, please notify an administrator.</p>
|
||||
<p><a href="http{if $smarty.server.HTTPS|default:"" eq "on"}s{/if}://{$smarty.server.SERVER_NAME}{$smarty.server.SCRIPT_NAME}?page=account&action=edit&cp_token={nocache}{$DATA.token}{/nocache}">http{if $smarty.server.HTTPS|default:"" eq "on"}s{/if}://{$smarty.server.SERVER_NAME}{$smarty.server.SCRIPT_NAME}?page=account&action=edit&cp_token={nocache}{$DATA.token}{/nocache}</a></p>
|
||||
<p><a href="http{if $smarty.server.HTTPS|default:"" eq "on"}s{/if}://{$smarty.server.SERVER_NAME}{if $smarty.server.SERVER_PORT != "443" && $smarty.server.SERVER_PORT != "80"}:{$smarty.server.SERVER_PORT}{/if}{$smarty.server.SCRIPT_NAME}?page=account&action=edit&cp_token={nocache}{$DATA.token}{/nocache}">http{if $smarty.server.HTTPS|default:"" eq "on"}s{/if}://{$smarty.server.SERVER_NAME}{$smarty.server.SCRIPT_NAME}?page=account&action=edit&cp_token={nocache}{$DATA.token}{/nocache}</a></p>
|
||||
<br/>
|
||||
<br/>
|
||||
</body>
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
<html>
|
||||
<body>
|
||||
<p>You account has been locked due to too many failed password or PIN attempts. Please follow the URL below to unlock your account.</p>
|
||||
<p><a href="http{if $smarty.server.HTTPS|default:"" eq "on"}s{/if}://{$smarty.server.SERVER_NAME}{$smarty.server.SCRIPT_NAME}?page=account&action=unlock&token={nocache}{$DATA.token}{/nocache}">http{if $smarty.server.HTTPS|default:"" eq "on"}s{/if}://{$smarty.server.SERVER_NAME}{$smarty.server.SCRIPT_NAME}?page=account&action=unlock&token={nocache}{$DATA.token}{/nocache}</a></p>
|
||||
<p><a href="http{if $smarty.server.HTTPS|default:"" eq "on"}s{/if}://{$smarty.server.SERVER_NAME}{if $smarty.server.SERVER_PORT != "443" && $smarty.server.SERVER_PORT != "80"}:{$smarty.server.SERVER_PORT}{/if}{$smarty.server.SCRIPT_NAME}?page=account&action=unlock&token={nocache}{$DATA.token}{/nocache}">http{if $smarty.server.HTTPS|default:"" eq "on"}s{/if}://{$smarty.server.SERVER_NAME}{$smarty.server.SCRIPT_NAME}?page=account&action=unlock&token={nocache}{$DATA.token}{/nocache}</a></p>
|
||||
<br/>
|
||||
<br/>
|
||||
</body>
|
||||
|
||||
6
templates/mail/notifications/test_email.tpl
Normal file
6
templates/mail/notifications/test_email.tpl
Normal file
@ -0,0 +1,6 @@
|
||||
{include file="../global/header.tpl"}
|
||||
<h1>Test email</h1>
|
||||
<p>If you see this email - your email protocol is configured correctly</p>
|
||||
<p>Coin name: {$DATA.coinname}</p>
|
||||
<p>Stratum: {$DATA.stratumurl}:{$DATA.stratumport}</p>
|
||||
{include file="../global/footer.tpl"}
|
||||
@ -2,7 +2,7 @@
|
||||
<body>
|
||||
<p>Hello {nocache}{$DATA.username}{/nocache},</p><br />
|
||||
<p>You have requested a password reset through our online form. In order to complete the request please follow this link:</p>
|
||||
<p><a href="http{if $smarty.server.HTTPS|default:"" eq "on"}s{/if}://{$smarty.server.SERVER_NAME}{$smarty.server.SCRIPT_NAME}?page=password&action=change&token={nocache}{$DATA.token}{/nocache}">http{if $smarty.server.HTTPS|default:"" eq "on"}s{/if}://{$smarty.server.SERVER_NAME}{$smarty.server.SCRIPT_NAME}?page=password&action=change&token={nocache}{$DATA.token}{/nocache}</a></p>
|
||||
<p><a href="http{if $smarty.server.HTTPS|default:"" eq "on"}s{/if}://{$smarty.server.SERVER_NAME}{if $smarty.server.SERVER_PORT != "443" && $smarty.server.SERVER_PORT != "80"}:{$smarty.server.SERVER_PORT}{/if}{$smarty.server.SCRIPT_NAME}?page=password&action=change&token={nocache}{$DATA.token}{/nocache}">http{if $smarty.server.HTTPS|default:"" eq "on"}s{/if}://{$smarty.server.SERVER_NAME}{$smarty.server.SCRIPT_NAME}?page=password&action=change&token={nocache}{$DATA.token}{/nocache}</a></p>
|
||||
<p>You will be asked to change your password. You can then use this new password to login to your account.</p>
|
||||
<p>Cheers,</p>
|
||||
<p>{$WEBSITENAME}</p>
|
||||
|
||||
32
upgrade/definitions/0.0.11_to_0.0.12.inc.php
Normal file
32
upgrade/definitions/0.0.11_to_0.0.12.inc.php
Normal file
@ -0,0 +1,32 @@
|
||||
<?php
|
||||
function run_0012() {
|
||||
// Ugly but haven't found a better way
|
||||
global $setting, $config, $user, $mysqli;
|
||||
|
||||
// Version information
|
||||
$db_version_old = '0.0.11'; // What version do we expect
|
||||
$db_version_new = '0.0.12'; // What is the new version we wish to upgrade to
|
||||
$db_version_now = $setting->getValue('DB_VERSION'); // Our actual version installed
|
||||
|
||||
// Upgrade specific variables
|
||||
$aSql[] = "CREATE TABLE `coin_addresses` ( `id` int(11) NOT NULL AUTO_INCREMENT, `account_id` int(11) NOT NULL, `currency` varchar(5) NOT NULL, `coin_address` varchar(255) NOT NULL, PRIMARY KEY (`id`), UNIQUE KEY `coin_address` (`coin_address`), KEY `account_id` (`account_id`)) ENGINE=InnoDB DEFAULT CHARSET=utf8";
|
||||
$aSql[] = "INSERT IGNORE INTO coin_addresses (account_id, currency, coin_address) SELECT id, '" . $config['currency'] . "', coin_address FROM " . $user->getTableName() . " WHERE coin_address IS NOT NULL";
|
||||
$aSql[] = "ALTER TABLE `" . $user->getTableName() . "` DROP `coin_address`";
|
||||
$aSql[] = "UPDATE " . $setting->getTableName() . " SET value = '0.0.12' WHERE name = 'DB_VERSION'";
|
||||
|
||||
if ($db_version_now == $db_version_old && version_compare($db_version_now, DB_VERSION, '<')) {
|
||||
// Run the upgrade
|
||||
echo '- Starting database migration to version ' . $db_version_new . PHP_EOL;
|
||||
foreach ($aSql as $sql) {
|
||||
echo '- Preparing: ' . $sql . PHP_EOL;
|
||||
$stmt = $mysqli->prepare($sql);
|
||||
if ($stmt && $stmt->execute()) {
|
||||
echo '- success' . PHP_EOL;
|
||||
} else {
|
||||
echo '- failed: ' . $mysqli->error . PHP_EOL;
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
?>
|
||||
39
upgrade/definitions/0.0.12_to_0.0.13.inc.php
Normal file
39
upgrade/definitions/0.0.12_to_0.0.13.inc.php
Normal file
@ -0,0 +1,39 @@
|
||||
<?php
|
||||
function run_0013() {
|
||||
// Ugly but haven't found a better way
|
||||
global $setting, $config, $user, $mysqli;
|
||||
|
||||
// Version information
|
||||
$db_version_old = '0.0.12'; // What version do we expect
|
||||
$db_version_new = '0.0.13'; // What is the new version we wish to upgrade to
|
||||
$db_version_now = $setting->getValue('DB_VERSION'); // Our actual version installed
|
||||
|
||||
// Upgrade specific variables
|
||||
$aSql[] = "CREATE TABLE `statistics_users` (
|
||||
`id` int(11) NOT NULL AUTO_INCREMENT,
|
||||
`account_id` int(11) NOT NULL,
|
||||
`hashrate` int(11) NOT NULL,
|
||||
`workers` int(11) NOT NULL,
|
||||
`sharerate` float NOT NULL,
|
||||
`timestamp` int(11) NOT NULL,
|
||||
PRIMARY KEY (`id`),
|
||||
KEY `account_id_timestamp` (`account_id`,`timestamp`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8";
|
||||
$aSql[] = "UPDATE " . $setting->getTableName() . " SET value = '0.0.13' WHERE name = 'DB_VERSION'";
|
||||
|
||||
if ($db_version_now == $db_version_old && version_compare($db_version_now, DB_VERSION, '<')) {
|
||||
// Run the upgrade
|
||||
echo '- Starting database migration to version ' . $db_version_new . PHP_EOL;
|
||||
foreach ($aSql as $sql) {
|
||||
echo '- Preparing: ' . $sql . PHP_EOL;
|
||||
$stmt = $mysqli->prepare($sql);
|
||||
if ($stmt && $stmt->execute()) {
|
||||
echo '- success' . PHP_EOL;
|
||||
} else {
|
||||
echo '- failed: ' . $mysqli->error . PHP_EOL;
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
?>
|
||||
30
upgrade/definitions/0.0.13_to_0.0.14.inc.php
Normal file
30
upgrade/definitions/0.0.13_to_0.0.14.inc.php
Normal file
@ -0,0 +1,30 @@
|
||||
<?php
|
||||
function run_0014() {
|
||||
// Ugly but haven't found a better way
|
||||
global $setting, $config, $user, $mysqli;
|
||||
|
||||
// Version information
|
||||
$db_version_old = '0.0.13'; // What version do we expect
|
||||
$db_version_new = '0.0.14'; // What is the new version we wish to upgrade to
|
||||
$db_version_now = $setting->getValue('DB_VERSION'); // Our actual version installed
|
||||
|
||||
// Upgrade specific variables
|
||||
$aSql[] = "ALTER TABLE `statistics_users` CHANGE `hashrate` `hashrate` BIGINT UNSIGNED NOT NULL";
|
||||
$aSql[] = "UPDATE " . $setting->getTableName() . " SET value = '0.0.14' WHERE name = 'DB_VERSION'";
|
||||
|
||||
if ($db_version_now == $db_version_old && version_compare($db_version_now, DB_VERSION, '<')) {
|
||||
// Run the upgrade
|
||||
echo '- Starting database migration to version ' . $db_version_new . PHP_EOL;
|
||||
foreach ($aSql as $sql) {
|
||||
echo '- Preparing: ' . $sql . PHP_EOL;
|
||||
$stmt = $mysqli->prepare($sql);
|
||||
if ($stmt && $stmt->execute()) {
|
||||
echo '- success' . PHP_EOL;
|
||||
} else {
|
||||
echo '- failed: ' . $mysqli->error . PHP_EOL;
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
?>
|
||||
Loading…
Reference in New Issue
Block a user