Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

#2539 - Feature request: Pushover.net notifications #2540

Merged
merged 9 commits into from
Feb 28, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions include/autoloader.inc.php
Original file line number Diff line number Diff line change
Expand Up @@ -78,5 +78,8 @@
require_once(CLASS_DIR . '/roundstats.class.php');
require_once(CLASS_DIR . '/news.class.php');
require_once(CLASS_DIR . '/api.class.php');
require_once(CLASS_DIR . '/usersettings.class.php');
require_once(CLASS_DIR . '/ipushnotification.interface.php');
require_once(CLASS_DIR . '/pushnotification.class.php');
require_once(INCLUDE_DIR . '/lib/Michelf/Markdown.php');
require_once(INCLUDE_DIR . '/lib/scrypt.php');
12 changes: 12 additions & 0 deletions include/classes/base.class.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ class Base {
public function getTableName() {
return $this->table;
}

protected $debug;
public function setDebug($debug) {
$this->debug = $debug;
}
Expand All @@ -25,9 +27,13 @@ public function setCoin($coin) {
public function setCoinAddress($coin_address) {
$this->coin_address = $coin_address;
}

public $log;
public function setLog($log) {
$this->log = $log;
}

protected $mysqli;
public function setMysql($mysqli) {
$this->mysqli = $mysqli;
}
Expand All @@ -40,6 +46,10 @@ public function setSalt($salt) {
public function setSalty($salt) {
$this->salty = $salt;
}
/**
* @var Smarty
*/
var $smarty;
public function setSmarty($smarty) {
$this->smarty = $smarty;
}
Expand All @@ -52,6 +62,8 @@ public function setSessionManager($session) {
public function setConfig($config) {
$this->config = $config;
}

protected $aErrorCodes;
public function setErrorCodes(&$aErrorCodes) {
$this->aErrorCodes =& $aErrorCodes;
}
Expand Down
6 changes: 6 additions & 0 deletions include/classes/ipushnotification.interface.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
<?php
interface IPushNotification {
public static function getName();
public static function getParameters();
public function notify($message, $severity, $event);
}
29 changes: 21 additions & 8 deletions include/classes/notification.class.php
Original file line number Diff line number Diff line change
Expand Up @@ -149,14 +149,27 @@ public function sendNotification($account_id, $strType, $aMailData) {
return false;
}
// Check if this user wants strType notifications
$stmt = $this->mysqli->prepare("SELECT account_id FROM $this->tableSettings WHERE type = ? AND active = 1 AND account_id = ?");
if ($stmt && $stmt->bind_param('si', $strType, $account_id) && $stmt->execute() && $stmt->bind_result($id) && $stmt->fetch()) {
if ($stmt->close() && $this->sendMail('notifications/' . $strType, $aMailData) && $this->addNotification($account_id, $strType, $aMailData)) {
return true;
} else {
$this->setErrorMessage('SendMail call failed: ' . $this->getError());
return false;
}
$stmt = $this->mysqli->prepare("SELECT type FROM $this->tableSettings WHERE type IN (?, ?) AND active = 1 AND account_id = ?");
if ($stmt && $stmt->bind_param('ssi', $strType, substr('push_'.$strType, 0, 15), $account_id) && $stmt->execute() && $result = $stmt->get_result()) {
$types = array_map(function($a){ return reset($a);}, $result->fetch_all(MYSQLI_ASSOC));
$stmt->close();
$result = true;
foreach ($types as $type){
if (strpos($type, 'push_') === 0){
if (PushNotification::Instance() instanceof PushNotification){
$result &= PushNotification::Instance()->sendNotification($account_id, $strType, $aMailData);
}
} else {
$result &= $this->sendMail('notifications/' . $strType, $aMailData);
}
}
if ($result){
$this->addNotification($account_id, $strType, $aMailData);
return true;
} else {
$this->setErrorMessage('SendMail call failed: ' . $this->getError());
return false;
}
} else {
$this->setErrorMessage('User disabled ' . $strType . ' notifications');
return true;
Expand Down
41 changes: 41 additions & 0 deletions include/classes/push_notification/notifymyandroid.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
<?php
class Notifications_NotifyMyAndroid implements IPushNotification {

private $apiKey;
public function __construct($apikey){
$this->apiKey = $apikey;
}

static $priorities = array(
0 => 'info',
2 => 'error',
);

public static function getName(){
return "notifymyandroid.com";
}

public static function getParameters(){
return array(
'apikey' => 'API key',
);
}

public function notify($message, $severity = 'info', $event = null){
curl_setopt_array($ch = curl_init(), array(
CURLOPT_URL => "https://www.notifymyandroid.com/publicapi/notify",
CURLOPT_POST => true,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_POSTFIELDS => http_build_query($data = array(
"apikey" => $this->apiKey,
"application" => "CryptoGlance",
"description" => $message,
"content-type" => "text/html",
"event" => $event,
"priority" => array_search($severity, self::$priorities),
)),
));
curl_exec($ch);
curl_close($ch);
}
}
46 changes: 46 additions & 0 deletions include/classes/push_notification/pushover.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
<?php
class Notifications_Pushover implements IPushNotification {

private $token;
private $user;
public function __construct($token, $user){
$this->token = $token;
$this->user = $user;
}

static $priorities = array(
0 => 'info',
1 => 'warning',
2 => 'error',
);

public static function getName(){
return "pushover.net";
}

public static function getParameters(){
return array(
'token' => 'API Token/Key',
'user' => 'Your User Key',
);
}

public function notify($message, $severity = 'info', $event = null){
curl_setopt_array($ch = curl_init(), array(
CURLOPT_URL => "https://api.pushover.net/1/messages.json",
CURLOPT_POST => true,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_POSTFIELDS => http_build_query($data = array(
"token" => $this->token,
"user" => $this->user,
"message" => $code = strip_tags(preg_replace('/<([\/]?)span[^>]*>/i', '<\1b>', $message), "<b><i><u><a><font><p><br>"),
"title" => strip_tags($event),
"priority" => (int)array_search($severity, self::$priorities),
"timestamp" => time(),
"html" => preg_match('/<[^>]+>/', $code),
)),
));
curl_exec($ch);
curl_close($ch);
}
}
171 changes: 171 additions & 0 deletions include/classes/pushnotification.class.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,171 @@
<?php
$defflip = (!cfip()) ? exit(header('HTTP/1.1 401 Unauthorized')) : 1;

class PushNotification extends Base {
var $tableSettings = 'push_notification_settings';

private static function getClassesInFile($file){
$classes = array();
$tokens = token_get_all(file_get_contents($file));
$count = count($tokens);
for ($i = 2; $i < $count; $i++) {
if ($tokens[$i - 2][0] == T_CLASS && $tokens[$i - 1][0] == T_WHITESPACE && $tokens[$i][0] == T_STRING) {
$class_name = $tokens[$i][1];
$classes[] = $class_name;
}
}
return $classes;
}

private static $classes = null;
public function getClasses(){
if (self::$classes === null){
$directory = new DirectoryIterator(__DIR__.'/push_notification');
foreach ($directory as $fileInfo) {
if (($fileInfo->getExtension() != 'php') || $fileInfo->isDot()) {
continue;
}
foreach (self::getClassesInFile($fileInfo->getRealPath()) as $class){
if (!class_exists($class)){
include $fileInfo->getRealPath();
}
$cr = new ReflectionClass($class);
if ($cr->isSubclassOf('IPushNotification')){
self::$classes[$class] = array($fileInfo->getFilename(), $cr->getMethod('getName')->invoke(null), $cr->getMethod('getParameters')->invoke(null));
}
}
}
}
return self::$classes;
}

public function getClassesForSmarty(){
$c = $this->getClasses();
return array_map(function($a, $b){
return array(
'class' => $b,
'file' => $a[0],
'name' => $a[1],
'parameters' => $a[2],
);
}, $c, array_keys($c));
}

/**
* @param string|array $notificator
* @param array $data
* @return IPushNotification|bool
*/
public function getNotificatorInstance($notificator, $data){
$class = null;
$file = null;

if (is_array($notificator)){
if (count($notificator) == 2){
list($class, $file) = $notificator;
} else {
$class = reset($notificator);
}
} else {
$class = $notificator;
}

if (!class_exists($class)){
if ($file === null){
foreach (self::getClasses() as $_class => $_info){
if ($_class == $class){
$file = $_info[0];
break;
}
}
} else {
include __DIR__.'/push_notification/'.$file;
}
if (!class_exists($class)){
return false;
}
}
$cr = new ReflectionClass($class);
$constructor = $cr->getConstructor();
$constructorParameters = array();
foreach (array_map(function($a){ return $a->getName();}, $constructor->getParameters()) as $param){
$constructorParameters[] = array_key_exists($param, $data)?$data[$param]:null;
}
$instance = $cr->newInstanceArgs($constructorParameters);
return $instance;
}

/**
* Update accounts push notification settings
* @param account_id int Account ID
* @param data array Data array
* @return bool
**/
public function updateSettings($account_id, $data) {
UserSettings::construct($account_id)->PushNotifications = $data;
return true;
}

/**
* Fetch notification settings for user account
* @param id int Account ID
* @return array Notification settings
**/
public function getNotificationSettings($account_id) {
if ($settings = UserSettings::construct($account_id)->PushNotifications){
return $settings;
}
return array(
'class' => false,
'params' => null,
'file' => null,
);
}

private static $instance = null;
/**
* @param PushNotification $instance
*/
public static function Instance($instance = null){
if (func_num_args() == 0){
return self::$instance;
}
return self::$instance = $instance;
}

public function sendNotification($account_id, $template, $aData){
$settings = $this->getNotificationSettings($account_id);
if ($settings['class']){
$instance = $this->getNotificatorInstance(array($settings['class'], $settings['file']), $settings['params']);
if ($instance){
$this->smarty->assign('WEBSITENAME', $this->setting->getValue('website_name'));
$this->smarty->assign('SUBJECT', $aData['subject']);
$this->smarty->assign('DATA', $aData);

$message = false;
foreach (array('/mail/push_notifications/', '/mail/notifications/') as $dir){
$this->smarty->clearCache($templateFile = TEMPLATE_DIR.$dir.$template.'.tpl');
try {
$message = $this->smarty->fetch($templateFile);
break;
} catch (SmartyException $e){

}
}
if ($message){
$instance->notify($message, 'info', $aData['subject']);
}
}
}
return true;
}
}

$pushnotification = PushNotification::Instance(new PushNotification());
$pushnotification->setDebug($debug);
$pushnotification->setLog($log);
$pushnotification->setMysql($mysqli);
$pushnotification->setSmarty($smarty);
$pushnotification->setConfig($config);
$pushnotification->setSetting($setting);
$pushnotification->setErrorCodes($aErrorCodes);
1 change: 1 addition & 0 deletions include/classes/transaction.class.php
Original file line number Diff line number Diff line change
Expand Up @@ -430,6 +430,7 @@ private function createDebitRecord($account_id, $coin_address, $amount, $type) {
$aMailData['email'] = $this->user->getUserEmailById($account_id);
$aMailData['subject'] = $type . ' Completed';
$aMailData['amount'] = $amount;
$aMailData['currency'] = $this->config['currency'];
if (!$this->notification->sendNotification($account_id, 'payout', $aMailData)) {
$this->setErrorMessage('Failed to send notification email to users address: ' . $aMailData['email'] . 'ERROR: ' . $this->notification->getCronError());
}
Expand Down
2 changes: 1 addition & 1 deletion include/classes/user.class.php
Original file line number Diff line number Diff line change
Expand Up @@ -244,7 +244,7 @@ public function checkLogin($username, $password) {
$notifs->setSetting($this->setting);
$notifs->setErrorCodes($this->aErrorCodes);
$ndata = $notifs->getNotificationSettings($uid);
if (@$ndata['success_login'] == 1) {
if ((array_key_exists('push_success_lo', $ndata) && $ndata['push_success_lo']) || (array_key_exists('success_login', $ndata) && $ndata['success_login'])){
// seems to be active, let's send it
$aDataN['username'] = $username;
$aDataN['email'] = $this->getUserEmail($username);
Expand Down
Loading