Merge pull request #817 from TheSerapher/issue-773

Issue 773
This commit is contained in:
Sebastian Grewe 2013-11-07 00:15:45 -08:00
commit a0015103a2
43 changed files with 732 additions and 780 deletions

View File

@ -28,10 +28,7 @@ require_once('shared.inc.php');
// If we don't keep archives, delete some now to release disk space // If we don't keep archives, delete some now to release disk space
if (!$share->purgeArchive()) { if (!$share->purgeArchive()) {
$log->logError("Failed to delete archived shares, not critical but should be checked!"); $log->logError("Failed to delete archived shares, not critical but should be checked!");
$monitoring->setStatus($cron_name . "_active", "yesno", 0); $monitoring->endCronjob($cron_name, 'E0008', 1, true);
$monitoring->setStatus($cron_name . "_message", "message", "Failed to delete archived shares");
$monitoring->setStatus($cron_name . "_status", "okerror", 1);
exit(1);
} }
// Cron cleanup and monitoring // Cron cleanup and monitoring

View File

@ -27,19 +27,12 @@ require_once('shared.inc.php');
if ($setting->getValue('disable_ap') == 1) { if ($setting->getValue('disable_ap') == 1) {
$log->logInfo(" auto payout disabled via admin panel"); $log->logInfo(" auto payout disabled via admin panel");
$monitoring->setStatus($cron_name . "_active", "yesno", 0); $monitoring->endCronjob($cron_name, 'E0009', 0, true);
$monitoring->setStatus($cron_name . "_message", "message", "Auto-Payout disabled");
$monitoring->setStatus($cron_name . "_status", "okerror", 1);
$monitoring->setStatus($cron_name . "_endtime", "date", time());
exit(0);
} }
if ($bitcoin->can_connect() !== true) { if ($bitcoin->can_connect() !== true) {
$log->logFatal(" unable to connect to RPC server, exiting"); $log->logFatal(" unable to connect to RPC server, exiting");
$monitoring->setStatus($cron_name . "_active", "yesno", 0); $monitoring->endCronjob($cron_name, 'E0006', 1, true);
$monitoring->setStatus($cron_name . "_message", "message", "Unable to connect to RPC server");
$monitoring->setStatus($cron_name . "_status", "okerror", 1);
exit(1);
} }
// Fetch all users with setup AP // Fetch all users with setup AP

View File

@ -27,10 +27,7 @@ require_once('shared.inc.php');
if ( $bitcoin->can_connect() !== true ) { if ( $bitcoin->can_connect() !== true ) {
$log->logFatal("Failed to connect to RPC server\n"); $log->logFatal("Failed to connect to RPC server\n");
$monitoring->setStatus($cron_name . "_active", "yesno", 0); $monitoring->endCronjob($cron_name, 'E0006', 1, true);
$monitoring->setStatus($cron_name . "_message", "message", "Unable to connect to RPC server");
$monitoring->setStatus($cron_name . "_status", "okerror", 1);
exit(1);
} }
// Fetch all unconfirmed blocks // Fetch all unconfirmed blocks
@ -54,7 +51,7 @@ foreach ($aAllBlocks as $iIndex => $aBlock) {
if ($aBlock['confirmations'] == $aBlockInfo['confirmations']) { if ($aBlock['confirmations'] == $aBlockInfo['confirmations']) {
$log->logDebug(' No update needed'); $log->logDebug(' No update needed');
} else if (!$block->setConfirmations($aBlock['id'], $aBlockInfo['confirmations'])) { } else if (!$block->setConfirmations($aBlock['id'], $aBlockInfo['confirmations'])) {
$log->logError(' Failed to update block confirmations'); $log->logError(' Failed to update block confirmations: ' . $block->getCronMessage());
} }
} }

View File

@ -19,10 +19,7 @@ limitations under the License.
*/ */
// Monitoring cleanup and status update // Monitoring cleanup and status update
$monitoring->setStatus($cron_name . "_message", "message", "OK"); $monitoring->endCronjob($cron_name, 'OK', 0, false, false);
$monitoring->setStatus($cron_name . "_status", "okerror", 0);
$monitoring->setStatus($cron_name . "_runtime", "time", microtime(true) - $cron_start[$cron_name]); $monitoring->setStatus($cron_name . "_runtime", "time", microtime(true) - $cron_start[$cron_name]);
$monitoring->setStatus($cron_name . "_endtime", "date", time()); $monitoring->setStatus($cron_name . "_endtime", "date", time());
// Mark cron as running for monitoring
$monitoring->setStatus($cron_name . '_active', "yesno", 0);
?> ?>

View File

@ -35,10 +35,7 @@ if ( $bitcoin->can_connect() === true ){
$aTransactions = $bitcoin->query('listsinceblock', $strLastBlockHash); $aTransactions = $bitcoin->query('listsinceblock', $strLastBlockHash);
} else { } else {
$log->logFatal('Unable to conenct to RPC server backend'); $log->logFatal('Unable to conenct to RPC server backend');
$monitoring->setStatus($cron_name . "_active", "yesno", 0); $monitoring->endCronjob($cron_name, 'E0006', 1, true);
$monitoring->setStatus($cron_name . "_message", "message", "Unable to connect to RPC server");
$monitoring->setStatus($cron_name . "_status", "okerror", 1);
exit(1);
} }
// Nothing to do so bail out // Nothing to do so bail out
@ -97,43 +94,28 @@ if (empty($aAllBlocks)) {
if ( !$aShareError = $share->getShareById($aBlockError['share_id']) || !$aShareCurrent = $share->getShareById($iCurrentUpstreamId)) { if ( !$aShareError = $share->getShareById($aBlockError['share_id']) || !$aShareCurrent = $share->getShareById($iCurrentUpstreamId)) {
// We were not able to fetch all shares that were causing this detection to trigger, bail out // We were not able to fetch all shares that were causing this detection to trigger, bail out
$log->logFatal('E0002: Failed to fetch both offending shares ' . $iCurrentUpstreamId . ' and ' . $iPreviousShareId . '. Block height: ' . $aBlock['height']); $log->logFatal('E0002: Failed to fetch both offending shares ' . $iCurrentUpstreamId . ' and ' . $iPreviousShareId . '. Block height: ' . $aBlock['height']);
$monitoring->setStatus($cron_name . "_active", "yesno", 0); $monitoring->endCronjob($cron_name, 'E0002', 1, true);
$monitoring->setStatus($cron_name . "_message", "message", "E0002: Upstream shares not found");
$monitoring->setStatus($cron_name . "_status", "okerror", 1);
exit(1);
} }
// Shares seem to be out of order, so lets change them // Shares seem to be out of order, so lets change them
if ( !$share->updateShareById($iCurrentUpstreamId, $aShareError) || !$share->updateShareById($iPreviousShareId, $aShareCurrent)) { if ( !$share->updateShareById($iCurrentUpstreamId, $aShareError) || !$share->updateShareById($iPreviousShareId, $aShareCurrent)) {
// We couldn't update one of the shares! That might mean they have been deleted already // We couldn't update one of the shares! That might mean they have been deleted already
$log->logFatal('E0003: Failed to change shares order!'); $log->logFatal('E0003: Failed to change shares order!');
$monitoring->setStatus($cron_name . "_active", "yesno", 0); $monitoring->endCronjob($cron_name, 'E0003', 1, true);
$monitoring->setStatus($cron_name . "_message", "message", "E0003: Failed share update");
$monitoring->setStatus($cron_name . "_status", "okerror", 1);
exit(1);
} }
// Reset our offending block so the next run re-checks the shares // Reset our offending block so the next run re-checks the shares
if (!$block->setShareId($aBlockError['id'], NULL) && !$block->setFinder($aBlockError['id'], NULL) || !$block->setShares($aBlockError['id'], NULL)) { if (!$block->setShareId($aBlockError['id'], NULL) && !$block->setFinder($aBlockError['id'], NULL) || !$block->setShares($aBlockError['id'], NULL)) {
$log->logFatal('E0004: Failed to reset previous block: ' . $aBlockError['height']); $log->logFatal('E0004: Failed to reset previous block: ' . $aBlockError['height']);
$log->logError('Failed to reset block in database: ' . $aBlockError['height']); $log->logError('Failed to reset block in database: ' . $aBlockError['height']);
$monitoring->setStatus($cron_name . "_active", "yesno", 0); $monitoring->endCronjob($cron_name, 'E0004', 1, true);
$monitoring->setStatus($cron_name . "_message", "message", "E0004: Failed to reset block");
$monitoring->setStatus($cron_name . "_status", "okerror", 1);
exit(1);
} }
$monitoring->setStatus($cron_name . "_active", "yesno", 0); $monitoring->endCronjob($cron_name, 'E0007', 0, true);
$monitoring->setStatus($cron_name . "_message", "message", "Out of Order Share detected, autofixed");
$monitoring->setStatus($cron_name . "_status", "okerror", 1);
exit(0);
} else { } else {
$iRoundShares = $share->getRoundShares($iPreviousShareId, $iCurrentUpstreamId); $iRoundShares = $share->getRoundShares($iPreviousShareId, $iCurrentUpstreamId);
$iAccountId = $user->getUserId($share->getUpstreamFinder()); $iAccountId = $user->getUserId($share->getUpstreamFinder());
} }
} else { } else {
$log->logFatal('E0005: Unable to fetch blocks upstream share, aborted:' . $share->getError()); $log->logFatal('E0005: Unable to fetch blocks upstream share, aborted:' . $share->getCronError());
$monitoring->setStatus($cron_name . "_active", "yesno", 0); $monitoring->endCronjob($cron_name, 'E0005', 1, true);
$monitoring->setStatus($cron_name . "_message", "message", "Unable to fetch blocks " . $aBlock['height'] . " upstream share: " . $share->getError());
$monitoring->setStatus($cron_name . "_status", "okerror", 1);
exit(1);
} }
$log->logInfo( $log->logInfo(
@ -148,13 +130,13 @@ if (empty($aAllBlocks)) {
// Store new information // Store new information
if (!$block->setShareId($aBlock['id'], $iCurrentUpstreamId)) if (!$block->setShareId($aBlock['id'], $iCurrentUpstreamId))
$log->logError('Failed to update share ID in database for block ' . $aBlock['height']); $log->logError('Failed to update share ID in database for block ' . $aBlock['height'] . ': ' . $block->getCronError());
if (!$block->setFinder($aBlock['id'], $iAccountId)) if (!$block->setFinder($aBlock['id'], $iAccountId))
$log->logError('Failed to update finder account ID in database for block ' . $aBlock['height']); $log->logError('Failed to update finder account ID in database for block ' . $aBlock['height'] . ': ' . $block->getCronError());
if (!$block->setShares($aBlock['id'], $iRoundShares)) if (!$block->setShares($aBlock['id'], $iRoundShares))
$log->logError('Failed to update share count in database for block ' . $aBlock['height']); $log->logError('Failed to update share count in database for block ' . $aBlock['height'] . ': ' . $block->getCronError());
if ($config['block_bonus'] > 0 && !$transaction->addTransaction($iAccountId, $config['block_bonus'], 'Bonus', $aBlock['id'])) { if ($config['block_bonus'] > 0 && !$transaction->addTransaction($iAccountId, $config['block_bonus'], 'Bonus', $aBlock['id'])) {
$log->logError('Failed to create Bonus transaction in database for user ' . $user->getUserName($iAccountId) . ' for block ' . $aBlock['height']); $log->logError('Failed to create Bonus transaction in database for user ' . $user->getUserName($iAccountId) . ' for block ' . $aBlock['height'] . ': ' . $transaction->getCronError());
} }
if ($setting->getValue('disable_notifications') != 1) { if ($setting->getValue('disable_notifications') != 1) {

View File

@ -26,20 +26,13 @@ chdir(dirname(__FILE__));
require_once('shared.inc.php'); require_once('shared.inc.php');
if ($setting->getValue('disable_mp') == 1) { if ($setting->getValue('disable_mp') == 1) {
$log->logInfo(" auto payout disabled via admin panel"); $log->logInfo(" manual payout disabled via admin panel");
$monitoring->setStatus($cron_name . "_active", "yesno", 0); $monitoring->endCronjob($cron_name, 'E0009', 0, true);
$monitoring->setStatus($cron_name . "_message", "message", "Auto-Payout disabled");
$monitoring->setStatus($cron_name . "_status", "okerror", 1);
$monitoring->setStatus($cron_name . "_endtime", "date", time());
exit(0);
} }
if ($bitcoin->can_connect() !== true) { if ($bitcoin->can_connect() !== true) {
$log->logFatal(" unable to connect to RPC server, exiting"); $log->logFatal(" unable to connect to RPC server, exiting");
$monitoring->setStatus($cron_name . "_active", "yesno", 0); $monitoring->endCronjob($cron_name, 'E0006', 1, true);
$monitoring->setStatus($cron_name . "_message", "message", "Unable to connect to RPC server");
$monitoring->setStatus($cron_name . "_status", "okerror", 1);
exit(1);
} }
// Fetch outstanding payout requests // Fetch outstanding payout requests
@ -53,6 +46,12 @@ if (count($aPayouts) > 0) {
$aData['coin_address'] = $user->getCoinAddress($aData['account_id']); $aData['coin_address'] = $user->getCoinAddress($aData['account_id']);
$aData['username'] = $user->getUserName($aData['account_id']); $aData['username'] = $user->getUserName($aData['account_id']);
if ($dBalance > $config['txfee']) { if ($dBalance > $config['txfee']) {
// To ensure we don't run this transaction again, lets mark it completed
if (!$oPayout->setProcessed($aData['id'])) {
$log->logFatal('unable to mark transactions ' . $aData['id'] . ' as processed.');
$monitoring->endCronjob($cron_name, 'E0010', 1, true);
}
$log->logInfo("\t" . $aData['account_id'] . "\t\t" . $aData['username'] . "\t" . $dBalance . "\t\t" . $aData['coin_address']); $log->logInfo("\t" . $aData['account_id'] . "\t\t" . $aData['username'] . "\t" . $dBalance . "\t\t" . $aData['coin_address']);
try { try {
$aStatus = $bitcoin->validateaddress($aData['coin_address']); $aStatus = $bitcoin->validateaddress($aData['coin_address']);
@ -70,14 +69,6 @@ if (count($aPayouts) > 0) {
$log->logError('Failed to send requested balance to coin address, please check payout process'); $log->logError('Failed to send requested balance to coin address, please check payout process');
continue; continue;
} }
// To ensure we don't run this transaction again, lets mark it completed
if (!$oPayout->setProcessed($aData['id'])) {
$log->logFatal('unable to mark transactions ' . $aData['id'] . ' as processed.');
$monitoring->setStatus($cron_name . "_active", "yesno", 0);
$monitoring->setStatus($cron_name . "_message", "message", "Unable set payout as processed");
$monitoring->setStatus($cron_name . "_status", "okerror", 1);
exit(1);
}
if ($transaction->addTransaction($aData['account_id'], $dBalance - $config['txfee'], 'Debit_MP', NULL, $aData['coin_address']) && $transaction->addTransaction($aData['account_id'], $config['txfee'], 'TXFee', NULL, $aData['coin_address'])) { if ($transaction->addTransaction($aData['account_id'], $dBalance - $config['txfee'], 'Debit_MP', NULL, $aData['coin_address']) && $transaction->addTransaction($aData['account_id'], $config['txfee'], 'TXFee', NULL, $aData['coin_address'])) {
// Mark all older transactions as archived // Mark all older transactions as archived

View File

@ -26,10 +26,7 @@ chdir(dirname(__FILE__));
require_once('shared.inc.php'); require_once('shared.inc.php');
if ($setting->getValue('disable_notifications') == 1) { if ($setting->getValue('disable_notifications') == 1) {
$monitoring->setStatus($cron_name . "_active", "yesno", 0); $monitoring->endCronjob($cron_name, 'E0009', 0, true);
$monitoring->setStatus($cron_name . "_message", "message", "Cron disabled by admin");
$monitoring->setStatus($cron_name . "_status", "okerror", 0);
exit(0);
} }
$log->logDebug(" IDLE Worker Notifications ..."); $log->logDebug(" IDLE Worker Notifications ...");
@ -47,7 +44,7 @@ if (empty($aWorkers)) {
$aData['email'] = $user->getUserEmail($aData['username']); $aData['email'] = $user->getUserEmail($aData['username']);
$log->logDebug(" " . $aWorker['username'] . "..."); $log->logDebug(" " . $aWorker['username'] . "...");
if (!$notification->sendNotification($aWorker['account_id'], 'idle_worker', $aData)) if (!$notification->sendNotification($aWorker['account_id'], 'idle_worker', $aData))
$log->logError(" Failed sending notifications: " . $notification->getError() . "\n"); $log->logError(" Failed sending notifications: " . $notification->getCronError() . "\n");
} }
} }

View File

@ -35,10 +35,7 @@ if ($config['payout_system'] != 'pplns') {
$aAllBlocks = $block->getAllUnaccounted('ASC'); $aAllBlocks = $block->getAllUnaccounted('ASC');
if (empty($aAllBlocks)) { if (empty($aAllBlocks)) {
$log->logDebug("No new unaccounted blocks found"); $log->logDebug("No new unaccounted blocks found");
$monitoring->setStatus($cron_name . "_active", "yesno", 0); $monitoring->endCronjob($cron_name, 'E0011', 0, true, false);
$monitoring->setStatus($cron_name . "_message", "message", "No new unaccounted blocks");
$monitoring->setStatus($cron_name . "_status", "okerror", 0);
exit(0);
} }
$count = 0; $count = 0;
@ -64,10 +61,7 @@ foreach ($aAllBlocks as $iIndex => $aBlock) {
$iCurrentUpstreamId = $aBlock['share_id']; $iCurrentUpstreamId = $aBlock['share_id'];
if (!is_numeric($iCurrentUpstreamId)) { if (!is_numeric($iCurrentUpstreamId)) {
$log->logFatal("Block " . $aBlock['height'] . " has no share_id associated with it, not going to continue"); $log->logFatal("Block " . $aBlock['height'] . " has no share_id associated with it, not going to continue");
$monitoring->setStatus($cron_name . "_active", "yesno", 0); $monitoring->endCronjob($cron_name, 'E0012', 1, true);
$monitoring->setStatus($cron_name . "_message", "message", "Block " . $aBlock['height'] . " has no share_id associated with it");
$monitoring->setStatus($cron_name . "_status", "okerror", 1);
exit(1);
} }
$iRoundShares = $share->getRoundShares($iPreviousShareId, $aBlock['share_id']); $iRoundShares = $share->getRoundShares($iPreviousShareId, $aBlock['share_id']);
$iNewRoundShares = 0; $iNewRoundShares = 0;
@ -83,10 +77,7 @@ foreach ($aAllBlocks as $iIndex => $aBlock) {
$aAccountShares = $share->getSharesForAccounts($iMinimumShareId - 1, $aBlock['share_id']); $aAccountShares = $share->getSharesForAccounts($iMinimumShareId - 1, $aBlock['share_id']);
if (empty($aAccountShares)) { if (empty($aAccountShares)) {
$log->logFatal("No shares found for this block, aborted! Block Height : " . $aBlock['height']); $log->logFatal("No shares found for this block, aborted! Block Height : " . $aBlock['height']);
$monitoring->setStatus($cron_name . "_active", "yesno", 0); $monitoring->endCronjob($cron_name, 'E0013', 1, true);
$monitoring->setStatus($cron_name . "_message", "message", "No shares found for this block: " . $aBlock['height']);
$monitoring->setStatus($cron_name . "_status", "okerror", 1);
exit(1);
} }
foreach($aAccountShares as $key => $aData) { foreach($aAccountShares as $key => $aData) {
$iNewRoundShares += $aData['valid']; $iNewRoundShares += $aData['valid'];
@ -100,10 +91,7 @@ foreach ($aAllBlocks as $iIndex => $aBlock) {
$aAccountShares = $aRoundAccountShares; $aAccountShares = $aRoundAccountShares;
if (empty($aAccountShares)) { if (empty($aAccountShares)) {
$log->logFatal("No shares found for this block, aborted! Block height: " . $aBlock['height']); $log->logFatal("No shares found for this block, aborted! Block height: " . $aBlock['height']);
$monitoring->setStatus($cron_name . "_active", "yesno", 0); $monitoring->endCronjob($cron_name, 'E0013', 1, true);
$monitoring->setStatus($cron_name . "_message", "message", "No shares found for this block: " . $aBlock['height']);
$monitoring->setStatus($cron_name . "_status", "okerror", 1);
exit(1);
} }
// Grab only the most recent shares from Archive that fill the missing shares // Grab only the most recent shares from Archive that fill the missing shares
@ -141,7 +129,7 @@ foreach ($aAllBlocks as $iIndex => $aBlock) {
} }
} }
$aAccountShares = $aSharesData; $aAccountShares = $aSharesData;
} }
} }
// We tried to fill up to PPLNS target, now we need to check the actual shares to properly payout users // We tried to fill up to PPLNS target, now we need to check the actual shares to properly payout users
foreach($aAccountShares as $key => $aData) { foreach($aAccountShares as $key => $aData) {
@ -221,21 +209,19 @@ foreach ($aAllBlocks as $iIndex => $aBlock) {
// Move counted shares to archive before this blockhash upstream share // Move counted shares to archive before this blockhash upstream share
if (!$share->moveArchive($iCurrentUpstreamId, $aBlock['id'], $iPreviousShareId)) if (!$share->moveArchive($iCurrentUpstreamId, $aBlock['id'], $iPreviousShareId))
$log->logError('Failed to copy shares to archive table'); $log->logError('Failed to copy shares to archive table: ' . $share->getCronError());
// Delete all accounted shares // Delete all accounted shares
if (!$share->deleteAccountedShares($iCurrentUpstreamId, $iPreviousShareId)) { if (!$share->deleteAccountedShares($iCurrentUpstreamId, $iPreviousShareId)) {
$log->logFatal("Failed to delete accounted shares from $iPreviousShareId to $iCurrentUpstreamId, aborting!"); $log->logFatal("Failed to delete accounted shares from $iPreviousShareId to $iCurrentUpstreamId, aborting! Error: " . $share->getCronError());
exit(1); $monitoring->endCronjob($cron_name, 'E0016', 1, true);
} }
// Mark this block as accounted for // Mark this block as accounted for
if (!$block->setAccounted($aBlock['id'])) { if (!$block->setAccounted($aBlock['id'])) {
$log->logFatal("Failed to mark block as accounted! Aborting!"); $log->logFatal("Failed to mark block as accounted! Aborting! Error: " . $block->getCronError());
$monitoring->setStatus($cron_name . "_active", "yesno", 0); $monitoring->endCronjob($cron_name, 'E0014', 1, true);
$monitoring->setStatus($cron_name . "_message", "message", "Failed to mark block " . $aBlock['height'] . " as accounted");
$monitoring->setStatus($cron_name . "_status", "okerror", 1);
exit(1);
} }
} else { } else {
$log->logFatal('Potential double payout detected. Aborted.');
$aMailData = array( $aMailData = array(
'email' => $setting->getValue('system_error_email'), 'email' => $setting->getValue('system_error_email'),
'subject' => 'Payout processing aborted', 'subject' => 'Payout processing aborted',
@ -245,12 +231,8 @@ foreach ($aAllBlocks as $iIndex => $aBlock) {
'Block Share ID' => $aBlock['share_id'] 'Block Share ID' => $aBlock['share_id']
); );
if (!$mail->sendMail('notifications/error', $aMailData)) if (!$mail->sendMail('notifications/error', $aMailData))
$log->logError(" Failed sending notifications: " . $notification->getError() . "\n"); $log->logError(" Failed sending notifications: " . $notification->getCronError() . "\n");
$log->logFatal('Potential double payout detected. Aborted.'); $monitoring->endCronjob($cron_name, 'E0015', 1, true);
$monitoring->setStatus($cron_name . "_active", "yesno", 0);
$monitoring->setStatus($cron_name . "_message", "message", "Block height for block too low! Potential double payout detected.");
$monitoring->setStatus($cron_name . "_status", "okerror", 1);
exit(1);
} }
} }

View File

@ -121,7 +121,10 @@ $setting->setValue('pps_last_share_id', $iLastShareId);
// Fetch all unaccounted blocks // Fetch all unaccounted blocks
$aAllBlocks = $block->getAllUnaccounted('ASC'); $aAllBlocks = $block->getAllUnaccounted('ASC');
if (empty($aAllBlocks)) $log->logDebug("No new unaccounted blocks found"); if (empty($aAllBlocks)) {
$log->logDebug("No new unaccounted blocks found");
// No monitoring event here, not fatal for PPS
}
// Go through blocks and archive/delete shares that have been accounted for // Go through blocks and archive/delete shares that have been accounted for
foreach ($aAllBlocks as $iIndex => $aBlock) { foreach ($aAllBlocks as $iIndex => $aBlock) {
@ -143,23 +146,17 @@ foreach ($aAllBlocks as $iIndex => $aBlock) {
// Move shares to archive // Move shares to archive
if ($aBlock['share_id'] < $iLastShareId) { if ($aBlock['share_id'] < $iLastShareId) {
if (!$share->moveArchive($aBlock['share_id'], $aBlock['id'], @$iLastBlockShare)) if (!$share->moveArchive($aBlock['share_id'], $aBlock['id'], @$iLastBlockShare))
$log->logError("Archving failed"); $log->logError("Failed to copy shares to archive: " . $share->getCronError());
} }
// Delete shares // Delete shares
if ($aBlock['share_id'] < $iLastShareId && !$share->deleteAccountedShares($aBlock['share_id'], $iLastBlockShare)) { if ($aBlock['share_id'] < $iLastShareId && !$share->deleteAccountedShares($aBlock['share_id'], $iLastBlockShare)) {
$log->logFatal("Failed to delete accounted shares from " . $aBlock['share_id'] . " to " . $iLastBlockShare . ", aborting!"); $log->logFatal("Failed to delete accounted shares from " . $aBlock['share_id'] . " to " . $iLastBlockShare . ", aborting! Error: " . $share->getCronError());
$monitoring->setStatus($cron_name . "_active", "yesno", 0); $monitoring->endCronjob($cron_name, 'E0016', 1, true);
$monitoring->setStatus($cron_name . "_message", "message", "Failed to delete accounted shares from " . $aBlock['share_id'] . " to " . $iLastBlockShare);
$monitoring->setStatus($cron_name . "_status", "okerror", 1);
exit(1);
} }
// Mark this block as accounted for // Mark this block as accounted for
if (!$block->setAccounted($aBlock['id'])) { if (!$block->setAccounted($aBlock['id'])) {
$log->logFatal("Failed to mark block as accounted! Aborting!"); $log->logFatal("Failed to mark block as accounted! Aborting! Error: " . $block->getCronError());
$monitoring->setStatus($cron_name . "_active", "yesno", 0); $monitoring->endCronjob($cron_name, 'E0014', 1, true);
$monitoring->setStatus($cron_name . "_message", "message", "Failed to mark block " . $aBlock['height'] . " as accounted");
$monitoring->setStatus($cron_name . "_status", "okerror", 1);
exit(1);
} }
} }

View File

@ -35,10 +35,7 @@ if ($config['payout_system'] != 'prop') {
$aAllBlocks = $block->getAllUnaccounted('ASC'); $aAllBlocks = $block->getAllUnaccounted('ASC');
if (empty($aAllBlocks)) { if (empty($aAllBlocks)) {
$log->logDebug('No new unaccounted blocks found in database'); $log->logDebug('No new unaccounted blocks found in database');
$monitoring->setStatus($cron_name . "_active", "yesno", 0); $monitoring->endCronjob($cron_name, 'E0011', 0, true, false);
$monitoring->setStatus($cron_name . "_message", "message", "No new unaccounted blocks");
$monitoring->setStatus($cron_name . "_status", "okerror", 0);
exit(0);
} }
$count = 0; $count = 0;
@ -60,10 +57,7 @@ foreach ($aAllBlocks as $iIndex => $aBlock) {
if (empty($aAccountShares)) { if (empty($aAccountShares)) {
$log->logFatal('No shares found for this block, aborted: ' . $aBlock['height']); $log->logFatal('No shares found for this block, aborted: ' . $aBlock['height']);
$monitoring->setStatus($cron_name . "_active", "yesno", 0); $monitoring->endCronjob($cron_name, 'E0013', 1, true);
$monitoring->setStatus($cron_name . "_message", "message", "No shares found for this block, aborted: " . $aBlock['height']);
$monitoring->setStatus($cron_name . "_status", "okerror", 1);
exit(1);
} }
// Loop through all accounts that have found shares for this round // Loop through all accounts that have found shares for this round
@ -111,25 +105,19 @@ foreach ($aAllBlocks as $iIndex => $aBlock) {
// Move counted shares to archive before this blockhash upstream share // Move counted shares to archive before this blockhash upstream share
if (!$share->moveArchive($iCurrentUpstreamId, $aBlock['id'], $iPreviousShareId)) if (!$share->moveArchive($iCurrentUpstreamId, $aBlock['id'], $iPreviousShareId))
$log->logError('Failed to copy shares to archive'); $log->logError('Failed to copy shares to archive: ' . $share->getCronError());
// Delete all accounted shares // Delete all accounted shares
if (!$share->deleteAccountedShares($iCurrentUpstreamId, $iPreviousShareId)) { if (!$share->deleteAccountedShares($iCurrentUpstreamId, $iPreviousShareId)) {
$log->logFatal('Failed to delete accounted shares from ' . $iPreviousShareId . ' to ' . $iCurrentUpstreamId . ', aborted'); $log->logFatal('Failed to delete accounted shares from ' . $iPreviousShareId . ' to ' . $iCurrentUpstreamId . ', aborted! Error: ' . $share->getCronError());
$monitoring->setStatus($cron_name . "_active", "yesno", 0); $monitoring->endCronjob($cron_name, 'E0016', 1, true);
$monitoring->setStatus($cron_name . "_message", "message", "Failed to delete accounted shares from " . $iPreviousShareId . " to " . $iCurrentUpstreamId);
$monitoring->setStatus($cron_name . "_status", "okerror", 1);
exit(1);
} }
// Mark this block as accounted for // Mark this block as accounted for
if (!$block->setAccounted($aBlock['id'])) { if (!$block->setAccounted($aBlock['id'])) {
$log->logFatal('Failed to mark block as accounted! Aborted.'); $log->logFatal('Failed to mark block as accounted! Aborted! Error: ' . $block->getCronError());
$monitoring->setStatus($cron_name . "_active", "yesno", 0); $monitoring->endCronjob($cron_name, 'E0014', 1, true);
$monitoring->setStatus($cron_name . "_message", "message", "Failed to mark block " . $aBlock['height'] . " as accounted");
$monitoring->setStatus($cron_name . "_status", "okerror", 1);
exit(1);
} }
} else { } else {
$log->logFatal('Possible double payout detected. Aborted.'); $log->logFatal('Potential double payout detected. Aborted.');
$aMailData = array( $aMailData = array(
'email' => $setting->getValue('system_error_email'), 'email' => $setting->getValue('system_error_email'),
'subject' => 'Payout Failure: Double Payout', 'subject' => 'Payout Failure: Double Payout',
@ -139,11 +127,8 @@ foreach ($aAllBlocks as $iIndex => $aBlock) {
'Block Share ID' => $aBlock['share_id'] 'Block Share ID' => $aBlock['share_id']
); );
if (!$mail->sendMail('notifications/error', $aMailData)) if (!$mail->sendMail('notifications/error', $aMailData))
$log->logError(" Failed sending notifications: " . $notification->getError() . "\n"); $log->logFatal('Potential double payout detected. Aborted.');
$monitoring->setStatus($cron_name . "_active", "yesno", 0); $monitoring->endCronjob($cron_name, 'E0015', 1, true);
$monitoring->setStatus($cron_name . "_message", "message", 'Possible double payout detected. Aborted.');
$monitoring->setStatus($cron_name . "_status", "okerror", 1);
exit(1);
} }
} }

View File

@ -29,17 +29,32 @@ SUBFOLDER=""
# # # #
################################################################ ################################################################
# Mac OS detection
OS=`uname`
case "$OS" in
Darwin) READLINK=$( which greadlink ) ;;
*) READLINK=$( which readlink ) ;;
esac
if [[ ! -x $READLINK ]]; then
echo "readlink not found, please install first";
exit 1;
fi
# My own name # My own name
ME=$( basename $0 ) ME=$( basename $0 )
# Overwrite some settings via command line arguments # Overwrite some settings via command line arguments
while getopts "hvp:d:" opt; do while getopts "hfvp:d:" opt; do
case "$opt" in case "$opt" in
h|\?) h|\?)
echo "Usage: $0 [-v] [-p PHP_BINARY] [-d SUBFOLDER]"; echo "Usage: $0 [-v] [-p PHP_BINARY] [-d SUBFOLDER]";
exit 0 exit 0
;; ;;
v) VERBOSE=1 ;; v) VERBOSE=1 ;;
f) PHP_OPTS="$PHP_OPTS -f";;
p) PHP_BIN=$OPTARG ;; p) PHP_BIN=$OPTARG ;;
d) SUBFOLDER=$OPTARG ;; d) SUBFOLDER=$OPTARG ;;
:) :)
@ -52,7 +67,7 @@ done
# Path to PID file, needs to be writable by user running this # Path to PID file, needs to be writable by user running this
PIDFILE="${BASEPATH}/${SUBFOLDER}/${ME}.pid" PIDFILE="${BASEPATH}/${SUBFOLDER}/${ME}.pid"
# Clean PIDFILE path # Clean PIDFILE path
PIDFILE=$(readlink -m "$PIDFILE") PIDFILE=$($READLINK -m "$PIDFILE")
# Create folders recursively if necessary # Create folders recursively if necessary
if ! $(mkdir -p $( dirname $PIDFILE)); then if ! $(mkdir -p $( dirname $PIDFILE)); then
@ -62,7 +77,7 @@ fi
# Find scripts path # Find scripts path
if [[ -L $0 ]]; then if [[ -L $0 ]]; then
CRONHOME=$( dirname $( readlink $0 ) ) CRONHOME=$( dirname $( $READLINK $0 ) )
else else
CRONHOME=$( dirname $0 ) CRONHOME=$( dirname $0 )
fi fi
@ -104,7 +119,7 @@ echo $PID > $PIDFILE
for cron in $CRONS; do for cron in $CRONS; do
[[ $VERBOSE == 1 ]] && echo "Running $cron, check logfile for details" [[ $VERBOSE == 1 ]] && echo "Running $cron, check logfile for details"
$PHP_BIN $cron $PHP_BIN $cron $PHP_OPTS
done done
# Remove pidfile # Remove pidfile

