Adding support for various notifications

* Adding new SQL upgrade for notifications
* Added support for per user notification settings
* Added account_id to notifications table
* Added new notification_settings table
* Added new account page: notifications

Addresses #144
This commit is contained in:
Sebastian Grewe 2013-06-09 13:10:58 +02:00
parent 9eeb088734
commit 88ade9cfa3
6 changed files with 171 additions and 6 deletions

View File

@ -36,7 +36,7 @@ if (empty($aWorkers)) {
verbose("Worker already notified\n");
continue;
}
if ($notification->addNotification('idle_worker', $aData) && $notification->sendMail($aData['email'], 'idle_worker', $aData)) {
if ($notification->addNotification($aWorker['account_id'], 'idle_worker', $aData) && $notification->sendMail($aData['email'], 'idle_worker', $aData)) {
verbose ("Notified " . $aData['email'] . " for IDLE worker " . $aWorker['username'] . "\n");
} else {
verbose("Unable to send notification: " . $notification->getError() . "\n");

View File

@ -6,6 +6,7 @@ if (!defined('SECURITY'))
class Notification extends Mail {
var $table = 'notifications';
var $tableSettings = 'notification_settings';
public function setInactive($id) {
$field = array(
@ -22,9 +23,10 @@ class Notification extends Mail {
* @param field string Field to update
* @return bool
**/
private function updateSingle($id, $field) {
private function updateSingle($id, $field, $table='') {
if (empty($table)) $table = $this->table;
$this->debug->append("STA " . __METHOD__, 4);
$stmt = $this->mysqli->prepare("UPDATE $this->table SET " . $field['name'] . " = ? WHERE id = ? LIMIT 1");
$stmt = $this->mysqli->prepare("UPDATE $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");
@ -35,6 +37,7 @@ class Notification extends Mail {
* so we can avoid duplicate entries
**/
public function isNotified($aData) {
$this->debug->append("STA " . __METHOD__, 4);
$data = json_encode($aData);
$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)
@ -49,6 +52,7 @@ class Notification extends Mail {
* Get all active notifications
**/
public function getAllActive() {
$this->debug->append("STA " . __METHOD__, 4);
$stmt =$this->mysqli->prepare("SELECT id, data FROM $this->table WHERE active = 1 LIMIT 1");
if ($stmt && $stmt->execute() && $result = $stmt->get_result())
return $result->fetch_all(MYSQLI_ASSOC);
@ -61,16 +65,85 @@ class Notification extends Mail {
* @param type string Type of the notification
* @return bool
**/
public function addNotification($type, $data) {
public function addNotification($account_id, $type, $data) {
$this->debug->append("STA " . __METHOD__, 4);
// Store notification data as json
$data = json_encode($data);
$stmt = $this->mysqli->prepare("INSERT INTO $this->table (type, data, active) VALUES (?,?,1)");
if ($stmt && $stmt->bind_param('ss', $type, $data) && $stmt->execute())
$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())
return true;
$this->debug->append("Failed to add notification for $type with $data: " . $this->mysqli->error);
$this->setErrorMessage("Unable to add new notification");
return false;
}
/**
* Fetch notifications for a user account
* @param id int Account ID
* @return array Notification data
**/
public function getNofifications($account_id) {
$this->debug->append("STA " . __METHOD__, 4);
$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())
return $result->fetch_all(MYSQLI_ASSOC);
// Catchall
return false;
}
/**
* Fetch notification settings for user account
* @param id int Account ID
* @return array Notification settings
**/
public function getNotificationSettings($account_id) {
$this->debug->append("STA " . __METHOD__, 4);
$stmt = $this->mysqli->prepare("SELECT * FROM $this->tableSettings WHERE account_id = ?");
if ($stmt && $stmt->bind_param('i', $account_id) && $stmt->execute() && $result = $stmt->get_result()) {
while ($row = $result->fetch_assoc()) {
$aData[$row['type']] = $row['active'];
}
return $aData;
}
// Catchall
return false;
}
/**
* Update accounts notification settings
* @param account_id int Account ID
* @param data array Data array
* @return bool
**/
public function updateSettings($account_id, $data) {
$this->debug->append("STA " . __METHOD__, 4);
$failed = $ok = 0;
foreach ($data as $type => $active) {
// Does an entry exist already
$stmt = $this->mysqli->prepare("SELECT * FROM $this->tableSettings WHERE account_id = ? AND type = ?");
if ($stmt && $stmt->bind_param('is', $account_id, $type) && $stmt->execute() && $stmt->store_result() && $stmt->num_rows() > 0) {
// We found a matching row
$stmt = $this->mysqli->prepare("UPDATE $this->tableSettings SET active = ? WHERE type = ? AND account_id = ?");
if ($stmt && $stmt->bind_param('isi', $active, $type, $account_id) && $stmt->execute() && $stmt->close()) {
$ok++;
} else {
$failed++;
}
} else {
$stmt = $this->mysqli->prepare("INSERT INTO $this->tableSettings (active, type, account_id) VALUES (?,?,?)");
if ($stmt && $stmt->bind_param('isi', $active, $type, $account_id) && $stmt->execute()) {
$ok++;
} else {
$failed++;
}
}
}
if ($failed > 0) {
$this->setErrorMessage('Failed to update ' . $failed . ' settings');
return false;
}
return true;
}
}
$notification = new Notification();

View File

@ -0,0 +1,25 @@
<?php
// Make sure we are called from index.php
if (!defined('SECURITY')) die('Hacking attempt');
if (!$_SESSION['AUTHENTICATED']) header('Location: index.php?page=home');
if ($_REQUEST['do'] == 'save') {
if ($notification->updateSettings($_SESSION['USERDATA']['id'], $_REQUEST['data'])) {
$_SESSION['POPUP'][] = array('CONTENT' => 'Updated notification settings');
} else {
$_SESSION['POPUP'][] = array('CONTENT' => 'Failed to update settings', 'TYPE' => 'errormsg');
}
}
// Fetch notifications
$aNotifications = $notification->getNofifications($_SESSION['USERDATA']['id']);
if (!$aNotifications) $_SESSION['POPUP'][] = array('CONTENT' => 'Could not find any notifications', 'TYPE' => 'errormsg');
// Fetch user notification settings
$aSettings = $notification->getNotificationSettings($_SESSION['USERDATA']['id']);
$smarty->assign('NOTIFICATIONS', $aNotifications);
$smarty->assign('SETTINGS', $aSettings);
$smarty->assign('CONTENT', 'default.tpl');
?>

View File

@ -0,0 +1,60 @@
{include file="global/block_header.tpl" ALIGN="left" BLOCK_HEADER="Notification Settings"}
<form action="{$smarty.server.PHP_SELF}" method="POST">
<input type="hidden" name="page" value="{$smarty.request.page}">
<input type="hidden" name="action" value="{$smarty.request.action}">
<input type="hidden" name="do" value="save">
<table width="100%">
<tr>
<th class="left">Type</th>
<th class="center">Active</th>
</tr>
<tr>
<td class="left">New Blocks</td>
<td class="center">
<input type="hidden" name="data[new_block]" value="0" />
<input type="checkbox" name="data[new_block]" value="1"{if $SETTINGS['new_block']}checked{/if} />
</td>
</tr>
<tr>
<td class="left">Auto Payout</td>
<td class="center">
<input type="hidden" name="data[auto_payout]" value="0" />
<input type="checkbox" name="data[auto_payout]" value="1"{if $SETTINGS['auto_payout']}checked{/if} />
</td>
</tr>
<tr>
<td colspan="2" class="center">
<input type="submit" class="submit small" value="Update">
</td>
</tr>
</table>
</form>
{include file="global/block_footer.tpl"}
{include file="global/block_header.tpl" ALIGN="right" BLOCK_HEADER="Notification History"}
<center>
{include file="global/pagination.tpl"}
<table width="100%" class="pagesort">
<thead style="font-size:13px;">
<tr>
<th class="center" style="cursor: pointer;">ID</th>
<th class="center" style="cursor: pointer;">Time</th>
<th class="center" style="cursor: pointer;">Type</th>
<th class="center" style="cursor: pointer;">Active</th>
</tr>
</thead>
<tbody style="font-size:12px;">
{section notification $NOTIFICATIONS}
<tr class="{cycle values="odd,even"}">
<td class="center">{$NOTIFICATIONS[notification].id}</td>
<td class="center">{$NOTIFICATIONS[notification].time}</td>
<td class="center">{$NOTIFICATIONS[notification].type}</td>
<td class="center">
<img src="{$PATH}/images/{if $NOTIFICATIONS[notification].active}success{else}error{/if}.gif" />
</td>
</tr>
{/section}
</tbody>
</table>
</center>
{include file="global/block_footer.tpl"}

View File

@ -7,6 +7,7 @@
<li><a href="{$smarty.server.PHP_SELF}?page=account&action=workers">My Workers</a></li>
<li><a href="{$smarty.server.PHP_SELF}?page=statistics&action=user">My Graphs</a></li>
<li><a href="{$smarty.server.PHP_SELF}?page=account&action=transactions">Transactions</a></li>
<li><a href="{$smarty.server.PHP_SELF}?page=account&action=notifications">Notifications</a></li>
</ul>
</li>
{/if}

View File

@ -0,0 +1,6 @@
ALTER TABLE `notifications` ADD `account_id` INT UNSIGNED NULL DEFAULT NULL , ADD INDEX ( `account_id` )
CREATE TABLE IF NOT EXISTS `notification_settings` (
`type` varchar(15) NOT NULL,
`account_id` int(11) NOT NULL,
`active` tinyint(1) NOT NULL DEFAULT '0'
) ENGINE=InnoDB DEFAULT CHARSET=utf8;