From bf225fb0de230c8425755b0abce0266e9772bf60 Mon Sep 17 00:00:00 2001 From: Sebastian Grewe Date: Thu, 6 Jun 2013 14:25:36 +0200 Subject: [PATCH 1/9] Add worker montioring to template and worker class * Add configurable monitoring for workers into template * Store monitoring status in DB First commit for #116 --- public/include/classes/worker.class.php | 18 ++++++++++-------- .../mmcFE/account/workers/default.tpl | 2 ++ 2 files changed, 12 insertions(+), 8 deletions(-) diff --git a/public/include/classes/worker.class.php b/public/include/classes/worker.class.php index 5a5c19c4..6052eaac 100644 --- a/public/include/classes/worker.class.php +++ b/public/include/classes/worker.class.php @@ -43,17 +43,19 @@ class Worker { public function updateWorkers($account_id, $data) { $this->debug->append("STA " . __METHOD__, 4); $username = $this->user->getUserName($account_id); + $iFailed = 0; foreach ($data as $key => $value) { // Prefix the WebUser to Worker name $value['username'] = "$username." . $value['username']; - $stmt = $this->mysqli->prepare("UPDATE $this->table SET password = ?, username = ? WHERE account_id = ? AND id = ?"); - if ($this->checkStmt($stmt)) { - if (!$stmt->bind_param('ssii', $value['password'], $value['username'], $account_id, $key)) return false; - if (!$stmt->execute()) return false; - $stmt->close(); - } + $stmt = $this->mysqli->prepare("UPDATE $this->table SET password = ?, 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()) ) + $iFailed++; } - return true; + if ($iFailed == 0) + return true; + // Catchall + $this->setErrorMessage('Failed to update ' . $iFailed . ' worker.'); + return false; } /** @@ -64,7 +66,7 @@ class Worker { public function getWorkers($account_id) { $this->debug->append("STA " . __METHOD__, 4); $stmt = $this->mysqli->prepare(" - SELECT id, username, password, + SELECT id, username, password, monitor, ( SELECT SIGN(COUNT(id)) FROM " . $this->share->getTableName() . " WHERE username = $this->table.username AND time > DATE_SUB(now(), INTERVAL 10 MINUTE)) AS active, ( SELECT ROUND(COUNT(id) * POW(2, " . $this->config['difficulty'] . ")/600/1000) FROM " . $this->share->getTableName() . " WHERE username = $this->table.username AND time > DATE_SUB(now(), INTERVAL 10 MINUTE)) AS hashrate FROM $this->table diff --git a/public/templates/mmcFE/account/workers/default.tpl b/public/templates/mmcFE/account/workers/default.tpl index f1b6e875..612bd227 100644 --- a/public/templates/mmcFE/account/workers/default.tpl +++ b/public/templates/mmcFE/account/workers/default.tpl @@ -10,6 +10,7 @@ Worker Name Password Active + Monitor Khash/s     @@ -20,6 +21,7 @@ {$username.0|escape}. + {$WORKERS[worker].hashrate|number_format} From d7e65c7b3797a15d7bc3fbd86ab23852989a2961 Mon Sep 17 00:00:00 2001 From: Sebastian Grewe Date: Fri, 7 Jun 2013 14:42:29 +0200 Subject: [PATCH 2/9] Progress on notifications * Added main mail class * notification class extends mail class * Added mail template for IDLE workers * Added notification table to SQL structure This works already but once notified the status is not reset as soon as a worker is active again. Need to think of a system to do that automatically. Addresses #116 --- cronjobs/notifications.php | 42 ++++++++++++++ public/include/autoloader.inc.php | 2 + public/include/classes/mail.class.php | 58 +++++++++++++++++++ public/include/classes/notification.class.php | 45 ++++++++++++++ public/include/classes/worker.class.php | 20 +++++++ public/templates/mail/idle_worker.tpl | 9 +++ sql/mmcfe_ng_structure.sql | 20 ++++++- 7 files changed, 193 insertions(+), 3 deletions(-) create mode 100755 cronjobs/notifications.php create mode 100644 public/include/classes/mail.class.php create mode 100644 public/include/classes/notification.class.php create mode 100644 public/templates/mail/idle_worker.tpl diff --git a/cronjobs/notifications.php b/cronjobs/notifications.php new file mode 100755 index 00000000..7bca08ec --- /dev/null +++ b/cronjobs/notifications.php @@ -0,0 +1,42 @@ +#!/usr/bin/php +getAllIdleWorkers(); +if (empty($aWorkers)) { + verbose("No idle workers found\n"); + exit; +} + +foreach ($aWorkers as $aWorker) { + $aData = $aWorker; + $aData['username'] = $user->getUserName($aWorker['account_id']); + $aData['email'] = $user->getUserEmail($aData['username']); + if (!$notification->isNotified($aData)) { + if (!$notification->addNotification('idle_worker', $aData) && $notification->sendMail('sebastian@grewe.ca', 'idle_worker', $aData)) + verbose("Unable to send notification: " . $notification->getError() . "\n"); + } else { + verbose("Already notified for this worker\n"); + } +} +?> diff --git a/public/include/autoloader.inc.php b/public/include/autoloader.inc.php index ea16564e..a78d4a62 100644 --- a/public/include/autoloader.inc.php +++ b/public/include/autoloader.inc.php @@ -14,3 +14,5 @@ require_once(CLASS_DIR . '/worker.class.php'); require_once(CLASS_DIR . '/statistics.class.php'); require_once(CLASS_DIR . '/transaction.class.php'); require_once(CLASS_DIR . '/setting.class.php'); +require_once(CLASS_DIR . '/mail.class.php'); +require_once(CLASS_DIR . '/notification.class.php'); diff --git a/public/include/classes/mail.class.php b/public/include/classes/mail.class.php new file mode 100644 index 00000000..6c7cc0f1 --- /dev/null +++ b/public/include/classes/mail.class.php @@ -0,0 +1,58 @@ +debug = $debug; + } + public function setMysql($mysqli) { + $this->mysqli = $mysqli; + } + public function setSmarty($smarty) { + $this->smarty = $smarty; + } + public function setConfig($config) { + $this->config = $config; + } + + 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; + } + + public function sendMail($email, $template, $vars) { + $this->smarty->assign('WEBSITENAME', $this->config['website']['name']); + $headers = 'From: Website Administration <' . $this->config['website']['email'] . ">\n"; + $headers .= "MIME-Version: 1.0\n"; + $headers .= "Content-Type: text/html; charset=ISO-8859-1\r\n"; + if (mail($email, + $this->smarty->fetch(BASEPATH . 'templates/mail/subject.tpl'), + $this->smarty->fetch(BASEPATH . 'templates/mail/' . $template . '.tpl'), + $headers)) { + return true; + } else { + $this->setErrorMessage("Unable to send mail"); + return false; + } + return false; + } +} + +// Make our class available automatically +$mail = new Mail (); +$mail->setDebug($debug); +$mail->setMysql($mysqli); +$mail->setSmarty($smarty); +$mail->setConfig($config); + +?> diff --git a/public/include/classes/notification.class.php b/public/include/classes/notification.class.php new file mode 100644 index 00000000..a9eca1af --- /dev/null +++ b/public/include/classes/notification.class.php @@ -0,0 +1,45 @@ +mysqli->prepare("SELECT id FROM $this->table WHERE data = ? LIMIT 1"); + if ($stmt && $stmt->bind_param('s', $data) && $stmt->execute() && $stmt->store_result() && $stmt->num_rows == 1) + return true; + // Catchall + // Does not seem to have a notification set + return false; + } + + /** + * Add a new notification to the table + * @param type string Type of the notification + * @return bool + **/ + public function addNotification($type, $data) { + // Store notification data as json + $data = json_encode($data); + $stmt = $this->mysqli->prepare("INSERT INTO $this->table (type, data) VALUES (?,?)"); + if ($stmt && $stmt->bind_param('ss', $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; + } +} + +$notification = new Notification(); +$notification->setDebug($debug); +$notification->setMysql($mysqli); +$notification->setSmarty($smarty); +$notification->setConfig($config); diff --git a/public/include/classes/worker.class.php b/public/include/classes/worker.class.php index 6052eaac..a5052ba9 100644 --- a/public/include/classes/worker.class.php +++ b/public/include/classes/worker.class.php @@ -58,6 +58,26 @@ class Worker { return false; } + /** + * Fetch all IDLE workers that have monitoring enabled + * @param none + * @return data array Workers in IDLE state and monitoring enabled + **/ + public function getAllIdleWorkers() { + $this->debug->append("STA " . __METHOD__, 4); + $stmt = $this->mysqli->prepare(" + SELECT account_id, id, username + FROM " . $this->table . " + WHERE monitor = 1 AND ( SELECT SIGN(COUNT(id)) FROM " . $this->share->getTableName() . " WHERE username = $this->table.username AND time > DATE_SUB(now(), INTERVAL 10 MINUTE)) = 0"); + + if ($this->checkStmt($stmt) && $stmt->execute() && $result = $stmt->get_result()) + return $result->fetch_all(MYSQLI_ASSOC); + // Catchall + $this->setErrorMessage("Unable to fetch IDLE, monitored workers"); + echo $this->mysqli->error; + return false; + } + /** * Fetch all workers for an account * @param account_id int User ID diff --git a/public/templates/mail/idle_worker.tpl b/public/templates/mail/idle_worker.tpl new file mode 100644 index 00000000..a21aaac3 --- /dev/null +++ b/public/templates/mail/idle_worker.tpl @@ -0,0 +1,9 @@ + + +