View File

@ -41,6 +41,16 @@ require_once(BASEPATH . 'include/config/global.inc.php');
// We include all needed files here, even though our templates could load them themself // We include all needed files here, even though our templates could load them themself
require_once(INCLUDE_DIR . '/autoloader.inc.php'); require_once(INCLUDE_DIR . '/autoloader.inc.php');
// Command line switches
array_shift($argv);
foreach ($argv as $option) {
switch ($option) {
case '-f':
$monitoring->setStatus($cron_name . "_disabled", "yesno", 0);
break;
}
}
// Load 3rd party logging library for running crons // Load 3rd party logging library for running crons
$log = new KLogger ( 'logs/' . $cron_name . '.txt' , KLogger::INFO ); $log = new KLogger ( 'logs/' . $cron_name . '.txt' , KLogger::INFO );
$log->LogDebug('Starting ' . $cron_name); $log->LogDebug('Starting ' . $cron_name);
@ -48,8 +58,13 @@ $log->LogDebug('Starting ' . $cron_name);
// Load the start time for later runtime calculations for monitoring // Load the start time for later runtime calculations for monitoring
$cron_start[$cron_name] = microtime(true); $cron_start[$cron_name] = microtime(true);
// Check if our cron is activated
if ($monitoring->isDisabled($cron_name)) {
$log->logFatal('Cronjob is currently disabled due to errors, use -f option to force running cron.');
$monitoring->endCronjob($cron_name, 'E0018', 1, true, false);
}
// Mark cron as running for monitoring // Mark cron as running for monitoring
$log->logDebug('Marking cronjob as running for monitoring'); $log->logDebug('Marking cronjob as running for monitoring');
$monitoring->setStatus($cron_name . '_active', 'yesno', 1);
$monitoring->setStatus($cron_name . '_starttime', 'date', time()); $monitoring->setStatus($cron_name . '_starttime', 'date', time());
?> ?>

View File

@ -29,22 +29,22 @@ require_once('shared.inc.php');
require_once(CLASS_DIR . '/tools.class.php'); require_once(CLASS_DIR . '/tools.class.php');
if ($price = $tools->getPrice()) { if ($price = $tools->getPrice()) {
$log->logInfo("Price update: found $price as price"); $log->logDebug("Price update: found $price as price");
if (!$setting->setValue('price', $price)) if (!$setting->setValue('price', $price))
$log->logError("unable to update value in settings table"); $log->logError("unable to update value in settings table");
} else { } else {
$log->logError("failed to fetch API data: " . $tools->getError()); $log->logError("failed to fetch API data: " . $tools->getCronError());
} }
if ($setting->getValue('monitoring_uptimerobot_private_key')) { if ($setting->getValue('monitoring_uptimerobot_private_key')) {
$monitoring->setTools($tools); $monitoring->setTools($tools);
if (!$monitoring->storeUptimeRobotStatus()) { if (!$monitoring->storeUptimeRobotStatus()) {
$log->logError('Failed to update Uptime Robot Status: ' . $monitoring->getError()); $log->logError($monitoring->getCronError());
$monitoring->endCronjob($cron_name, 'E0017', 1, true);
} }
} else { } else {
$log->logDebug('Skipped Uptime Robot API update, missing private key'); $log->logDebug('Skipped Uptime Robot API update, missing private key');
} }
require_once('cron_end.inc.php'); require_once('cron_end.inc.php');
?> ?>

View File

@ -11,6 +11,7 @@ require_once(CLASS_DIR . '/debug.class.php');
require_once(INCLUDE_DIR . '/lib/KLogger.php'); require_once(INCLUDE_DIR . '/lib/KLogger.php');
require_once(INCLUDE_DIR . '/database.inc.php'); require_once(INCLUDE_DIR . '/database.inc.php');
require_once(INCLUDE_DIR . '/config/memcache_keys.inc.php'); require_once(INCLUDE_DIR . '/config/memcache_keys.inc.php');
require_once(INCLUDE_DIR . '/config/error_codes.inc.php');
// We need to load these two first // We need to load these two first
require_once(CLASS_DIR . '/base.class.php'); require_once(CLASS_DIR . '/base.class.php');
@ -50,8 +51,8 @@ require_once(CLASS_DIR . '/invitation.class.php');
require_once(CLASS_DIR . '/share.class.php'); require_once(CLASS_DIR . '/share.class.php');
require_once(CLASS_DIR . '/worker.class.php'); require_once(CLASS_DIR . '/worker.class.php');
require_once(CLASS_DIR . '/statistics.class.php'); require_once(CLASS_DIR . '/statistics.class.php');
require_once(CLASS_DIR . '/roundstats.class.php');
require_once(CLASS_DIR . '/transaction.class.php'); require_once(CLASS_DIR . '/transaction.class.php');
require_once(CLASS_DIR . '/roundstats.class.php');
require_once(CLASS_DIR . '/notification.class.php'); require_once(CLASS_DIR . '/notification.class.php');
require_once(CLASS_DIR . '/news.class.php'); require_once(CLASS_DIR . '/news.class.php');
require_once(CLASS_DIR . '/api.class.php'); require_once(CLASS_DIR . '/api.class.php');

View File

