V1.0 add email notifications
This commit is contained in:
parent
65786aa191
commit
7c2e7f00b9
@ -55,7 +55,7 @@ RUN chmod +x /var/www/html/startup.sh
|
|||||||
# Expose port 80 for Nginx
|
# Expose port 80 for Nginx
|
||||||
EXPOSE 80
|
EXPOSE 80
|
||||||
|
|
||||||
ARG SOFTWARE_VERSION=0.9.0
|
ARG SOFTWARE_VERSION=1.0.0
|
||||||
|
|
||||||
# Start both PHP-FPM, Nginx
|
# Start both PHP-FPM, Nginx
|
||||||
CMD ["sh", "-c", "/var/www/html/startup.sh"]
|
CMD ["sh", "-c", "/var/www/html/startup.sh"]
|
||||||
@ -48,6 +48,7 @@ See instructions to run Wallos below.
|
|||||||
- curl
|
- curl
|
||||||
- gd
|
- gd
|
||||||
- imagick
|
- imagick
|
||||||
|
- openssl
|
||||||
- sqlite3
|
- sqlite3
|
||||||
|
|
||||||
#### Docker
|
#### Docker
|
||||||
@ -63,10 +64,13 @@ Download or clone this repo and move the files into your web root - usually `/va
|
|||||||
Add the following scripts to your cronjobs with `crontab -e`
|
Add the following scripts to your cronjobs with `crontab -e`
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
0 0 * * * php /var/www/html/endpoints/cronjobs/updatenextpayment.php >> /var/log/cron/updatenextpayment.log 2>&1
|
0 1 * * * php /var/www/html/endpoints/cronjobs/updatenextpayment.php >> /var/log/cron/updatenextpayment.log 2>&1
|
||||||
0 1 * * * php /var/www/html/endpoints/cronjobs/updateexchange.php >> /var/log/cron/updateexchange.log 2>&1
|
0 2 * * * php /var/www/html/endpoints/cronjobs/updateexchange.php >> /var/log/cron/updateexchange.log 2>&1
|
||||||
|
0 9 * * * php /var/www/html/endpoints/cronjobs/sendnotifications.php >> /var/log/cron/sendnotifications.log 2>&1
|
||||||
```
|
```
|
||||||
|
|
||||||
|
If your web root is not `/var/www/html/` adjust both the cronjobs above and `/endpoints/cronjobs/conf.php` accordingly.
|
||||||
|
|
||||||
#### Docker
|
#### Docker
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
|
|||||||
7
cronjobs
7
cronjobs
@ -1,3 +1,4 @@
|
|||||||
# Run the script every day
|
# Run the scripts every day
|
||||||
0 0 * * * /usr/local/bin/php /var/www/html/endpoints/cronjobs/updatenextpayment.php >> /var/log/cron/updatenextpayment.log 2>&1
|
0 1 * * * /usr/local/bin/php /var/www/html/endpoints/cronjobs/updatenextpayment.php >> /var/log/cron/updatenextpayment.log 2>&1
|
||||||
0 1 * * * /usr/local/bin/php /var/www/html/endpoints/cronjobs/updateexchange.php >> /var/log/cron/updateexchange.log 2>&1
|
0 2 * * * /usr/local/bin/php /var/www/html/endpoints/cronjobs/updateexchange.php >> /var/log/cron/updateexchange.log 2>&1
|
||||||
|
0 9 * * * /usr/local/bin/php /var/www/html/endpoints/cronjobs/sendnotifications.php >> /var/log/cron/sendnotifications.log 2>&1
|
||||||
|
|||||||
@ -27,6 +27,7 @@ CREATE TABLE subscriptions (
|
|||||||
payment_method_id INTEGER,
|
payment_method_id INTEGER,
|
||||||
payer_user_id INTEGER,
|
payer_user_id INTEGER,
|
||||||
category_id INTEGER,
|
category_id INTEGER,
|
||||||
|
notify BOOLEAN DEFAULT false,
|
||||||
FOREIGN KEY(currency_id) REFERENCES currencies(id),
|
FOREIGN KEY(currency_id) REFERENCES currencies(id),
|
||||||
FOREIGN KEY(cycle) REFERENCES cycles(id),
|
FOREIGN KEY(cycle) REFERENCES cycles(id),
|
||||||
FOREIGN KEY(frequency) REFERENCES frequencies(id),
|
FOREIGN KEY(frequency) REFERENCES frequencies(id),
|
||||||
@ -81,7 +82,17 @@ CREATE TABLE last_exchange_update (
|
|||||||
|
|
||||||
CREATE TABLE last_update_next_payment_date (
|
CREATE TABLE last_update_next_payment_date (
|
||||||
date DATE NOT NULL
|
date DATE NOT NULL
|
||||||
)
|
);
|
||||||
|
|
||||||
|
CREATE TABLE notifications (
|
||||||
|
id INTEGER PRIMARY KEY,
|
||||||
|
enabled BOOLEAN DEFAULT false,
|
||||||
|
days INTEGER,
|
||||||
|
smtp_address VARCHAR(255),
|
||||||
|
smtp_port INTEGER,
|
||||||
|
smtp_username VARCHAR(255),
|
||||||
|
smtp_password VARCHAR(255)
|
||||||
|
);
|
||||||
|
|
||||||
INSERT INTO categories (id, name) VALUES
|
INSERT INTO categories (id, name) VALUES
|
||||||
(1, 'No category'),
|
(1, 'No category'),
|
||||||
|
|||||||
BIN
db/wallos.db
BIN
db/wallos.db
Binary file not shown.
6
endpoints/cronjobs/conf.php
Normal file
6
endpoints/cronjobs/conf.php
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
#Webroot path
|
||||||
|
$webPath = "/var/www/html/";
|
||||||
|
|
||||||
|
?>
|
||||||
@ -1,9 +1,11 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
$databaseFile = '/var/www/html/db/wallos.db';
|
require_once 'conf.php';
|
||||||
|
|
||||||
|
$databaseFile = $webPath . 'db/wallos.db';
|
||||||
|
|
||||||
if (!file_exists($databaseFile)) {
|
if (!file_exists($databaseFile)) {
|
||||||
echo "Database does not exist. Creating it...";
|
echo "Database does not exist. Creating it...\n";
|
||||||
$db = new SQLite3($databaseFile, SQLITE3_OPEN_CREATE | SQLITE3_OPEN_READWRITE);
|
$db = new SQLite3($databaseFile, SQLITE3_OPEN_CREATE | SQLITE3_OPEN_READWRITE);
|
||||||
$db->busyTimeout(5000);
|
$db->busyTimeout(5000);
|
||||||
|
|
||||||
@ -36,6 +38,7 @@ if (!file_exists($databaseFile)) {
|
|||||||
payment_method_id INTEGER,
|
payment_method_id INTEGER,
|
||||||
payer_user_id INTEGER,
|
payer_user_id INTEGER,
|
||||||
category_id INTEGER,
|
category_id INTEGER,
|
||||||
|
notify BOOLEAN DEFAULT false,
|
||||||
FOREIGN KEY(currency_id) REFERENCES currencies(id),
|
FOREIGN KEY(currency_id) REFERENCES currencies(id),
|
||||||
FOREIGN KEY(cycle) REFERENCES cycles(id),
|
FOREIGN KEY(cycle) REFERENCES cycles(id),
|
||||||
FOREIGN KEY(frequency) REFERENCES frequencies(id),
|
FOREIGN KEY(frequency) REFERENCES frequencies(id),
|
||||||
@ -92,6 +95,16 @@ if (!file_exists($databaseFile)) {
|
|||||||
date DATE NOT NULL
|
date DATE NOT NULL
|
||||||
)');
|
)');
|
||||||
|
|
||||||
|
$db-exec('CREATE TABLE notifications (
|
||||||
|
id INTEGER PRIMARY KEY,
|
||||||
|
enabled BOOLEAN DEFAULT false,
|
||||||
|
days INTEGER,
|
||||||
|
smtp_address VARCHAR(255),
|
||||||
|
smtp_port INTEGER,
|
||||||
|
smtp_username VARCHAR(255),
|
||||||
|
smtp_password VARCHAR(255)
|
||||||
|
)');
|
||||||
|
|
||||||
$db->exec("INSERT INTO categories (id, name) VALUES
|
$db->exec("INSERT INTO categories (id, name) VALUES
|
||||||
(1, 'No category'),
|
(1, 'No category'),
|
||||||
(2, 'Entertainment'),
|
(2, 'Entertainment'),
|
||||||
@ -218,8 +231,53 @@ if (!file_exists($databaseFile)) {
|
|||||||
(30, 'VeriFone', 'verifone.png'),
|
(30, 'VeriFone', 'verifone.png'),
|
||||||
(31, 'WebMoney', 'webmoney.png')");
|
(31, 'WebMoney', 'webmoney.png')");
|
||||||
|
|
||||||
|
echo "Database created.\n";
|
||||||
} else {
|
} else {
|
||||||
echo "Database already exist. Skipping...";
|
echo "Database already exist. Checking for upgrades...\n";
|
||||||
|
|
||||||
|
$databaseFile = $webPath . 'db/wallos.db';
|
||||||
|
$db = new SQLite3($databaseFile);
|
||||||
|
$db->busyTimeout(5000);
|
||||||
|
|
||||||
|
if (!$db) {
|
||||||
|
die('Connection to the database failed.');
|
||||||
|
}
|
||||||
|
|
||||||
|
# v0.9 to v1.0
|
||||||
|
# Added new notifications table
|
||||||
|
# Added notify column to subscriptions table
|
||||||
|
|
||||||
|
$result = $db->query("SELECT name FROM sqlite_master WHERE type='table' AND name='notifications'");
|
||||||
|
if (!$result->fetchArray(SQLITE3_ASSOC)) {
|
||||||
|
$db->exec('CREATE TABLE notifications (
|
||||||
|
id INTEGER PRIMARY KEY,
|
||||||
|
enabled BOOLEAN DEFAULT false,
|
||||||
|
days INTEGER,
|
||||||
|
smtp_address VARCHAR(255),
|
||||||
|
smtp_port INTEGER,
|
||||||
|
smtp_username VARCHAR(255),
|
||||||
|
smtp_password VARCHAR(255)
|
||||||
|
)');
|
||||||
|
echo "Table 'notifications' created.\n";
|
||||||
|
} else {
|
||||||
|
echo "Table 'notifications' already exists.\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
$result = $db->query("PRAGMA table_info(subscriptions)");
|
||||||
|
$notifyColumnExists = false;
|
||||||
|
while ($row = $result->fetchArray(SQLITE3_ASSOC)) {
|
||||||
|
if ($row['name'] === 'notify') {
|
||||||
|
$notifyColumnExists = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!$notifyColumnExists) {
|
||||||
|
$db->exec('ALTER TABLE subscriptions ADD COLUMN notify BOOLEAN DEFAULT false');
|
||||||
|
echo "Column 'notify' added to table 'subscriptions'.\n";
|
||||||
|
} else {
|
||||||
|
echo "Column 'notify' already exists in table 'subscriptions'.\n";
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
?>
|
?>
|
||||||
89
endpoints/cronjobs/sendnotifications.php
Normal file
89
endpoints/cronjobs/sendnotifications.php
Normal file
@ -0,0 +1,89 @@
|
|||||||
|
<?php
|
||||||
|
use PHPMailer\PHPMailer\PHPMailer;
|
||||||
|
use PHPMailer\PHPMailer\SMTP;
|
||||||
|
use PHPMailer\PHPMailer\Exception;
|
||||||
|
|
||||||
|
require_once 'conf.php';
|
||||||
|
require_once $webPath . 'includes/connect_endpoint_crontabs.php';
|
||||||
|
|
||||||
|
$query = "SELECT * FROM notifications WHERE id = 1";
|
||||||
|
$result = $db->query($query);
|
||||||
|
|
||||||
|
if ($row = $result->fetchArray(SQLITE3_ASSOC)) {
|
||||||
|
$notificationsEnabled = $row['enabled'];
|
||||||
|
$days = $row['days'];
|
||||||
|
$smtpAddress = $row["smtp_address"];
|
||||||
|
$smtpPort = $row["smtp_port"];
|
||||||
|
$smtpUsername = $row["smtp_username"];
|
||||||
|
$smtpPassword = $row["smtp_password"];
|
||||||
|
} else {
|
||||||
|
echo "Notifications are disabled. No need to run.";
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($notificationsEnabled) {
|
||||||
|
$currencies = array();
|
||||||
|
$query = "SELECT * FROM currencies";
|
||||||
|
$result = $db->query($query);
|
||||||
|
while ($row = $result->fetchArray(SQLITE3_ASSOC)) {
|
||||||
|
$currencyId = $row['id'];
|
||||||
|
$currencies[$currencyId] = $row;
|
||||||
|
}
|
||||||
|
|
||||||
|
$querySubscriptions = "SELECT * FROM subscriptions WHERE notify = 1";
|
||||||
|
$resultSubscriptions = $db->query($querySubscriptions);
|
||||||
|
|
||||||
|
$notify = []; $i = 0;
|
||||||
|
$currentDate = new DateTime('now');
|
||||||
|
while ($rowSubscription = $resultSubscriptions->fetchArray(SQLITE3_ASSOC)) {
|
||||||
|
$nextPaymentDate = new DateTime($rowSubscription['next_payment']);
|
||||||
|
$difference = $currentDate->diff($nextPaymentDate)->days + 1;
|
||||||
|
if ($difference === $days) {
|
||||||
|
$notify[$i]['name'] = $rowSubscription['name'];
|
||||||
|
$notify[$i]['price'] = $rowSubscription['price'] . $currencies[$rowSubscription['currency_id']]['symbol'];
|
||||||
|
$i++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!empty($notify)) {
|
||||||
|
require $webPath . 'libs/PHPMailer/PHPMailer.php';
|
||||||
|
require $webPath . 'libs/PHPMailer/SMTP.php';
|
||||||
|
require $webPath . 'libs/PHPMailer/Exception.php';
|
||||||
|
|
||||||
|
$dayText = $days == 1 ? "tomorrow" : "in " . $days . " days"
|
||||||
|
$message = "The following subscriptions are up for renewal " . $dayText . ":\n";
|
||||||
|
foreach ($notify as $subscription) {
|
||||||
|
$message .= $subscription['name'] . " for " . $subscription['price'] . "\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
$mail = new PHPMailer(true);
|
||||||
|
$mail->isSMTP();
|
||||||
|
|
||||||
|
$mail->Host = $smtpAddress;
|
||||||
|
$mail->SMTPAuth = true;
|
||||||
|
$mail->Username = $smtpUsername;
|
||||||
|
$mail->Password = $smtpPassword;
|
||||||
|
$mail->SMTPSecure = 'tls';
|
||||||
|
$mail->Port = $smtpPort;
|
||||||
|
|
||||||
|
$getUser = "SELECT * FROM user WHERE id = 1";
|
||||||
|
$user = $db->querySingle($getUser, true);
|
||||||
|
$email = $user['email'];
|
||||||
|
$name = $user['username'];
|
||||||
|
|
||||||
|
$mail->setFrom('wallos@wallosapp.com', 'Wallos App');
|
||||||
|
$mail->addAddress($email, $name);
|
||||||
|
|
||||||
|
$mail->Subject = 'Wallos Notification';
|
||||||
|
$mail->Body = $message;
|
||||||
|
|
||||||
|
if ($mail->send()) {
|
||||||
|
echo "Notifications sent";
|
||||||
|
} else {
|
||||||
|
echo "Error sending notifications: " . $mail->ErrorInfo;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
echo "Nothing to notify.";
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
?>
|
||||||
@ -1,5 +1,6 @@
|
|||||||
<?php
|
<?php
|
||||||
require_once '/var/www/html/includes/connect_endpoint_crontabs.php';
|
require_once 'conf.php';
|
||||||
|
require_once $webPath . 'includes/connect_endpoint_crontabs.php';
|
||||||
|
|
||||||
$query = "SELECT api_key FROM fixer";
|
$query = "SELECT api_key FROM fixer";
|
||||||
$result = $db->query($query);
|
$result = $db->query($query);
|
||||||
|
|||||||
@ -1,5 +1,6 @@
|
|||||||
<?php
|
<?php
|
||||||
require_once '/var/www/html/includes/connect_endpoint_crontabs.php';
|
require_once 'conf.php';
|
||||||
|
require_once $webPath . 'includes/connect_endpoint_crontabs.php';
|
||||||
|
|
||||||
$currentDate = new DateTime();
|
$currentDate = new DateTime();
|
||||||
$currentDateString = $currentDate->format('Y-m-d');
|
$currentDateString = $currentDate->format('Y-m-d');
|
||||||
|
|||||||
71
endpoints/notifications/save.php
Normal file
71
endpoints/notifications/save.php
Normal file
@ -0,0 +1,71 @@
|
|||||||
|
<?php
|
||||||
|
require_once '../../includes/connect_endpoint.php';
|
||||||
|
session_start();
|
||||||
|
|
||||||
|
if ($_SERVER["REQUEST_METHOD"] === "POST") {
|
||||||
|
$postData = file_get_contents("php://input");
|
||||||
|
$data = json_decode($postData, true);
|
||||||
|
|
||||||
|
if (
|
||||||
|
!isset($data["days"]) || $data['days'] == "" ||
|
||||||
|
!isset($data["smtpaddress"]) || $data["smtpaddress"] == "" ||
|
||||||
|
!isset($data["smtpport"]) || $data["smtpport"] == "" ||
|
||||||
|
!isset($data["smtpusername"]) || $data["smtpusername"] == "" ||
|
||||||
|
!isset($data["smtppassword"]) || $data["smtppassword"] == ""
|
||||||
|
) {
|
||||||
|
$response = [
|
||||||
|
"success" => false,
|
||||||
|
"errorMessage" => "Please fill all fields"
|
||||||
|
];
|
||||||
|
echo json_encode($response);
|
||||||
|
} else {
|
||||||
|
$enabled = $data["enabled"];
|
||||||
|
$days = $data["days"];
|
||||||
|
$smtpAddress = $data["smtpaddress"];
|
||||||
|
$smtpPort = $data["smtpport"];
|
||||||
|
$smtpUsername = $data["smtpusername"];
|
||||||
|
$smtpPassword = $data["smtppassword"];
|
||||||
|
|
||||||
|
$query = "SELECT COUNT(*) FROM notifications";
|
||||||
|
$result = $db->querySingle($query);
|
||||||
|
|
||||||
|
if ($result === false) {
|
||||||
|
$response = [
|
||||||
|
"success" => false,
|
||||||
|
"errorMessage" => "Error saving notifications data"
|
||||||
|
];
|
||||||
|
echo json_encode($response);
|
||||||
|
} else {
|
||||||
|
if ($result == 0) {
|
||||||
|
$query = "INSERT INTO notifications (enabled, days, smtp_address, smtp_port, smtp_username, smtp_password)
|
||||||
|
VALUES (:enabled, :days, :smtpAddress, :smtpPort, :smtpUsername, :smtpPassword)";
|
||||||
|
} else {
|
||||||
|
$query = "UPDATE notifications
|
||||||
|
SET enabled = :enabled, days = :days, smtp_address = :smtpAddress, smtp_port = :smtpPort,
|
||||||
|
smtp_username = :smtpUsername, smtp_password = :smtpPassword";
|
||||||
|
}
|
||||||
|
|
||||||
|
$stmt = $db->prepare($query);
|
||||||
|
$stmt->bindValue(':enabled', $enabled, SQLITE3_INTEGER);
|
||||||
|
$stmt->bindValue(':days', $days, SQLITE3_INTEGER);
|
||||||
|
$stmt->bindValue(':smtpAddress', $smtpAddress, SQLITE3_TEXT);
|
||||||
|
$stmt->bindValue(':smtpPort', $smtpPort, SQLITE3_INTEGER);
|
||||||
|
$stmt->bindValue(':smtpUsername', $smtpUsername, SQLITE3_TEXT);
|
||||||
|
$stmt->bindValue(':smtpPassword', $smtpPassword, SQLITE3_TEXT);
|
||||||
|
|
||||||
|
if ($stmt->execute()) {
|
||||||
|
$response = [
|
||||||
|
"success" => true
|
||||||
|
];
|
||||||
|
echo json_encode($response);
|
||||||
|
} else {
|
||||||
|
$response = [
|
||||||
|
"success" => false,
|
||||||
|
"errorMessage" => "Error saving notification data"
|
||||||
|
];
|
||||||
|
echo json_encode($response);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
?>
|
||||||
72
endpoints/notifications/sendtestmail.php
Normal file
72
endpoints/notifications/sendtestmail.php
Normal file
@ -0,0 +1,72 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
use PHPMailer\PHPMailer\PHPMailer;
|
||||||
|
use PHPMailer\PHPMailer\SMTP;
|
||||||
|
use PHPMailer\PHPMailer\Exception;
|
||||||
|
|
||||||
|
require_once '../../includes/connect_endpoint.php';
|
||||||
|
session_start();
|
||||||
|
|
||||||
|
if ($_SERVER["REQUEST_METHOD"] === "POST") {
|
||||||
|
$postData = file_get_contents("php://input");
|
||||||
|
$data = json_decode($postData, true);
|
||||||
|
|
||||||
|
if (
|
||||||
|
!isset($data["smtpaddress"]) || $data["smtpaddress"] == "" ||
|
||||||
|
!isset($data["smtpport"]) || $data["smtpport"] == "" ||
|
||||||
|
!isset($data["smtpusername"]) || $data["smtpusername"] == "" ||
|
||||||
|
!isset($data["smtppassword"]) || $data["smtppassword"] == ""
|
||||||
|
) {
|
||||||
|
$response = [
|
||||||
|
"success" => false,
|
||||||
|
"errorMessage" => "Please fill all fields"
|
||||||
|
];
|
||||||
|
echo json_encode($response);
|
||||||
|
} else {
|
||||||
|
require '../../libs/PHPMailer/PHPMailer.php';
|
||||||
|
require '../../libs/PHPMailer/SMTP.php';
|
||||||
|
require '../../libs/PHPMailer/Exception.php';
|
||||||
|
|
||||||
|
$smtpAddress = $data["smtpaddress"];
|
||||||
|
$smtpPort = $data["smtpport"];
|
||||||
|
$smtpUsername = $data["smtpusername"];
|
||||||
|
$smtpPassword = $data["smtppassword"];
|
||||||
|
|
||||||
|
$mail = new PHPMailer(true);
|
||||||
|
$mail->isSMTP();
|
||||||
|
|
||||||
|
$mail->Host = $smtpAddress;
|
||||||
|
$mail->SMTPAuth = true;
|
||||||
|
$mail->Username = $smtpUsername;
|
||||||
|
$mail->Password = $smtpPassword;
|
||||||
|
$mail->SMTPSecure = 'tls';
|
||||||
|
$mail->Port = $smtpPort;
|
||||||
|
|
||||||
|
$getUser = "SELECT * FROM user WHERE id = 1";
|
||||||
|
$user = $db->querySingle($getUser, true);
|
||||||
|
$email = $user['email'];
|
||||||
|
$name = $user['username'];
|
||||||
|
|
||||||
|
$mail->setFrom('wallos@wallosapp.com', 'Wallos App');
|
||||||
|
$mail->addAddress($email, $name);
|
||||||
|
|
||||||
|
$mail->Subject = 'Wallos Notification';
|
||||||
|
$mail->Body = 'This is a test notification. If you\'re seeing this, the configuration is correct.';
|
||||||
|
|
||||||
|
if ($mail->send()) {
|
||||||
|
$response = [
|
||||||
|
"success" => true,
|
||||||
|
];
|
||||||
|
echo json_encode($response);
|
||||||
|
} else {
|
||||||
|
$response = [
|
||||||
|
"success" => false,
|
||||||
|
"errorMessage" => "Error sending email." . $mail->ErrorInfo
|
||||||
|
];
|
||||||
|
echo json_encode($response);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
?>
|
||||||
@ -144,6 +144,7 @@
|
|||||||
$notes = $_POST["notes"];
|
$notes = $_POST["notes"];
|
||||||
$logoUrl = $_POST['logo-url'];
|
$logoUrl = $_POST['logo-url'];
|
||||||
$logo = "";
|
$logo = "";
|
||||||
|
$notify = isset($_POST['notifications']) ? true : false;
|
||||||
|
|
||||||
if($logoUrl !== "") {
|
if($logoUrl !== "") {
|
||||||
$logo = getLogoFromUrl($logoUrl, '../../images/uploads/logos/', $name);
|
$logo = getLogoFromUrl($logoUrl, '../../images/uploads/logos/', $name);
|
||||||
@ -155,15 +156,15 @@
|
|||||||
|
|
||||||
if (!$isEdit) {
|
if (!$isEdit) {
|
||||||
$sql = "INSERT INTO subscriptions (name, logo, price, currency_id, next_payment, cycle, frequency, notes,
|
$sql = "INSERT INTO subscriptions (name, logo, price, currency_id, next_payment, cycle, frequency, notes,
|
||||||
payment_method_id, payer_user_id, category_id)
|
payment_method_id, payer_user_id, category_id, notify)
|
||||||
VALUES (:name, :logo, :price, :currencyId, :nextPayment, :cycle, :frequency, :notes,
|
VALUES (:name, :logo, :price, :currencyId, :nextPayment, :cycle, :frequency, :notes,
|
||||||
:paymentMethodId, :payerUserId, :categoryId)";
|
:paymentMethodId, :payerUserId, :categoryId, :notify)";
|
||||||
} else {
|
} else {
|
||||||
$id = $_POST['id'];
|
$id = $_POST['id'];
|
||||||
if ($logo != "") {
|
if ($logo != "") {
|
||||||
$sql = "UPDATE subscriptions SET name = :name, logo = :logo, price = :price, currency_id = :currencyId, next_payment = :nextPayment, cycle = :cycle, frequency = :frequency, notes = :notes, payment_method_id = :paymentMethodId, payer_user_id = :payerUserId, category_id = :categoryId WHERE id = :id";
|
$sql = "UPDATE subscriptions SET name = :name, logo = :logo, price = :price, currency_id = :currencyId, next_payment = :nextPayment, cycle = :cycle, frequency = :frequency, notes = :notes, payment_method_id = :paymentMethodId, payer_user_id = :payerUserId, category_id = :categoryId, notify = :notify WHERE id = :id";
|
||||||
} else {
|
} else {
|
||||||
$sql = "UPDATE subscriptions SET name = :name, price = :price, currency_id = :currencyId, next_payment = :nextPayment, cycle = :cycle, frequency = :frequency, notes = :notes, payment_method_id = :paymentMethodId, payer_user_id = :payerUserId, category_id = :categoryId WHERE id = :id";
|
$sql = "UPDATE subscriptions SET name = :name, price = :price, currency_id = :currencyId, next_payment = :nextPayment, cycle = :cycle, frequency = :frequency, notes = :notes, payment_method_id = :paymentMethodId, payer_user_id = :payerUserId, category_id = :categoryId, notify = :notify WHERE id = :id";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -184,6 +185,7 @@
|
|||||||
$stmt->bindParam(':paymentMethodId', $paymentMethodId, SQLITE3_INTEGER);
|
$stmt->bindParam(':paymentMethodId', $paymentMethodId, SQLITE3_INTEGER);
|
||||||
$stmt->bindParam(':payerUserId', $payerUserId, SQLITE3_INTEGER);
|
$stmt->bindParam(':payerUserId', $payerUserId, SQLITE3_INTEGER);
|
||||||
$stmt->bindParam(':categoryId', $categoryId, SQLITE3_INTEGER);
|
$stmt->bindParam(':categoryId', $categoryId, SQLITE3_INTEGER);
|
||||||
|
$stmt->bindParam(':notify', $notify, SQLITE3_INTEGER);
|
||||||
|
|
||||||
if ($stmt->execute()) {
|
if ($stmt->execute()) {
|
||||||
$success['status'] = "Success";
|
$success['status'] = "Success";
|
||||||
|
|||||||
@ -24,6 +24,7 @@
|
|||||||
$subscriptionData['payment_method_id'] = $row['payment_method_id'];
|
$subscriptionData['payment_method_id'] = $row['payment_method_id'];
|
||||||
$subscriptionData['payer_user_id'] = $row['payer_user_id'];
|
$subscriptionData['payer_user_id'] = $row['payer_user_id'];
|
||||||
$subscriptionData['category_id'] = $row['category_id'];
|
$subscriptionData['category_id'] = $row['category_id'];
|
||||||
|
$subscriptionData['notify'] = $row['notify'];
|
||||||
|
|
||||||
$subscriptionJson = json_encode($subscriptionData);
|
$subscriptionJson = json_encode($subscriptionData);
|
||||||
header('Content-Type: application/json');
|
header('Content-Type: application/json');
|
||||||
|
|||||||
21
index.php
21
index.php
@ -26,6 +26,16 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$notificationsEnabled = false;
|
||||||
|
$query = "SELECT enabled FROM notifications WHERE id = 1";
|
||||||
|
$result = $db->query($query);
|
||||||
|
if ($result) {
|
||||||
|
$row = $result->fetchArray(SQLITE3_ASSOC);
|
||||||
|
if ($row) {
|
||||||
|
$notificationsEnabled = $row['enabled'];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
$headerClass = count($subscriptions) > 0 ? "main-actions" : "main-actions hidden";
|
$headerClass = count($subscriptions) > 0 ? "main-actions" : "main-actions hidden";
|
||||||
$defaultLogo = $theme == "light" ? "images/wallos.png" : "images/walloswhite.png";
|
$defaultLogo = $theme == "light" ? "images/wallos.png" : "images/walloswhite.png";
|
||||||
?>
|
?>
|
||||||
@ -229,6 +239,17 @@
|
|||||||
<input type="text" id="notes" name="notes" placeholder="Notes">
|
<input type="text" id="notes" name="notes" placeholder="Notes">
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<?php
|
||||||
|
if ($notificationsEnabled) {
|
||||||
|
?>
|
||||||
|
<div class="form-group-inline">
|
||||||
|
<input type="checkbox" id="notifications" name="notifications">
|
||||||
|
<label for="notifications">Enable Notifications for this subscription</label>
|
||||||
|
</div>
|
||||||
|
<?php
|
||||||
|
}
|
||||||
|
?>
|
||||||
|
|
||||||
<div class="buttons">
|
<div class="buttons">
|
||||||
<input type="button" value="Delete" class="warning-button left" id="deletesub" style="display: none">
|
<input type="button" value="Delete" class="warning-button left" id="deletesub" style="display: none">
|
||||||
<input type="button" value="Cancel" class="secondary-button" onClick="closeAddSubscription()">
|
<input type="button" value="Cancel" class="secondary-button" onClick="closeAddSubscription()">
|
||||||
|
|||||||
40
libs/PHPMailer/Exception.php
Normal file
40
libs/PHPMailer/Exception.php
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/**
|
||||||
|
* PHPMailer Exception class.
|
||||||
|
* PHP Version 5.5.
|
||||||
|
*
|
||||||
|
* @see https://github.com/PHPMailer/PHPMailer/ The PHPMailer GitHub project
|
||||||
|
*
|
||||||
|
* @author Marcus Bointon (Synchro/coolbru) <phpmailer@synchromedia.co.uk>
|
||||||
|
* @author Jim Jagielski (jimjag) <jimjag@gmail.com>
|
||||||
|
* @author Andy Prevost (codeworxtech) <codeworxtech@users.sourceforge.net>
|
||||||
|
* @author Brent R. Matzelle (original founder)
|
||||||
|
* @copyright 2012 - 2020 Marcus Bointon
|
||||||
|
* @copyright 2010 - 2012 Jim Jagielski
|
||||||
|
* @copyright 2004 - 2009 Andy Prevost
|
||||||
|
* @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License
|
||||||
|
* @note This program is distributed in the hope that it will be useful - WITHOUT
|
||||||
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace PHPMailer\PHPMailer;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* PHPMailer exception handler.
|
||||||
|
*
|
||||||
|
* @author Marcus Bointon <phpmailer@synchromedia.co.uk>
|
||||||
|
*/
|
||||||
|
class Exception extends \Exception
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Prettify error message output.
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function errorMessage()
|
||||||
|
{
|
||||||
|
return '<strong>' . htmlspecialchars($this->getMessage(), ENT_COMPAT | ENT_HTML401) . "</strong><br />\n";
|
||||||
|
}
|
||||||
|
}
|
||||||
5137
libs/PHPMailer/PHPMailer.php
Normal file
5137
libs/PHPMailer/PHPMailer.php
Normal file
File diff suppressed because it is too large
Load Diff
1466
libs/PHPMailer/SMTP.php
Normal file
1466
libs/PHPMailer/SMTP.php
Normal file
File diff suppressed because it is too large
Load Diff
@ -61,6 +61,9 @@ function fillEditFormFields(subscription) {
|
|||||||
const notes = document.querySelector("#notes");
|
const notes = document.querySelector("#notes");
|
||||||
notes.value = subscription.notes;
|
notes.value = subscription.notes;
|
||||||
|
|
||||||
|
const notifications = document.querySelector("#notifications");
|
||||||
|
notifications.checked = subscription.notify;
|
||||||
|
|
||||||
const deleteButton = document.querySelector("#deletesub");
|
const deleteButton = document.querySelector("#deletesub");
|
||||||
deleteButton.style = 'display: block';
|
deleteButton.style = 'display: block';
|
||||||
deleteButton.setAttribute("onClick", `deleteSubscription(${subscription.id})`);
|
deleteButton.setAttribute("onClick", `deleteSubscription(${subscription.id})`);
|
||||||
|
|||||||
@ -468,6 +468,86 @@ function addFixerKeyButton() {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function saveNotificationsButton() {
|
||||||
|
const button = document.getElementById("saveNotifications");
|
||||||
|
button.disabled = true;
|
||||||
|
|
||||||
|
const enabled = document.getElementById("notifications").checked ? 1 : 0;
|
||||||
|
const days = document.getElementById("days").value;
|
||||||
|
const smtpAddress = document.getElementById("smtpaddress").value;
|
||||||
|
const smtpPort = document.getElementById("smtpport").value;
|
||||||
|
const smtpUsername = document.getElementById("smtpusername").value;
|
||||||
|
const smtpPassword = document.getElementById("smtppassword").value;
|
||||||
|
|
||||||
|
const data = {
|
||||||
|
enabled: enabled,
|
||||||
|
days: days,
|
||||||
|
smtpaddress: smtpAddress,
|
||||||
|
smtpport: smtpPort,
|
||||||
|
smtpusername: smtpUsername,
|
||||||
|
smtppassword: smtpPassword
|
||||||
|
};
|
||||||
|
|
||||||
|
fetch('/endpoints/notifications/save.php', {
|
||||||
|
method: 'POST',
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/json'
|
||||||
|
},
|
||||||
|
body: JSON.stringify(data)
|
||||||
|
})
|
||||||
|
.then(response => response.json())
|
||||||
|
.then(data => {
|
||||||
|
if (data.success) {
|
||||||
|
showSuccessMessage("Notification settings saved successfully.");
|
||||||
|
} else {
|
||||||
|
showErrorMessage(data.errorMessage);
|
||||||
|
}
|
||||||
|
button.disabled = false;
|
||||||
|
})
|
||||||
|
.catch(error => {
|
||||||
|
showErrorMessage("Error saving notification data");
|
||||||
|
button.disabled = false;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function testNotificationButton() {
|
||||||
|
const button = document.getElementById("testNotifications");
|
||||||
|
button.disabled = true;
|
||||||
|
|
||||||
|
const smtpAddress = document.getElementById("smtpaddress").value;
|
||||||
|
const smtpPort = document.getElementById("smtpport").value;
|
||||||
|
const smtpUsername = document.getElementById("smtpusername").value;
|
||||||
|
const smtpPassword = document.getElementById("smtppassword").value;
|
||||||
|
|
||||||
|
const data = {
|
||||||
|
smtpaddress: smtpAddress,
|
||||||
|
smtpport: smtpPort,
|
||||||
|
smtpusername: smtpUsername,
|
||||||
|
smtppassword: smtpPassword
|
||||||
|
};
|
||||||
|
|
||||||
|
fetch('/endpoints/notifications/sendtestmail.php', {
|
||||||
|
method: 'POST',
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/json'
|
||||||
|
},
|
||||||
|
body: JSON.stringify(data)
|
||||||
|
})
|
||||||
|
.then(response => response.json())
|
||||||
|
.then(data => {
|
||||||
|
if (data.success) {
|
||||||
|
showSuccessMessage("Notification sent successfully.");
|
||||||
|
} else {
|
||||||
|
showErrorMessage(data.errorMessage);
|
||||||
|
}
|
||||||
|
button.disabled = false;
|
||||||
|
})
|
||||||
|
.catch(error => {
|
||||||
|
showErrorMessage("Error sending notification");
|
||||||
|
button.disabled = false;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
function switchTheme() {
|
function switchTheme() {
|
||||||
const darkThemeCss = document.querySelector("#dark-theme");
|
const darkThemeCss = document.querySelector("#dark-theme");
|
||||||
darkThemeCss.disabled = !darkThemeCss.disabled;
|
darkThemeCss.disabled = !darkThemeCss.disabled;
|
||||||
|
|||||||
71
settings.php
71
settings.php
@ -134,6 +134,75 @@
|
|||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
|
<?php
|
||||||
|
$sql = "SELECT * FROM notifications LIMIT 1";
|
||||||
|
$result = $db->query($sql);
|
||||||
|
|
||||||
|
$rowCount = 0;
|
||||||
|
while ($row = $result->fetchArray(SQLITE3_ASSOC)) {
|
||||||
|
$notifications = $row;
|
||||||
|
$rowCount++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($rowCount == 0) {
|
||||||
|
$notifications['enabled'] = false;
|
||||||
|
$notifications['days'] = 1;
|
||||||
|
$notifications['smtp_address'] = "";
|
||||||
|
$notifications['smtp_port'] = "";
|
||||||
|
$notifications['smtp_username'] = "";
|
||||||
|
$notifications['smtp_password'] = "";
|
||||||
|
}
|
||||||
|
|
||||||
|
?>
|
||||||
|
|
||||||
|
<section class="account-section">
|
||||||
|
<header>
|
||||||
|
<h2>Notifications</h2>
|
||||||
|
</header>
|
||||||
|
<div class="account-notifications">
|
||||||
|
<div class="form-group-inline">
|
||||||
|
<input type="checkbox" id="notifications" name="notifications" <?= $notifications['enabled'] ? "checked" : "" ?>>
|
||||||
|
<label for="notifications">Enable email notifications</label>
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="days">Notify me: </label>
|
||||||
|
<select name="days" id="days">
|
||||||
|
<?php
|
||||||
|
for ($i = 1; $i <= 7; $i++) {
|
||||||
|
$dayText = $i > 1 ? "days" : "day";
|
||||||
|
$selected = $i == $notifications['days'] ? "selected" : "";
|
||||||
|
?>
|
||||||
|
<option value="<?= $i ?>" <?= $selected ?>>
|
||||||
|
<?= $i ?> <?= $dayText ?> before
|
||||||
|
</option>
|
||||||
|
<?php
|
||||||
|
}
|
||||||
|
?>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
<div class="form-group-inline">
|
||||||
|
<input type="text" name="smtpaddress" id="smtpaddress" placeholder="SMTP Address" value="<?= $notifications['smtp_address'] ?>" />
|
||||||
|
<input type="text" name="smtpport" id="smtpport" placeholder="Port" class="one-third" value="<?= $notifications['smtp_port'] ?>" />
|
||||||
|
</div>
|
||||||
|
<div class="form-group-inline">
|
||||||
|
<input type="text" name="smtpusername" id="smtpusername" placeholder="SMTP Username" value="<?= $notifications['smtp_username'] ?>" />
|
||||||
|
</div>
|
||||||
|
<div class="form-group-inline">
|
||||||
|
<input type="password" name="smtppassword" id="smtppassword" placeholder="SMTP Password" value="<?= $notifications['smtp_password'] ?>" />
|
||||||
|
</div>
|
||||||
|
<div class="settings-notes">
|
||||||
|
<p>
|
||||||
|
<i class="fa-solid fa-circle-info"></i> SMTP Password is transmitted and stored in plaintext.
|
||||||
|
For security, please create an account just for this.</p>
|
||||||
|
<p>
|
||||||
|
</div>
|
||||||
|
<div class="buttons">
|
||||||
|
<input type="button" class="secondary-button" value="Test" id="testNotifications" onClick="testNotificationButton()"/>
|
||||||
|
<input type="submit" value="Save" id="saveNotifications" onClick="saveNotificationsButton()"/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
<?php
|
<?php
|
||||||
$sql = "SELECT * FROM categories";
|
$sql = "SELECT * FROM categories";
|
||||||
$result = $db->query($sql);
|
$result = $db->query($sql);
|
||||||
@ -436,7 +505,7 @@
|
|||||||
<h2>About and Credits</h2>
|
<h2>About and Credits</h2>
|
||||||
</header>
|
</header>
|
||||||
<div class="credits-list">
|
<div class="credits-list">
|
||||||
<p>Wallos v0.9</p>
|
<p>Wallos v1.0</p>
|
||||||
<p>License:
|
<p>License:
|
||||||
<span>
|
<span>
|
||||||
GPLv3
|
GPLv3
|
||||||
|
|||||||
@ -317,10 +317,6 @@ main > .contain {
|
|||||||
margin-bottom: 0px;
|
margin-bottom: 0px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.account-section .account-settings-list .form-group-inline label {
|
|
||||||
font-size: 16px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.user-form {
|
.user-form {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
@ -424,13 +420,18 @@ main > .contain {
|
|||||||
.account-members .buttons,
|
.account-members .buttons,
|
||||||
.account-currencies .buttons,
|
.account-currencies .buttons,
|
||||||
.account-fixer .buttons,
|
.account-fixer .buttons,
|
||||||
.account-categories .buttons {
|
.account-categories .buttons,
|
||||||
|
.account-notifications .buttons {
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: flex-end;
|
justify-content: flex-end;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
gap: 30px;
|
gap: 30px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.account-notifications .buttons {
|
||||||
|
gap: 15px;
|
||||||
|
}
|
||||||
|
|
||||||
.image-button {
|
.image-button {
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
border: none;
|
border: none;
|
||||||
@ -563,7 +564,7 @@ label {
|
|||||||
|
|
||||||
.form-group-inline label {
|
.form-group-inline label {
|
||||||
font-weight: 300;
|
font-weight: 300;
|
||||||
font-size: 13px;
|
font-size: 16px;
|
||||||
margin-bottom: 0px;
|
margin-bottom: 0px;
|
||||||
margin-left: 0px;
|
margin-left: 0px;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
@ -591,6 +592,10 @@ select {
|
|||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.one-third {
|
||||||
|
max-width: 33%;
|
||||||
|
}
|
||||||
|
|
||||||
select {
|
select {
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
height: 50px;
|
height: 50px;
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user