One of your workers is currently IDLE.

+

Since monitoring is enabled for this worker, this notification was sent.

+

Please check your workers!

+
+
+ + diff --git a/sql/mmcfe_ng_structure.sql b/sql/mmcfe_ng_structure.sql index c3c626bd..a971d455 100644 --- a/sql/mmcfe_ng_structure.sql +++ b/sql/mmcfe_ng_structure.sql @@ -3,7 +3,7 @@ -- http://www.phpmyadmin.net -- -- Host: localhost --- Generation Time: Jun 06, 2013 at 09:01 PM +-- Generation Time: Jun 07, 2013 at 02:42 PM -- Server version: 5.5.31-0ubuntu0.13.04.1 -- PHP Version: 5.4.9-4ubuntu2 @@ -69,6 +69,20 @@ CREATE TABLE IF NOT EXISTS `blocks` ( -- -------------------------------------------------------- +-- +-- Table structure for table `notifications` +-- + +CREATE TABLE IF NOT EXISTS `notifications` ( + `id` int(11) NOT NULL AUTO_INCREMENT, + `type` varchar(25) NOT NULL, + `data` text NOT NULL, + `time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, + PRIMARY KEY (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +-- -------------------------------------------------------- + -- -- Table structure for table `pool_worker` -- @@ -136,7 +150,7 @@ CREATE TABLE IF NOT EXISTS `shares_archive` ( PRIMARY KEY (`id`), UNIQUE KEY `share_id` (`share_id`), KEY `time` (`time`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='Archive shares for potential later debugging purposes'; +) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='Archive shares for potential later debugging purposes'; -- -------------------------------------------------------- @@ -153,7 +167,7 @@ CREATE TABLE IF NOT EXISTS `statistics_shares` ( PRIMARY KEY (`id`), KEY `account_id` (`account_id`), KEY `block_id` (`block_id`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8; +) ENGINE=InnoDB DEFAULT CHARSET=utf8; -- -------------------------------------------------------- From 4966f64a5912698694297d3a9738575d05999af3 Mon Sep 17 00:00:00 2001 From: Sebastian Grewe Date: Fri, 7 Jun 2013 15:07:26 +0200 Subject: [PATCH 3/9] Adding notification reset once worker is active Go through all active notifications (active means they are not notified again) and check if their state has changed. If so, mark as inactive and allow for re-notification of the same type and data. --- cronjobs/notifications.php | 34 +++++++++++------ public/include/classes/mail.class.php | 2 +- public/include/classes/notification.class.php | 38 ++++++++++++++++++- public/include/classes/worker.class.php | 21 ++++++++++ 4 files changed, 80 insertions(+), 15 deletions(-) diff --git a/cronjobs/notifications.php b/cronjobs/notifications.php index 7bca08ec..e70d2b07 100755 --- a/cronjobs/notifications.php +++ b/cronjobs/notifications.php @@ -22,21 +22,31 @@ limitations under the License. // Include all settings and classes require_once('shared.inc.php'); +// Find all IDLE workers $aWorkers = $worker->getAllIdleWorkers(); if (empty($aWorkers)) { verbose("No idle workers found\n"); - exit; -} - -foreach ($aWorkers as $aWorker) { - $aData = $aWorker; - $aData['username'] = $user->getUserName($aWorker['account_id']); - $aData['email'] = $user->getUserEmail($aData['username']); - if (!$notification->isNotified($aData)) { - if (!$notification->addNotification('idle_worker', $aData) && $notification->sendMail('sebastian@grewe.ca', 'idle_worker', $aData)) - verbose("Unable to send notification: " . $notification->getError() . "\n"); - } else { - verbose("Already notified for this worker\n"); +} else { + foreach ($aWorkers as $aWorker) { + $aData = $aWorker; + $aData['username'] = $user->getUserName($aWorker['account_id']); + $aData['email'] = $user->getUserEmail($aData['username']); + if (!$notification->isNotified($aData)) { + if (!$notification->addNotification('idle_worker', $aData) && $notification->sendMail('sebastian@grewe.ca', 'idle_worker', $aData)) + verbose("Unable to send notification: " . $notification->getError() . "\n"); + } else { + verbose("Already notified for this worker\n"); + } } } +// We notified, lets check which recovered +$aNotifications = $notification->getAllActive(); +foreach ($aNotifications as $aNotification) { + $aData = json_decode($aNotification['data'], true); + $aWorker = $worker->getWorker($aData['id']); + if ($aWorker['active'] == 1) + if (!$notification->setInactive($aNotification['id'])) + verbose("Failed to set notification inactive for " . $aWorker['username'] . "\n"); +} + ?> diff --git a/public/include/classes/mail.class.php b/public/include/classes/mail.class.php index 6c7cc0f1..a1cf2137 100644 --- a/public/include/classes/mail.class.php +++ b/public/include/classes/mail.class.php @@ -20,7 +20,7 @@ class Mail { $this->config = $config; } - private function checkStmt($bState) { + function checkStmt($bState) { $this->debug->append("STA " . __METHOD__, 4); if ($bState ===! true) { $this->debug->append("Failed to prepare statement: " . $this->mysqli->error); diff --git a/public/include/classes/notification.class.php b/public/include/classes/notification.class.php index a9eca1af..9a6dcf3b 100644 --- a/public/include/classes/notification.class.php +++ b/public/include/classes/notification.class.php @@ -7,13 +7,36 @@ if (!defined('SECURITY')) class Notification extends Mail { var $table = 'notifications'; + public function setInactive($id) { + $field = array( + 'name' => 'active', + 'type' => 'i', + 'value' => 0 + ); + return $this->updateSingle($id, $field); + } + + /** + * 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; + } /** * We check our notification table for existing data * so we can avoid duplicate entries **/ public function isNotified($aData) { $data = json_encode($aData); - $stmt = $this->mysqli->prepare("SELECT id FROM $this->table WHERE data = ? 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) return true; // Catchall @@ -21,6 +44,17 @@ class Notification extends Mail { return false; } + /** + * Get all active notifications + **/ + public function getAllActive() { + $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); + // Catchall + return false; + } + /** * Add a new notification to the table * @param type string Type of the notification @@ -29,7 +63,7 @@ class Notification extends Mail { public function addNotification($type, $data) { // Store notification data as json $data = json_encode($data); - $stmt = $this->mysqli->prepare("INSERT INTO $this->table (type, data) VALUES (?,?)"); + $stmt = $this->mysqli->prepare("INSERT INTO $this->table (type, data, active) VALUES (?,?,1)"); if ($stmt && $stmt->bind_param('ss', $type, $data) && $stmt->execute()) return true; $this->debug->append("Failed to add notification for $type with $data: " . $this->mysqli->error); diff --git a/public/include/classes/worker.class.php b/public/include/classes/worker.class.php index a5052ba9..6a9f6524 100644 --- a/public/include/classes/worker.class.php +++ b/public/include/classes/worker.class.php @@ -78,6 +78,27 @@ class Worker { return false; } + /** + * Fetch a specific worker and its status + * @param id int Worker ID + * @return mixed array Worker details + **/ + public function getWorker($id) { + $this->debug->append("STA " . __METHOD__, 4); + $stmt = $this->mysqli->prepare(" + SELECT id, username, password, monitor, + ( SELECT SIGN(COUNT(id)) FROM " . $this->share->getTableName() . " WHERE username = $this->table.username AND time > DATE_SUB(now(), INTERVAL 10 MINUTE)) AS active, + ( SELECT ROUND(COUNT(id) * POW(2, " . $this->config['difficulty'] . ")/600/1000) FROM " . $this->share->getTableName() . " WHERE username = $this->table.username AND time > DATE_SUB(now(), INTERVAL 10 MINUTE)) AS hashrate + FROM $this->table + WHERE id = ? + "); + if ($this->checkStmt($stmt) && $stmt->bind_param('i', $id) && $stmt->execute() && $result = $stmt->get_result()) + return $result->fetch_assoc(); + // Catchall + echo $this->mysqli->error; + return false; + } + /** * Fetch all workers for an account * @param account_id int User ID From 432540335fd966ee000b385b5082fa3e71a59be1 Mon Sep 17 00:00:00 2001 From: Sebastian Grewe Date: Fri, 7 Jun 2013 15:35:58 +0200 Subject: [PATCH 4/9] Working notification system * Added things to mail templates * Modified user password reset call for new mail template * Added BASEPATH to smarty code to ensure templates are compiled in the proper directory * Updated mail and notification class * Updated notification cron * Added notification cron to run-cron list --- cronjobs/notifications.php | 23 +++++++++++++------ cronjobs/run-crons.sh | 2 +- public/include/classes/mail.class.php | 11 +++++++-- public/include/classes/notification.class.php | 1 + public/include/classes/user.class.php | 1 + public/include/smarty.inc.php | 6 ++--- public/templates/mail/idle_worker.tpl | 2 +- public/templates/mail/subject.tpl | 2 +- 8 files changed, 33 insertions(+), 15 deletions(-) diff --git a/cronjobs/notifications.php b/cronjobs/notifications.php index e70d2b07..45bda82a 100755 --- a/cronjobs/notifications.php +++ b/cronjobs/notifications.php @@ -30,23 +30,32 @@ if (empty($aWorkers)) { foreach ($aWorkers as $aWorker) { $aData = $aWorker; $aData['username'] = $user->getUserName($aWorker['account_id']); + $aData['subject'] = 'IDLE Worker : ' . $aWorker['username']; $aData['email'] = $user->getUserEmail($aData['username']); - if (!$notification->isNotified($aData)) { - if (!$notification->addNotification('idle_worker', $aData) && $notification->sendMail('sebastian@grewe.ca', 'idle_worker', $aData)) - verbose("Unable to send notification: " . $notification->getError() . "\n"); - } else { - verbose("Already notified for this worker\n"); + if ( $notification->isNotified($aData) ) { + verbose("Worker already notified\n"); + continue; } + if ($notification->addNotification('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"); + } } } + // We notified, lets check which recovered $aNotifications = $notification->getAllActive(); foreach ($aNotifications as $aNotification) { $aData = json_decode($aNotification['data'], true); $aWorker = $worker->getWorker($aData['id']); - if ($aWorker['active'] == 1) - if (!$notification->setInactive($aNotification['id'])) + if ($aWorker['active'] == 1) { + if ($notification->setInactive($aNotification['id'])) { + verbose("Marked notification " . $aNotification['id'] . " as inactive\n"); + } else { verbose("Failed to set notification inactive for " . $aWorker['username'] . "\n"); + } + } } ?> diff --git a/cronjobs/run-crons.sh b/cronjobs/run-crons.sh index 730a9063..5f9179dc 100755 --- a/cronjobs/run-crons.sh +++ b/cronjobs/run-crons.sh @@ -16,7 +16,7 @@ PIDFILE='/tmp/mmcfe-ng-cron.pid' CRONHOME='.' # List of cruns to execute -CRONS="findblock.php proportional_payout.php blockupdate.php auto_payout.php tickerupdate.php" +CRONS="findblock.php proportional_payout.php blockupdate.php auto_payout.php tickerupdate.php notifications.php" # Additional arguments to pass to cronjobs CRONARGS="-v" diff --git a/public/include/classes/mail.class.php b/public/include/classes/mail.class.php index a1cf2137..2800500c 100644 --- a/public/include/classes/mail.class.php +++ b/public/include/classes/mail.class.php @@ -19,7 +19,12 @@ class Mail { public function setConfig($config) { $this->config = $config; } - + public function setErrorMessage($msg) { + $this->sError = $msg; + } + public function getError() { + return $this->sError; + } function checkStmt($bState) { $this->debug->append("STA " . __METHOD__, 4); if ($bState ===! true) { @@ -30,8 +35,10 @@ class Mail { return true; } - public function sendMail($email, $template, $vars) { + public function sendMail($email, $template, $aData) { $this->smarty->assign('WEBSITENAME', $this->config['website']['name']); + $this->smarty->assign('SUBJECT', $aData['subject']); + $this->smarty->assign('DATA', $aData); $headers = 'From: Website Administration <' . $this->config['website']['email'] . ">\n"; $headers .= "MIME-Version: 1.0\n"; $headers .= "Content-Type: text/html; charset=ISO-8859-1\r\n"; diff --git a/public/include/classes/notification.class.php b/public/include/classes/notification.class.php index 9a6dcf3b..983db437 100644 --- a/public/include/classes/notification.class.php +++ b/public/include/classes/notification.class.php @@ -41,6 +41,7 @@ class Notification extends Mail { return true; // Catchall // Does not seem to have a notification set + $this->setErrorMessage("Unable to run query: " . $this->mysqli->error); return false; } diff --git a/public/include/classes/user.class.php b/public/include/classes/user.class.php index 8db17a1e..b4627729 100644 --- a/public/include/classes/user.class.php +++ b/public/include/classes/user.class.php @@ -486,6 +486,7 @@ class User { } $smarty->assign('TOKEN', $token); $smarty->assign('USERNAME', $username); + $smarty->assign('SUBJECT', 'Password Reset Request'); $smarty->assign('WEBSITENAME', $this->config['website']['name']); $headers = 'From: Website Administration <' . $this->config['website']['email'] . ">\n"; $headers .= "MIME-Version: 1.0\n"; diff --git a/public/include/smarty.inc.php b/public/include/smarty.inc.php index b2e67f37..5668e1d3 100644 --- a/public/include/smarty.inc.php +++ b/public/include/smarty.inc.php @@ -16,10 +16,10 @@ $smarty = new Smarty; // Assign our local paths $debug->append('Define Smarty Paths', 3); -$smarty->template_dir = 'templates/' . THEME . '/'; -$smarty->compile_dir = 'templates/compile/'; +$smarty->template_dir = BASEPATH . 'templates/' . THEME . '/'; +$smarty->compile_dir = BASEPATH . 'templates/compile/'; // Optional smarty caching, check Smarty documentation for details $smarty->caching = $config['cache']; -$smarty->cache_dir = "templates/cache"; +$smarty->cache_dir = BASEPATH . "templates/cache"; ?> diff --git a/public/templates/mail/idle_worker.tpl b/public/templates/mail/idle_worker.tpl index a21aaac3..6d1c282c 100644 --- a/public/templates/mail/idle_worker.tpl +++ b/public/templates/mail/idle_worker.tpl @@ -1,6 +1,6 @@ -

One of your workers is currently IDLE.

+

One of your workers is currently IDLE: {$DATA.username}

Since monitoring is enabled for this worker, this notification was sent.

Please check your workers!


diff --git a/public/templates/mail/subject.tpl b/public/templates/mail/subject.tpl index 665e26f5..94fd6a28 100644 --- a/public/templates/mail/subject.tpl +++ b/public/templates/mail/subject.tpl @@ -1 +1 @@ -[ {$WEBSITENAME} ] Password Reset Request +[ {$WEBSITENAME} ] {$SUBJECT} From c69fbe4fc416f93e42fd1998dc562a06830d8be0 Mon Sep 17 00:00:00 2001 From: Sebastian Grewe Date: Thu, 6 Jun 2013 14:25:36 +0200 Subject: [PATCH 5/9] Add worker montioring to template and worker class * Add configurable monitoring for workers into template * Store monitoring status in DB First commit for #116 --- public/include/classes/worker.class.php | 18 ++++++++++-------- .../mmcFE/account/workers/default.tpl | 2 ++ 2 files changed, 12 insertions(+), 8 deletions(-) diff --git a/public/include/classes/worker.class.php b/public/include/classes/worker.class.php index 5a5c19c4..6052eaac 100644 --- a/public/include/classes/worker.class.php +++ b/public/include/classes/worker.class.php @@ -43,17 +43,19 @@ class Worker { public function updateWorkers($account_id, $data) { $this->debug->append("STA " . __METHOD__, 4); $username = $this->user->getUserName($account_id); + $iFailed = 0; foreach ($data as $key => $value) { // Prefix the WebUser to Worker name $value['username'] = "$username." . $value['username']; - $stmt = $this->mysqli->prepare("UPDATE $this->table SET password = ?, username = ? WHERE account_id = ? AND id = ?"); - if ($this->checkStmt($stmt)) { - if (!$stmt->bind_param('ssii', $value['password'], $value['username'], $account_id, $key)) return false; - if (!$stmt->execute()) return false; - $stmt->close(); - } + $stmt = $this->mysqli->prepare("UPDATE $this->table SET password = ?, 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()) ) + $iFailed++; } - return true; + if ($iFailed == 0) + return true; + // Catchall + $this->setErrorMessage('Failed to update ' . $iFailed . ' worker.'); + return false; } /** @@ -64,7 +66,7 @@ class Worker { public function getWorkers($account_id) { $this->debug->append("STA " . __METHOD__, 4); $stmt = $this->mysqli->prepare(" - SELECT id, username, password, + SELECT id, username, password, monitor, ( SELECT SIGN(COUNT(id)) FROM " . $this->share->getTableName() . " WHERE username = $this->table.username AND time > DATE_SUB(now(), INTERVAL 10 MINUTE)) AS active, ( SELECT ROUND(COUNT(id) * POW(2, " . $this->config['difficulty'] . ")/600/1000) FROM " . $this->share->getTableName() . " WHERE username = $this->table.username AND time > DATE_SUB(now(), INTERVAL 10 MINUTE)) AS hashrate FROM $this->table diff --git a/public/templates/mmcFE/account/workers/default.tpl b/public/templates/mmcFE/account/workers/default.tpl index f1b6e875..612bd227 100644 --- a/public/templates/mmcFE/account/workers/default.tpl +++ b/public/templates/mmcFE/account/workers/default.tpl @@ -10,6 +10,7 @@ Worker Name Password Active + Monitor Khash/s     @@ -20,6 +21,7 @@ {$username.0|escape}. + {$WORKERS[worker].hashrate|number_format} From 9ac2dadd973d1f2d465a81cb4addaec2333bc043 Mon Sep 17 00:00:00 2001 From: Sebastian Grewe Date: Fri, 7 Jun 2013 14:42:29 +0200 Subject: [PATCH 6/9] Progress on notifications * Added main mail class * notification class extends mail class * Added mail template for IDLE workers * Added notification table to SQL structure This works already but once notified the status is not reset as soon as a worker is active again. Need to think of a system to do that automatically. Addresses #116 --- cronjobs/notifications.php | 42 ++++++++++++++ public/include/autoloader.inc.php | 2 + public/include/classes/mail.class.php | 58 +++++++++++++++++++ public/include/classes/notification.class.php | 45 ++++++++++++++ public/include/classes/worker.class.php | 20 +++++++ public/templates/mail/idle_worker.tpl | 9 +++ sql/mmcfe_ng_structure.sql | 20 ++++++- 7 files changed, 193 insertions(+), 3 deletions(-) create mode 100755 cronjobs/notifications.php create mode 100644 public/include/classes/mail.class.php create mode 100644 public/include/classes/notification.class.php create mode 100644 public/templates/mail/idle_worker.tpl diff --git a/cronjobs/notifications.php b/cronjobs/notifications.php new file mode 100755 index 00000000..7bca08ec --- /dev/null +++ b/cronjobs/notifications.php @@ -0,0 +1,42 @@ +#!/usr/bin/php +getAllIdleWorkers(); +if (empty($aWorkers)) { + verbose("No idle workers found\n"); + exit; +} + +foreach ($aWorkers as $aWorker) { + $aData = $aWorker; + $aData['username'] = $user->getUserName($aWorker['account_id']); + $aData['email'] = $user->getUserEmail($aData['username']); + if (!$notification->isNotified($aData)) { + if (!$notification->addNotification('idle_worker', $aData) && $notification->sendMail('sebastian@grewe.ca', 'idle_worker', $aData)) + verbose("Unable to send notification: " . $notification->getError() . "\n"); + } else { + verbose("Already notified for this worker\n"); + } +} +?> diff --git a/public/include/autoloader.inc.php b/public/include/autoloader.inc.php index ea16564e..a78d4a62 100644 --- a/public/include/autoloader.inc.php +++ b/public/include/autoloader.inc.php @@ -14,3 +14,5 @@ require_once(CLASS_DIR . '/worker.class.php'); require_once(CLASS_DIR . '/statistics.class.php'); require_once(CLASS_DIR . '/transaction.class.php'); require_once(CLASS_DIR . '/setting.class.php'); +require_once(CLASS_DIR . '/mail.class.php'); +require_once(CLASS_DIR . '/notification.class.php'); diff --git a/public/include/classes/mail.class.php b/public/include/classes/mail.class.php new file mode 100644 index 00000000..6c7cc0f1 --- /dev/null +++ b/public/include/classes/mail.class.php @@ -0,0 +1,58 @@ +debug = $debug; + } + public function setMysql($mysqli) { + $this->mysqli = $mysqli; + } + public function setSmarty($smarty) { + $this->smarty = $smarty; + } + public function setConfig($config) { + $this->config = $config; + } + + 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; + } + + public function sendMail($email, $template, $vars) { + $this->smarty->assign('WEBSITENAME', $this->config['website']['name']); + $headers = 'From: Website Administration <' . $this->config['website']['email'] . ">\n"; + $headers .= "MIME-Version: 1.0\n"; + $headers .= "Content-Type: text/html; charset=ISO-8859-1\r\n"; + if (mail($email, + $this->smarty->fetch(BASEPATH . 'templates/mail/subject.tpl'), + $this->smarty->fetch(BASEPATH . 'templates/mail/' . $template . '.tpl'), + $headers)) { + return true; + } else { + $this->setErrorMessage("Unable to send mail"); + return false; + } + return false; + } +} + +// Make our class available automatically +$mail = new Mail (); +$mail->setDebug($debug); +$mail->setMysql($mysqli); +$mail->setSmarty($smarty); +$mail->setConfig($config); + +?> diff --git a/public/include/classes/notification.class.php b/public/include/classes/notification.class.php new file mode 100644 index 00000000..a9eca1af --- /dev/null +++ b/public/include/classes/notification.class.php @@ -0,0 +1,45 @@ +mysqli->prepare("SELECT id FROM $this->table WHERE data = ? LIMIT 1"); + if ($stmt && $stmt->bind_param('s', $data) && $stmt->execute() && $stmt->store_result() && $stmt->num_rows == 1) + return true; + // Catchall + // Does not seem to have a notification set + return false; + } + + /** + * Add a new notification to the table + * @param type string Type of the notification + * @return bool + **/ + public function addNotification($type, $data) { + // Store notification data as json + $data = json_encode($data); + $stmt = $this->mysqli->prepare("INSERT INTO $this->table (type, data) VALUES (?,?)"); + if ($stmt && $stmt->bind_param('ss', $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; + } +} + +$notification = new Notification(); +$notification->setDebug($debug); +$notification->setMysql($mysqli); +$notification->setSmarty($smarty); +$notification->setConfig($config); diff --git a/public/include/classes/worker.class.php b/public/include/classes/worker.class.php index 6052eaac..a5052ba9 100644 --- a/public/include/classes/worker.class.php +++ b/public/include/classes/worker.class.php @@ -58,6 +58,26 @@ class Worker { return false; } + /** + * Fetch all IDLE workers that have monitoring enabled + * @param none + * @return data array Workers in IDLE state and monitoring enabled + **/ + public function getAllIdleWorkers() { + $this->debug->append("STA " . __METHOD__, 4); + $stmt = $this->mysqli->prepare(" + SELECT account_id, id, username + FROM " . $this->table . " + WHERE monitor = 1 AND ( SELECT SIGN(COUNT(id)) FROM " . $this->share->getTableName() . " WHERE username = $this->table.username AND time > DATE_SUB(now(), INTERVAL 10 MINUTE)) = 0"); + + if ($this->checkStmt($stmt) && $stmt->execute() && $result = $stmt->get_result()) + return $result->fetch_all(MYSQLI_ASSOC); + // Catchall + $this->setErrorMessage("Unable to fetch IDLE, monitored workers"); + echo $this->mysqli->error; + return false; + } + /** * Fetch all workers for an account * @param account_id int User ID diff --git a/public/templates/mail/idle_worker.tpl b/public/templates/mail/idle_worker.tpl new file mode 100644 index 00000000..a21aaac3 --- /dev/null +++ b/public/templates/mail/idle_worker.tpl @@ -0,0 +1,9 @@ + + +