@ -4,10 +4,15 @@
if (!defined('SECURITY')) if (!defined('SECURITY'))
die('Hacking attempt'); die('Hacking attempt');
// Our base class that defines /**
// some cross-class functions. * Our base class that we extend our other classes from
*
* It supplies some basic features as cross-linking with other classes
* after loading a newly created class.
**/
class Base { class Base {
private $sError = ''; private $sError = '';
private $sCronError = '';
protected $table = ''; protected $table = '';
private $values = array(), $types = ''; private $values = array(), $types = '';
@ -23,6 +28,9 @@ class Base {
public function setMail($mail) { public function setMail($mail) {
$this->mail = $mail; $this->mail = $mail;
} }
public function setSalt($salt) {
$this->salt = $salt;
}
public function setSmarty($smarty) { public function setSmarty($smarty) {
$this->smarty = $smarty; $this->smarty = $smarty;
} }
@ -32,12 +40,24 @@ class Base {
public function setConfig($config) { public function setConfig($config) {
$this->config = $config; $this->config = $config;
} }
public function setErrorCodes(&$aErrorCodes) {
$this->aErrorCodes =& $aErrorCodes;
}
public function setToken($token) { public function setToken($token) {
$this->token = $token; $this->token = $token;
} }
public function setBlock($block) { public function setBlock($block) {
$this->block = $block; $this->block = $block;
} }
public function setTransaction($transaction) {
$this->transaction = $transaction;
}
public function setMemcache($memcache) {
$this->memcache = $memcache;
}
public function setStatistics($statistics) {
$this->statistics = $statistics;
}
public function setSetting($setting) { public function setSetting($setting) {
$this->setting = $setting; $this->setting = $setting;
} }
@ -55,11 +75,49 @@ class Base {
} }
public function setErrorMessage($msg) { public function setErrorMessage($msg) {
$this->sError = $msg; $this->sError = $msg;
// Default to same error for crons
$this->sCronError = $msg;
}
public function setCronMessage($msg) {
// Used to overwrite any errors with a custom cron one
$this->sCronError = $msg;
} }
public function getError() { public function getError() {
return $this->sError; return $this->sError;
} }
/**
* Additional information in error string for cronjobs logging
**/
public function getCronError() {
return $this->sCronError;
}
/**
* Get error message from error code array
* @param errCode string Error code string
* @param optional string Optional addtitional error strings to append
* @retrun string Error Message
**/
public function getErrorMsg($errCode='') {
if (!is_array($this->aErrorCodes)) return 'Error codes not loaded';
if (!array_key_exists($errCode, $this->aErrorCodes)) return 'Unknown Error Code: ' . $errCode;
if (func_num_args() > 1) {
$args = func_get_args();
array_shift($args);
$param_count = substr_count($this->aErrorCodes[$errCode], '%s');
if ($param_count == count($args)) {
return vsprintf($this->aErrorCodes[$errCode], $args);
} else {
return $this->aErrorCodes[$errCode] . ' (missing information to complete string)';
}
} else {
return $this->aErrorCodes[$errCode];
}
}
/**
* Get an element as an associated array
**/
protected function getAllAssoc($value, $field='id', $type='i') { protected function getAllAssoc($value, $field='id', $type='i') {
$this->debug->append("STA " . __METHOD__, 4); $this->debug->append("STA " . __METHOD__, 4);
$stmt = $this->mysqli->prepare("SELECT * FROM $this->table WHERE $field = ? LIMIT 1"); $stmt = $this->mysqli->prepare("SELECT * FROM $this->table WHERE $field = ? LIMIT 1");
@ -73,11 +131,15 @@ class Base {
* @param search Return column to search for * @param search Return column to search for
* @param field string Search column * @param field string Search column
* @param type string Type of value * @param type string Type of value
* @param lower bool try with LOWER comparision
* @return array Return result * @return array Return result
**/ **/
protected function getSingle($value, $search='id', $field='id', $type="i") { protected function getSingle($value, $search='id', $field='id', $type="i", $lower=false) {
$this->debug->append("STA " . __METHOD__, 4); $this->debug->append("STA " . __METHOD__, 4);
$stmt = $this->mysqli->prepare("SELECT $search FROM $this->table WHERE $field = ? LIMIT 1"); $sql = "SELECT $search FROM $this->table WHERE";
$lower ? $sql .= " LOWER($field) = LOWER(?)" : $sql .= " $field = ?";
$sql .= " LIMIT 1";
$stmt = $this->mysqli->prepare($sql);
if ($this->checkStmt($stmt)) { if ($this->checkStmt($stmt)) {
$stmt->bind_param($type, $value); $stmt->bind_param($type, $value);
$stmt->execute(); $stmt->execute();
@ -89,18 +151,38 @@ class Base {
return false; return false;
} }
/**
* Check if the prepared statement is valid
* @param $bState Statement return value
* @return bool true or false
**/
function checkStmt($bState) { function checkStmt($bState) {
$this->debug->append("STA " . __METHOD__, 4); $this->debug->append("STA " . __METHOD__, 4);
if ($bState ===! true) { if ($bState ===! true)
$this->debug->append("Failed to prepare statement: " . $this->mysqli->error); return $this->sqlError();
$this->setErrorMessage('Internal application Error');
return false;
}
return true; return true;
} }
/**
* Catch SQL errors with this method
* @param error_code string Error code to read
**/
protected function sqlError($error_code='E0020') {
// More human-readable error for UI
if (func_num_args() == 0) {
$this->setErrorMessage($this->getErrorMsg($error_code));
} else {
$this->setErrorMessage(call_user_func_array(array($this, 'getErrorMsg'), func_get_args()));
}
// Default to SQL error for debug and cron errors
$this->debug->append($this->getErrorMsg('E0019', $this->mysqli->error));
$this->setCronMessage($this->getErrorMsg('E0019', $this->mysqli->error));
return false;
}
/** /**
* Update a single row in a table
* @param userID int Account ID * @param userID int Account ID
* Update a single row in a table
* @param field string Field to update * @param field string Field to update
* @return bool * @return bool
**/ **/
@ -111,7 +193,7 @@ class Base {
if ($this->checkStmt($stmt) && $stmt->bind_param($field['type'].'i', $field['value'], $id) && $stmt->execute()) if ($this->checkStmt($stmt) && $stmt->bind_param($field['type'].'i', $field['value'], $id) && $stmt->execute())
return true; return true;
$this->debug->append("Unable to update " . $field['name'] . " with " . $field['value'] . " for ID $id"); $this->debug->append("Unable to update " . $field['name'] . " with " . $field['value'] . " for ID $id");
return false; $this->sqlError();
} }
/** /**

View File

@ -1,32 +1,10 @@
<?php <?php
// Make sure we are called from index.php // Make sure we are called from index.php
if (!defined('SECURITY')) if (!defined('SECURITY')) die('Hacking attempt');
die('Hacking attempt');
class Block { class Block extends Base {
private $sError = ''; protected $table = 'blocks';
private $table = 'blocks';
// This defines each block
public $height, $blockhash, $confirmations, $time, $accounted;
public function __construct($debug, $mysqli, $config) {
$this->debug = $debug;
$this->mysqli = $mysqli;
$this->config = $config;
$this->debug->append("Instantiated Block class", 2);
}
// get and set methods
private function setErrorMessage($msg) {
$this->sError = $msg;
}
public function getError() {
return $this->sError;
}
public function getTableName() {
return $this->table;
}
/** /**
* Specific method to fetch the latest block found * Specific method to fetch the latest block found
@ -35,13 +13,9 @@ class Block {
**/ **/
public function getLast() { public function getLast() {
$stmt = $this->mysqli->prepare("SELECT * FROM $this->table ORDER BY height DESC LIMIT 1"); $stmt = $this->mysqli->prepare("SELECT * FROM $this->table ORDER BY height DESC LIMIT 1");
if ($this->checkStmt($stmt)) { if ($this->checkStmt($stmt) && $stmt->execute() && $result = $stmt->get_result())
$stmt->execute();
$result = $stmt->get_result();
$stmt->close();
return $result->fetch_assoc(); return $result->fetch_assoc();
} return $this->sqlError();
return false;
} }
/** /**
@ -53,7 +27,7 @@ class Block {
$stmt = $this->mysqli->prepare("SELECT * FROM $this->table WHERE height = ? LIMIT 1"); $stmt = $this->mysqli->prepare("SELECT * FROM $this->table WHERE height = ? LIMIT 1");
if ($this->checkStmt($stmt) && $stmt->bind_param('i', $height) && $stmt->execute() && $result = $stmt->get_result()) if ($this->checkStmt($stmt) && $stmt->bind_param('i', $height) && $stmt->execute() && $result = $stmt->get_result())
return $result->fetch_assoc(); return $result->fetch_assoc();
return false; return $this->sqlError();
} }
/** /**
@ -65,7 +39,7 @@ class Block {
$stmt = $this->mysqli->prepare("SELECT * FROM $this->table WHERE share_id = ? LIMIT 1"); $stmt = $this->mysqli->prepare("SELECT * FROM $this->table WHERE share_id = ? LIMIT 1");
if ($this->checkStmt($stmt) && $stmt->bind_param('i', $share_id) && $stmt->execute() && $result = $stmt->get_result()) if ($this->checkStmt($stmt) && $stmt->bind_param('i', $share_id) && $stmt->execute() && $result = $stmt->get_result())
return $result->fetch_assoc(); return $result->fetch_assoc();
return false; return $this->sqlError();
} }
/** /**
@ -77,7 +51,7 @@ class Block {
$stmt = $this->mysqli->prepare("SELECT * FROM $this->table WHERE id = ? LIMIT 1"); $stmt = $this->mysqli->prepare("SELECT * FROM $this->table WHERE id = ? LIMIT 1");
if ($this->checkStmt($stmt) && $stmt->bind_param('i', $id) && $stmt->execute() && $result = $stmt->get_result()) if ($this->checkStmt($stmt) && $stmt->bind_param('i', $id) && $stmt->execute() && $result = $stmt->get_result())
return $result->fetch_assoc(); return $result->fetch_assoc();
return false; return $this->sqlError();
} }
/** /**
@ -89,7 +63,7 @@ class Block {
$stmt = $this->mysqli->prepare("SELECT MAX(share_id) AS share_id FROM $this->table LIMIT 1"); $stmt = $this->mysqli->prepare("SELECT MAX(share_id) AS share_id FROM $this->table LIMIT 1");
if ($this->checkStmt($stmt) && $stmt->execute() && $result = $stmt->get_result()) if ($this->checkStmt($stmt) && $stmt->execute() && $result = $stmt->get_result())
return $result->fetch_object()->share_id; return $result->fetch_object()->share_id;
return false; return $this->sqlError();
} }
/** /**
@ -101,7 +75,7 @@ class Block {
$stmt = $this->mysqli->prepare("SELECT * FROM $this->table WHERE ISNULL(share_id) ORDER BY height $order"); $stmt = $this->mysqli->prepare("SELECT * FROM $this->table WHERE ISNULL(share_id) ORDER BY height $order");
if ($this->checkStmt($stmt) && $stmt->execute() && $result = $stmt->get_result()) if ($this->checkStmt($stmt) && $stmt->execute() && $result = $stmt->get_result())
return $result->fetch_all(MYSQLI_ASSOC); return $result->fetch_all(MYSQLI_ASSOC);
return false; return $this->sqlError();
} }
/** /**
@ -113,7 +87,7 @@ class Block {
$stmt = $this->mysqli->prepare("SELECT * FROM $this->table WHERE accounted = 0 ORDER BY height $order"); $stmt = $this->mysqli->prepare("SELECT * FROM $this->table WHERE accounted = 0 ORDER BY height $order");
if ($this->checkStmt($stmt) && $stmt->execute() && $result = $stmt->get_result()) if ($this->checkStmt($stmt) && $stmt->execute() && $result = $stmt->get_result())
return $result->fetch_all(MYSQLI_ASSOC); return $result->fetch_all(MYSQLI_ASSOC);
return false; return $this->sqlError();
} }
/** /**
@ -125,7 +99,7 @@ class Block {
$stmt = $this->mysqli->prepare("SELECT COUNT(id) AS blocks FROM $this->table"); $stmt = $this->mysqli->prepare("SELECT COUNT(id) AS blocks FROM $this->table");
if ($this->checkStmt($stmt) && $stmt->execute() && $result = $stmt->get_result()) if ($this->checkStmt($stmt) && $stmt->execute() && $result = $stmt->get_result())
return (int)$result->fetch_object()->blocks; return (int)$result->fetch_object()->blocks;
return false; return $this->sqlError();
} }
/** /**
@ -137,7 +111,7 @@ class Block {
$stmt = $this->mysqli->prepare("SELECT AVG(x.shares) AS average FROM (SELECT shares FROM $this->table WHERE height <= ? ORDER BY height DESC LIMIT ?) AS x"); $stmt = $this->mysqli->prepare("SELECT AVG(x.shares) AS average FROM (SELECT shares FROM $this->table WHERE height <= ? ORDER BY height DESC LIMIT ?) AS x");
if ($this->checkStmt($stmt) && $stmt->bind_param('ii', $height, $limit) && $stmt->execute() && $result = $stmt->get_result()) if ($this->checkStmt($stmt) && $stmt->bind_param('ii', $height, $limit) && $stmt->execute() && $result = $stmt->get_result())
return (float)$result->fetch_object()->average; return (float)$result->fetch_object()->average;
return false; return $this->sqlError();
} }
/** /**
@ -149,7 +123,7 @@ class Block {
$stmt = $this->mysqli->prepare("SELECT AVG(x.amount) AS average FROM (SELECT amount FROM $this->table ORDER BY height DESC LIMIT ?) AS x"); $stmt = $this->mysqli->prepare("SELECT AVG(x.amount) AS average FROM (SELECT amount FROM $this->table ORDER BY height DESC LIMIT ?) AS x");
if ($this->checkStmt($stmt) && $stmt->bind_param('i', $limit) && $stmt->execute() && $result = $stmt->get_result()) if ($this->checkStmt($stmt) && $stmt->bind_param('i', $limit) && $stmt->execute() && $result = $stmt->get_result())
return (float)$result->fetch_object()->average; return (float)$result->fetch_object()->average;
return false; return $this->sqlError();
} }
/** /**
@ -161,7 +135,7 @@ class Block {
$stmt = $this->mysqli->prepare("SELECT * FROM $this->table WHERE confirmations < ? AND confirmations > -1"); $stmt = $this->mysqli->prepare("SELECT * FROM $this->table WHERE confirmations < ? AND confirmations > -1");
if ($this->checkStmt($stmt) && $stmt->bind_param("i", $confirmations) && $stmt->execute() && $result = $stmt->get_result()) if ($this->checkStmt($stmt) && $stmt->bind_param("i", $confirmations) && $stmt->execute() && $result = $stmt->get_result())
return $result->fetch_all(MYSQLI_ASSOC); return $result->fetch_all(MYSQLI_ASSOC);
return false; return $this->sqlError();
} }
/** /**
@ -172,13 +146,9 @@ class Block {
**/ **/
public function setConfirmations($block_id, $confirmations) { public function setConfirmations($block_id, $confirmations) {
$stmt = $this->mysqli->prepare("UPDATE $this->table SET confirmations = ? WHERE id = ?"); $stmt = $this->mysqli->prepare("UPDATE $this->table SET confirmations = ? WHERE id = ?");
if ($this->checkStmt($stmt)) { if ($this->checkStmt($stmt) && $stmt->bind_param("ii", $confirmations, $block_id) && $stmt->execute())
$stmt->bind_param("ii", $confirmations, $block_id) or die($stmt->error);
$stmt->execute() or die("Failed");
$stmt->close();
return true; return true;
} return $this->sqlError();
return false;
} }
/** /**
@ -188,13 +158,9 @@ class Block {
**/ **/
public function getAll($order='DESC') { public function getAll($order='DESC') {
$stmt = $this->mysqli->prepare("SELECT * FROM $this->table ORDER BY height $order"); $stmt = $this->mysqli->prepare("SELECT * FROM $this->table ORDER BY height $order");
if ($this->checkStmt($stmt)) { if ($this->checkStmt($stmt) && $stmt->execute() && $result = $stmt->get_result())
$stmt->execute();
$result = $stmt->get_result();
$stmt->close();
return $result->fetch_all(MYSQLI_ASSOC); return $result->fetch_all(MYSQLI_ASSOC);
} return $this->sqlError();
return false;
} }
/** /**
@ -204,50 +170,21 @@ class Block {
**/ **/
public function addBlock($block) { public function addBlock($block) {
$stmt = $this->mysqli->prepare("INSERT INTO $this->table (height, blockhash, confirmations, amount, difficulty, time) VALUES (?, ?, ?, ?, ?, ?)"); $stmt = $this->mysqli->prepare("INSERT INTO $this->table (height, blockhash, confirmations, amount, difficulty, time) VALUES (?, ?, ?, ?, ?, ?)");
if ($this->checkStmt($stmt)) { if ($this->checkStmt($stmt) && $stmt->bind_param('isiddi', $block['height'], $block['blockhash'], $block['confirmations'], $block['amount'], $block['difficulty'], $block['time']) && $stmt->execute())
$stmt->bind_param('isiddi', $block['height'], $block['blockhash'], $block['confirmations'], $block['amount'], $block['difficulty'], $block['time']);
if (!$stmt->execute()) {
$this->debug->append("Failed to execute statement: " . $stmt->error);
$this->setErrorMessage($stmt->error);
$stmt->close();
return false;
}
$stmt->close();
return true; return true;
} return $this->sqlError();
return false;
}
public function getLastUpstreamId() {
$stmt = $this->mysqli->prepare("
SELECT MAX(share_id) AS share_id FROM $this->table
");
if ($this->checkStmt($stmt) && $stmt->execute() && $stmt->bind_result($share_id) && $stmt->fetch())
return $share_id ? $share_id : 0;
// Catchall
return false;
} }
/** /**
* Update a single column within a single row * Get our last inserted upstream ID from table
* @param block_id int Block ID to update * @param none
* @param field string Column name to update * @return mixed upstream ID or 0, false on error
* @param value string Value to insert
* @return bool
**/ **/
private function updateSingle($block_id, $field, $value) { public function getLastUpstreamId() {
$stmt = $this->mysqli->prepare("UPDATE $this->table SET $field = ? WHERE id = ?"); $stmt = $this->mysqli->prepare("SELECT MAX(share_id) AS share_id FROM $this->table");
if ($this->checkStmt($stmt)) { if ($this->checkStmt($stmt) && $stmt->execute() && $stmt->bind_result($share_id) && $stmt->fetch())
$stmt->bind_param('ii', $value, $block_id); return $share_id ? $share_id : 0;
if (!$stmt->execute()) { return $this->sqlError();
$this->debug->append("Failed to update block ID $block_id with finder ID $account_id");
$stmt->close();
return false;
}
$stmt->close();
return true;
}
return false;
} }
/** /**
@ -257,7 +194,8 @@ class Block {
* @return bool * @return bool
**/ **/
public function setFinder($block_id, $account_id=NULL) { public function setFinder($block_id, $account_id=NULL) {
return $this->updateSingle($block_id, 'account_id', $account_id); $field = array( 'name' => 'account_id', 'value' => $account_id, 'type' => 'i' );
return $this->updateSingle($block_id, $field);
} }
/** /**
@ -267,7 +205,8 @@ class Block {
* @return bool * @return bool
**/ **/
public function setShareId($block_id, $share_id) { public function setShareId($block_id, $share_id) {
return $this->updateSingle($block_id, 'share_id', $share_id); $field = array( 'name' => 'share_id', 'value' => $share_id, 'type' => 'i');
return $this->updateSingle($block_id, $field);
} }
/** /**
@ -277,7 +216,8 @@ class Block {
* @return bool * @return bool
**/ **/
public function setShares($block_id, $shares=NULL) { public function setShares($block_id, $shares=NULL) {
return $this->updateSingle($block_id, 'shares', $shares); $field = array( 'name' => 'shares', 'value' => $shares, 'type' => 'i');
return $this->updateSingle($block_id, $field);
} }
/** /**
@ -287,21 +227,14 @@ class Block {
**/ **/
public function setAccounted($block_id=NULL) { public function setAccounted($block_id=NULL) {
if (empty($block_id)) return false; if (empty($block_id)) return false;
return $this->updateSingle($block_id, 'accounted', 1); $field = array( 'name' => 'accounted', 'value' => 1, 'type' => 'i');
} return $this->updateSingle($block_id, $field);
/**
* Helper function
**/
private function checkStmt($bState) {
if ($bState ===! true) {
$this->debug->append("Failed to prepare statement: " . $this->mysqli->error);
$this->setErrorMessage('Internal application Error');
return false;
}
return true;
} }
} }
// Automatically load our class for furhter usage // Automatically load our class for furhter usage
$block = new Block($debug, $mysqli, $config); $block = new Block();
$block->setDebug($debug);
$block->setMysql($mysqli);
$block->setConfig($config);
$block->setErrorCodes($aErrorCodes);

View File

@ -16,9 +16,7 @@ class Invitation extends Base {
$stmt = $this->mysqli->prepare("SELECT * FROM $this->table WHERE account_id = ?"); $stmt = $this->mysqli->prepare("SELECT * FROM $this->table WHERE account_id = ?");
if ($stmt && $stmt->bind_param('i', $account_id) && $stmt->execute() && $result = $stmt->get_result()) if ($stmt && $stmt->bind_param('i', $account_id) && $stmt->execute() && $result = $stmt->get_result())
return $result->fetch_all(MYSQLI_ASSOC); return $result->fetch_all(MYSQLI_ASSOC);
$this->setErrorMessage('Unable to fetch invitiations send from your account'); $this->sqlError('E0021');
$this->debug->append('Failed to fetch invitations from database: ' . $this->mysqli->errro);
return false;
} }
/** /**
@ -31,9 +29,7 @@ class Invitation extends Base {
$stmt = $this->mysqli->prepare("SELECT count(id) AS total FROM $this->table WHERE account_id = ?"); $stmt = $this->mysqli->prepare("SELECT count(id) AS total FROM $this->table WHERE account_id = ?");
if ($stmt && $stmt->bind_param('i', $account_id) && $stmt->execute() && $stmt->bind_result($total) && $stmt->fetch()) if ($stmt && $stmt->bind_param('i', $account_id) && $stmt->execute() && $stmt->bind_result($total) && $stmt->fetch())
return $total; return $total;
$this->setErrorMessage('Unable to fetch invitiations send from your account'); $this->sqlError('E0021');
$this->debug->append('Failed to fetch invitations from database: ' . $this->mysqli->errro);
return false;
} }
/** /**
@ -65,7 +61,7 @@ class Invitation extends Base {
**/ **/
public function setActivated($token_id) { public function setActivated($token_id) {
if (!$iInvitationId = $this->getByTokenId($token_id)) { if (!$iInvitationId = $this->getByTokenId($token_id)) {
$this->setErrorMessage('Unable to convert token ID to invitation ID'); $this->setErrorMessage($this->getErrorMsg('E0030'));
return false; return false;
} }
$field = array('name' => 'is_activated', 'type' => 'i', 'value' => 1); $field = array('name' => 'is_activated', 'type' => 'i', 'value' => 1);
@ -84,8 +80,9 @@ class Invitation extends Base {
$stmt = $this->mysqli->prepare("INSERT INTO $this->table ( account_id, email, token_id ) VALUES ( ?, ?, ?)"); $stmt = $this->mysqli->prepare("INSERT INTO $this->table ( account_id, email, token_id ) VALUES ( ?, ?, ?)");
if ($stmt && $stmt->bind_param('isi', $account_id, $email, $token_id) && $stmt->execute()) if ($stmt && $stmt->bind_param('isi', $account_id, $email, $token_id) && $stmt->execute())
return true; return true;
return false; $this->sqlError('E0022');
} }
/** /**
* Send an invitation out to a user * Send an invitation out to a user
* Uses the mail class to send mails * Uses the mail class to send mails
@ -97,39 +94,37 @@ class Invitation extends Base {
$this->debug->append("STA " . __METHOD__, 4); $this->debug->append("STA " . __METHOD__, 4);
// Check data input // Check data input
if (empty($aData['email']) || !filter_var($aData['email'], FILTER_VALIDATE_EMAIL)) { if (empty($aData['email']) || !filter_var($aData['email'], FILTER_VALIDATE_EMAIL)) {
$this->setErrorMessage( 'Invalid e-mail address' ); $this->setErrorMessage($this->getErrorMsg('E0023'));
return false; return false;
} }
if (preg_match('/[^a-z_\.\!\?\-0-9 ]/i', $aData['message'])) { if (preg_match('/[^a-z_\.\!\?\-0-9 ]/i', $aData['message'])) {
$this->setErrorMessage('Message may only contain alphanumeric characters'); $this->setErrorMessage($this->getErrorMsg('E0024'));
return false; return false;
} }
// Ensure this invitation does not exist yet nor do we have an account with that email // Ensure this invitation does not exist yet nor do we have an account with that email
if ($this->user->getEmail($aData['email'])) { if ($this->user->getEmail($aData['email'])) {
$this->setErrorMessage('This email is already registered as an account'); $this->setErrorMessage($this->getErrorMsg('E0025'));
return false; return false;
} }
if ($this->getByEmail($aData['email'])) { if ($this->getByEmail($aData['email'])) {
$this->setErrorMessage('A pending invitation for this address already exists'); $this->setErrorMessage($this->getErrorMsg('E0026'));
return false; return false;
} }
if (!$aData['token'] = $this->token->createToken('invitation', $account_id)) { if (!$aData['token'] = $this->token->createToken('invitation', $account_id)) {
$this->setErrorMessage('Unable to generate invitation token: ' . $this->token->getError()); $this->setErrorMessage($this->getErrorMsg('E0027', $this->token->getError()));
return false; return false;
} }
$aData['username'] = $this->user->getUserName($account_id); $aData['username'] = $this->user->getUserName($account_id);
$aData['subject'] = 'Pending Invitation'; $aData['subject'] = 'Pending Invitation';
if ($this->mail->sendMail('invitations/body', $aData)) { if ($this->mail->sendMail('invitations/body', $aData)) {
$aToken = $this->token->getToken($aData['token']); $aToken = $this->token->getToken($aData['token']);
if (!$this->createInvitation($account_id, $aData['email'], $aToken['id'])) { if (!$this->createInvitation($account_id, $aData['email'], $aToken['id']))
$this->setErrorMessage('Unable to create invitation record');
return false; return false;
}
return true; return true;
} else { } else {
$this->setErrorMessage('Unable to send email to recipient'); $this->setErrorMessage($this->getErrorMsg('E0028'));
} }
$this->setErrorMessage('Unable to send invitation'); $this->setErrorMessage($this->getErrorMsg('E0029'));
return false; return false;
} }
} }
@ -142,5 +137,5 @@ $invitation->setMail($mail);
$invitation->setUser($user); $invitation->setUser($user);
$invitation->setToken($oToken); $invitation->setToken($oToken);
$invitation->setConfig($config); $invitation->setConfig($config);
$invitation->setErrorCodes($aErrorCodes);
?> ?>

View File

@ -5,16 +5,6 @@ if (!defined('SECURITY'))
die('Hacking attempt'); die('Hacking attempt');
class Mail extends Base { class Mail extends Base {
function checkStmt($bState) {
$this->debug->append("STA " . __METHOD__, 4);
if ($bState ===! true) {
$this->debug->append("Failed to prepare statement: " . $this->mysqli->error);
$this->setErrorMessage('Internal application Error');
return false;
}
return true;
}
/** /**
* Mail form contact site admin * Mail form contact site admin
* @param senderName string senderName * @param senderName string senderName
@ -28,19 +18,19 @@ class Mail extends Base {
public function contactform($senderName, $senderEmail, $senderSubject, $senderMessage) { public function contactform($senderName, $senderEmail, $senderSubject, $senderMessage) {
$this->debug->append("STA " . __METHOD__, 4); $this->debug->append("STA " . __METHOD__, 4);
if (preg_match('/[^a-z_\.\!\?\-0-9\\s ]/i', $senderName)) { if (preg_match('/[^a-z_\.\!\?\-0-9\\s ]/i', $senderName)) {
$this->setErrorMessage('Username may only contain alphanumeric characters'); $this->setErrorMessage($this->getErrorMsg('E0024'));
return false; return false;
} }
if (empty($senderEmail) || !filter_var($senderEmail, FILTER_VALIDATE_EMAIL)) { if (empty($senderEmail) || !filter_var($senderEmail, FILTER_VALIDATE_EMAIL)) {
$this->setErrorMessage( 'Invalid e-mail address' ); $this->setErrorMessage($this->getErrorMsg('E0023'));
return false; return false;
} }
if (preg_match('/[^a-z_\.\!\?\-0-9\\s ]/i', $senderSubject)) { if (preg_match('/[^a-z_\.\!\?\-0-9\\s ]/i', $senderSubject)) {
$this->setErrorMessage('Subject may only contain alphanumeric characters'); $this->setErrorMessage($this->getErrorMsg('E0034'));
return false; return false;
} }
if (strlen(strip_tags($senderMessage)) < strlen($senderMessage)) { if (strlen(strip_tags($senderMessage)) < strlen($senderMessage)) {
$this->setErrorMessage('Your message may only contain alphanumeric characters'); $this->setErrorMessage($this->getErrorMsg('E0024'));
return false; return false;
} }
$aData['senderName'] = $senderName; $aData['senderName'] = $senderName;
@ -58,6 +48,13 @@ class Mail extends Base {
return false; return false;
} }
/**
* Send a mail with templating via Smarty
* @param template string Template name within the mail folder, no extension
* @param aData array Data array with some required fields
* SUBJECT : Mail Subject
* email : Destination address
**/
public function sendMail($template, $aData) { public function sendMail($template, $aData) {
$this->smarty->assign('WEBSITENAME', $this->setting->getValue('website_name')); $this->smarty->assign('WEBSITENAME', $this->setting->getValue('website_name'));
$this->smarty->assign('SUBJECT', $aData['subject']); $this->smarty->assign('SUBJECT', $aData['subject']);
@ -67,7 +64,7 @@ class Mail extends Base {
$headers .= "Content-Type: text/html; charset=ISO-8859-1\r\n"; $headers .= "Content-Type: text/html; charset=ISO-8859-1\r\n";
if (mail($aData['email'], $this->smarty->fetch(BASEPATH . 'templates/mail/subject.tpl'), $this->smarty->fetch(BASEPATH . 'templates/mail/' . $template . '.tpl'), $headers)) if (mail($aData['email'], $this->smarty->fetch(BASEPATH . 'templates/mail/subject.tpl'), $this->smarty->fetch(BASEPATH . 'templates/mail/' . $template . '.tpl'), $headers))
return true; return true;
$this->setErrorMessage('Unable to send mail'); $this->setErrorMessage($this->sqlError('E0031'));
return false; return false;
} }
} }
@ -79,4 +76,5 @@ $mail->setMysql($mysqli);
$mail->setSmarty($smarty); $mail->setSmarty($smarty);
$mail->setConfig($config); $mail->setConfig($config);
$mail->setSetting($setting); $mail->setSetting($setting);
$mail->setErrorCodes($aErrorCodes);
?> ?>

View File

@ -1,13 +1,10 @@
<?php <?php
// Make sure we are called from index.php // Make sure we are called from index.php
if (!defined('SECURITY')) if (!defined('SECURITY')) die('Hacking attempt');
die('Hacking attempt');
class Monitoring extends Base { class Monitoring extends Base {
public function __construct() { protected $table = 'monitoring';
$this->table = 'monitoring';
}
/** /**
* Store Uptime Robot status information as JSON in settings table * Store Uptime Robot status information as JSON in settings table
@ -24,15 +21,20 @@ class Monitoring extends Base {
$aMonitor['api_key'] = $temp[0]; $aMonitor['api_key'] = $temp[0];
$aMonitor['monitor_id'] = $temp[1]; $aMonitor['monitor_id'] = $temp[1];
$target = '/getMonitors?apiKey=' . $aMonitor['api_key'] . '&monitors=' . $aMonitor['monitor_id'] . '&format=json&noJsonCallback=1&customUptimeRatio=1-7-30&logs=1'; $target = '/getMonitors?apiKey=' . $aMonitor['api_key'] . '&monitors=' . $aMonitor['monitor_id'] . '&format=json&noJsonCallback=1&customUptimeRatio=1-7-30&logs=1';
if (!$aMonitorStatus = $this->tools->getApi($url, $target)) { $aMonitorStatus = $this->tools->getApi($url, $target);
$this->setErrorMessage('Failed to run API call: ' . $this->tools->getError()); if (!$aMonitorStatus || @$aMonitorStatus['stat'] == 'fail') {
if (is_array($aMonitorStatus) && array_key_exists('message', @$aMonitorStatus)) {
$this->setErrorMessage($this->getErrorMsg('E0032', $aMonitorStatus['message']));
} else {
$this->setErrorMessage($this->getErrorMsg('E0032', $this->tools->getError()));
}
return false; return false;
} }
$aMonitorStatus['monitors']['monitor'][0]['customuptimeratio'] = explode('-', $aMonitorStatus['monitors']['monitor'][0]['customuptimeratio']); $aMonitorStatus['monitors']['monitor'][0]['customuptimeratio'] = explode('-', $aMonitorStatus['monitors']['monitor'][0]['customuptimeratio']);
$aAllMonitorsStatus[] = $aMonitorStatus['monitors']['monitor'][0]; $aAllMonitorsStatus[] = $aMonitorStatus['monitors']['monitor'][0];
} }
if (!$this->setting->setValue('monitoring_uptimerobot_status', json_encode($aAllMonitorsStatus)) || !$this->setting->setValue('monitoring_uptimerobot_lastcheck', time())) { if (!$this->setting->setValue('monitoring_uptimerobot_status', json_encode($aAllMonitorsStatus)) || !$this->setting->setValue('monitoring_uptimerobot_lastcheck', time())) {
$this->setErrorMessage('Failed to store uptime status: ' . $setting->getError()); $this->setErrorMessage($this->getErrorMsg('E0033'), $setting->getError());
return false; return false;
} }
} }
@ -50,6 +52,16 @@ class Monitoring extends Base {
return false; return false;
} }
/**
* Check that our cron is currently activated
* @param name string Cronjob name
* @return bool true or false
**/
public function isDisabled($name) {
$aStatus = $this->getStatus($name . '_disabled');
return $aStatus['value'];
}
/** /**
* Fetch a value from our table * Fetch a value from our table
* @param name string Setting name * @param name string Setting name
@ -60,8 +72,7 @@ class Monitoring extends Base {
if ($query && $query->bind_param('s', $name) && $query->execute() && $result = $query->get_result()) { if ($query && $query->bind_param('s', $name) && $query->execute() && $result = $query->get_result()) {
return $result->fetch_assoc(); return $result->fetch_assoc();
} else { } else {
$this->debug->append("Failed to fetch variable $name from $this->table"); $this->sqlError();
return false;
} }
return $value; return $value;
} }
@ -83,10 +94,41 @@ class Monitoring extends Base {
$this->debug->append("Failed to set $name to $value"); $this->debug->append("Failed to set $name to $value");
return false; return false;
} }
/**
* End cronjob with an error message
* @param cron_name string Cronjob Name
* @param msgCode string Message code as stored in error_codes array
* @param exitCode int Exit code to pass on to exit function and monitor report
* @param fatal boolean Should we exit out entirely
* @return none
**/
public function endCronjob($cron_name, $msgCode, $exitCode=0, $fatal=false, $mail=true) {
$this->setStatus($cron_name . "_active", "yesno", 0);
$this->setStatus($cron_name . "_message", "message", $this->getErrorMsg($msgCode));
$this->setStatus($cron_name . "_status", "okerror", $exitCode);
$this->setStatus($cron_name . "_endtime", "date", time());
if ($mail) {
$aMailData = array(
'email' => $this->setting->getValue('system_error_email'),
'subject' => 'Cronjob Failure',
'Error Code' => $msgCode,
'Error Message' => $this->getErrorMsg($msgCode)
);
if (!$this->mail->sendMail('notifications/error', $aMailData))
$this->setErrorMessage('Failed to send mail notification');
}
if ($fatal) {
if ($exitCode != 0) $this->setStatus($cron_name . "_disabled", "yesno", 1);
exit($exitCode);
}
}
} }
$monitoring = new Monitoring(); $monitoring = new Monitoring();
$monitoring->setErrorCodes($aErrorCodes);
$monitoring->setConfig($config); $monitoring->setConfig($config);
$monitoring->setDebug($debug); $monitoring->setDebug($debug);
$monitoring->setMail($mail);
$monitoring->setMysql($mysqli); $monitoring->setMysql($mysqli);
$monitoring->setSetting($setting); $monitoring->setSetting($setting);

View File

@ -5,13 +5,23 @@ if (!defined('SECURITY'))
die('Hacking attempt'); die('Hacking attempt');
class News extends Base { class News extends Base {
var $table = 'news'; protected $table = 'news';
/**
* Get activation status of post
* @param id int News ID
* @return bool true or false
**/
public function getActive($id) { public function getActive($id) {
$this->debug->append("STA " . __METHOD__, 5); $this->debug->append("STA " . __METHOD__, 5);
return $this->getSingle($id, 'active', 'id'); return $this->getSingle($id, 'active', 'id');
} }
/**
* Switch activation status
* @param id int News ID
* @return bool true or false
**/
public function toggleActive($id) { public function toggleActive($id) {
$this->debug->append("STA " . __METHOD__, 5); $this->debug->append("STA " . __METHOD__, 5);
$field = array('name' => 'active', 'type' => 'i', 'value' => !$this->getActive($id)); $field = array('name' => 'active', 'type' => 'i', 'value' => !$this->getActive($id));
@ -26,8 +36,7 @@ class News extends Base {
$stmt = $this->mysqli->prepare("SELECT n.*, a.username AS author FROM $this->table AS n LEFT JOIN " . $this->user->getTableName() . " AS a ON a.id = n.account_id WHERE active = 1 ORDER BY time DESC"); $stmt = $this->mysqli->prepare("SELECT n.*, a.username AS author FROM $this->table AS n LEFT JOIN " . $this->user->getTableName() . " AS a ON a.id = n.account_id WHERE active = 1 ORDER BY time DESC");
if ($stmt && $stmt->execute() && $result = $stmt->get_result()) if ($stmt && $stmt->execute() && $result = $stmt->get_result())
return $result->fetch_all(MYSQLI_ASSOC); return $result->fetch_all(MYSQLI_ASSOC);
// Catchall return $this->sqlError('E0040');
return false;
} }
/** /**
@ -38,8 +47,7 @@ class News extends Base {
$stmt = $this->mysqli->prepare("SELECT n.*, a.username AS author FROM $this->table AS n LEFT JOIN " . $this->user->getTableName() . " AS a ON a.id = n.account_id ORDER BY time DESC"); $stmt = $this->mysqli->prepare("SELECT n.*, a.username AS author FROM $this->table AS n LEFT JOIN " . $this->user->getTableName() . " AS a ON a.id = n.account_id ORDER BY time DESC");
if ($stmt && $stmt->execute() && $result = $stmt->get_result()) if ($stmt && $stmt->execute() && $result = $stmt->get_result())
return $result->fetch_all(MYSQLI_ASSOC); return $result->fetch_all(MYSQLI_ASSOC);
// Catchall return $this->sqlError('E0039');
return false;
} }
/** /**
@ -50,8 +58,7 @@ class News extends Base {
$stmt = $this->mysqli->prepare("SELECT * FROM $this->table WHERE id = ?"); $stmt = $this->mysqli->prepare("SELECT * FROM $this->table WHERE id = ?");
if ($stmt && $stmt->bind_param('i', $id) && $stmt->execute() && $result = $stmt->get_result()) if ($stmt && $stmt->bind_param('i', $id) && $stmt->execute() && $result = $stmt->get_result())
return $result->fetch_assoc(); return $result->fetch_assoc();
// Catchall return $this->sqlError('E0038');
return false;
} }
/** /**
@ -62,8 +69,7 @@ class News extends Base {
$stmt = $this->mysqli->prepare("UPDATE $this->table SET content = ?, header = ?, active = ? WHERE id = ?"); $stmt = $this->mysqli->prepare("UPDATE $this->table SET content = ?, header = ?, active = ? WHERE id = ?");
if ($stmt && $stmt->bind_param('ssii', $content, $header, $active, $id) && $stmt->execute() && $stmt->affected_rows == 1) if ($stmt && $stmt->bind_param('ssii', $content, $header, $active, $id) && $stmt->execute() && $stmt->affected_rows == 1)
return true; return true;
$this->setErrorMessage("Failed to update news entry $id"); return $this->sqlError('E0037');
return false;
} }
public function deleteNews($id) { public function deleteNews($id) {
@ -72,8 +78,7 @@ class News extends Base {
$stmt = $this->mysqli->prepare("DELETE FROM $this->table WHERE id = ?"); $stmt = $this->mysqli->prepare("DELETE FROM $this->table WHERE id = ?");
if ($this->checkStmt($stmt) && $stmt->bind_param('i', $id) && $stmt->execute() && $stmt->affected_rows == 1) if ($this->checkStmt($stmt) && $stmt->bind_param('i', $id) && $stmt->execute() && $stmt->affected_rows == 1)
return true; return true;
$this->setErrorMessage("Failed to delete news entry $id"); return $this->sqlError('E0036');
return false;
} }
/** /**
@ -89,9 +94,7 @@ class News extends Base {
$stmt = $this->mysqli->prepare("INSERT INTO $this->table (account_id, header, content, active) VALUES (?,?,?,?)"); $stmt = $this->mysqli->prepare("INSERT INTO $this->table (account_id, header, content, active) VALUES (?,?,?,?)");
if ($stmt && $stmt->bind_param('issi', $account_id, $aData['header'], $aData['content'], $active) && $stmt->execute()) if ($stmt && $stmt->bind_param('issi', $account_id, $aData['header'], $aData['content'], $active) && $stmt->execute())
return true; return true;
$this->debug->append("Failed to add news: " . $this->mysqli->error); return $this->sqlError('E0035');
$this->setErrorMessage("Unable to add new news: " . $this->mysqli->error);
return false;
} }
} }

View File

@ -27,9 +27,7 @@ class Notification extends Mail {
$stmt = $this->mysqli->prepare("SELECT id FROM $this->table WHERE data = ? AND active = 1 LIMIT 1"); $stmt = $this->mysqli->prepare("SELECT id FROM $this->table WHERE data = ? AND active = 1 LIMIT 1");
if ($stmt && $stmt->bind_param('s', $data) && $stmt->execute() && $stmt->store_result() && $stmt->num_rows == 1) if ($stmt && $stmt->bind_param('s', $data) && $stmt->execute() && $stmt->store_result() && $stmt->num_rows == 1)
return true; return true;
// Catchall return $this->sqlError('E0041');
// Does not seem to have a notification set
return false;
} }
/** /**
@ -37,11 +35,10 @@ class Notification extends Mail {
**/ **/
public function getAllActive($strType) { public function getAllActive($strType) {
$this->debug->append("STA " . __METHOD__, 4); $this->debug->append("STA " . __METHOD__, 4);
$stmt =$this->mysqli->prepare("SELECT id, data FROM $this->table WHERE active = 1 AND type = ?"); $stmt =$this->mysqli->prepare("SELECT id2, data FROM $this->table WHERE active = 1 AND type = ?");
if ($stmt && $stmt->bind_param('s', $strType) && $stmt->execute() && $result = $stmt->get_result()) if ($stmt && $stmt->bind_param('s', $strType) && $stmt->execute() && $result = $stmt->get_result())
return $result->fetch_all(MYSQLI_ASSOC); return $result->fetch_all(MYSQLI_ASSOC);
// Catchall return $this->sqlError('E0042');
return false;
} }
/** /**
@ -56,9 +53,7 @@ class Notification extends Mail {
$stmt = $this->mysqli->prepare("INSERT INTO $this->table (account_id, type, data, active) VALUES (?, ?,?,1)"); $stmt = $this->mysqli->prepare("INSERT INTO $this->table (account_id, type, data, active) VALUES (?, ?,?,1)");
if ($stmt && $stmt->bind_param('iss', $account_id, $type, $data) && $stmt->execute()) if ($stmt && $stmt->bind_param('iss', $account_id, $type, $data) && $stmt->execute())
return true; return true;
$this->debug->append("Failed to add notification for $type with $data: " . $this->mysqli->error); return $this->sqlError('E0043');
$this->setErrorMessage("Unable to add new notification " . $this->mysqli->error);
return false;
} }
/** /**
@ -71,8 +66,7 @@ class Notification extends Mail {
$stmt = $this->mysqli->prepare("SELECT * FROM $this->table WHERE account_id = ? ORDER BY time DESC"); $stmt = $this->mysqli->prepare("SELECT * FROM $this->table WHERE account_id = ? ORDER BY time DESC");
if ($stmt && $stmt->bind_param('i', $account_id) && $stmt->execute() && $result = $stmt->get_result()) if ($stmt && $stmt->bind_param('i', $account_id) && $stmt->execute() && $result = $stmt->get_result())
return $result->fetch_all(MYSQLI_ASSOC); return $result->fetch_all(MYSQLI_ASSOC);
// Catchall return $this->getError();
return false;
} }
/** /**
@ -91,10 +85,7 @@ class Notification extends Mail {
return $aData; return $aData;
} }
} }
// Catchall return $this->sqlError('E0045');
$this->setErrorMessage('Unable to fetch notification settings');
$this->debug->append('Failed fetching notification settings for ' . $account_id . ': ' . $this->mysqli->error);
return false;
} }
/** /**
@ -108,8 +99,7 @@ class Notification extends Mail {
if ($stmt && $stmt->bind_param('s', $strType) && $stmt->execute() && $result = $stmt->get_result()) { if ($stmt && $stmt->bind_param('s', $strType) && $stmt->execute() && $result = $stmt->get_result()) {
return $result->fetch_all(MYSQLI_ASSOC); return $result->fetch_all(MYSQLI_ASSOC);
} }
// Catchall return $this->sqlError('E0046');
return false;
} }
/** /**
@ -142,7 +132,7 @@ class Notification extends Mail {
} }
} }
if ($failed > 0) { if ($failed > 0) {
$this->setErrorMessage('Failed to update ' . $failed . ' settings'); $this->setErrorMessage($this->getErrorMsg('E0047', $failed));
return false; return false;
} }
return true; return true;
@ -183,4 +173,5 @@ $notification->setMysql($mysqli);
$notification->setSmarty($smarty); $notification->setSmarty($smarty);
$notification->setConfig($config); $notification->setConfig($config);
$notification->setSetting($setting); $notification->setSetting($setting);
$notification->setErrorCodes($aErrorCodes);
?> ?>

View File

@ -4,7 +4,7 @@
if (!defined('SECURITY')) die('Hacking attempt'); if (!defined('SECURITY')) die('Hacking attempt');
class Payout Extends Base { class Payout Extends Base {
var $table = 'payouts'; protected $table = 'payouts';
/** /**
* Check if the user has an active payout request already * Check if the user has an active payout request already
@ -15,7 +15,7 @@ class Payout Extends Base {
$stmt = $this->mysqli->prepare("SELECT id FROM $this->table WHERE completed = 0 AND account_id = ? LIMIT 1"); $stmt = $this->mysqli->prepare("SELECT id FROM $this->table WHERE completed = 0 AND account_id = ? LIMIT 1");
if ($stmt && $stmt->bind_param('i', $account_id) && $stmt->execute( )&& $stmt->store_result() && $stmt->num_rows > 0) if ($stmt && $stmt->bind_param('i', $account_id) && $stmt->execute( )&& $stmt->store_result() && $stmt->num_rows > 0)
return true; return true;
return false; return $this->sqlError('E0048');
} }
/** /**
@ -27,7 +27,7 @@ class Payout Extends Base {
$stmt = $this->mysqli->prepare("SELECT * FROM $this->table WHERE completed = 0"); $stmt = $this->mysqli->prepare("SELECT * FROM $this->table WHERE completed = 0");
if ($this->checkStmt($stmt) && $stmt->execute() && $result = $stmt->get_result()) if ($this->checkStmt($stmt) && $stmt->execute() && $result = $stmt->get_result())
return $result->fetch_all(MYSQLI_ASSOC); return $result->fetch_all(MYSQLI_ASSOC);
return false; return $this->sqlError('E0050');
} }
/** /**
@ -40,9 +40,7 @@ class Payout Extends Base {
if ($stmt && $stmt->bind_param('i', $account_id) && $stmt->execute()) { if ($stmt && $stmt->bind_param('i', $account_id) && $stmt->execute()) {
return $stmt->insert_id; return $stmt->insert_id;
} }
$this->setErrorMessage('Unable to create new payout request'); return $this->sqlError('E0049');
$this->debug->append('Failed to create new payout request in database: ' . $this->mysqli->error);
return false;
} }
/** /**
@ -54,10 +52,13 @@ class Payout Extends Base {
$stmt = $this->mysqli->prepare("UPDATE $this->table SET completed = 1 WHERE id = ?"); $stmt = $this->mysqli->prepare("UPDATE $this->table SET completed = 1 WHERE id = ?");
if ($stmt && $stmt->bind_param('i', $id) && $stmt->execute()) if ($stmt && $stmt->bind_param('i', $id) && $stmt->execute())
return true; return true;
return false; return $this->sqlError('E0051');
} }
} }
$oPayout = new Payout(); $oPayout = new Payout();
$oPayout->setDebug($debug); $oPayout->setDebug($debug);
$oPayout->setMysql($mysqli); $oPayout->setMysql($mysqli);
$oPayout->setErrorCodes($aErrorCodes);
?>

View File

@ -4,41 +4,25 @@
if (!defined('SECURITY')) if (!defined('SECURITY'))
die('Hacking attempt'); die('Hacking attempt');
class RoundStats { class RoundStats extends Base {
private $sError = '';
private $tableTrans = 'transactions'; private $tableTrans = 'transactions';
private $tableStats = 'statistics_shares'; private $tableStats = 'statistics_shares';
private $tableBlocks = 'blocks'; private $tableBlocks = 'blocks';
private $tableUsers = 'accounts'; private $tableUsers = 'accounts';
public function __construct($debug, $mysqli, $config) {
$this->debug = $debug;
$this->mysqli = $mysqli;
$this->config = $config;
$this->debug->append("Instantiated RoundStats class", 2);
}
// get and set methods
private function setErrorMessage($msg) {
$this->sError = $msg;
}
public function getError() {
return $this->sError;
}
/** /**
* Get next block for round stats * Get next block for round stats
**/ **/
public function getNextBlock($iHeight=0) { public function getNextBlock($iHeight=0) {
$stmt = $this->mysqli->prepare(" $stmt = $this->mysqli->prepare("
SELECT height SELECT height
FROM $this->tableBlocks FROM " . $this->block->getTableName() . "
WHERE height > ? WHERE height > ?
ORDER BY height ASC ORDER BY height ASC
LIMIT 1"); LIMIT 1");
if ($this->checkStmt($stmt) && $stmt->bind_param('i', $iHeight) && $stmt->execute() && $result = $stmt->get_result()) if ($this->checkStmt($stmt) && $stmt->bind_param('i', $iHeight) && $stmt->execute() && $result = $stmt->get_result())
return $result->fetch_object()->height; return $result->fetch_object()->height;
return false; return $this->sqlError();
} }
/** /**
@ -47,13 +31,13 @@ class RoundStats {
public function getPreviousBlock($iHeight=0) { public function getPreviousBlock($iHeight=0) {
$stmt = $this->mysqli->prepare(" $stmt = $this->mysqli->prepare("
SELECT height SELECT height
FROM $this->tableBlocks FROM " . $this->block->getTableName() . "
WHERE height < ? WHERE height < ?
ORDER BY height DESC ORDER BY height DESC
LIMIT 1"); LIMIT 1");
if ($this->checkStmt($stmt) && $stmt->bind_param('i', $iHeight) && $stmt->execute() && $result = $stmt->get_result()) if ($this->checkStmt($stmt) && $stmt->bind_param('i', $iHeight) && $stmt->execute() && $result = $stmt->get_result())
return $result->fetch_object()->height; return $result->fetch_object()->height;
return false; return $this->sqlError();
} }
/** /**
@ -62,13 +46,13 @@ class RoundStats {
public function searchForBlockHeight($iHeight=0) { public function searchForBlockHeight($iHeight=0) {
$stmt = $this->mysqli->prepare(" $stmt = $this->mysqli->prepare("
SELECT height SELECT height
FROM $this->tableBlocks FROM " . $this->block->getTableName() . "
WHERE height >= ? WHERE height >= ?
ORDER BY height ASC ORDER BY height ASC
LIMIT 1"); LIMIT 1");
if ($this->checkStmt($stmt) && $stmt->bind_param('i', $iHeight) && $stmt->execute() && $result = $stmt->get_result()) if ($this->checkStmt($stmt) && $stmt->bind_param('i', $iHeight) && $stmt->execute() && $result = $stmt->get_result())
return $result->fetch_object()->height; return $result->fetch_object()->height;
return false; return $this->sqlError();
} }
/** /**
@ -76,13 +60,15 @@ class RoundStats {
**/ **/
public function getNextBlockForStats($iHeight=0, $limit=10) { public function getNextBlockForStats($iHeight=0, $limit=10) {
$stmt = $this->mysqli->prepare(" $stmt = $this->mysqli->prepare("
SELECT MAX(x.height) AS height SELECT MAX(x.height) AS height
FROM (SELECT height FROM $this->tableBlocks FROM (
WHERE height >= ? SELECT height FROM " . $this->block->getTableName() . "
ORDER BY height ASC LIMIT ?) AS x"); WHERE height >= ?
ORDER BY height ASC LIMIT ?
) AS x");
if ($this->checkStmt($stmt) && $stmt->bind_param("ii", $iHeight, $limit) && $stmt->execute() && $result = $stmt->get_result()) if ($this->checkStmt($stmt) && $stmt->bind_param("ii", $iHeight, $limit) && $stmt->execute() && $result = $stmt->get_result())
return $result->fetch_object()->height; return $result->fetch_object()->height;
return false; return $this->sqlError();
} }
/** /**
@ -95,14 +81,14 @@ class RoundStats {
SELECT SELECT
b.id, height, blockhash, amount, confirmations, difficulty, FROM_UNIXTIME(time) as time, shares, b.id, height, blockhash, amount, confirmations, difficulty, FROM_UNIXTIME(time) as time, shares,
IF(a.is_anonymous, 'anonymous', a.username) AS finder, IF(a.is_anonymous, 'anonymous', a.username) AS finder,
ROUND((difficulty * 65535) / POW(2, (" . $this->config['difficulty'] . " -16)), 0) AS estshares, ROUND((difficulty * 65535) / POW(2, (" . $this->config['difficulty'] . " -16)), 0) AS estshares,
(time - (SELECT time FROM $this->tableBlocks WHERE height < ? ORDER BY height DESC LIMIT 1)) AS round_time (time - (SELECT time FROM $this->tableBlocks WHERE height < ? ORDER BY height DESC LIMIT 1)) AS round_time
FROM $this->tableBlocks as b FROM " . $this->block->getTableName() . " as b
LEFT JOIN $this->tableUsers AS a ON b.account_id = a.id LEFT JOIN " . $this->user->getTableName() . " AS a ON b.account_id = a.id
WHERE b.height = ? LIMIT 1"); WHERE b.height = ? LIMIT 1");
if ($this->checkStmt($stmt) && $stmt->bind_param('ii', $iHeight, $iHeight) && $stmt->execute() && $result = $stmt->get_result()) if ($this->checkStmt($stmt) && $stmt->bind_param('ii', $iHeight, $iHeight) && $stmt->execute() && $result = $stmt->get_result())
return $result->fetch_assoc(); return $result->fetch_assoc();
return false; return $this->sqlError();
} }
/** /**
@ -118,9 +104,9 @@ class RoundStats {
a.is_anonymous, a.is_anonymous,
s.valid, s.valid,
s.invalid s.invalid
FROM $this->tableStats AS s FROM " . $this->statistics->getTableName() . " AS s
LEFT JOIN $this->tableBlocks AS b ON s.block_id = b.id LEFT JOIN " . $this->block->getTableName() . " AS b ON s.block_id = b.id
LEFT JOIN $this->tableUsers AS a ON a.id = s.account_id LEFT JOIN " . $this->user->getTableName() . " AS a ON a.id = s.account_id
WHERE b.height = ? WHERE b.height = ?
GROUP BY username ASC GROUP BY username ASC
ORDER BY valid DESC ORDER BY valid DESC
@ -131,7 +117,7 @@ class RoundStats {
} }
return $aData; return $aData;
} }
return false; return $this->sqlError();
} }
/** /**
@ -146,16 +132,16 @@ class RoundStats {
a.is_anonymous, a.is_anonymous,
s.pplns_valid, s.pplns_valid,
s.pplns_invalid s.pplns_invalid
FROM $this->tableStats AS s FROM " . $this->statistics->getTableName() . " AS s
LEFT JOIN $this->tableBlocks AS b ON s.block_id = b.id LEFT JOIN " . $this->block->getTableName() . " AS b ON s.block_id = b.id
LEFT JOIN $this->tableUsers AS a ON a.id = s.account_id LEFT JOIN " . $this->user->getTableName() . " AS a ON a.id = s.account_id
WHERE b.height = ? WHERE b.height = ?
GROUP BY username ASC GROUP BY username ASC
ORDER BY pplns_valid DESC ORDER BY pplns_valid DESC
"); ");
if ($this->checkStmt($stmt) && $stmt->bind_param('i', $iHeight) && $stmt->execute() && $result = $stmt->get_result()) if ($this->checkStmt($stmt) && $stmt->bind_param('i', $iHeight) && $stmt->execute() && $result = $stmt->get_result())
return $result->fetch_all(MYSQLI_ASSOC); return $result->fetch_all(MYSQLI_ASSOC);
return false; return $this->sqlError();
} }
/** /**
@ -165,13 +151,13 @@ class RoundStats {
$stmt = $this->mysqli->prepare(" $stmt = $this->mysqli->prepare("
SELECT SELECT
SUM(s.pplns_valid) AS pplns_valid SUM(s.pplns_valid) AS pplns_valid
FROM $this->tableStats AS s FROM " . $this->statistics->getTableName() . " AS s
LEFT JOIN $this->tableBlocks AS b ON s.block_id = b.id LEFT JOIN " . $this->block->getTableName() . " AS b ON s.block_id = b.id
WHERE b.height = ? WHERE b.height = ?
"); ");
if ($this->checkStmt($stmt) && $stmt->bind_param('i', $iHeight) && $stmt->execute() && $result = $stmt->get_result()) if ($this->checkStmt($stmt) && $stmt->bind_param('i', $iHeight) && $stmt->execute() && $result = $stmt->get_result())
return $result->fetch_object()->pplns_valid; return $result->fetch_object()->pplns_valid;
return false; return $this->sqlError();
} }
/** /**
@ -189,15 +175,15 @@ class RoundStats {
a.is_anonymous, a.is_anonymous,
t.type AS type, t.type AS type,
t.amount AS amount t.amount AS amount
FROM $this->tableTrans AS t FROM " . $this->transaction->getTableName() . " AS t
LEFT JOIN $this->tableBlocks AS b ON t.block_id = b.id LEFT JOIN " . $this->block->getTableName() . " AS b ON t.block_id = b.id
LEFT JOIN $this->tableUsers AS a ON t.account_id = a.id LEFT JOIN " . $this->user->getTableName() . " AS a ON t.account_id = a.id
WHERE b.height = ? AND t.type = 'Credit' WHERE b.height = ? AND t.type = 'Credit'
ORDER BY amount DESC"); ORDER BY amount DESC");
if ($this->checkStmt($stmt) && $stmt->bind_param('i', $iHeight) && $stmt->execute() && $result = $stmt->get_result()) if ($this->checkStmt($stmt) && $stmt->bind_param('i', $iHeight) && $stmt->execute() && $result = $stmt->get_result())
return $result->fetch_all(MYSQLI_ASSOC); return $result->fetch_all(MYSQLI_ASSOC);
$this->debug->append('Unable to fetch transactions'); $this->debug->append('Unable to fetch transactions');
return false; return $this->sqlError();
} }
/** /**
@ -214,15 +200,15 @@ class RoundStats {
a.username AS username, a.username AS username,
t.type AS type, t.type AS type,
t.amount AS amount t.amount AS amount
FROM $this->tableTrans AS t FROM " . $this->transaction->getTableName() . " AS t
LEFT JOIN $this->tableBlocks AS b ON t.block_id = b.id LEFT JOIN " . $this->block->getTableName() . " AS b ON t.block_id = b.id
LEFT JOIN $this->tableUsers AS a ON t.account_id = a.id LEFT JOIN " . $this->user->getTableName() . " AS a ON t.account_id = a.id
WHERE b.height = ? AND a.id = ? WHERE b.height = ? AND a.id = ?
ORDER BY id ASC"); ORDER BY id ASC");
if ($this->checkStmt($stmt) && $stmt->bind_param('ii', $iHeight, $id) && $stmt->execute() && $result = $stmt->get_result()) if ($this->checkStmt($stmt) && $stmt->bind_param('ii', $iHeight, $id) && $stmt->execute() && $result = $stmt->get_result())
return $result->fetch_all(MYSQLI_ASSOC); return $result->fetch_all(MYSQLI_ASSOC);
$this->debug->append('Unable to fetch transactions'); $this->debug->append('Unable to fetch transactions');
return false; return $this->sqlError();
} }
/** /**
@ -232,12 +218,12 @@ class RoundStats {
$stmt = $this->mysqli->prepare(" $stmt = $this->mysqli->prepare("
SELECT SELECT
height, shares height, shares
FROM $this->tableBlocks FROM " . $this->block->getTableName() . "
WHERE height <= ? WHERE height <= ?
ORDER BY height DESC LIMIT ?"); ORDER BY height DESC LIMIT ?");
if ($this->checkStmt($stmt) && $stmt->bind_param("ii", $iHeight, $limit) && $stmt->execute() && $result = $stmt->get_result()) if ($this->checkStmt($stmt) && $stmt->bind_param("ii", $iHeight, $limit) && $stmt->execute() && $result = $stmt->get_result())
return $result->fetch_all(MYSQLI_ASSOC); return $result->fetch_all(MYSQLI_ASSOC);
return false; return $this->sqlError();
} }
/** /**
@ -247,14 +233,14 @@ class RoundStats {
$stmt = $this->mysqli->prepare(" $stmt = $this->mysqli->prepare("
SELECT SELECT
b.height, b.shares b.height, b.shares
FROM $this->tableBlocks AS b FROM " . $this->block->getTableName() . " AS b
LEFT JOIN $this->tableStats AS s ON s.block_id = b.id LEFT JOIN " . $this->statistics->getTableName() . " AS s ON s.block_id = b.id
LEFT JOIN $this->tableUsers AS a ON a.id = s.account_id LEFT JOIN " . $this->user->getTableName() . " AS a ON a.id = s.account_id
WHERE b.height <= ? AND a.id = ? WHERE b.height <= ? AND a.id = ?
ORDER BY height DESC LIMIT ?"); ORDER BY height DESC LIMIT ?");
if ($this->checkStmt($stmt) && $stmt->bind_param('iii', $iHeight, $iUser, $limit) && $stmt->execute() && $result = $stmt->get_result()) if ($this->checkStmt($stmt) && $stmt->bind_param('iii', $iHeight, $iUser, $limit) && $stmt->execute() && $result = $stmt->get_result())
return $result->fetch_all(MYSQLI_ASSOC); return $result->fetch_all(MYSQLI_ASSOC);
return false; return $this->sqlError();
} }
/** /**
@ -267,13 +253,13 @@ class RoundStats {
s.invalid, s.invalid,
s.pplns_valid, s.pplns_valid,
s.pplns_invalid s.pplns_invalid
FROM $this->tableStats AS s FROM " . $this->statistics->getTableName() . " AS s
LEFT JOIN $this->tableBlocks AS b ON s.block_id = b.id LEFT JOIN " . $this->block->getTableName() . " AS b ON s.block_id = b.id
LEFT JOIN $this->tableUsers AS a ON a.id = s.account_id LEFT JOIN " . $this->user->getTableName() . " AS a ON a.id = s.account_id
WHERE b.height = ? AND a.id = ?"); WHERE b.height = ? AND a.id = ?");
if ($this->checkStmt($stmt) && $stmt->bind_param('ii', $iHeight, $iUser) && $stmt->execute() && $result = $stmt->get_result()) if ($this->checkStmt($stmt) && $stmt->bind_param('ii', $iHeight, $iUser) && $stmt->execute() && $result = $stmt->get_result())
return $result->fetch_assoc(); return $result->fetch_assoc();
return false; return $this->sqlError();
} }
/** /**
@ -284,47 +270,23 @@ class RoundStats {
$stmt = $this->mysqli->prepare(" $stmt = $this->mysqli->prepare("
SELECT SELECT
IFNULL(t.amount, 0) AS amount IFNULL(t.amount, 0) AS amount
FROM $this->tableTrans AS t FROM " . $this->transaction->getTableName() . " AS t
LEFT JOIN $this->tableBlocks AS b ON t.block_id = b.id LEFT JOIN " . $this->block->getTableName() . " AS b ON t.block_id = b.id
LEFT JOIN $this->tableUsers AS a ON t.account_id = a.id LEFT JOIN " . $this->user->getTableName() . " AS a ON t.account_id = a.id
WHERE b.height = ? AND t.type = 'Credit' AND t.account_id = ?"); WHERE b.height = ? AND t.type = 'Credit' AND t.account_id = ?");
if ($this->checkStmt($stmt) && $stmt->bind_param('ii', $iHeight, $iUser) && $stmt->execute() && $result = $stmt->get_result()) if ($this->checkStmt($stmt) && $stmt->bind_param('ii', $iHeight, $iUser) && $stmt->execute() && $result = $stmt->get_result())
return $result->fetch_object()->amount; return $result->fetch_object()->amount;
$this->debug->append('Unable to fetch transactions'); $this->debug->append('Unable to fetch transactions');
return false; return $this->sqlError();
} }
/**
* Get all users for admin panel
**/
public function getAllUsers($filter='%') {
$this->debug->append("STA " . __METHOD__, 4);
$stmt = $this->mysqli->prepare("
SELECT
a.id AS id,
a.username AS username
FROM $this->tableUsers AS a
WHERE a.username LIKE ?
GROUP BY username
ORDER BY username");
if ($this->checkStmt($stmt) && $stmt->bind_param('s', $filter) && $stmt->execute() && $result = $stmt->get_result()) {
while ($row = $result->fetch_assoc()) {
$aData[$row['id']] = $row['username'];
}
return $aData;
}
return false;
}
private function checkStmt($bState) {
if ($bState ===! true) {
$this->debug->append("Failed to prepare statement: " . $this->mysqli->error);
$this->setErrorMessage('Internal application Error');
return false;
}
return true;
}
} }
$roundstats = new RoundStats($debug, $mysqli, $config); $roundstats = new RoundStats();
$roundstats->setDebug($debug);
$roundstats->setMysql($mysqli);
$roundstats->setConfig($config);
$roundstats->setErrorCodes($aErrorCodes);
$roundstats->setUser($user);
$roundstats->setStatistics($statistics);
$roundstats->setBlock($block);
$roundstats->setTransaction($transaction);

View File

@ -12,18 +12,11 @@ class Setting extends Base {
* @return value string Value * @return value string Value
**/ **/
public function getValue($name) { public function getValue($name) {
$query = $this->mysqli->prepare("SELECT value FROM $this->table WHERE name=? LIMIT 1"); $stmt = $this->mysqli->prepare("SELECT value FROM $this->table WHERE name = ? LIMIT 1");
if ($query) { if ($this->checkStmt($stmt) && $stmt->bind_param('s', $name) && $stmt->execute() && $result = $stmt->get_result())
$query->bind_param('s', $name); if ($result->num_rows > 0)
$query->execute(); return $result->fetch_object()->value;
$query->bind_result($value); return $this->sqlError();
$query->fetch();
$query->close();
} else {
$this->debug->append("Failed to fetch variable $name from $this->table");
return false;
}
return $value;
} }
/** /**
@ -36,15 +29,14 @@ class Setting extends Base {
$stmt = $this->mysqli->prepare(" $stmt = $this->mysqli->prepare("
INSERT INTO $this->table (name, value) INSERT INTO $this->table (name, value)
VALUES (?, ?) VALUES (?, ?)
ON DUPLICATE KEY UPDATE value = ? ON DUPLICATE KEY UPDATE value = ?");
");
if ($stmt && $stmt->bind_param('sss', $name, $value, $value) && $stmt->execute()) if ($stmt && $stmt->bind_param('sss', $name, $value, $value) && $stmt->execute())
return true; return true;
$this->debug->append("Failed to set $name to $value"); return $this->sqlError();
return false;
} }
} }
$setting = new Setting($debug, $mysqli); $setting = new Setting($debug, $mysqli);
$setting->setDebug($debug); $setting->setDebug($debug);
$setting->setMysql($mysqli); $setting->setMysql($mysqli);
$setting->setErrorCodes($aErrorCodes);

View File

@ -6,21 +6,12 @@ if (!defined('SECURITY'))
class Share Extends Base { class Share Extends Base {
protected $table = 'shares'; protected $table = 'shares';
private $tableArchive = 'shares_archive'; protected $tableArchive = 'shares_archive';
private $oUpstream; private $oUpstream;
private $iLastUpstreamId; private $iLastUpstreamId;
// This defines each share // This defines each share
public $rem_host, $username, $our_result, $upstream_result, $reason, $solution, $time, $difficulty; public $rem_host, $username, $our_result, $upstream_result, $reason, $solution, $time, $difficulty;
public function __construct($debug, $mysqli, $user, $block, $config) {
$this->debug = $debug;
$this->mysqli = $mysqli;
$this->user = $user;
$this->config = $config;
$this->block = $block;
$this->debug->append("Instantiated Share class", 2);
}
/** /**
* Fetch archive tables name for this class * Fetch archive tables name for this class
* @param none * @param none
@ -65,7 +56,7 @@ class Share Extends Base {
$stmt = $this->mysqli->prepare($sql); $stmt = $this->mysqli->prepare($sql);
if ($this->checkStmt($stmt) && call_user_func_array( array($stmt, 'bind_param'), $this->getParam()) && $stmt->execute()) if ($this->checkStmt($stmt) && call_user_func_array( array($stmt, 'bind_param'), $this->getParam()) && $stmt->execute())
return true; return true;
return false; return $this->sqlError();
} }
/** /**
@ -73,14 +64,10 @@ class Share Extends Base {
* Used for PPS calculations without moving to archive * Used for PPS calculations without moving to archive
**/ **/
public function getLastInsertedShareId() { public function getLastInsertedShareId() {
$stmt = $this->mysqli->prepare(" $stmt = $this->mysqli->prepare("SELECT MAX(id) AS id FROM $this->table");
SELECT MAX(id) AS id FROM $this->table
");
if ($this->checkStmt($stmt) && $stmt->execute() && $result = $stmt->get_result()) if ($this->checkStmt($stmt) && $stmt->execute() && $result = $stmt->get_result())
return $result->fetch_object()->id; return $result->fetch_object()->id;
// Catchall return $this->sqlError();
$this->setErrorMessage('Failed to fetch last inserted share ID');
return false;
} }
/** /**
@ -96,14 +83,9 @@ class Share Extends Base {
WHERE our_result = 'Y' WHERE our_result = 'Y'
AND id > ? AND id <= ? AND id > ? AND id <= ?
"); ");
if ($this->checkStmt($stmt)) { if ($this->checkStmt($stmt) && $stmt->bind_param('ii', $previous_upstream, $current_upstream) && $stmt->execute() && $result = $stmt->get_result())
$stmt->bind_param('ii', $previous_upstream, $current_upstream);
$stmt->execute();
$result = $stmt->get_result();
$stmt->close();
return $result->fetch_object()->total; return $result->fetch_object()->total;
} return $this->sqlError();
return false;
} }
/** /**
@ -129,7 +111,7 @@ class Share Extends Base {
"); ");
if ($this->checkStmt($stmt) && $stmt->bind_param('ii', $previous_upstream, $current_upstream) && $stmt->execute() && $result = $stmt->get_result()) if ($this->checkStmt($stmt) && $stmt->bind_param('ii', $previous_upstream, $current_upstream) && $stmt->execute() && $result = $stmt->get_result())
return $result->fetch_all(MYSQLI_ASSOC); return $result->fetch_all(MYSQLI_ASSOC);
return false; return $this->sqlError();
} }
/** /**
@ -139,19 +121,17 @@ class Share Extends Base {
$stmt = $this->mysqli->prepare("SELECT MAX(id) AS id FROM $this->table"); $stmt = $this->mysqli->prepare("SELECT MAX(id) AS id FROM $this->table");
if ($this->checkStmt($stmt) && $stmt->execute() && $result = $stmt->get_result()) if ($this->checkStmt($stmt) && $stmt->execute() && $result = $stmt->get_result())
return $result->fetch_object()->id; return $result->fetch_object()->id;
return false; return $this->sqlError();
} }
/** /**
* Fetch the highest available share ID from archive * Fetch the highest available share ID from archive
**/ **/
function getMaxArchiveShareId() { function getMaxArchiveShareId() {
$stmt = $this->mysqli->prepare(" $stmt = $this->mysqli->prepare("SELECT MAX(share_id) AS share_id FROM $this->tableArchive");
SELECT MAX(share_id) AS share_id FROM $this->tableArchive
");
if ($this->checkStmt($stmt) && $stmt->execute() && $result = $stmt->get_result()) if ($this->checkStmt($stmt) && $stmt->execute() && $result = $stmt->get_result())
return $result->fetch_object()->share_id; return $result->fetch_object()->share_id;
return false; return $this->sqlError();
} }
/** /**
@ -182,7 +162,7 @@ class Share Extends Base {
} }
if (is_array($aData)) return $aData; if (is_array($aData)) return $aData;
} }
return false; return $this->sqlError();
} }
/** /**
@ -206,8 +186,7 @@ class Share Extends Base {
if ($this->checkStmt($stmt) && $stmt->bind_param('i', $this->config['archive']['maxage']) && $stmt->execute()) if ($this->checkStmt($stmt) && $stmt->bind_param('i', $this->config['archive']['maxage']) && $stmt->execute())
return true; return true;
} }
// Catchall return $this->sqlError();
return false;
} }
/** /**
@ -223,20 +202,22 @@ class Share Extends Base {
SELECT id, username, our_result, upstream_result, ?, time, IF(difficulty=0, pow(2, (" . $this->config['difficulty'] . " - 16)), difficulty) AS difficulty SELECT id, username, our_result, upstream_result, ?, time, IF(difficulty=0, pow(2, (" . $this->config['difficulty'] . " - 16)), difficulty) AS difficulty
FROM $this->table FROM $this->table
WHERE id > ? AND id <= ?"); WHERE id > ? AND id <= ?");
if ($this->checkStmt($archive_stmt) && $archive_stmt->bind_param('iii', $block_id, $previous_upstream, $current_upstream) && $archive_stmt->execute()) { if ($this->checkStmt($archive_stmt) && $archive_stmt->bind_param('iii', $block_id, $previous_upstream, $current_upstream) && $archive_stmt->execute())
$archive_stmt->close();
return true; return true;
} return $this->sqlError();
// Catchall
return false;
} }
/**
* Delete accounted shares from shares table
* @param current_upstream int Current highest upstream ID
* @param previous_upstream int Previous upstream ID
* @return bool true or false
**/
public function deleteAccountedShares($current_upstream, $previous_upstream=0) { public function deleteAccountedShares($current_upstream, $previous_upstream=0) {
$stmt = $this->mysqli->prepare("DELETE FROM $this->table WHERE id > ? AND id <= ?"); $stmt = $this->mysqli->prepare("DELETE FROM $this->table WHERE id > ? AND id <= ?");
if ($this->checkStmt($stmt) && $stmt->bind_param('ii', $previous_upstream, $current_upstream) && $stmt->execute()) if ($this->checkStmt($stmt) && $stmt->bind_param('ii', $previous_upstream, $current_upstream) && $stmt->execute())
return true; return true;
// Catchall return $this->sqlError();
return false;
} }
/** /**
* Set/get last found share accepted by upstream: id and accounts * Set/get last found share accepted by upstream: id and accounts
@ -334,8 +315,7 @@ class Share Extends Base {
if (!empty($this->oUpstream->account) && is_int($this->oUpstream->id)) if (!empty($this->oUpstream->account) && is_int($this->oUpstream->id))
return true; return true;
} }
// Catchall return $this->getErrorMsg('E0052', $aBlock['height']);
return false;
} }
/** /**
@ -353,11 +333,10 @@ class Share Extends Base {
AND id <= ? AND @total < ? AND id <= ? AND @total < ?
ORDER BY id DESC ORDER BY id DESC
) AS b ) AS b
WHERE total <= ? WHERE total <= ?");
");
if ($this->checkStmt($stmt) && $stmt->bind_param('iii', $current_upstream, $iCount, $iCount) && $stmt->execute() && $result = $stmt->get_result()) if ($this->checkStmt($stmt) && $stmt->bind_param('iii', $current_upstream, $iCount, $iCount) && $stmt->execute() && $result = $stmt->get_result())
return $result->fetch_object()->id; return $result->fetch_object()->id;
return false; return $this->sqlError();
} }
/** /**
@ -379,13 +358,14 @@ class Share Extends Base {
"); ");
if ($this->checkStmt($stmt) && $stmt->bind_param('ii', $iCount, $iCount) && $stmt->execute() && $result = $stmt->get_result()) if ($this->checkStmt($stmt) && $stmt->bind_param('ii', $iCount, $iCount) && $stmt->execute() && $result = $stmt->get_result())
return $result->fetch_object()->share_id; return $result->fetch_object()->share_id;
$this->setErrorMessage("Failed fetching additional shares from archive: " . $this->mysqli->error); return $this->sqlError();
return false;
} }
} }
$share = new Share($debug, $mysqli, $user, $block, $config); $share = new Share();
$share->setDebug($debug);
$share->setMysql($mysqli); $share->setMysql($mysqli);
$share->setConfig($config); $share->setConfig($config);
$share->setUser($user); $share->setUser($user);
$share->setBlock($block); $share->setBlock($block);
$share->setErrorCodes($aErrorCodes);

View File

@ -10,31 +10,10 @@ if (!defined('SECURITY'))
* Statistics should be non-intrusive and not change any * Statistics should be non-intrusive and not change any
* rows in our database to ensure data integrity for the backend * rows in our database to ensure data integrity for the backend
**/ **/
class Statistics { class Statistics extends Base {
private $sError = ''; protected $table = 'statistics_shares';
private $table = 'statistics_shares';
private $getcache = true; private $getcache = true;
public function __construct($debug, $mysqli, $config, $share, $user, $block, $memcache) {
$this->debug = $debug;
$this->mysqli = $mysqli;
$this->share = $share;
$this->config = $config;
$this->user = $user;
$this->block = $block;
$this->memcache = $memcache;
$this->debug->append("Instantiated Share class", 2);
}
/* Some basic get and set methods
**/
private function setErrorMessage($msg) {
$this->sError = $msg;
}
public function getError() {
return $this->sError;
}
// Disable fetching values from cache // Disable fetching values from cache
public function setGetCache($set=false) { public function setGetCache($set=false) {
$this->getcache = $set; $this->getcache = $set;
@ -43,15 +22,6 @@ class Statistics {
return $this->getcache; return $this->getcache;
} }
private function checkStmt($bState) {
if ($bState ===! true) {
$this->debug->append("Failed to prepare statement: " . $this->mysqli->error);
$this->setErrorMessage('Failed to prepare statement');
return false;
}
return true;
}
/** /**
* Fetch last found blocks by time * Fetch last found blocks by time
**/ **/
@ -64,17 +34,12 @@ class Statistics {
if ($aTimeFrame == 0) $aTimeDiff = 0; if ($aTimeFrame == 0) $aTimeDiff = 0;
$stmt = $this->mysqli->prepare(" $stmt = $this->mysqli->prepare("
SELECT COUNT(id) AS count FROM " . $this->block->getTableName() . " SELECT COUNT(id) AS count FROM " . $this->block->getTableName() . "
WHERE confirmations > 0 WHERE confirmations > 0
AND time >= ? AND time >= ?");
");
if ($this->checkStmt($stmt) && $stmt->bind_param('i', $aTimeDiff) && $stmt->execute() && $result = $stmt->get_result()) if ($this->checkStmt($stmt) && $stmt->bind_param('i', $aTimeDiff) && $stmt->execute() && $result = $stmt->get_result())
return $this->memcache->setCache(__FUNCTION__ . $aTimeFrame, $result->fetch_object()->count); return $this->memcache->setCache(__FUNCTION__ . $aTimeFrame, $result->fetch_object()->count);
$this->debug->append("Failed to get valid Blocks by time: ". $this->mysqli->error); return $this->sqlError();
return false;
} }
function getLastOrphanBlocksbyTime($aTimeFrame) { function getLastOrphanBlocksbyTime($aTimeFrame) {
$this->debug->append("STA " . __METHOD__, 4); $this->debug->append("STA " . __METHOD__, 4);
@ -85,16 +50,12 @@ class Statistics {
if ($aTimeFrame == 0) $aTimeDiff = 0; if ($aTimeFrame == 0) $aTimeDiff = 0;
$stmt = $this->mysqli->prepare(" $stmt = $this->mysqli->prepare("
SELECT COUNT(id) AS count FROM " . $this->block->getTableName() . " SELECT COUNT(id) AS count FROM " . $this->block->getTableName() . "
WHERE confirmations = -1 WHERE confirmations = -1
AND time >= ? AND time >= ?");
");
if ($this->checkStmt($stmt) && $stmt->bind_param('i', $aTimeDiff) && $stmt->execute() && $result = $stmt->get_result()) if ($this->checkStmt($stmt) && $stmt->bind_param('i', $aTimeDiff) && $stmt->execute() && $result = $stmt->get_result())
return $this->memcache->setCache(__FUNCTION__ . $aTimeFrame, $result->fetch_object()->count); return $this->memcache->setCache(__FUNCTION__ . $aTimeFrame, $result->fetch_object()->count);
$this->debug->append("Failed to get orphan Blocks by time: ". $this->mysqli->error); return $this->sqlError();
return false;
} }
/** /**
* Get our last $limit blocks found * Get our last $limit blocks found
@ -116,9 +77,7 @@ class Statistics {
ORDER BY height DESC LIMIT ?"); ORDER BY height DESC LIMIT ?");
if ($this->checkStmt($stmt) && $stmt->bind_param("i", $limit) && $stmt->execute() && $result = $stmt->get_result()) if ($this->checkStmt($stmt) && $stmt->bind_param("i", $limit) && $stmt->execute() && $result = $stmt->get_result())
return $this->memcache->setCache(__FUNCTION__ . $limit, $result->fetch_all(MYSQLI_ASSOC), 5); return $this->memcache->setCache(__FUNCTION__ . $limit, $result->fetch_all(MYSQLI_ASSOC), 5);
// Catchall return $this->sqlError();
$this->debug->append("Failed to find blocks:" . $this->mysqli->error);
return false;
} }
/** /**
@ -142,9 +101,7 @@ class Statistics {
ORDER BY height DESC LIMIT ?"); ORDER BY height DESC LIMIT ?");
if ($this->checkStmt($stmt) && $stmt->bind_param("ii", $iHeight, $limit) && $stmt->execute() && $result = $stmt->get_result()) if ($this->checkStmt($stmt) && $stmt->bind_param("ii", $iHeight, $limit) && $stmt->execute() && $result = $stmt->get_result())
return $this->memcache->setCache(__FUNCTION__ . $iHeight . $limit, $result->fetch_all(MYSQLI_ASSOC), 5); return $this->memcache->setCache(__FUNCTION__ . $iHeight . $limit, $result->fetch_all(MYSQLI_ASSOC), 5);
// Catchall return $this->sqlError();
$this->debug->append("Failed to find blocks:" . $this->mysqli->error);
return false;
} }
/** /**
@ -158,9 +115,7 @@ class Statistics {
$this->debug->append("STA " . __METHOD__, 4); $this->debug->append("STA " . __METHOD__, 4);
$stmt = $this->mysqli->prepare("INSERT INTO $this->table (account_id, valid, invalid, block_id) VALUES (?, ?, ?, ?)"); $stmt = $this->mysqli->prepare("INSERT INTO $this->table (account_id, valid, invalid, block_id) VALUES (?, ?, ?, ?)");
if ($this->checkStmt($stmt) && $stmt->bind_param('iiii', $aStats['id'], $aStats['valid'], $aStats['invalid'], $iBlockId) && $stmt->execute()) return true; if ($this->checkStmt($stmt) && $stmt->bind_param('iiii', $aStats['id'], $aStats['valid'], $aStats['invalid'], $iBlockId) && $stmt->execute()) return true;
// Catchall return $this->sqlError();
$this->debug->append("Failed to update share stats: " . $this->mysqli->error);
return false;
} }
/** /**
@ -171,9 +126,7 @@ class Statistics {
$stmt = $this->mysqli->prepare(" $stmt = $this->mysqli->prepare("
UPDATE $this->table SET pplns_valid = ?, pplns_invalid = ? WHERE account_id = ? AND block_id = ?"); UPDATE $this->table SET pplns_valid = ?, pplns_invalid = ? WHERE account_id = ? AND block_id = ?");
if ($this->checkStmt($stmt) && $stmt->bind_param('iiii', $aStats['valid'], $aStats['invalid'], $aStats['id'], $iBlockId) && $stmt->execute()) return true; if ($this->checkStmt($stmt) && $stmt->bind_param('iiii', $aStats['valid'], $aStats['invalid'], $aStats['id'], $iBlockId) && $stmt->execute()) return true;
// Catchall return $this->sqlError();
$this->debug->append("Failed to update pplns share stats: " . $this->mysqli->error);
return false;
} }
/** /**
@ -183,9 +136,7 @@ class Statistics {
$this->debug->append("STA " . __METHOD__, 4); $this->debug->append("STA " . __METHOD__, 4);
$stmt = $this->mysqli->prepare("INSERT INTO $this->table (account_id, valid, invalid, pplns_valid, pplns_invalid, block_id) VALUES (?, 0, 0, ?, ?, ?)"); $stmt = $this->mysqli->prepare("INSERT INTO $this->table (account_id, valid, invalid, pplns_valid, pplns_invalid, block_id) VALUES (?, 0, 0, ?, ?, ?)");
if ($this->checkStmt($stmt) && $stmt->bind_param('iiii', $aStats['id'], $aStats['valid'], $aStats['invalid'], $iBlockId) && $stmt->execute()) return true; if ($this->checkStmt($stmt) && $stmt->bind_param('iiii', $aStats['id'], $aStats['valid'], $aStats['invalid'], $iBlockId) && $stmt->execute()) return true;
// Catchall return $this->sqlError();
$this->debug->append("Failed to insert pplns share stats: " . $this->mysqli->error);
return false;
} }
/** /**
@ -198,7 +149,7 @@ class Statistics {
"); ");
if ($this->checkStmt($stmt) && $stmt->bind_param('ii', $aStats['id'], $iBlockId) && $stmt->execute() && $result = $stmt->get_result()) if ($this->checkStmt($stmt) && $stmt->bind_param('ii', $aStats['id'], $iBlockId) && $stmt->execute() && $result = $stmt->get_result())
return $result->fetch_object()->id; return $result->fetch_object()->id;
return false; return $this->sqlError();
} }
/** /**
@ -226,10 +177,8 @@ class Statistics {
) )
) AS hashrate ) AS hashrate
FROM DUAL"); FROM DUAL");
// Catchall
if ($this->checkStmt($stmt) && $stmt->bind_param('iiii', $interval, $interval, $interval, $interval) && $stmt->execute() && $result = $stmt->get_result() ) return $this->memcache->setCache(__FUNCTION__, $result->fetch_object()->hashrate); if ($this->checkStmt($stmt) && $stmt->bind_param('iiii', $interval, $interval, $interval, $interval) && $stmt->execute() && $result = $stmt->get_result() ) return $this->memcache->setCache(__FUNCTION__, $result->fetch_object()->hashrate);
$this->debug->append("Failed to get hashrate: " . $this->mysqli->error); return $this->sqlError();
return false;
} }
/** /**
@ -257,9 +206,7 @@ class Statistics {
) AS sharerate ) AS sharerate
FROM DUAL"); FROM DUAL");
if ($this->checkStmt($stmt) && $stmt->bind_param('iiii', $interval, $interval, $interval, $interval) && $stmt->execute() && $result = $stmt->get_result() ) return $this->memcache->setCache(__FUNCTION__, $result->fetch_object()->sharerate); if ($this->checkStmt($stmt) && $stmt->bind_param('iiii', $interval, $interval, $interval, $interval) && $stmt->execute() && $result = $stmt->get_result() ) return $this->memcache->setCache(__FUNCTION__, $result->fetch_object()->sharerate);
// Catchall return $this->sqlError();
$this->debug->append("Failed to fetch share rate: " . $this->mysqli->error);
return false;
} }
/** /**
@ -291,9 +238,7 @@ class Statistics {
WHERE UNIX_TIMESTAMP(time) > IFNULL((SELECT MAX(time) FROM " . $this->block->getTableName() . "), 0)"); WHERE UNIX_TIMESTAMP(time) > IFNULL((SELECT MAX(time) FROM " . $this->block->getTableName() . "), 0)");
if ( $this->checkStmt($stmt) && $stmt->execute() && $result = $stmt->get_result() ) if ( $this->checkStmt($stmt) && $stmt->execute() && $result = $stmt->get_result() )
return $this->memcache->setCache(STATISTICS_ROUND_SHARES, $result->fetch_assoc()); return $this->memcache->setCache(STATISTICS_ROUND_SHARES, $result->fetch_assoc());
// Catchall return $this->sqlError();
$this->debug->append("Failed to fetch round shares: " . $this->mysqli->error);
return false;
} }
/** /**
@ -341,9 +286,7 @@ class Statistics {
$data['share_id'] = $this->share->getMaxShareId(); $data['share_id'] = $this->share->getMaxShareId();
return $this->memcache->setCache(STATISTICS_ALL_USER_SHARES, $data); return $this->memcache->setCache(STATISTICS_ALL_USER_SHARES, $data);
} }
// Catchall return $this->sqlError();
$this->debug->append("Unable to fetch all users round shares: " . $this->mysqli->error);
return false;
} }
/** /**
@ -373,9 +316,7 @@ class Statistics {
AND u.id = ?"); AND u.id = ?");
if ($stmt && $stmt->bind_param("i", $account_id) && $stmt->execute() && $result = $stmt->get_result()) if ($stmt && $stmt->bind_param("i", $account_id) && $stmt->execute() && $result = $stmt->get_result())
return $this->memcache->setCache(__FUNCTION__ . $account_id, $result->fetch_assoc()); return $this->memcache->setCache(__FUNCTION__ . $account_id, $result->fetch_assoc());
// Catchall return $this->sqlError();
$this->debug->append("Unable to fetch user round shares: " . $this->mysqli->error);
return false;
} }
/** /**
@ -402,9 +343,9 @@ class Statistics {
a.username LIKE ? a.username LIKE ?
GROUP BY username GROUP BY username
ORDER BY username"); ORDER BY username");
if ($this->checkStmt($stmt) && $stmt->bind_param('s', $filter) && $stmt->execute() && $result = $stmt->get_result()) { if ($this->checkStmt($stmt) && $stmt->bind_param('s', $filter) && $stmt->execute() && $result = $stmt->get_result())
return $this->memcache->setCache(__FUNCTION__ . $filter, $result->fetch_all(MYSQLI_ASSOC)); return $this->memcache->setCache(__FUNCTION__ . $filter, $result->fetch_all(MYSQLI_ASSOC));
} return $this->sqlError();
} }
/** /**
@ -437,9 +378,7 @@ class Statistics {
FROM DUAL"); FROM DUAL");
if ($this->checkStmt($stmt) && $stmt->bind_param("iiiiii", $interval, $interval, $account_id, $interval, $interval, $account_id) && $stmt->execute() && $result = $stmt->get_result() ) if ($this->checkStmt($stmt) && $stmt->bind_param("iiiiii", $interval, $interval, $account_id, $interval, $interval, $account_id) && $stmt->execute() && $result = $stmt->get_result() )
return $this->memcache->setCache(__FUNCTION__ . $account_id, $result->fetch_object()->hashrate); return $this->memcache->setCache(__FUNCTION__ . $account_id, $result->fetch_object()->hashrate);
// Catchall return $this->sqlError();
$this->debug->append("Failed to fetch hashrate: " . $this->mysqli->error);
return false;
} }
public function getUserUnpaidPPSShares($account_id, $last_paid_pps_id) { public function getUserUnpaidPPSShares($account_id, $last_paid_pps_id) {
@ -456,8 +395,7 @@ class Statistics {
WHERE our_result = 'Y'"); WHERE our_result = 'Y'");
if ($this->checkStmt($stmt) && $stmt->bind_param("ii", $account_id, $last_paid_pps_id) && $stmt->execute() && $result = $stmt->get_result() ) if ($this->checkStmt($stmt) && $stmt->bind_param("ii", $account_id, $last_paid_pps_id) && $stmt->execute() && $result = $stmt->get_result() )
return $this->memcache->setCache(__FUNCTION__ . $account_id, $result->fetch_object()->total); return $this->memcache->setCache(__FUNCTION__ . $account_id, $result->fetch_object()->total);
$this->debug->append("Failed fetching average share dificulty: " . $this->mysqli->error, 3); return $this->sqlError();
return 0;
} }
/** /**
@ -480,8 +418,7 @@ class Statistics {
AND a.id = ?"); AND a.id = ?");
if ($this->checkStmt($stmt) && $stmt->bind_param("ii", $interval, $account_id) && $stmt->execute() && $result = $stmt->get_result() ) if ($this->checkStmt($stmt) && $stmt->bind_param("ii", $interval, $account_id) && $stmt->execute() && $result = $stmt->get_result() )
return $this->memcache->setCache(__FUNCTION__ . $account_id, $result->fetch_object()->avgsharediff); return $this->memcache->setCache(__FUNCTION__ . $account_id, $result->fetch_object()->avgsharediff);
$this->debug->append("Failed fetching average share dificulty: " . $this->mysqli->error, 3); return $this->sqlError();
return 0;
} }
/** /**
@ -516,9 +453,7 @@ class Statistics {
FROM DUAL"); FROM DUAL");
if ($this->checkStmt($stmt) && $stmt->bind_param("iiiiii", $interval, $interval, $account_id, $interval, $interval, $account_id) && $stmt->execute() && $result = $stmt->get_result() ) if ($this->checkStmt($stmt) && $stmt->bind_param("iiiiii", $interval, $interval, $account_id, $interval, $interval, $account_id) && $stmt->execute() && $result = $stmt->get_result() )
return $this->memcache->setCache(__FUNCTION__ . $account_id, $result->fetch_object()->sharerate); return $this->memcache->setCache(__FUNCTION__ . $account_id, $result->fetch_object()->sharerate);
// Catchall return $this->sqlError();
$this->debug->append("Failed to fetch sharerate: " . $this->mysqli->error);
return false;
} }
/** /**
@ -539,9 +474,7 @@ class Statistics {
AND u.id = ?"); AND u.id = ?");
if ($this->checkStmt($stmt) && $stmt->bind_param("i", $account_id) && $stmt->execute() && $result = $stmt->get_result() ) if ($this->checkStmt($stmt) && $stmt->bind_param("i", $account_id) && $stmt->execute() && $result = $stmt->get_result() )
return $this->memcache->setCache(__FUNCTION__ . $worker_id, $result->fetch_object()->hashrate); return $this->memcache->setCache(__FUNCTION__ . $worker_id, $result->fetch_object()->hashrate);
// Catchall return $this->sqlError();
$this->debug->append("Failed to fetch hashrate: " . $this->mysqli->error);
return false;
} }
/** /**
@ -591,8 +524,7 @@ class Statistics {
LIMIT ?"); LIMIT ?");
if ($this->checkStmt($stmt) && $stmt->bind_param("i", $limit) && $stmt->execute() && $result = $stmt->get_result()) if ($this->checkStmt($stmt) && $stmt->bind_param("i", $limit) && $stmt->execute() && $result = $stmt->get_result())
return $this->memcache->setCache(__FUNCTION__ . $type . $limit, $result->fetch_all(MYSQLI_ASSOC)); return $this->memcache->setCache(__FUNCTION__ . $type . $limit, $result->fetch_all(MYSQLI_ASSOC));
$this->debug->append("Fetching shares failed: "); return $this->sqlError();
return false;
break; break;
case 'hashes': case 'hashes':
@ -614,8 +546,7 @@ class Statistics {
ORDER BY hashrate DESC LIMIT ?"); ORDER BY hashrate DESC LIMIT ?");
if ($this->checkStmt($stmt) && $stmt->bind_param("i", $limit) && $stmt->execute() && $result = $stmt->get_result()) if ($this->checkStmt($stmt) && $stmt->bind_param("i", $limit) && $stmt->execute() && $result = $stmt->get_result())
return $this->memcache->setCache(__FUNCTION__ . $type . $limit, $result->fetch_all(MYSQLI_ASSOC)); return $this->memcache->setCache(__FUNCTION__ . $type . $limit, $result->fetch_all(MYSQLI_ASSOC));
$this->debug->append("Fetching shares failed: " . $this->mysqli->error); return $this->sqlError();
return false;
break; break;
} }
} }
@ -658,9 +589,7 @@ class Statistics {
while ($row = $result->fetch_assoc()) $aData[$row['hour']] = $row['hashrate']; while ($row = $result->fetch_assoc()) $aData[$row['hour']] = $row['hashrate'];
return $this->memcache->setCache(__FUNCTION__ . $account_id, $aData); return $this->memcache->setCache(__FUNCTION__ . $account_id, $aData);
} }
// Catchall return $this->sqlError();
$this->debug->append("Failed to fetch hourly hashrate: " . $this->mysqli->error);
return false;
} }
/** /**
@ -697,9 +626,7 @@ class Statistics {
while ($row = $result->fetch_assoc()) $aData[$row['hour']] = (int) $row['hashrate']; while ($row = $result->fetch_assoc()) $aData[$row['hour']] = (int) $row['hashrate'];
return $this->memcache->setCache(__FUNCTION__, $aData); return $this->memcache->setCache(__FUNCTION__, $aData);
} }
// Catchall return $this->sqlError();
$this->debug->append("Failed to fetch hourly hashrate: " . $this->mysqli->error);
return false;
} }
/** /**
@ -767,9 +694,7 @@ class Statistics {
AND confirmations >= 1"); AND confirmations >= 1");
if ($this->checkStmt($stmt) && $stmt->bind_param("i", $hour) && $stmt->execute() && $result = $stmt->get_result()) if ($this->checkStmt($stmt) && $stmt->bind_param("i", $hour) && $stmt->execute() && $result = $stmt->get_result())
return $this->memcache->setCache(__FUNCTION__ . $hour, $result->fetch_assoc()); return $this->memcache->setCache(__FUNCTION__ . $hour, $result->fetch_assoc());
// Catchall return $this->sqlError();
$this->debug->append("Failed to get pool statistics:" . $this->mysqli->error);
return false;
} }
/** /**
@ -782,5 +707,14 @@ class Statistics {
} }
} }
$statistics = new Statistics();
$statistics->setDebug($debug);
$statistics->setMysql($mysqli);
$statistics->setShare($share);
$statistics->setUser($user);
$statistics->setBlock($block);
$statistics->setMemcache($memcache);
$statistics->setConfig($config);
$statistics->setErrorCodes($aErrorCodes);
$statistics = new Statistics($debug, $mysqli, $config, $share, $user, $block, $memcache); ?>

View File

@ -4,7 +4,7 @@
if (!defined('SECURITY')) die('Hacking attempt'); if (!defined('SECURITY')) die('Hacking attempt');
class Token Extends Base { class Token Extends Base {
var $table = 'tokens'; protected $table = 'tokens';
/** /**
* Fetch a token from our table * Fetch a token from our table
@ -15,7 +15,7 @@ class Token Extends Base {
$stmt = $this->mysqli->prepare("SELECT * FROM $this->table WHERE token = ? LIMIT 1"); $stmt = $this->mysqli->prepare("SELECT * FROM $this->table WHERE token = ? LIMIT 1");
if ($stmt && $stmt->bind_param('s', $strToken) && $stmt->execute() && $result = $stmt->get_result()) if ($stmt && $stmt->bind_param('s', $strToken) && $stmt->execute() && $result = $stmt->get_result())
return $result->fetch_assoc(); return $result->fetch_assoc();
return false; return $this->sqlError();
} }
/** /**
@ -36,9 +36,7 @@ class Token Extends Base {
"); ");
if ($stmt && $stmt->bind_param('sii', $strToken, $iToken_id, $account_id) && $stmt->execute()) if ($stmt && $stmt->bind_param('sii', $strToken, $iToken_id, $account_id) && $stmt->execute())
return $strToken; return $strToken;
$this->setErrorMessage('Unable to create new token'); return $this->sqlError();
$this->debug->append('Failed to create new token in database: ' . $this->mysqli->error);
return false;
} }
/** /**
@ -50,7 +48,7 @@ class Token Extends Base {
$stmt = $this->mysqli->prepare("DELETE FROM $this->table WHERE token = ? LIMIT 1"); $stmt = $this->mysqli->prepare("DELETE FROM $this->table WHERE token = ? LIMIT 1");
if ($stmt && $stmt->bind_param('s', $token) && $stmt->execute()) if ($stmt && $stmt->bind_param('s', $token) && $stmt->execute())
return true; return true;
return false; return $this->sqlError();
} }
} }
@ -58,3 +56,4 @@ $oToken = new Token();
$oToken->setDebug($debug); $oToken->setDebug($debug);
$oToken->setMysql($mysqli); $oToken->setMysql($mysqli);
$oToken->setTokenType($tokentype); $oToken->setTokenType($tokentype);
$oToken->setErrorCodes($aErrorCodes);

View File

@ -5,7 +5,8 @@ if (!defined('SECURITY'))
die('Hacking attempt'); die('Hacking attempt');
class Token_Type Extends Base { class Token_Type Extends Base {
var $table = 'token_types'; protected $table = 'token_types';
/** /**
* Return ID for specific token * Return ID for specific token
* @param strName string Token Name * @param strName string Token Name
@ -19,3 +20,4 @@ class Token_Type Extends Base {
$tokentype = new Token_Type(); $tokentype = new Token_Type();
$tokentype->setDebug($debug); $tokentype->setDebug($debug);
$tokentype->setMysql($mysqli); $tokentype->setMysql($mysqli);
$tokentype->setErrorCodes($aErrorCodes);

View File

@ -5,7 +5,6 @@ if (!defined('SECURITY'))
die('Hacking attempt'); die('Hacking attempt');
class Transaction extends Base { class Transaction extends Base {
private $sError = '';
protected $table = 'transactions'; protected $table = 'transactions';
public $num_rows = 0, $insert_id = 0; public $num_rows = 0, $insert_id = 0;
@ -25,8 +24,7 @@ class Transaction extends Base {
$this->insert_id = $stmt->insert_id; $this->insert_id = $stmt->insert_id;
return true; return true;
} }
$this->setErrorMessage("Failed to store transaction"); return $this->sqlError();
return false;
} }
/* /*
@ -45,7 +43,7 @@ class Transaction extends Base {
OR ( t.account_id = ? AND t.id <= ? AND t.type IN ( 'Credit_PPS', 'Donation_PPS', 'Fee_PPS', 'TXFee', 'Debit_MP', 'Debit_AP' ) )"); OR ( t.account_id = ? AND t.id <= ? AND t.type IN ( 'Credit_PPS', 'Donation_PPS', 'Fee_PPS', 'TXFee', 'Debit_MP', 'Debit_AP' ) )");
if ($this->checkStmt($stmt) && $stmt->bind_param('iiiii', $account_id, $txid, $this->config['confirmations'], $account_id, $txid) && $stmt->execute()) if ($this->checkStmt($stmt) && $stmt->bind_param('iiiii', $account_id, $txid, $this->config['confirmations'], $account_id, $txid) && $stmt->execute())
return true; return true;
return false; return $this->sqlError();
} }
/** /**
@ -60,8 +58,7 @@ class Transaction extends Base {
FROM transactions AS t FROM transactions AS t
LEFT OUTER JOIN blocks AS b LEFT OUTER JOIN blocks AS b
ON b.id = t.block_id ON b.id = t.block_id
WHERE ( b.confirmations > 0 OR b.id IS NULL ) WHERE ( b.confirmations > 0 OR b.id IS NULL )";
";
if (!empty($account_id)) { if (!empty($account_id)) {
$sql .= " AND t.account_id = ? "; $sql .= " AND t.account_id = ? ";
$this->addParam('i', $account_id); $this->addParam('i', $account_id);
@ -84,7 +81,7 @@ class Transaction extends Base {
} }
return $aData; return $aData;
} }
return false; return $this->sqlError();
} }
/** /**
@ -152,7 +149,7 @@ class Transaction extends Base {
} }
} }
if (!empty($aFilter)) { if (!empty($aFilter)) {
empty($account_id) ? $sql .= " WHERE " : $sql .= " AND "; empty($account_id) ? $sql .= " WHERE " : $sql .= " AND ";
$sql .= implode(' AND ', $aFilter); $sql .= implode(' AND ', $aFilter);
} }
} }
@ -171,8 +168,7 @@ class Transaction extends Base {
$this->num_rows = $row_count; $this->num_rows = $row_count;
return $result->fetch_all(MYSQLI_ASSOC); return $result->fetch_all(MYSQLI_ASSOC);
} }
$this->debug->append('Failed to fetch transactions: ' . $this->mysqli->error); return $this->sqlError();
return false;
} }
/** /**
@ -188,8 +184,7 @@ class Transaction extends Base {
} }
return $aData; return $aData;
} }
$this->debug->append('Failed to fetch transaction types: ' . $this->mysqli->error); return $this->sqlError();
return false;
} }
/** /**
@ -220,8 +215,7 @@ class Transaction extends Base {
"); ");
if ($this->checkStmt($stmt) && $stmt->execute() && $result = $stmt->get_result()) if ($this->checkStmt($stmt) && $stmt->execute() && $result = $stmt->get_result())
return $result->fetch_all(MYSQLI_ASSOC); return $result->fetch_all(MYSQLI_ASSOC);
$this->debug->append("Failed to fetch website donors: " . $this->mysqli->error); return $this->sqlError();
return false;
} }
/** /**
@ -245,10 +239,7 @@ class Transaction extends Base {
WHERE archived = 0"); WHERE archived = 0");
if ($this->checkStmt($stmt) && $stmt->bind_param('ii', $this->config['confirmations'], $this->config['confirmations']) && $stmt->execute() && $stmt->bind_result($dBalance) && $stmt->fetch()) if ($this->checkStmt($stmt) && $stmt->bind_param('ii', $this->config['confirmations'], $this->config['confirmations']) && $stmt->execute() && $stmt->bind_result($dBalance) && $stmt->fetch())
return $dBalance; return $dBalance;
// Catchall return $this->sqlError();
$this->setErrorMessage('Unable to find locked credits for all users');
$this->debug->append('MySQL query failed : ' . $this->mysqli->error);
return false;
} }
/** /**
@ -281,8 +272,7 @@ class Transaction extends Base {
"); ");
if ($this->checkStmt($stmt) && $stmt->bind_param("iiiii", $this->config['confirmations'], $this->config['confirmations'], $this->config['confirmations'], $this->config['confirmations'], $account_id) && $stmt->execute() && $result = $stmt->get_result()) if ($this->checkStmt($stmt) && $stmt->bind_param("iiiii", $this->config['confirmations'], $this->config['confirmations'], $this->config['confirmations'], $this->config['confirmations'], $account_id) && $stmt->execute() && $result = $stmt->get_result())
return $result->fetch_assoc(); return $result->fetch_assoc();
$this->debug->append('Failed to fetch users balance: ' . $this->mysqli->error); return $this->sqlError();
return false;
} }
} }
@ -292,3 +282,6 @@ $transaction->setMysql($mysqli);
$transaction->setConfig($config); $transaction->setConfig($config);
$transaction->setBlock($block); $transaction->setBlock($block);
$transaction->setUser($user); $transaction->setUser($user);
$transaction->setErrorCodes($aErrorCodes);
?>

View File

@ -4,39 +4,12 @@
if (!defined('SECURITY')) if (!defined('SECURITY'))
die('Hacking attempt'); die('Hacking attempt');
class User { class User extends Base {
private $sError = ''; protected $table = 'accounts';
private $userID = false; private $userID = false;
private $table = 'accounts';
private $user = array(); private $user = array();
public function __construct($debug, $mysqli, $salt, $config) {
$this->debug = $debug;
$this->mysqli = $mysqli;
$this->salt = $salt;
$this->config = $config;
$this->debug->append("Instantiated User class", 2);
}
// get and set methods // get and set methods
public function setMail($mail) {
$this->mail = $mail;
}
public function setToken($token) {
$this->token = $token;
}
public function setBitcoin($bitcoin) {
$this->bitcoin = $bitcoin;
}
public function setSetting($setting) {
$this->setting = $setting;
}
private function setErrorMessage($msg) {
$this->sError = $msg;
}
public function getError() {
return $this->sError;
}
private function getHash($string) { private function getHash($string) {
return hash('sha256', $string.$this->salt); return hash('sha256', $string.$this->salt);
} }
@ -174,31 +147,6 @@ class User {
return $pin_hash === $row_pin; return $pin_hash === $row_pin;
} }
/**
* Get a single row from the table
* @param value string Value to search for
* @param search Return column to search for
* @param field string Search column
* @param type string Type of value
* @return array Return result
**/
private function getSingle($value, $search='id', $field='id', $type="i", $lower=false) {
$this->debug->append("STA " . __METHOD__, 4);
$sql = "SELECT $search FROM $this->table WHERE";
$lower ? $sql .= " LOWER($field) = LOWER(?)" : $sql .= " $field = ?";
$sql .= " LIMIT 1";
$stmt = $this->mysqli->prepare($sql);
if ($this->checkStmt($stmt)) {
$stmt->bind_param($type, $value);
$stmt->execute();
$stmt->bind_result($retval);
$stmt->fetch();
$stmt->close();
return $retval;
}
return false;
}
/** /**
* Get all users that have auto payout setup * Get all users that have auto payout setup
* @param none * @param none
@ -243,31 +191,6 @@ class User {
return $dPercent; return $dPercent;
} }
/**
* Update a single row in a table
* @param userID int Account ID
* @param field string Field to update
* @return bool
**/
private function updateSingle($id, $field) {
$this->debug->append("STA " . __METHOD__, 4);
$stmt = $this->mysqli->prepare("UPDATE $this->table SET `" . $field['name'] . "` = ? WHERE id = ? LIMIT 1");
if ($this->checkStmt($stmt) && $stmt->bind_param($field['type'].'i', $field['value'], $id) && $stmt->execute())
return true;
$this->debug->append("Unable to update " . $field['name'] . " with " . $field['value'] . " for ID $id");
return false;
}
private function checkStmt($bState) {
$this->debug->append("STA " . __METHOD__, 4);
if ($bState ===! true) {
$this->debug->append("Failed to prepare statement: " . $this->mysqli->error);
$this->setErrorMessage('Internal application Error');
return false;
}
return true;
}
/** /**
* Update the accounts password * Update the accounts password
* @param userID int User ID * @param userID int User ID
@ -445,6 +368,27 @@ class User {
exit('<meta http-equiv="refresh" content="0; url=' . $location . '"/>'); exit('<meta http-equiv="refresh" content="0; url=' . $location . '"/>');
} }
/**
* Get all users for admin panel
**/
public function getAllUsers($filter='%') {
$this->debug->append("STA " . __METHOD__, 4);
$stmt = $this->mysqli->prepare("
SELECT
a.id AS id,
a.username AS username
FROM " . $this->getTableName() . " AS a
WHERE a.username LIKE ?
GROUP BY username");
if ($this->checkStmt($stmt) && $stmt->bind_param('s', $filter) && $stmt->execute() && $result = $stmt->get_result()) {
while ($row = $result->fetch_assoc()) {
$aData[$row['id']] = $row['username'];
}
return $aData;
}
return false;
}
/** /**
* Fetch this classes table name * Fetch this classes table name
* @return table string This classes table name * @return table string This classes table name
@ -688,7 +632,11 @@ class User {
} }
// Make our class available automatically // Make our class available automatically
$user = new User($debug, $mysqli, SALT, $config); $user = new User();
$user->setDebug($debug);
$user->setMysql($mysqli);
$user->setSalt(SALT);
$user->setConfig($config);
$user->setMail($mail); $user->setMail($mail);
$user->setToken($oToken); $user->setToken($oToken);
$user->setBitcoin($bitcoin); $user->setBitcoin($bitcoin);

View File

@ -26,16 +26,14 @@ class Worker extends Base {
} else { } else {
// Prefix the WebUser to Worker name // Prefix the WebUser to Worker name
$value['username'] = "$username." . $value['username']; $value['username'] = "$username." . $value['username'];
$stmt = $this->mysqli->prepare("UPDATE $this->table SET password = ?, username = ?, monitor = ? WHERE account_id = ? AND id = ?"); $stmt = $this->mysqli->prepare("UPDATE $this->table SET password2 = ?, username = ?, monitor = ? WHERE account_id = ? AND id = ?");
if ( ! ( $this->checkStmt($stmt) && $stmt->bind_param('ssiii', $value['password'], $value['username'], $value['monitor'], $account_id, $key) && $stmt->execute()) ) if ( ! ( $this->checkStmt($stmt) && $stmt->bind_param('ssiii', $value['password'], $value['username'], $value['monitor'], $account_id, $key) && $stmt->execute()) )
$iFailed++; $iFailed++;
} }
} }
if ($iFailed == 0) if ($iFailed == 0)
return true; return true;
// Catchall return $this->sqlError('E0053', $iFailed);
$this->setErrorMessage('Failed to update ' . $iFailed . ' worker.');
return false;
} }
/** /**
@ -57,9 +55,7 @@ class Worker extends Base {
"); ");
if ($this->checkStmt($stmt) && $stmt->bind_param('i', $interval) && $stmt->execute() && $result = $stmt->get_result()) if ($this->checkStmt($stmt) && $stmt->bind_param('i', $interval) && $stmt->execute() && $result = $stmt->get_result())
return $result->fetch_all(MYSQLI_ASSOC); return $result->fetch_all(MYSQLI_ASSOC);
// Catchall return $this->sqlError('E0054');
$this->setErrorMessage("Unable to fetch IDLE, monitored workers");
return false;
} }
/** /**
@ -102,9 +98,7 @@ class Worker extends Base {
"); ");
if ($this->checkStmt($stmt) && $stmt->bind_param('iiiiiii', $interval, $interval, $interval, $interval, $interval, $interval, $id) && $stmt->execute() && $result = $stmt->get_result()) if ($this->checkStmt($stmt) && $stmt->bind_param('iiiiiii', $interval, $interval, $interval, $interval, $interval, $interval, $id) && $stmt->execute() && $result = $stmt->get_result())
return $result->fetch_assoc(); return $result->fetch_assoc();
// Catchall return $this->sqlError('E0055');
$this->serErrorMessage('Failed fetching worker details: '. $this->mysqli->error());
return false;
} }
/** /**
@ -146,10 +140,7 @@ class Worker extends Base {
WHERE account_id = ?"); WHERE account_id = ?");
if ($this->checkStmt($stmt) && $stmt->bind_param('iiiiiiiii', $interval, $interval, $interval, $interval, $interval, $interval, $interval, $interval, $account_id) && $stmt->execute() && $result = $stmt->get_result()) if ($this->checkStmt($stmt) && $stmt->bind_param('iiiiiiiii', $interval, $interval, $interval, $interval, $interval, $interval, $interval, $interval, $account_id) && $stmt->execute() && $result = $stmt->get_result())
return $result->fetch_all(MYSQLI_ASSOC); return $result->fetch_all(MYSQLI_ASSOC);
// Catchall return $this->sqlError('E0056');
$this->setErrorMessage('Failed to fetch workers for your account');
$this->debug->append('Fetching workers failed: ' . $this->mysqli->error);
return false;
} }
/** /**
@ -198,10 +189,7 @@ class Worker extends Base {
ORDER BY hashrate DESC LIMIT ?"); ORDER BY hashrate DESC LIMIT ?");
if ($this->checkStmt($stmt) && $stmt->bind_param('iiiiiiiii', $interval, $interval, $interval, $interval, $interval, $interval, $interval, $interval, $iLimit) && $stmt->execute() && $result = $stmt->get_result()) if ($this->checkStmt($stmt) && $stmt->bind_param('iiiiiiiii', $interval, $interval, $interval, $interval, $interval, $interval, $interval, $interval, $iLimit) && $stmt->execute() && $result = $stmt->get_result())
return $result->fetch_all(MYSQLI_ASSOC); return $result->fetch_all(MYSQLI_ASSOC);
// Catchall return $this->sqlError('E0057');
$this->setErrorMessage('Failed to fetch workers');
$this->debug->append('Fetching workers failed: ' . $this->mysqli->error);
return false;
} }
/** /**
@ -215,11 +203,10 @@ class Worker extends Base {
SELECT COUNT(DISTINCT(username)) AS total SELECT COUNT(DISTINCT(username)) AS total
FROM " . $this->share->getTableName() . " FROM " . $this->share->getTableName() . "
WHERE our_result = 'Y' WHERE our_result = 'Y'
AND time > DATE_SUB(now(), INTERVAL 10 MINUTE) AND time > DATE_SUB(now(), INTERVAL 10 MINUTE)");
");
if ($this->checkStmt($stmt) && $stmt->execute() && $result = $stmt->get_result()) if ($this->checkStmt($stmt) && $stmt->execute() && $result = $stmt->get_result())
return $result->fetch_object()->total; return $result->fetch_object()->total;
return false; return $this->sqlError();
} }
/** /**
@ -234,22 +221,20 @@ class Worker extends Base {
public function addWorker($account_id, $workerName, $workerPassword) { public function addWorker($account_id, $workerName, $workerPassword) {
$this->debug->append("STA " . __METHOD__, 4); $this->debug->append("STA " . __METHOD__, 4);
if ('' === $workerName || '' === $workerPassword) { if ('' === $workerName || '' === $workerPassword) {
$this->setErrorMessage('Worker name and/or password may not be empty'); $this->setErrorMessage($this->getErrorMsg('E0058'));
return false; return false;
} }
$username = $this->user->getUserName($account_id); $username = $this->user->getUserName($account_id);
$workerName = "$username.$workerName"; $workerName = "$username.$workerName";
$stmt = $this->mysqli->prepare("INSERT INTO $this->table (account_id, username, password) VALUES(?, ?, ?)"); $stmt = $this->mysqli->prepare("INSERT INTO $this->table (account_id, username, password) VALUES(?, ?, ?)");
if ($this->checkStmt($stmt)) { if ($this->checkStmt($stmt) && $stmt->bind_param('iss', $account_id, $workerName, $workerPassword)) {
$stmt->bind_param('iss', $account_id, $workerName, $workerPassword);
if (!$stmt->execute()) { if (!$stmt->execute()) {
$this->setErrorMessage( 'Failed to add worker' ); if ($stmt->sqlstate == '23000') return $this->sqlError('E0059');
if ($stmt->sqlstate == '23000') $this->setErrorMessage( 'Worker already exists' ); } else {
return false; return true;
} }
return true;
} }
return false; return $this->sqlError('E0060');
} }
/** /**
@ -261,15 +246,9 @@ class Worker extends Base {
public function deleteWorker($account_id, $id) { public function deleteWorker($account_id, $id) {
$this->debug->append("STA " . __METHOD__, 4); $this->debug->append("STA " . __METHOD__, 4);
$stmt = $this->mysqli->prepare("DELETE FROM $this->table WHERE account_id = ? AND id = ?"); $stmt = $this->mysqli->prepare("DELETE FROM $this->table WHERE account_id = ? AND id = ?");
if ($this->checkStmt($stmt)) { if ($this->checkStmt($stmt) && $stmt->bind_param('ii', $account_id, $id) && $stmt->execute() && $stmt->affected_rows == 1)
$stmt->bind_param('ii', $account_id, $id);
if ($stmt->execute() && $stmt->affected_rows == 1) {
return true; return true;
} else { return $this->sqlError('E0061');
$this->setErrorMessage( 'Unable to delete worker' );
}
}
return false;
} }
} }
@ -279,3 +258,6 @@ $worker->setMysql($mysqli);
$worker->setShare($share); $worker->setShare($share);
$worker->setConfig($config); $worker->setConfig($config);
$worker->setUser($user); $worker->setUser($user);
$worker->setErrorCodes($aErrorCodes);
?>

View File

@ -0,0 +1,68 @@
<?php
// Make sure we are called from index.php
if (!defined('SECURITY')) die('Hacking attempt');
$aErrorCodes['OK'] = 'OK';
$aErrorCodes['E0001'] = 'Out of Order Share Detected';
$aErrorCodes['E0002'] = 'Upstream shares not found';
$aErrorCodes['E0003'] = 'Failed to change shares order';
$aErrorCodes['E0004'] = 'Failed to reset previous block';
$aErrorCodes['E0005'] = 'Unable to fetch blocks upstream share';
$aErrorCodes['E0006'] = 'Unable to conenct to RPC server backend';
$aErrorCodes['E0007'] = 'Out of Order Share detected, autofixed';
$aErrorCodes['E0008'] = 'Failed to delete archived shares';
$aErrorCodes['E0009'] = 'Cron disabled by admin';
$aErrorCodes['E0010'] = 'Unable set payout as processed';
$aErrorCodes['E0011'] = 'No new unaccounted blocks';
$aErrorCodes['E0012'] = 'No share_id found for block';
$aErrorCodes['E0013'] = 'No shares found for block';
$aErrorCodes['E0014'] = 'Failed marking block as accounted';
$aErrorCodes['E0015'] = 'Potential Double Payout detected';
$aErrorCodes['E0016'] = 'Failed to delete accounted shares';
$aErrorCodes['E0017'] = 'Failed to update Uptime Robot status';
$aErrorCodes['E0018'] = 'Cron disbaled due to errors';
$aErrorCodes['E0019'] = "SQL Query failed: %s";
$aErrorCodes['E0020'] = 'Internal error while executing SQL';
$aErrorCodes['E0021'] = 'Unable to fetch invitiations send from your account';
$aErrorCodes['E0022'] = 'Unable to create invitation record';
$aErrorCodes['E0023'] = 'Invalid E-Mail Address';
$aErrorCodes['E0024'] = 'Message may only contain alphanumeric characters';
$aErrorCodes['E0025'] = 'This email is already registered as an account';
$aErrorCodes['E0026'] = 'A pending invitation for this address already exists';
$aErrorCodes['E0027'] = 'Unable to generate invitation token: %s';
$aErrorCodes['E0028'] = 'Unable to send email to recipient';
$aErrorCodes['E0029'] = 'Unable to send invitation';
$aErrorCodes['E0030'] = 'Unable to fetch a valid token for this invitation';
$aErrorCodes['E0031'] = 'Failed to send e-mail via mail() function';
$aErrorCodes['E0032'] = 'Failed to run API call: %s';
$aErrorCodes['E0033'] = 'Failed to store uptime status: %s';
$aErrorCodes['E0034'] = 'Subjcet may only contain alphanumeric characters';
$aErrorCodes['E0035'] = 'Failed to add news record';
$aErrorCodes['E0036'] = 'Failed to delete news record';
$aErrorCodes['E0037'] = 'Failed to update news record';
$aErrorCodes['E0038'] = 'Failed to fetch news record entry';
$aErrorCodes['E0039'] = 'Failed to fetch news records';
$aErrorCodes['E0040'] = 'Failed to fetch active news records';
$aErrorCodes['E0041'] = 'Failed to fetch existing notification records';
$aErrorCodes['E0042'] = 'Failed to fetch active notification records';
$aErrorCodes['E0043'] = 'Unable to add new notification';
$aErrorCodes['E0044'] = 'Failed to fetch notifications for user account';
$aErrorCodes['E0045'] = 'Failed fetching notification settings for user account';
$aErrorCodes['E0046'] = 'Failed to fetch notification setting for user account';
$aErrorCodes['E0047'] = "Failed to update %s settings";
$aErrorCodes['E0048'] = 'Failed to check for existing active payouts';
$aErrorCodes['E0049'] = 'Unable to create new payout request';
$aErrorCodes['E0050'] = 'Failed to fetch unprocessed payouts';
$aErrorCodes['E0051'] = 'Failed to mark payout as processed';
$aErrorCodes['E0052'] = 'Unable to find valid upstream share for block: %s';
$aErrorCodes['E0053'] = 'Failed to update %s workers';
$aErrorCodes['E0054'] = 'Unable to fetch IDLE, monitored workers';
$aErrorCodes['E0055'] = 'Failed fetching worker details';
$aErrorCodes['E0056'] = 'Failed to fetch workers for your account';
$aErrorCodes['E0057'] = 'Failed to fetch workers for admin panel';
$aErrorCodes['E0058'] = 'Worker name and/or password must not be empty';
$aErrorCodes['E0059'] = 'Worker already exists';
$aErrorCodes['E0060'] = 'Failed to add new worker';
$aErrorCodes['E0061'] = 'Failed to delete worker';
?>

View File

@ -11,7 +11,7 @@ if ($user->isAuthenticated()) {
if ($notification->updateSettings($_SESSION['USERDATA']['id'], $_REQUEST['data'])) { if ($notification->updateSettings($_SESSION['USERDATA']['id'], $_REQUEST['data'])) {
$_SESSION['POPUP'][] = array('CONTENT' => 'Updated notification settings'); $_SESSION['POPUP'][] = array('CONTENT' => 'Updated notification settings');
} else { } else {
$_SESSION['POPUP'][] = array('CONTENT' => 'Failed to update settings', 'TYPE' => 'errormsg'); $_SESSION['POPUP'][] = array('CONTENT' => $notification->getError(), 'TYPE' => 'errormsg');
} }
} }

View File

@ -28,6 +28,7 @@ case 'prop':
// Data array for template // Data array for template
foreach ($aCrons as $strCron) { foreach ($aCrons as $strCron) {
$aCronStatus[$strCron] = array( $aCronStatus[$strCron] = array(
'disabled' => $monitoring->getStatus($strCron . '_disabled'),
'exit' => $monitoring->getStatus($strCron . '_status'), 'exit' => $monitoring->getStatus($strCron . '_status'),
'active' => $monitoring->getStatus($strCron . '_active'), 'active' => $monitoring->getStatus($strCron . '_active'),
'runtime' => $monitoring->getStatus($strCron . '_runtime'), 'runtime' => $monitoring->getStatus($strCron . '_runtime'),

View File

@ -12,7 +12,7 @@ if (!$user->isAuthenticated() || !$user->isAdmin($_SESSION['USERDATA']['id'])) {
if (!$smarty->isCached('master.tpl', $smarty_cache_key)) { if (!$smarty->isCached('master.tpl', $smarty_cache_key)) {
$debug->append('No cached version available, fetching from backend', 3); $debug->append('No cached version available, fetching from backend', 3);
$aUserList = $roundstats->getAllUsers('%'); $aUserList = $user->getAllUsers('%');
$iHeight = 0; $iHeight = 0;
$iUserId = 0; $iUserId = 0;

View File

@ -0,0 +1,2 @@
</body>
</html>

View File

@ -0,0 +1,82 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
<title>{$DATA.subject}</title>
<style type="text/css">
{literal}
#outlook a {padding:0;} /* Force Outlook to provide a "view in browser" menu link. */
body{width:100% !important; -webkit-text-size-adjust:100%; -ms-text-size-adjust:100%; margin:0; padding:0;}
.ExternalClass {width:100%;} /* Force Hotmail to display emails at full width */
.ExternalClass, .ExternalClass p, .ExternalClass span, .ExternalClass font, .ExternalClass td, .ExternalClass div {line-height: 100%;} /* Force Hotmail to display normal line spacing. More on that: http://www.emailonacid.com/forum/viewthread/43/ */
#backgroundTable {margin:0; padding:0; width:100% !important; line-height: 100% !important;}
img {outline:none; text-decoration:none; -ms-interpolation-mode: bicubic;}
a img {border:none;}
.image_fix {display:block;}
p {margin: 1em 0;}
h1, h2, h3, h4, h5, h6 {color: black !important;}
h1 a, h2 a, h3 a, h4 a, h5 a, h6 a {color: blue !important;}
h1 a:active, h2 a:active, h3 a:active, h4 a:active, h5 a:active, h6 a:active {
color: red !important; /* Preferably not the same color as the normal header link color. There is limited support for psuedo classes in email clients, this was added just for good measure. */
}
h1 a:visited, h2 a:visited, h3 a:visited, h4 a:visited, h5 a:visited, h6 a:visited {
color: purple !important; /* Preferably not the same color as the normal header link color. There is limited support for psuedo classes in email clients, this was added just for good measure. */
}
table td {border-collapse: collapse;}
table { border-collapse:collapse; mso-table-lspace:0pt; mso-table-rspace:0pt; }
a:link { color: orange; }
a:visited { color: blue; }
a:hover { color: green; }
@media only screen and (max-device-width: 480px) {
a[href^="tel"], a[href^="sms"] {
text-decoration: none;
color: black; /* or whatever your want */
pointer-events: none;
cursor: default;
}
.mobile_link a[href^="tel"], .mobile_link a[href^="sms"] {
text-decoration: default;
color: orange !important; /* or whatever your want */
pointer-events: auto;
cursor: default;
}
}
@media only screen and (min-device-width: 768px) and (max-device-width: 1024px) {
a[href^="tel"], a[href^="sms"] {
text-decoration: none;
color: blue; /* or whatever your want */
pointer-events: none;
cursor: default;
}
.mobile_link a[href^="tel"], .mobile_link a[href^="sms"] {
text-decoration: default;
color: orange !important;
pointer-events: auto;
cursor: default;
}
}
@media only screen and (-webkit-min-device-pixel-ratio: 2) {
}
@media only screen and (-webkit-device-pixel-ratio:.75){
}
@media only screen and (-webkit-device-pixel-ratio:1){
}
@media only screen and (-webkit-device-pixel-ratio:1.5){
}
{/literal}
</style>
<!--[if IEMobile 7]>
<style type="text/css">
</style>
<![endif]-->
<!--[if gte mso 9]>
<style>
/* Target Outlook 2007 and 2010 */
</style>
<![endif]-->
</head>
<body>

View File

@ -1,10 +1,20 @@
<html> {include file="../global/header.tpl"}
<body> <h1>An error occured!</h1>
<h1>An error occured!</h1> <p>This should never happen. Please review the error output below.</p>
<p>This should never happen. Please review the error output below.</p> <table cellpadding="0" cellspacing="0" border="0" id="backgroundTable">
<tr>
<td>
<table cellpadding="0" cellspacing="1" border="0" align="left" width="800px">
{foreach from=$DATA key=text item=message} {foreach from=$DATA key=text item=message}
{if $text != 'email' && $text != 'subject'} {if $text != 'email' && $text != 'subject'}
<p>{$text}: {$message}</p> <tr>
<th align="left" width="150px">{$text}</th>
<td>{$message}</td>
</tr>
{/if} {/if}
{/foreach} {/foreach}
</table>
</td>
</tr>
</table>
{include file="../global/footer.tpl"}

View File

@ -1,6 +1,7 @@
{include file="global/block_header.tpl" BLOCK_HEADER="Monitoring"} {include file="global/block_header.tpl" BLOCK_HEADER="Monitoring"}
<table width="88%"> <table width="88%">
<thead> <thead>
<th>Disabled</th>
<th>Cronjob</th> <th>Cronjob</th>
<th>Exit Code</th> <th>Exit Code</th>
<th>Active</th> <th>Active</th>

View File

@ -3,6 +3,7 @@
<table class="tablesorter" cellspacing="0"> <table class="tablesorter" cellspacing="0">
<thead> <thead>
<th>Cronjob</th> <th>Cronjob</th>
<th align="center">Disabled</th>
<th align="center">Exit Code</th> <th align="center">Exit Code</th>
<th align="center">Active</th> <th align="center">Active</th>
<th align="center">Runtime</th> <th align="center">Runtime</th>

View File

@ -19,7 +19,7 @@
<tr> <tr>
<th scope="row">Actual</th> <th scope="row">Actual</th>
{section block $BLOCKSFOUND step=-1} {section block $BLOCKSFOUND step=-1}
<td>{$BLOCKSFOUND[block].shares}</td> <td>{$BLOCKSFOUND[block].shares|default:"0"}</td>
{/section} {/section}
</tr> </tr>
{if $GLOBAL.config.payout_system == 'pplns'}<tr> {if $GLOBAL.config.payout_system == 'pplns'}<tr>
@ -136,7 +136,7 @@
{if $GLOBAL.config.payout_system == 'pplns'}<td align="right">{$BLOCKSFOUND[block].pplns_shares|number_format}</td>{/if} {if $GLOBAL.config.payout_system == 'pplns'}<td align="right">{$BLOCKSFOUND[block].pplns_shares|number_format}</td>{/if}
<td align="right">{$BLOCKSFOUND[block].shares|number_format}</td> <td align="right">{$BLOCKSFOUND[block].shares|number_format}</td>
<td align="right" style="padding-right: 25px;"> <td align="right" style="padding-right: 25px;">
{math assign="percentage" equation="shares / estshares * 100" shares=$BLOCKSFOUND[block].shares estshares=$BLOCKSFOUND[block].estshares} {math assign="percentage" equation="shares / estshares * 100" shares=$BLOCKSFOUND[block].shares|default:"0" estshares=$BLOCKSFOUND[block].estshares}
<font color="{if ($percentage <= 100)}green{else}red{/if}">{$percentage|number_format:"2"}</font> <font color="{if ($percentage <= 100)}green{else}red{/if}">{$percentage|number_format:"2"}</font>
</td> </td>
</tr> </tr>

View File

@ -61,7 +61,7 @@ CREATE TABLE IF NOT EXISTS `monitoring` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT, `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`name` varchar(30) NOT NULL, `name` varchar(30) NOT NULL,
`type` varchar(15) NOT NULL, `type` varchar(15) NOT NULL,
`value` varchar(25) NOT NULL, `value` varchar(255) NOT NULL,
PRIMARY KEY (`id`), PRIMARY KEY (`id`),
UNIQUE KEY `name` (`name`) UNIQUE KEY `name` (`name`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='Monitoring events from cronjobs'; ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='Monitoring events from cronjobs';

View File

@ -0,0 +1 @@
ALTER TABLE `monitoring` CHANGE `value` `value` VARCHAR( 255 ) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL ;