Skip to content

Commit

Permalink
add notification system for new and updated topics and comments.
Browse files Browse the repository at this point in the history
setting per user: each user can set the prefered option
related to #157
  • Loading branch information
tpokorra committed Nov 26, 2021
1 parent 45feeeb commit 806127f
Show file tree
Hide file tree
Showing 13 changed files with 305 additions and 44 deletions.
11 changes: 11 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -78,3 +78,14 @@ apt-get install php-xdebug php-pdo-sqlite
./vendor/bin/phpunit -c phpunit.xml
# Please note you should not install PHPUnit on anything but your development system. See https://thephp.cc/news/2020/02/phpunit-a-security-risk for further explanation.
```


# TODO

TODO composer du for adding own classes to autoload

TODO: Update database:

```
alter table participant add column `notifications` int(2) unsigned NOT NULL DEFAULT 10 after `language`;
```
1 change: 1 addition & 0 deletions sql/createtables.sql
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,7 @@ CREATE TABLE `participant` (
`password` varchar(255) COLLATE latin1_general_ci NOT NULL,
`userinfo` varchar(255) COLLATE latin1_general_ci NOT NULL DEFAULT '',
`language` varchar(5) COLLATE latin1_general_ci NOT NULL DEFAULT 'en',
`notifications` int(2) unsigned NOT NULL DEFAULT 10,
`confirmed` tinyint(1) NOT NULL DEFAULT '0',
`token` varchar(255) COLLATE latin1_general_ci NOT NULL DEFAULT '',
`active` tinyint(1) NOT NULL DEFAULT '1',
Expand Down
71 changes: 29 additions & 42 deletions src/classes/Auth.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,7 @@
use \Firebase\JWT\JWT;
use ICCM\BOF\Cookies;
use \PDO;
use PHPMailer\PHPMailer\PHPMailer;
use PHPMailer\PHPMailer\SMTP;
use PHPMailer\PHPMailer\Exception;
use ICCM\BOF\Mailer;

class Auth
{
Expand All @@ -28,6 +26,7 @@ function __construct($view, $router, $dbo, $secrettoken, $cookies, $translator)
$this->translator = $translator;
$this->settings = require __DIR__.'/../../cfg/settings.php';
$this->site = $_SERVER['SERVER_NAME'];
$this->mailer = new \ICCM\BOF\Mailer($dbo);
}

private function signin($response, $login, $userid) {
Expand Down Expand Up @@ -113,7 +112,7 @@ public function new_user($request, $response, $args) {
$accept_link = "https://".$this->site."/confirm_user?email=".urlencode($email)."&token=".$token;
$body_html = $this->translator->trans("email_confirm_user", ['%site%' => $this->site, '%login%' => $login, '%link%' => $accept_link]);
$body = str_replace("<br/>", "\n", $body_html);
$this->sendEmail($email, $subject, $body_html, $body);
$this->mailer->sendEmail($email, $subject, $body_html, $body);

return $this->view->render($response, 'login.html', array('message' => $this->translator->trans('Please confirm your email address by visiting the link sent to your email address.')));
}
Expand Down Expand Up @@ -143,7 +142,7 @@ public function reset_pwd($request, $response, $args) {
$text_body = str_replace("<br/>", "\n", $html_body);

if ($this->dbo->startResetPassword($email, $token)) {
$this->sendEmail($email, $subject, $html_body, $text_body);
$this->mailer->sendEmail($email, $subject, $html_body, $text_body);
}

return $this->view->render($response, 'reset_pwd.html', array('message' => $this->translator->trans("An Email has been sent for the password reset")));
Expand Down Expand Up @@ -192,41 +191,7 @@ public function moderateNewUser($email, $login, $userinfo) {
$text_body = str_replace("<br/>", "\n", $html_body);
$email_to = $this->settings['settings']['moderation_email'];
$this->translator->setLocale($userLang);
$this->sendEmail($email_to, $subject, $html_body, $text_body);
}

public function sendEmail($email_to, $subject, $html_body, $text_body) {

$mail = new PHPMailer();
$mail->isSMTP();
$mail->Host = $this->settings['settings']['smtp']['host'];
$mail->SMTPAuth = true;
$mail->Username = $this->settings['settings']['smtp']['user'];
$mail->Password = $this->settings['settings']['smtp']['passwd'];
$mail->SMTPSecure = PHPMailer::ENCRYPTION_SMTPS;
$mail->Port = $this->settings['settings']['smtp']['port'];
$mail->setFrom($this->settings['settings']['smtp']['from'], $this->settings['settings']['smtp']['from_name']);
$mail->addAddress($email_to);
$mail->Subject = $subject;
$mail->CharSet = "UTF-8";

if ($html_body != '') {
$mail->isHTML(true);
$mail->Body = $html_body;
$mail->AltBody = $text_body;
}
else
{
$mail->Body = $text_body;
}

try {
if (!$mail->send()) {
error_log($mail->ErrorInfo);
}
} catch (Exception $e) {
error_log("Message could not be sent. Mailer Error: {$mail->ErrorInfo}");
}
$this->mailer->sendEmail($email_to, $subject, $html_body, $text_body);
}

public function confirm_user($request, $response, $args) {
Expand All @@ -251,15 +216,15 @@ public function confirm_user($request, $response, $args) {
$adminLang = $this->translator->getLocale();
$this->translator->setLocale($userLang);
// $this->translator->trans(
$this->sendEmail($email,
$this->mailer->sendEmail($email,
$this->translator->trans("Account has been activated"),
"",
$this->translator->trans("Your account at %site% has been activated", ['%site%' => 'https://'.$this->site]));
$this->translator->setLocale($adminLang);

// send an email notification for the moderators
$email_to = $this->settings['settings']['moderation_email'];
$this->sendEmail($email_to, "$email has been activated", "", "$email has been activated");
$this->mailer->sendEmail($email_to, "$email has been activated", "", "$email has been activated");

return $this->view->render($response, 'confirm_user.html', array('message' => 'activated'));
}
Expand All @@ -285,6 +250,28 @@ public function logout($request, $response, $args) {
$config['show_githubforkme'] = true;
return $this->view->render($response, 'home.html', $config);
}

public function edit_settings($request, $response, $args) {
$data = $request->getParsedBody();

if (!$data) {
$data = $request->getQueryParams();
}

if (!array_key_exists('notifications', $data) || $data['notifications'] == '') {
$data = $this->dbo->getUserSettings($request->getAttribute('userid'));
return $this->view->render($response, 'settings.html',
['loggedin' => True, 'notifications'.$data['notifications'] => 'selected']);
}

$this->dbo->saveUserSettings($request->getAttribute('userid'), $data['notifications']);

return $this->view->render($response, 'settings.html',
['message' => $this->translator->trans("Your choice has been saved."),
'loggedin' => True,
'notifications'.$data['notifications'] => 'selected']);
}

}

?>
76 changes: 76 additions & 0 deletions src/classes/DBO.php
Original file line number Diff line number Diff line change
Expand Up @@ -315,6 +315,59 @@ public function changePassword($login, $password) {
return $query->rowCount() === 1;
}

/**
* Save the settings
*
* @param int $userid The id of the current user
* @param int $notifications The selected option for notifications per email
*
* @return None
*/
public function saveUserSettings($userid, $notifications) {
$sql="UPDATE participant
SET notifications = :notifications
WHERE id = :userid";
$query=$this->db->prepare($sql);
$query->bindValue('notifications', $notifications, PDO::PARAM_INT);
$query->bindValue('userid', $userid, PDO::PARAM_INT);
$query->execute();
}

/**
* Get the settings of the given user
*
* @param int $userid The id of the current user
*
* @return array with settings
*/
public function getUserSettings($userid) {
$sql="SELECT notifications FROM participant
WHERE id = :userid";
$query=$this->db->prepare($sql);
$query->bindValue('userid', $userid, PDO::PARAM_INT);
$query->execute();
$result = array();
if ($query->rowCount() == 1) {
$row = $query->fetch(PDO::FETCH_OBJ);
$result['notifications'] = $row->notifications;
}
return $result;
}

// get the user name and email if it has this notification setting
public function getUsersByNotificationsSetting($notifications) {
$sql="SELECT name, email FROM participant
WHERE notifications = :notifications AND active = 1 and confirmed = 1";
$query=$this->db->prepare($sql);
$query->bindValue('notifications', $notifications, PDO::PARAM_INT);
$query->execute();
$result = array();
while ($row=$query->fetch(PDO::FETCH_OBJ)) {
$result[] = $row;
}
return $result;
}

/**
* Checks if a user exists in the participant database.
*
Expand Down Expand Up @@ -1055,6 +1108,25 @@ public function getWorkshopDetails($topic_id) {
return $query->fetchAll(PDO::FETCH_OBJ);
}

/**
* returns all voters for a topic. needed for notifications
*
* @return all voters for a topic
*/
public function getAllVotersForWorkshop($topic_id) {
$sql = "SELECT w.id AS topic_id, wp.participant_id AS voter_id, pc.email as email
FROM workshop w
LEFT JOIN workshop_participant wp
ON wp.workshop_id = w.id
AND wp.participant > 0
LEFT JOIN participant pc
ON wp.participant_id = pc.id
WHERE w.id = :topic_id";
$query = $this->db->prepare($sql);
$query->execute(array(':topic_id' => $topic_id ));
return $query->fetchAll(PDO::FETCH_OBJ);
}

/**
* Returns the comments for one workshop.
*
Expand Down Expand Up @@ -1203,6 +1275,8 @@ public function nominate($name, $description, $creator_id) {

$query=$this->db->prepare($sql);
$query->execute(array(':name' => $name, ':description' => $description, ':creator_id' => $creator_id));

return $this->db->lastInsertId();
}

/**
Expand Down Expand Up @@ -1231,6 +1305,8 @@ public function comment_add($topic_id, $comment, $commentator_id) {

$query=$this->db->prepare($sql);
$query->execute(array(':topic_id' => $topic_id, ':comment' => $comment, ':user_id' => $commentator_id));

return $this->db->lastInsertId();
}

/**
Expand Down
52 changes: 52 additions & 0 deletions src/classes/Mailer.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
<?php

namespace ICCM\BOF;
use \PDO;
use PHPMailer\PHPMailer\PHPMailer;
use PHPMailer\PHPMailer\SMTP;
use PHPMailer\PHPMailer\Exception;

class Mailer
{
private $dbo;
private $settings;

function __construct($dbo) {
$this->dbo = $dbo;
$this->settings = require __DIR__.'/../../cfg/settings.php';
}

public function sendEmail($email_to, $subject, $html_body, $text_body) {

$mail = new PHPMailer();
$mail->isSMTP();
$mail->Host = $this->settings['settings']['smtp']['host'];
$mail->SMTPAuth = true;
$mail->Username = $this->settings['settings']['smtp']['user'];
$mail->Password = $this->settings['settings']['smtp']['passwd'];
$mail->SMTPSecure = PHPMailer::ENCRYPTION_SMTPS;
$mail->Port = $this->settings['settings']['smtp']['port'];
$mail->setFrom($this->settings['settings']['smtp']['from'], $this->settings['settings']['smtp']['from_name']);
$mail->addAddress($email_to);
$mail->Subject = $subject;
$mail->CharSet = "UTF-8";

if ($html_body != '') {
$mail->isHTML(true);
$mail->Body = $html_body;
$mail->AltBody = $text_body;
}
else
{
$mail->Body = $text_body;
}

try {
if (!$mail->send()) {
error_log($mail->ErrorInfo);
}
} catch (Exception $e) {
error_log("Message could not be sent. Mailer Error: {$mail->ErrorInfo}");
}
}
}
Loading

0 comments on commit 806127f

Please sign in to comment.