One of your workers is currently IDLE.

+

Since monitoring is enabled for this worker, this notification was sent.

+

Please check your workers!

+
+
+ + diff --git a/sql/mmcfe_ng_structure.sql b/sql/mmcfe_ng_structure.sql index c3c626bd..a971d455 100644 --- a/sql/mmcfe_ng_structure.sql +++ b/sql/mmcfe_ng_structure.sql @@ -3,7 +3,7 @@ -- http://www.phpmyadmin.net -- -- Host: localhost --- Generation Time: Jun 06, 2013 at 09:01 PM +-- Generation Time: Jun 07, 2013 at 02:42 PM -- Server version: 5.5.31-0ubuntu0.13.04.1 -- PHP Version: 5.4.9-4ubuntu2 @@ -69,6 +69,20 @@ CREATE TABLE IF NOT EXISTS `blocks` ( -- -------------------------------------------------------- +-- +-- Table structure for table `notifications` +-- + +CREATE TABLE IF NOT EXISTS `notifications` ( + `id` int(11) NOT NULL AUTO_INCREMENT, + `type` varchar(25) NOT NULL, + `data` text NOT NULL, + `time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, + PRIMARY KEY (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +-- -------------------------------------------------------- + -- -- Table structure for table `pool_worker` -- @@ -136,7 +150,7 @@ CREATE TABLE IF NOT EXISTS `shares_archive` ( PRIMARY KEY (`id`), UNIQUE KEY `share_id` (`share_id`), KEY `time` (`time`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='Archive shares for potential later debugging purposes'; +) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='Archive shares for potential later debugging purposes'; -- -------------------------------------------------------- @@ -153,7 +167,7 @@ CREATE TABLE IF NOT EXISTS `statistics_shares` ( PRIMARY KEY (`id`), KEY `account_id` (`account_id`), KEY `block_id` (`block_id`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8; +) ENGINE=InnoDB DEFAULT CHARSET=utf8; -- -------------------------------------------------------- From 69a3761be58e81868c2bb511b88e7f9c20af719d Mon Sep 17 00:00:00 2001 From: Sebastian Grewe Date: Fri, 7 Jun 2013 15:07:26 +0200 Subject: [PATCH 7/9] Adding notification reset once worker is active Go through all active notifications (active means they are not notified again) and check if their state has changed. If so, mark as inactive and allow for re-notification of the same type and data. --- cronjobs/notifications.php | 34 +++++++++++------ public/include/classes/mail.class.php | 2 +- public/include/classes/notification.class.php | 38 ++++++++++++++++++- public/include/classes/worker.class.php | 21 ++++++++++ 4 files changed, 80 insertions(+), 15 deletions(-) diff --git a/cronjobs/notifications.php b/cronjobs/notifications.php index 7bca08ec..e70d2b07 100755 --- a/cronjobs/notifications.php +++ b/cronjobs/notifications.php @@ -22,21 +22,31 @@ limitations under the License. // Include all settings and classes require_once('shared.inc.php'); +// Find all IDLE workers $aWorkers = $worker->getAllIdleWorkers(); if (empty($aWorkers)) { verbose("No idle workers found\n"); - exit; -} - -foreach ($aWorkers as $aWorker) { - $aData = $aWorker; - $aData['username'] = $user->getUserName($aWorker['account_id']); - $aData['email'] = $user->getUserEmail($aData['username']); - if (!$notification->isNotified($aData)) { - if (!$notification->addNotification('idle_worker', $aData) && $notification->sendMail('sebastian@grewe.ca', 'idle_worker', $aData)) - verbose("Unable to send notification: " . $notification->getError() . "\n"); - } else { - verbose("Already notified for this worker\n"); +} else { + foreach ($aWorkers as $aWorker) { + $aData = $aWorker; + $aData['username'] = $user->getUserName($aWorker['account_id']); + $aData['email'] = $user->getUserEmail($aData['username']); + if (!$notification->isNotified($aData)) { + if (!$notification->addNotification('idle_worker', $aData) && $notification->sendMail('sebastian@grewe.ca', 'idle_worker', $aData)) + verbose("Unable to send notification: " . $notification->getError() . "\n"); + } else { + verbose("Already notified for this worker\n"); + } } } +// We notified, lets check which recovered +$aNotifications = $notification->getAllActive(); +foreach ($aNotifications as $aNotification) { + $aData = json_decode($aNotification['data'], true); + $aWorker = $worker->getWorker($aData['id']); + if ($aWorker['active'] == 1) + if (!$notification->setInactive($aNotification['id'])) + verbose("Failed to set notification inactive for " . $aWorker['username'] . "\n"); +} + ?> diff --git a/public/include/classes/mail.class.php b/public/include/classes/mail.class.php index 6c7cc0f1..a1cf2137 100644 --- a/public/include/classes/mail.class.php +++ b/public/include/classes/mail.class.php @@ -20,7 +20,7 @@ class Mail { $this->config = $config; } - private function checkStmt($bState) { + function checkStmt($bState) { $this->debug->append("STA " . __METHOD__, 4); if ($bState ===! true) { $this->debug->append("Failed to prepare statement: " . $this->mysqli->error); diff --git a/public/include/classes/notification.class.php b/public/include/classes/notification.class.php index a9eca1af..9a6dcf3b 100644 --- a/public/include/classes/notification.class.php +++ b/public/include/classes/notification.class.php @@ -7,13 +7,36 @@ if (!defined('SECURITY')) class Notification extends Mail { var $table = 'notifications'; + public function setInactive($id) { + $field = array( + 'name' => 'active', + 'type' => 'i', + 'value' => 0 + ); + return $this->updateSingle($id, $field); + } + + /** + * 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; + } /** * We check our notification table for existing data * so we can avoid duplicate entries **/ public function isNotified($aData) { $data = json_encode($aData); - $stmt = $this->mysqli->prepare("SELECT id FROM $this->table WHERE data = ? 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) return true; // Catchall @@ -21,6 +44,17 @@ class Notification extends Mail { return false; } + /** + * Get all active notifications + **/ + public function getAllActive() { + $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); + // Catchall + return false; + } + /** * Add a new notification to the table * @param type string Type of the notification @@ -29,7 +63,7 @@ class Notification extends Mail { public function addNotification($type, $data) { // Store notification data as json $data = json_encode($data); - $stmt = $this->mysqli->prepare("INSERT INTO $this->table (type, data) VALUES (?,?)"); + $stmt = $this->mysqli->prepare("INSERT INTO $this->table (type, data, active) VALUES (?,?,1)"); if ($stmt && $stmt->bind_param('ss', $type, $data) && $stmt->execute()) return true; $this->debug->append("Failed to add notification for $type with $data: " . $this->mysqli->error); diff --git a/public/include/classes/worker.class.php b/public/include/classes/worker.class.php index a5052ba9..6a9f6524 100644 --- a/public/include/classes/worker.class.php +++ b/public/include/classes/worker.class.php @@ -78,6 +78,27 @@ class Worker { return false; } + /** + * Fetch a specific worker and its status + * @param id int Worker ID + * @return mixed array Worker details + **/ + public function getWorker($id) { + $this->debug->append("STA " . __METHOD__, 4); + $stmt = $this->mysqli->prepare(" + SELECT id, username, password, monitor, + ( SELECT SIGN(COUNT(id)) FROM " . $this->share->getTableName() . " WHERE username = $this->table.username AND time > DATE_SUB(now(), INTERVAL 10 MINUTE)) AS active, + ( SELECT ROUND(COUNT(id) * POW(2, " . $this->config['difficulty'] . ")/600/1000) FROM " . $this->share->getTableName() . " WHERE username = $this->table.username AND time > DATE_SUB(now(), INTERVAL 10 MINUTE)) AS hashrate + FROM $this->table + WHERE id = ? + "); + if ($this->checkStmt($stmt) && $stmt->bind_param('i', $id) && $stmt->execute() && $result = $stmt->get_result()) + return $result->fetch_assoc(); + // Catchall + echo $this->mysqli->error; + return false; + } + /** * Fetch all workers for an account * @param account_id int User ID From 4da9fd2369088d9ed3852b8f3465b7582895a1c4 Mon Sep 17 00:00:00 2001 From: Sebastian Grewe Date: Fri, 7 Jun 2013 15:35:58 +0200 Subject: [PATCH 8/9] Working notification system * Added things to mail templates * Modified user password reset call for new mail template * Added BASEPATH to smarty code to ensure templates are compiled in the proper directory * Updated mail and notification class * Updated notification cron * Added notification cron to run-cron list --- cronjobs/notifications.php | 23 +++++++++++++------ cronjobs/run-crons.sh | 2 +- public/include/classes/mail.class.php | 11 +++++++-- public/include/classes/notification.class.php | 1 + public/include/classes/user.class.php | 1 + public/include/smarty.inc.php | 6 ++--- public/templates/mail/idle_worker.tpl | 2 +- public/templates/mail/subject.tpl | 2 +- 8 files changed, 33 insertions(+), 15 deletions(-) diff --git a/cronjobs/notifications.php b/cronjobs/notifications.php index e70d2b07..45bda82a 100755 --- a/cronjobs/notifications.php +++ b/cronjobs/notifications.php @@ -30,23 +30,32 @@ if (empty($aWorkers)) { foreach ($aWorkers as $aWorker) { $aData = $aWorker; $aData['username'] = $user->getUserName($aWorker['account_id']); + $aData['subject'] = 'IDLE Worker : ' . $aWorker['username']; $aData['email'] = $user->getUserEmail($aData['username']); - if (!$notification->isNotified($aData)) { - if (!$notification->addNotification('idle_worker', $aData) && $notification->sendMail('sebastian@grewe.ca', 'idle_worker', $aData)) - verbose("Unable to send notification: " . $notification->getError() . "\n"); - } else { - verbose("Already notified for this worker\n"); + if ( $notification->isNotified($aData) ) { + verbose("Worker already notified\n"); + continue; } + if ($notification->addNotification('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"); + } } } + // We notified, lets check which recovered $aNotifications = $notification->getAllActive(); foreach ($aNotifications as $aNotification) { $aData = json_decode($aNotification['data'], true); $aWorker = $worker->getWorker($aData['id']); - if ($aWorker['active'] == 1) - if (!$notification->setInactive($aNotification['id'])) + if ($aWorker['active'] == 1) { + if ($notification->setInactive($aNotification['id'])) { + verbose("Marked notification " . $aNotification['id'] . " as inactive\n"); + } else { verbose("Failed to set notification inactive for " . $aWorker['username'] . "\n"); + } + } } ?> diff --git a/cronjobs/run-crons.sh b/cronjobs/run-crons.sh index 730a9063..5f9179dc 100755 --- a/cronjobs/run-crons.sh +++ b/cronjobs/run-crons.sh @@ -16,7 +16,7 @@ PIDFILE='/tmp/mmcfe-ng-cron.pid' CRONHOME='.' # List of cruns to execute -CRONS="findblock.php proportional_payout.php blockupdate.php auto_payout.php tickerupdate.php" +CRONS="findblock.php proportional_payout.php blockupdate.php auto_payout.php tickerupdate.php notifications.php" # Additional arguments to pass to cronjobs CRONARGS="-v" diff --git a/public/include/classes/mail.class.php b/public/include/classes/mail.class.php index a1cf2137..2800500c 100644 --- a/public/include/classes/mail.class.php +++ b/public/include/classes/mail.class.php @@ -19,7 +19,12 @@ class Mail { public function setConfig($config) { $this->config = $config; } - + public function setErrorMessage($msg) { + $this->sError = $msg; + } + public function getError() { + return $this->sError; + } function checkStmt($bState) { $this->debug->append("STA " . __METHOD__, 4); if ($bState ===! true) { @@ -30,8 +35,10 @@ class Mail { return true; } - public function sendMail($email, $template, $vars) { + public function sendMail($email, $template, $aData) { $this->smarty->assign('WEBSITENAME', $this->config['website']['name']); + $this->smarty->assign('SUBJECT', $aData['subject']); + $this->smarty->assign('DATA', $aData); $headers = 'From: Website Administration <' . $this->config['website']['email'] . ">\n"; $headers .= "MIME-Version: 1.0\n"; $headers .= "Content-Type: text/html; charset=ISO-8859-1\r\n"; diff --git a/public/include/classes/notification.class.php b/public/include/classes/notification.class.php index 9a6dcf3b..983db437 100644 --- a/public/include/classes/notification.class.php +++ b/public/include/classes/notification.class.php @@ -41,6 +41,7 @@ class Notification extends Mail { return true; // Catchall // Does not seem to have a notification set + $this->setErrorMessage("Unable to run query: " . $this->mysqli->error); return false; } diff --git a/public/include/classes/user.class.php b/public/include/classes/user.class.php index 8db17a1e..b4627729 100644 --- a/public/include/classes/user.class.php +++ b/public/include/classes/user.class.php @@ -486,6 +486,7 @@ class User { } $smarty->assign('TOKEN', $token); $smarty->assign('USERNAME', $username); + $smarty->assign('SUBJECT', 'Password Reset Request'); $smarty->assign('WEBSITENAME', $this->config['website']['name']); $headers = 'From: Website Administration <' . $this->config['website']['email'] . ">\n"; $headers .= "MIME-Version: 1.0\n"; diff --git a/public/include/smarty.inc.php b/public/include/smarty.inc.php index b2e67f37..5668e1d3 100644 --- a/public/include/smarty.inc.php +++ b/public/include/smarty.inc.php @@ -16,10 +16,10 @@ $smarty = new Smarty; // Assign our local paths $debug->append('Define Smarty Paths', 3); -$smarty->template_dir = 'templates/' . THEME . '/'; -$smarty->compile_dir = 'templates/compile/'; +$smarty->template_dir = BASEPATH . 'templates/' . THEME . '/'; +$smarty->compile_dir = BASEPATH . 'templates/compile/'; // Optional smarty caching, check Smarty documentation for details $smarty->caching = $config['cache']; -$smarty->cache_dir = "templates/cache"; +$smarty->cache_dir = BASEPATH . "templates/cache"; ?> diff --git a/public/templates/mail/idle_worker.tpl b/public/templates/mail/idle_worker.tpl index a21aaac3..6d1c282c 100644 --- a/public/templates/mail/idle_worker.tpl +++ b/public/templates/mail/idle_worker.tpl @@ -1,6 +1,6 @@ -

