Adding new admin transaction view
* Added transaction filters * Added proper paging support * Removed the tabs that caused confusion * Added transaction status column Fixes #404
This commit is contained in:
parent
44c31fe630
commit
1d6cbd44a6
@ -81,12 +81,13 @@ class Transaction {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Fetch all transactions for all users
|
* Fetch all transactions for all users
|
||||||
|
* Optionally apply a filter
|
||||||
* @param none
|
* @param none
|
||||||
* @return mixed array or false
|
* @return mixed array or false
|
||||||
**/
|
**/
|
||||||
public function getAllTransactions($start=0) {
|
public function getAllTransactions($start=0,$filter=NULL,$limit=30) {
|
||||||
$this->debug->append("STA " . __METHOD__, 4);
|
$this->debug->append("STA " . __METHOD__, 4);
|
||||||
$stmt = $this->mysqli->prepare("
|
$sql = "
|
||||||
SELECT
|
SELECT
|
||||||
t.id AS id,
|
t.id AS id,
|
||||||
a.username as username,
|
a.username as username,
|
||||||
@ -96,17 +97,77 @@ class Transaction {
|
|||||||
t.timestamp AS timestamp,
|
t.timestamp AS timestamp,
|
||||||
b.height AS height,
|
b.height AS height,
|
||||||
b.confirmations AS confirmations
|
b.confirmations AS confirmations
|
||||||
FROM transactions AS t
|
FROM $this->table AS t
|
||||||
LEFT JOIN " . $this->block->getTableName() . " AS b ON t.block_id = b.id
|
LEFT JOIN " . $this->block->getTableName() . " AS b ON t.block_id = b.id
|
||||||
LEFT JOIN " . $this->user->getTableName() . " AS a ON t.account_id = a.id
|
LEFT JOIN " . $this->user->getTableName() . " AS a ON t.account_id = a.id";
|
||||||
|
if (is_array($filter)) {
|
||||||
|
$aFilter = array();
|
||||||
|
foreach ($filter as $key => $value) {
|
||||||
|
if (!empty($value)) {
|
||||||
|
switch ($key) {
|
||||||
|
case 'type':
|
||||||
|
$aFilter[] = "t.type = '$value'";
|
||||||
|
break;
|
||||||
|
case 'status':
|
||||||
|
switch ($value) {
|
||||||
|
case 'Confirmed':
|
||||||
|
$aFilter[] = "b.confirmations >= " . $this->config['confirmations'];
|
||||||
|
break;
|
||||||
|
case 'Unconfirmed':
|
||||||
|
$aFilter[] = "b.confirmations < " . $this->config['confirmations'] . " AND b.confirmations >= 0";
|
||||||
|
break;
|
||||||
|
case 'Orphan':
|
||||||
|
$aFilter[] = "b.confirmations = -1";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 'account':
|
||||||
|
$aFilter[] = "LOWER(a.username) = LOWER('$value')";
|
||||||
|
break;
|
||||||
|
case 'address':
|
||||||
|
$aFilter[] = "t.coin_address = '$value'";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!empty($aFilter)) {
|
||||||
|
$sql .= " WHERE " . implode(' AND ', $aFilter);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$sql .= "
|
||||||
ORDER BY id DESC
|
ORDER BY id DESC
|
||||||
LIMIT ?,30");
|
LIMIT ?,?
|
||||||
if ($this->checkStmt($stmt) && $stmt->bind_param('i', $start) && $stmt->execute() && $result = $stmt->get_result())
|
";
|
||||||
|
$stmt = $this->mysqli->prepare($sql);
|
||||||
|
if ($this->checkStmt($stmt) && $stmt->bind_param('ii', $start, $limit) && $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 false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Count the amount of transactions in the table
|
||||||
|
**/
|
||||||
|
public function getCountAllTransactions($filter=NULL) {
|
||||||
|
$stmt = $this->mysqli->prepare("SELECT COUNT(id) AS total FROM $this->table");
|
||||||
|
if ($this->checkStmt($stmt) && $stmt->execute() && $result = $stmt->get_result())
|
||||||
|
return $result->fetch_object()->total;
|
||||||
|
$this->debug->append('Failed to fetch transaction count: ' . $this->mysqli->error);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
public function getTypes() {
|
||||||
|
$stmt = $this->mysqli->prepare("SELECT DISTINCT type FROM $this->table");
|
||||||
|
if ($this->checkStmt($stmt) && $stmt->execute() && $result = $stmt->get_result()) {
|
||||||
|
$aData = array('' => '');
|
||||||
|
while ($row = $result->fetch_assoc()) {
|
||||||
|
$aData[$row['type']] = $row['type'];
|
||||||
|
}
|
||||||
|
return $aData;
|
||||||
|
}
|
||||||
|
$this->debug->append('Failed to fetch transaction types: ' . $this->mysqli->error);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
private function checkStmt($bState) {
|
private function checkStmt($bState) {
|
||||||
if ($bState ===! true) {
|
if ($bState ===! true) {
|
||||||
$this->debug->append("Failed to prepare statement: " . $this->mysqli->error);
|
$this->debug->append("Failed to prepare statement: " . $this->mysqli->error);
|
||||||
|
|||||||
@ -11,11 +11,17 @@ 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);
|
||||||
$aTransactions = $transaction->getAllTransactions(@$_REQUEST['start']);
|
$aTransactions = $transaction->getAllTransactions(@$_REQUEST['start'], @$_REQUEST['filter'], 5);
|
||||||
|
$iCountTransactions = $transaction->getCountAllTransactions();
|
||||||
|
$aTransactionTypes = $transaction->getTypes();
|
||||||
if (!$aTransactions) $_SESSION['POPUP'][] = array('CONTENT' => 'Could not find any transaction', 'TYPE' => 'errormsg');
|
if (!$aTransactions) $_SESSION['POPUP'][] = array('CONTENT' => 'Could not find any transaction', 'TYPE' => 'errormsg');
|
||||||
} else {
|
} else {
|
||||||
$debug->append('Using cached page', 3);
|
$debug->append('Using cached page', 3);
|
||||||
}
|
}
|
||||||
|
|
||||||
$smarty->assign('TRANSACTIONS', $aTransactions);
|
$smarty->assign('TRANSACTIONS', $aTransactions);
|
||||||
|
$smarty->assign('TRANSACTIONTYPES', $aTransactionTypes);
|
||||||
|
$smarty->assign('TXSTATUS', array('' => '', 'Confirmed' => 'Confirmed', 'Unconfirmed' => 'Unconfirmed', 'Orphan' => 'Orphan'));
|
||||||
|
$smarty->assign('COUNTTRANSACTIONS', $iCountTransactions);
|
||||||
$smarty->assign('CONTENT', 'default.tpl');
|
$smarty->assign('CONTENT', 'default.tpl');
|
||||||
?>
|
?>
|
||||||
|
|||||||
@ -1,47 +1,91 @@
|
|||||||
{include file="global/block_header.tpl" BLOCK_HEADER="Transaction Log" BUTTONS=array(Confirmed,Unconfirmed,Orphan)}
|
{include file="global/block_header.tpl" ALIGN="left" BLOCK_STYLE="width: 23%" BLOCK_HEADER="Transaction Filter"}
|
||||||
|
<table cellpadding="1" cellspacing="1" width="100%">
|
||||||
|
<tbody>
|
||||||
|
<tr>
|
||||||
|
<td class="left">
|
||||||
|
{if $COUNTTRANSACTIONS / 5 > 1}
|
||||||
|
{if $smarty.request.start > 0}
|
||||||
|
<a href="{$smarty.server.PHP_SELF}?page=admin&action=transactions&start={$smarty.request.start|default:"0" - 5}"><img src="{$PATH}/images/prev.png" /></a>
|
||||||
|
{else}
|
||||||
|
<img src="{$PATH}/images/prev.png" />
|
||||||
|
{/if}
|
||||||
|
{/if}
|
||||||
|
</td>
|
||||||
|
<td class="right">
|
||||||
|
{if $COUNTTRANSACTIONS / 5 > 1}
|
||||||
|
{if $COUNTTRANSACTIONS - $smarty.request.start - 5 > 0}
|
||||||
|
<a href="{$smarty.server.PHP_SELF}?page=admin&action=transactions&start={$smarty.request.start|default:"0" + 5}"><img src="{$PATH}/images/next.png" /></a>
|
||||||
|
{else}
|
||||||
|
<img src="{$PATH}/images/next.png" />
|
||||||
|
{/if}
|
||||||
|
{/if}
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<form action="{$smarty.server.PHP_SELF}">
|
||||||
|
<input type="hidden" name="page" value="{$smarty.request.page}" />
|
||||||
|
<input type="hidden" name="action" value="{$smarty.request.action}" />
|
||||||
|
<tr>
|
||||||
|
<td class="left">Type</td>
|
||||||
|
<td class="right">{html_options name="filter[type]" options=$TRANSACTIONTYPES selected=$smarty.request.filter.type}</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td class="left">Status</td>
|
||||||
|
<td class="right">{html_options name="filter[status]" options=$TXSTATUS selected=$smarty.request.filter.status}</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td class="left">Account</td>
|
||||||
|
<td class="right"><input size="10" type="text" name="filter[account]" value="{$smarty.request.filter.account}" /></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td class="left">Address</td>
|
||||||
|
<td class="right"><input size="10" type="text" name="filter[address]" value="{$smarty.request.filter.address}" /></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td class="center" colspan="2"><input type="submit" class="submit small" value="Filter"></td>
|
||||||
|
</tr>
|
||||||
|
</form>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
{include file="global/block_footer.tpl"}
|
||||||
|
|
||||||
|
{include file="global/block_header.tpl" ALIGN="right" BLOCK_STYLE="width: 75%" BLOCK_HEADER="Transaction History"}
|
||||||
|
<div class="block_content" style="clear:;">
|
||||||
<center>
|
<center>
|
||||||
<a href="{$smarty.server.PHP_SELF}?page=admin&action=transactions&start={$smarty.request.start|default:"0" - 30}"><img src="{$PATH}/images/prev.png" /></a>
|
<table cellpadding="1" cellspacing="1" width="100%">
|
||||||
<a href="{$smarty.server.PHP_SELF}?page=admin&action=transactions&start={$smarty.request.start|default:"0" + 30}"><img src="{$PATH}/images/next.png" /></a>
|
|
||||||
</center>
|
|
||||||
<div class="block_content tab_content" id="Confirmed" style="clear:;">
|
|
||||||
<center>
|
|
||||||
<table cellpadding="1" cellspacing="1" width="98%" class="pagesort">
|
|
||||||
<thead style="font-size:13px;">
|
<thead style="font-size:13px;">
|
||||||
<tr>
|
<tr>
|
||||||
<th class="header" style="cursor: pointer;">TX #</th>
|
<th class="header" style="cursor: pointer;">TX #</th>
|
||||||
<th class="header" style="cursor: pointer;">Account</th>
|
<th class="header" style="cursor: pointer;">Account</th>
|
||||||
<th class="header" style="cursor: pointer;">Date</th>
|
<th class="header" style="cursor: pointer;">Date</th>
|
||||||
<th class="header" style="cursor: pointer;">TX Type</th>
|
<th class="header" style="cursor: pointer;">TX Type</th>
|
||||||
|
<th class="header" style="cursor: pointer;">Status</th>
|
||||||
<th class="header" style="cursor: pointer;">Payment Address</th>
|
<th class="header" style="cursor: pointer;">Payment Address</th>
|
||||||
<th class="header" style="cursor: pointer;">Block #</th>
|
<th class="header" style="cursor: pointer;">Block #</th>
|
||||||
<th class="header" style="cursor: pointer;">Amount</th>
|
<th class="header" style="cursor: pointer;">Amount</th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody style="font-size:12px;">
|
<tbody style="font-size:12px;">
|
||||||
{assign var=confirmed value=0}
|
|
||||||
{section transaction $TRANSACTIONS}
|
{section transaction $TRANSACTIONS}
|
||||||
{if (
|
|
||||||
( ( $TRANSACTIONS[transaction].type == 'Credit' or $TRANSACTIONS[transaction].type == 'Bonus' or $TRANSACTIONS[transaction].type == 'Donation' or $TRANSACTIONS[transaction].type == 'Fee' ) and $TRANSACTIONS[transaction].confirmations >= $GLOBAL.confirmations )
|
|
||||||
or $TRANSACTIONS[transaction].type == 'Credit_PPS' or $TRANSACTIONS[transaction].type == 'Fee_PPS' or $TRANSACTIONS[transaction].type == 'Donation_PPS'
|
|
||||||
or $TRANSACTIONS[transaction].type == 'Debit_AP' or $TRANSACTIONS[transaction].type == 'Debit_MP' or $TRANSACTIONS[transaction].type == 'TXFee'
|
|
||||||
)}
|
|
||||||
{assign var=confirmed value=1}
|
|
||||||
<tr class="{cycle values="odd,even"}">
|
<tr class="{cycle values="odd,even"}">
|
||||||
<td>{$TRANSACTIONS[transaction].id}</td>
|
<td>{$TRANSACTIONS[transaction].id}</td>
|
||||||
<td>{$TRANSACTIONS[transaction].username}</td>
|
<td>{$TRANSACTIONS[transaction].username}</td>
|
||||||
<td>{$TRANSACTIONS[transaction].timestamp}</td>
|
<td>{$TRANSACTIONS[transaction].timestamp}</td>
|
||||||
<td>{$TRANSACTIONS[transaction].type}</td>
|
<td>{$TRANSACTIONS[transaction].type}</td>
|
||||||
|
<td>
|
||||||
|
{if $TRANSACTIONS[transaction].type == 'Credit_PPS' OR
|
||||||
|
$TRANSACTIONS[transaction].type == 'Debit_MP' OR
|
||||||
|
$TRANSACTIONS[transaction].type == 'Debit_AP' OR
|
||||||
|
$TRANSACTIONS[transaction].confirmations > $GLOBAL.confirmations
|
||||||
|
}<font color="green">Confirmed</font>
|
||||||
|
{else if $TRANSACTIONS[transaction].confirmations == -1}<font color="red">Orphaned</font>
|
||||||
|
{else}<font color="orange">Unconfirmed</font>{/if}
|
||||||
|
<font size="1px">({$TRANSACTIONS[transaction].confirmations|default:"n/a"})</font>
|
||||||
|
</td>
|
||||||
<td>{$TRANSACTIONS[transaction].coin_address}</td>
|
<td>{$TRANSACTIONS[transaction].coin_address}</td>
|
||||||
<td>{if $TRANSACTIONS[transaction].height == 0}n/a{else}{$TRANSACTIONS[transaction].height}{/if}</td>
|
<td>{if $TRANSACTIONS[transaction].height == 0}n/a{else}{$TRANSACTIONS[transaction].height}{/if}</td>
|
||||||
<td><font color="{if $TRANSACTIONS[transaction].type == 'Credit' or $TRANSACTIONS[transaction].type == 'Credit_PPS' or $TRANSACTIONS[transaction].type == 'Bonus'}green{else}red{/if}">{$TRANSACTIONS[transaction].amount|number_format:"8"}</td>
|
<td><font color="{if $TRANSACTIONS[transaction].type == 'Credit' or $TRANSACTIONS[transaction].type == 'Credit_PPS' or $TRANSACTIONS[transaction].type == 'Bonus'}green{else}red{/if}">{$TRANSACTIONS[transaction].amount|number_format:"8"}</td>
|
||||||
</tr>
|
</tr>
|
||||||
{/if}
|
|
||||||
{/section}
|
{/section}
|
||||||
{if $confirmed != 1}
|
|
||||||
<tr>
|
|
||||||
<td class="center" colspan="7">No confirmed transactions</td>
|
|
||||||
</tr>
|
|
||||||
{/if}
|
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
<p>
|
<p>
|
||||||
@ -51,84 +95,4 @@
|
|||||||
</p>
|
</p>
|
||||||
</center>
|
</center>
|
||||||
</div>
|
</div>
|
||||||
<div class="block_content tab_content" id="Unconfirmed" style="">
|
|
||||||
<center>
|
|
||||||
<table cellpadding="1" cellspacing="1" width="98%" class="pagesort2">
|
|
||||||
<thead style="font-size:13px;">
|
|
||||||
<tr>
|
|
||||||
<th class="header" style="cursor: pointer;">TX #</th>
|
|
||||||
<th class="header" style="cursor: pointer;">Account</th>
|
|
||||||
<th class="header" style="cursor: pointer;">Date</th>
|
|
||||||
<th class="header" style="cursor: pointer;">TX Type</th>
|
|
||||||
<th class="header" style="cursor: pointer;">Payment Address</th>
|
|
||||||
<th class="header" style="cursor: pointer;">Block #</th>
|
|
||||||
<th class="header" style="cursor: pointer;">Amount</th>
|
|
||||||
</tr>
|
|
||||||
</thead>
|
|
||||||
<tbody style="font-size:12px;">
|
|
||||||
{assign var=unconfirmed value=0}
|
|
||||||
{section transaction $TRANSACTIONS}
|
|
||||||
{if ($TRANSACTIONS[transaction].type == 'Credit' or $TRANSACTIONS[transaction].type == 'Bonus' or $TRANSACTIONS[transaction].type == 'Donation' or $TRANSACTIONS[transaction].type == 'Fee') and $TRANSACTIONS[transaction].confirmations < $GLOBAL.confirmations and $TRANSACTIONS[transaction].confirmations >= 0}
|
|
||||||
{assign var=unconfirmed value=1}
|
|
||||||
<tr class="{cycle values="odd,even"}">
|
|
||||||
<td>{$TRANSACTIONS[transaction].id}</td>
|
|
||||||
<td>{$TRANSACTIONS[transaction].username}</td>
|
|
||||||
<td>{$TRANSACTIONS[transaction].timestamp}</td>
|
|
||||||
<td>{$TRANSACTIONS[transaction].type}</td>
|
|
||||||
<td>{$TRANSACTIONS[transaction].coin_address}</td>
|
|
||||||
<td>{if $TRANSACTIONS[transaction].height == 0}n/a{else}{$TRANSACTIONS[transaction].height}{/if}</td>
|
|
||||||
<td><font color="{if $TRANSACTIONS[transaction].type == 'Credit' or $TRANSACTIONS[transaction].type == 'Bonus'}green{else}red{/if}">{$TRANSACTIONS[transaction].amount|number_format:"8"}</td>
|
|
||||||
</tr>
|
|
||||||
{/if}
|
|
||||||
{/section}
|
|
||||||
{if $unconfirmed != 1}
|
|
||||||
<tr>
|
|
||||||
<td colspan="7">No unconfirmed transactions</td>
|
|
||||||
</tr>
|
|
||||||
{/if}
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
<p><font color="" sizeze="1">Listed are your estimated rewards and donations/fees for all blocks awaiting {$GLOBAL.confirmations} confirmations.</font></p>
|
|
||||||
</center>
|
|
||||||
</div>
|
|
||||||
<div class="block_content tab_content" id="Orphan" style="">
|
|
||||||
<center>
|
|
||||||
<table cellpadding="1" cellspacing="1" width="98%" class="pagesort3">
|
|
||||||
<thead style="font-size:13px;">
|
|
||||||
<tr>
|
|
||||||
<th class="header" style="cursor: pointer;">TX #</th>
|
|
||||||
<th class="header" style="cursor: pointer;">Account</th>
|
|
||||||
<th class="header" style="cursor: pointer;">Date</th>
|
|
||||||
<th class="header" style="cursor: pointer;">TX Type</th>
|
|
||||||
<th class="header" style="cursor: pointer;">Payment Address</th>
|
|
||||||
<th class="header" style="cursor: pointer;">Block #</th>
|
|
||||||
<th class="header" style="cursor: pointer;">Amount</th>
|
|
||||||
</tr>
|
|
||||||
</thead>
|
|
||||||
<tbody style="font-size:12px;">
|
|
||||||
{assign var=orphaned value=0}
|
|
||||||
{section transaction $TRANSACTIONS}
|
|
||||||
{if ($TRANSACTIONS[transaction].type == 'Credit' or $TRANSACTIONS[transaction].type == 'Fee' or $TRANSACTIONS[transaction].type == 'Donation' or $TRANSACTIONS[transaction].type == 'Bonus') and $TRANSACTIONS[transaction].confirmations == -1}
|
|
||||||
{assign var=orphaned value=1}
|
|
||||||
<tr class="{cycle values="odd,even"}">
|
|
||||||
<td>{$TRANSACTIONS[transaction].id}</td>
|
|
||||||
<td>{$TRANSACTIONS[transaction].username}</td>
|
|
||||||
<td>{$TRANSACTIONS[transaction].timestamp}</td>
|
|
||||||
<td>{$TRANSACTIONS[transaction].type}</td>
|
|
||||||
<td>{$TRANSACTIONS[transaction].coin_address}</td>
|
|
||||||
<td>{if $TRANSACTIONS[transaction].height == 0}n/a{else}{$TRANSACTIONS[transaction].height}{/if}</td>
|
|
||||||
<td><font color="{if $TRANSACTIONS[transaction].type == 'Credit' or $TRANSACTIONS[transaction].type == 'Bonus'}green{else}red{/if}">{$TRANSACTIONS[transaction].amount|number_format:"8"}</td>
|
|
||||||
</tr>
|
|
||||||
{/if}
|
|
||||||
{/section}
|
|
||||||
{if $orphaned != 1}
|
|
||||||
<tr>
|
|
||||||
<td class="center" colspan="7">No orphan transactions</td>
|
|
||||||
</tr>
|
|
||||||
{/if}
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
<p><font color="" sizeze="1">Listed are your orphaned transactions for blocks not part of the main blockchain.</font></p>
|
|
||||||
</center>
|
|
||||||
</div>
|
|
||||||
{include file="global/block_footer.tpl"}
|
{include file="global/block_footer.tpl"}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user