One of your workers is currently IDLE.

+

One of your workers is currently IDLE: {$DATA.username}

Since monitoring is enabled for this worker, this notification was sent.

Please check your workers!


diff --git a/public/templates/mail/subject.tpl b/public/templates/mail/subject.tpl index 665e26f5..94fd6a28 100644 --- a/public/templates/mail/subject.tpl +++ b/public/templates/mail/subject.tpl @@ -1 +1 @@ -[ {$WEBSITENAME} ] Password Reset Request +[ {$WEBSITENAME} ] {$SUBJECT} From d5d0b5470542514664dd8c1ca61ccbdd35253c58 Mon Sep 17 00:00:00 2001 From: Sebastian Grewe Date: Fri, 7 Jun 2013 15:39:43 +0200 Subject: [PATCH 9/9] adding new structure for notifications --- sql/mmcfe_ng_structure.sql | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/sql/mmcfe_ng_structure.sql b/sql/mmcfe_ng_structure.sql index a971d455..039b9a04 100644 --- a/sql/mmcfe_ng_structure.sql +++ b/sql/mmcfe_ng_structure.sql @@ -3,7 +3,7 @@ -- http://www.phpmyadmin.net -- -- Host: localhost --- Generation Time: Jun 07, 2013 at 02:42 PM +-- Generation Time: Jun 07, 2013 at 03:39 PM -- Server version: 5.5.31-0ubuntu0.13.04.1 -- PHP Version: 5.4.9-4ubuntu2 @@ -65,7 +65,7 @@ CREATE TABLE IF NOT EXISTS `blocks` ( PRIMARY KEY (`id`), UNIQUE KEY `height` (`height`,`blockhash`), KEY `time` (`time`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='Discovered blocks persisted from Litecoin Service'; +) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='Discovered blocks persisted from Litecoin Service'; -- -------------------------------------------------------- @@ -76,10 +76,13 @@ CREATE TABLE IF NOT EXISTS `blocks` ( CREATE TABLE IF NOT EXISTS `notifications` ( `id` int(11) NOT NULL AUTO_INCREMENT, `type` varchar(25) NOT NULL, - `data` text NOT NULL, + `data` varchar(255) NOT NULL, + `active` tinyint(1) NOT NULL DEFAULT '1', `time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, - PRIMARY KEY (`id`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8; + PRIMARY KEY (`id`), + KEY `active` (`active`), + KEY `data` (`data`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; -- -------------------------------------------------------- @@ -150,7 +153,7 @@ CREATE TABLE IF NOT EXISTS `shares_archive` ( PRIMARY KEY (`id`), UNIQUE KEY `share_id` (`share_id`), KEY `time` (`time`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='Archive shares for potential later debugging purposes'; +) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='Archive shares for potential later debugging purposes'; -- -------------------------------------------------------- @@ -167,7 +170,7 @@ CREATE TABLE IF NOT EXISTS `statistics_shares` ( PRIMARY KEY (`id`), KEY `account_id` (`account_id`), KEY `block_id` (`block_id`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8; +) ENGINE=InnoDB DEFAULT CHARSET=utf8; -- -------------------------------------------------------- @@ -187,7 +190,7 @@ CREATE TABLE IF NOT EXISTS `transactions` ( KEY `block_id` (`block_id`), KEY `account_id` (`account_id`), KEY `type` (`type`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8; +) ENGINE=InnoDB DEFAULT CHARSET=utf8; /*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */; /*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;