feat: support automatic dark mode

refactor: run linter and cleanup php files
fix: not every payment cycle was shown on the calendar
feat: also show previous payments on the calendar for the current month
This commit is contained in:
Miguel Ribeiro
2024-06-26 18:11:37 +02:00
committed by GitHub
parent 15fc8f1238
commit c2e85d6e10
101 changed files with 4538 additions and 4152 deletions

View File

@@ -1,5 +1,5 @@
<?php
require_once 'includes/header.php';
require_once 'includes/header.php';
?>
<section class="contain">
@@ -10,25 +10,27 @@
</header>
<div class="credits-list">
<p>Wallos <?= $version ?></p>
<p><?= translate('license', $i18n) ?>:
<p><?= translate('license', $i18n) ?>:
<span>
GPLv3
<a href="https://www.gnu.org/licenses/gpl-3.0.en.html" target="_blank" title="<?= translate('external_url', $i18n) ?>">
<a href="https://www.gnu.org/licenses/gpl-3.0.en.html" target="_blank"
title="<?= translate('external_url', $i18n) ?>">
<i class="fa-solid fa-arrow-up-right-from-square"></i>
</a>
</span>
</p>
<p>
<?= translate('issues_and_requests', $i18n) ?>:
<?= translate('issues_and_requests', $i18n) ?>:
<span>
GitHub
<a href="https://github.com/ellite/Wallos/issues" target="_blank" title="<?= translate('external_url', $i18n) ?>">
<a href="https://github.com/ellite/Wallos/issues" target="_blank"
title="<?= translate('external_url', $i18n) ?>">
<i class="fa-solid fa-arrow-up-right-from-square"></i>
</a>
</span>
</p>
<p>
<?= translate('the_author', $i18n) ?>:
<?= translate('the_author', $i18n) ?>:
<span>
https://henrique.pt
<a href="https://henrique.pt/" target="_blank" title="<?= translate('external_url', $i18n) ?>">
@@ -37,25 +39,27 @@
</span>
</p>
<p>
<?= translate('icons', $i18n) ?>:
<?= translate('icons', $i18n) ?>:
<span>
https://www.streamlinehq.com/freebies/plump-flat-free
<a href="https://www.streamlinehq.com/freebies/plump-flat-free" target="_blank" title="<?= translate('external_url', $i18n) ?>">
<a href="https://www.streamlinehq.com/freebies/plump-flat-free" target="_blank"
title="<?= translate('external_url', $i18n) ?>">
<i class="fa-solid fa-arrow-up-right-from-square"></i>
</a>
</span>
</p>
<p>
<?= translate('payment_icons', $i18n) ?>:
<?= translate('payment_icons', $i18n) ?>:
<span>
https://www.figma.com/file/5IMW8JfoXfB5GRlPNdTyeg/Credit-Cards-and-Payment-Methods-Icons-(Community)
<a href="https://www.figma.com/file/5IMW8JfoXfB5GRlPNdTyeg/Credit-Cards-and-Payment-Methods-Icons-(Community)" target="_blank" title="<?= translate('external_url', $i18n) ?>">
<a href="https://www.figma.com/file/5IMW8JfoXfB5GRlPNdTyeg/Credit-Cards-and-Payment-Methods-Icons-(Community)"
target="_blank" title="<?= translate('external_url', $i18n) ?>">
<i class="fa-solid fa-arrow-up-right-from-square"></i>
</a>
</span>
</p>
<p>
Chart.js:
Chart.js:
<span>
https://www.chartjs.org/
<a href="https://www.chartjs.org/" target="_blank" title="<?= translate('external_url', $i18n) ?>">
@@ -69,5 +73,5 @@
</section>
<?php
require_once 'includes/footer.php';
require_once 'includes/footer.php';
?>

179
admin.php
View File

@@ -1,27 +1,27 @@
<?php
require_once 'includes/header.php';
require_once 'includes/header.php';
if ($isAdmin != 1) {
header('Location: index.php');
exit;
}
if ($isAdmin != 1) {
header('Location: index.php');
exit;
}
// get admin settings from admin table
$stmt = $db->prepare('SELECT * FROM admin');
$result = $stmt->execute();
$settings = $result->fetchArray(SQLITE3_ASSOC);
// get admin settings from admin table
$stmt = $db->prepare('SELECT * FROM admin');
$result = $stmt->execute();
$settings = $result->fetchArray(SQLITE3_ASSOC);
// get user accounts
$stmt = $db->prepare('SELECT id, username, email FROM user ORDER BY id ASC');
$result = $stmt->execute();
// get user accounts
$stmt = $db->prepare('SELECT id, username, email FROM user ORDER BY id ASC');
$result = $stmt->execute();
$users = [];
while ($row = $result->fetchArray(SQLITE3_ASSOC)) {
$users[] = $row;
}
$userCount = is_array($users) ? count($users) : 0;
$users = [];
while ($row = $result->fetchArray(SQLITE3_ASSOC)) {
$users[] = $row;
}
$userCount = is_array($users) ? count($users) : 0;
$loginDisabledAllowed = $userCount == 1 && $settings['registrations_open'] == 0;
$loginDisabledAllowed = $userCount == 1 && $settings['registrations_open'] == 0;
?>
<section class="contain settings">
@@ -43,28 +43,30 @@
<p>
<i class="fa-solid fa-circle-info"></i>
<?= translate('max_users_info', $i18n) ?>
</p><p>
</p>
<p>
<i class="fa-solid fa-circle-info"></i>
By enabling user registrations, the setting to disable login will be unavailable.
</p>
</div>
<div class="form-group-inline">
<input type="checkbox" id="requireEmail" <?= $settings['require_email_verification'] ? 'checked' : '' ?> <?= empty($settings['smtp_address']) ? 'disabled' : '' ?>/>
<input type="checkbox" id="requireEmail" <?= $settings['require_email_verification'] ? 'checked' : '' ?>
<?= empty($settings['smtp_address']) ? 'disabled' : '' ?> />
<label for="requireEmail">
<?= translate('require_email_verification', $i18n) ?>
</label>
</div>
<?php
if (empty($settings['smtp_address'])) {
?>
<div class="settings-notes">
<p>
<i class="fa-solid fa-circle-info"></i>
<?= translate('configure_smtp_settings_to_enable', $i18n) ?>
</p>
</div>
<?php
}
if (empty($settings['smtp_address'])) {
?>
<div class="settings-notes">
<p>
<i class="fa-solid fa-circle-info"></i>
<?= translate('configure_smtp_settings_to_enable', $i18n) ?>
</p>
</div>
<?php
}
?>
<div class="form-group">
<label for="serverUrl"><?= translate('server_url', $i18n) ?></label>
@@ -82,7 +84,8 @@
</div>
<hr>
<div class="form-group-inline">
<input type="checkbox" id="disableLogin" <?= $settings['login_disabled'] ? 'checked' : '' ?> <?= $loginDisabledAllowed ? '' : 'disabled' ?> />
<input type="checkbox" id="disableLogin" <?= $settings['login_disabled'] ? 'checked' : '' ?>
<?= $loginDisabledAllowed ? '' : 'disabled' ?> />
<label for="disableLogin"><?= translate('disable_login', $i18n) ?></label>
</div>
<div class="settings-notes">
@@ -96,64 +99,68 @@
</p>
</div>
<div class="buttons">
<input type="submit" class="thin" value="<?= translate('save', $i18n) ?>" id="saveAccountRegistrations" onClick="saveAccountRegistrationsButton()"/>
<input type="submit" class="thin" value="<?= translate('save', $i18n) ?>" id="saveAccountRegistrations"
onClick="saveAccountRegistrationsButton()" />
</div>
</div>
</section>
<?php
if ($userCount >= 0) {
?>
if ($userCount >= 0) {
?>
<section class="account-section">
<header>
<h2><?= translate('user_management', $i18n) ?></h2>
</header>
<div class="user-list">
<?php
<section class="account-section">
<header>
<h2><?= translate('user_management', $i18n) ?></h2>
</header>
<div class="user-list">
<?php
foreach ($users as $user) {
$userIcon = $user['id'] == 1 ? 'fa-user-tie' : 'fa-id-badge';
?>
<div class="form-group-inline" data-userid="<?= $user['id'] ?>">
<div class="user-list-row">
<div title="<?= translate('username', $i18n) ?>"><i class="fa-solid <?= $userIcon ?>"></i><?= $user['username'] ?></div>
<div title="<?= translate('username', $i18n) ?>"><i
class="fa-solid <?= $userIcon ?>"></i><?= $user['username'] ?></div>
<div title="<?= translate('email', $i18n) ?>"><i class="fa-solid fa-envelope"></i>
<a href="mailto:<?= $user['email']?>"><?= $user['email']?></a>
<a href="mailto:<?= $user['email'] ?>"><?= $user['email'] ?></a>
</div>
</div>
<div>
<?php
if ($user['id'] != 1) {
?>
<button class="image-button medium" onClick="removeUser(<?= $user['id'] ?>)">
<img src="images/siteicons/<?= $colorTheme ?>/delete.png" title="<?= translate('delete_user', $i18n) ?>">
</button>
<?php
} else {
?>
<button class="image-button medium disabled" disabled>
<img src="images/siteicons/<?= $colorTheme ?>/delete.png" title="<?= translate('delete_user', $i18n) ?>">
</button>
<?php
}
if ($user['id'] != 1) {
?>
</div>
<button class="image-button medium" onClick="removeUser(<?= $user['id'] ?>)">
<img src="images/siteicons/<?= $colorTheme ?>/delete.png"
title="<?= translate('delete_user', $i18n) ?>">
</button>
<?php
} else {
?>
<button class="image-button medium disabled" disabled>
<img src="images/siteicons/<?= $colorTheme ?>/delete.png"
title="<?= translate('delete_user', $i18n) ?>">
</button>
<?php
}
?>
</div>
</div>
<?php
}
?>
</div>
<div class="settings-notes">
<p>
<i class="fa-solid fa-circle-info"></i>
<?= translate('delete_user_info', $i18n) ?>
</p>
</div>
</section>
?>
</div>
<div class="settings-notes">
<p>
<i class="fa-solid fa-circle-info"></i>
<?= translate('delete_user_info', $i18n) ?>
</p>
</div>
</section>
<?php
}
<?php
}
?>
<section class="account-section">
@@ -162,8 +169,10 @@
</header>
<div class="admin-form">
<div class="form-group-inline">
<input type="text" name="smtpaddress" id="smtpaddress" placeholder="<?= translate('smtp_address', $i18n) ?>" value="<?= $settings['smtp_address'] ?>" />
<input type="text" name="smtpport" id="smtpport" placeholder="<?= translate('port', $i18n) ?>" class="one-third" value="<?= $settings['smtp_port'] ?>" />
<input type="text" name="smtpaddress" id="smtpaddress"
placeholder="<?= translate('smtp_address', $i18n) ?>" value="<?= $settings['smtp_address'] ?>" />
<input type="text" name="smtpport" id="smtpport" placeholder="<?= translate('port', $i18n) ?>"
class="one-third" value="<?= $settings['smtp_port'] ?>" />
</div>
<div class="form-group-inline">
<input type="radio" name="encryption" id="encryptiontls" value="tls" <?= empty($settings['encryption']) || $settings['encryption'] == "tls" ? "checked" : "" ?> />
@@ -172,13 +181,16 @@
<label for="encryptionssl"><?= translate('ssl', $i18n) ?></label>
</div>
<div class="form-group-inline">
<input type="text" name="smtpusername" id="smtpusername" placeholder="<?= translate('smtp_username', $i18n) ?>" value="<?= $settings['smtp_username'] ?>" />
<input type="text" name="smtpusername" id="smtpusername"
placeholder="<?= translate('smtp_username', $i18n) ?>" value="<?= $settings['smtp_username'] ?>" />
</div>
<div class="form-group-inline">
<input type="password" name="smtppassword" id="smtppassword" placeholder="<?= translate('smtp_password', $i18n) ?>" value="<?= $settings['smtp_password'] ?>" />
<input type="password" name="smtppassword" id="smtppassword"
placeholder="<?= translate('smtp_password', $i18n) ?>" value="<?= $settings['smtp_password'] ?>" />
</div>
<div class="form-group-inline">
<input type="text" name="fromemail" id="fromemail" placeholder="<?= translate('from_email', $i18n) ?>" value="<?= $settings['from_email'] ?>" />
<input type="text" name="fromemail" id="fromemail" placeholder="<?= translate('from_email', $i18n) ?>"
value="<?= $settings['from_email'] ?>" />
</div>
<div class="settings-notes">
<p>
@@ -190,8 +202,10 @@
</p>
</div>
<div class="buttons">
<input type="button" class="secondary-button thin" value="<?= translate('test', $i18n) ?>" id="testSmtpSettingsButton" onClick="testSmtpSettingsButton()"/>
<input type="submit" class="thin" value="<?= translate('save', $i18n) ?>" id="saveSmtpSettingsButton" onClick="saveSmtpSettingsButton()"/>
<input type="button" class="secondary-button thin" value="<?= translate('test', $i18n) ?>"
id="testSmtpSettingsButton" onClick="testSmtpSettingsButton()" />
<input type="submit" class="thin" value="<?= translate('save', $i18n) ?>" id="saveSmtpSettingsButton"
onClick="saveSmtpSettingsButton()" />
</div>
</div>
</section>
@@ -203,11 +217,14 @@
</header>
<div class="form-group-inline">
<div>
<input type="button" class="button thin" value="<?= translate('backup', $i18n) ?>" id="backupDB" onClick="backupDB()"/>
</div>
<input type="button" class="button thin" value="<?= translate('backup', $i18n) ?>" id="backupDB"
onClick="backupDB()" />
</div>
<div>
<input type="button" class="secondary-button thin" value="<?= translate('restore', $i18n) ?>" id="restoreDB" onClick="openRestoreDBFileSelect()" />
<input type="file" name="restoreDBFile" id="restoreDBFile" style="display: none;" onChange="restoreDB()" accept=".zip">
<input type="button" class="secondary-button thin" value="<?= translate('restore', $i18n) ?>"
id="restoreDB" onClick="openRestoreDBFileSelect()" />
<input type="file" name="restoreDBFile" id="restoreDBFile" style="display: none;" onChange="restoreDB()"
accept=".zip">
</div>
</div>
<div class="settings-notes">
@@ -215,12 +232,12 @@
<i class="fa-solid fa-circle-info"></i>
<?= translate('restore_info', $i18n) ?>
</p>
</div>
</div>
</section>
</section>
<script src="scripts/admin.js?<?= $version ?>"></script>
<?php
require_once 'includes/footer.php';
require_once 'includes/footer.php';
?>

View File

View File

@@ -1,22 +1,6 @@
<?php
require_once 'includes/header.php';
function getCycleDays($cycleId)
{
switch ($cycleId) {
case 1:
return 1; // Daily
case 2:
return 7; // Weekly
case 3:
return 30; // Monthly
case 4:
return 365; // Yearly
default:
return 0;
}
}
$currentMonth = date('m');
$currentYear = date('Y');
$sameAsCurrent = false;
@@ -129,18 +113,44 @@ $yearsToLoad = $calendarYear - $currentYear + 1;
<?php
foreach ($subscriptions as $subscription) {
$nextPaymentDate = strtotime($subscription['next_payment']);
$cycleDays = getCycleDays($subscription['cycle']);
$cycle = $subscription['cycle']; // Integer from 1 to 4
$frequency = $subscription['frequency'];
// Calculate the end date for displaying this subscription, for simplicity, we'll assume a 2-year range
$endDate = strtotime("+" . $yearsToLoad . " years", $nextPaymentDate);
// Determine the strtotime increment string based on cycle
switch ($cycle) {
case 1: // Days
$incrementString = "+{$frequency} days";
break;
case 2: // Weeks
$incrementString = "+{$frequency} weeks";
break;
case 3: // Months
$incrementString = "+{$frequency} months";
break;
case 4: // Years
$incrementString = "+{$frequency} years";
break;
default:
$incrementString = "+{$frequency} months"; // Default case, if needed
}
for ($date = $nextPaymentDate; $date <= $endDate; $date = strtotime("+{$frequency} month", $date)) {
// Calculate the start of the month
$startOfMonth = strtotime($calendarYear . '-' . str_pad($calendarMonth, 2, '0', STR_PAD_LEFT) . '-01');
// Find the first payment date of the month by moving backwards
$startDate = $nextPaymentDate;
while ($startDate > $startOfMonth) {
$startDate = strtotime("-" . $incrementString, $startDate);
}
for ($date = $startDate; $date <= $endDate; $date = strtotime($incrementString, $date)) {
if (date('Y-m', $date) == $calendarYear . '-' . str_pad($calendarMonth, 2, '0', STR_PAD_LEFT)) {
if (date('d', $date) == $day) {
?>
<div class="calendar-subscription-title" onClick="openSubscriptionModal(<?= $subscription['id'] ?>)">
<?= $subscription['name'] ?>
<?= htmlspecialchars($subscription['name']) ?>
</div>
<?php
}
@@ -171,17 +181,44 @@ $yearsToLoad = $calendarYear - $currentYear + 1;
<?php
foreach ($subscriptions as $subscription) {
$nextPaymentDate = strtotime($subscription['next_payment']);
$cycleDays = getCycleDays($subscription['cycle']); // Function to get the number of days based on the cycle id
$cycle = $subscription['cycle']; // Integer from 1 to 4
$frequency = $subscription['frequency'];
$endDate = strtotime("+" . $yearsToLoad . " years", $nextPaymentDate);
for ($date = $nextPaymentDate; $date <= $endDate; $date = strtotime("+{$frequency} month", $date)) {
// Determine the strtotime increment string based on cycle
switch ($cycle) {
case 1: // Days
$incrementString = "+{$frequency} days";
break;
case 2: // Weeks
$incrementString = "+{$frequency} weeks";
break;
case 3: // Months
$incrementString = "+{$frequency} months";
break;
case 4: // Years
$incrementString = "+{$frequency} years";
break;
default:
$incrementString = "+{$frequency} months"; // Default case, if needed
}
// Calculate the start of the month
$startOfMonth = strtotime($calendarYear . '-' . str_pad($calendarMonth, 2, '0', STR_PAD_LEFT) . '-01');
// Find the first payment date of the month by moving backwards
$startDate = $nextPaymentDate;
while ($startDate > $startOfMonth) {
$startDate = strtotime("-" . $incrementString, $startDate);
}
for ($date = $startDate; $date <= $endDate; $date = strtotime($incrementString, $date)) {
if (date('Y-m', $date) == $calendarYear . '-' . str_pad($calendarMonth, 2, '0', STR_PAD_LEFT)) {
if (date('d', $date) == $day) {
?>
<div class="calendar-subscription-title" onClick="openSubscriptionModal(<?= $subscription['id'] ?>)">
<?= $subscription['name'] ?>
<?= htmlspecialchars($subscription['name']) ?>
</div>
<?php
}

View File

@@ -73,7 +73,7 @@ if ($_SERVER["REQUEST_METHOD"] === "POST") {
// Delete payment methods
$stmt = $db->prepare('DELETE FROM payment_methods WHERE user_id = :id');
$stmt->bindValue(':id', $userId, SQLITE3_INTEGER);
$result = $stmt->execute();
$result = $stmt->execute();
// Delete email notifications
$stmt = $db->prepare('DELETE FROM email_notifications WHERE user_id = :id');
@@ -114,7 +114,7 @@ if ($_SERVER["REQUEST_METHOD"] === "POST") {
$stmt = $db->prepare('DELETE FROM email_verification WHERE user_id = :id');
$stmt->bindValue(':id', $userId, SQLITE3_INTEGER);
$result = $stmt->execute();
die(json_encode([
"success" => true,
"message" => translate('success', $i18n)

View File

@@ -23,7 +23,7 @@ if (isset($_SESSION['loggedin']) && $_SESSION['loggedin'] === true) {
$stmtInsert->bindParam(':order', $order, SQLITE3_INTEGER);
$stmtInsert->bindParam(':userId', $userId, SQLITE3_INTEGER);
$resultInsert = $stmtInsert->execute();
if ($resultInsert) {
$categoryId = $db->lastInsertRowID();
$response = [
@@ -120,4 +120,4 @@ if (isset($_SESSION['loggedin']) && $_SESSION['loggedin'] === true) {
echo translate('error', $i18n);
}
?>
?>

View File

@@ -20,7 +20,7 @@ if (isset($_SESSION['loggedin']) && $_SESSION['loggedin'] === true) {
"success" => true,
"message" => translate("sort_order_saved", $i18n)
];
echo json_encode($response);
echo json_encode($response);
} else {
$response = [
"success" => false,

View File

@@ -1,4 +1,4 @@
<?php
<?php
$databaseFile = __DIR__ . '/../../db/wallos.db';
@@ -276,4 +276,4 @@ if (!file_exists($databaseFile)) {
}
?>
?>

View File

File diff suppressed because it is too large Load Diff

View File

@@ -1,82 +1,82 @@
<?php
use PHPMailer\PHPMailer\PHPMailer;
use PHPMailer\PHPMailer\SMTP;
use PHPMailer\PHPMailer\Exception;
use PHPMailer\PHPMailer\PHPMailer;
use PHPMailer\PHPMailer\SMTP;
use PHPMailer\PHPMailer\Exception;
require_once __DIR__ . '/../../includes/connect_endpoint_crontabs.php';
require_once __DIR__ . '/../../includes/connect_endpoint_crontabs.php';
$query = "SELECT * FROM admin";
$stmt = $db->prepare($query);
$result = $stmt->execute();
$admin = $result->fetchArray(SQLITE3_ASSOC);
$query = "SELECT * FROM admin";
$stmt = $db->prepare($query);
$result = $stmt->execute();
$admin = $result->fetchArray(SQLITE3_ASSOC);
$query = "SELECT * FROM password_resets WHERE email_sent = 0";
$stmt = $db->prepare($query);
$result = $stmt->execute();
$query = "SELECT * FROM password_resets WHERE email_sent = 0";
$stmt = $db->prepare($query);
$result = $stmt->execute();
$rows = [];
while ($row = $result->fetchArray(SQLITE3_ASSOC)) {
$rows[] = $row;
}
$rows = [];
while ($row = $result->fetchArray(SQLITE3_ASSOC)) {
$rows[] = $row;
}
if ($rows) {
if ($admin['smtp_address'] && $admin['smtp_port'] && $admin['smtp_username'] && $admin['smtp_password'] && $admin['encryption']) {
// There are SMTP settings
$smtpAddress = $admin['smtp_address'];
$smtpPort = $admin['smtp_port'];
$smtpUsername = $admin['smtp_username'];
$smtpPassword = $admin['smtp_password'];
$fromEmail = empty($admin['from_email']) ? 'wallos@wallosapp.com' : $admin['from_email'];
$encryption = $admin['encryption'];
$server_url = $admin['server_url'];
if ($rows) {
if ($admin['smtp_address'] && $admin['smtp_port'] && $admin['smtp_username'] && $admin['smtp_password'] && $admin['encryption']) {
// There are SMTP settings
$smtpAddress = $admin['smtp_address'];
$smtpPort = $admin['smtp_port'];
$smtpUsername = $admin['smtp_username'];
$smtpPassword = $admin['smtp_password'];
$fromEmail = empty($admin['from_email']) ? 'wallos@wallosapp.com' : $admin['from_email'];
$encryption = $admin['encryption'];
$server_url = $admin['server_url'];
require __DIR__ . '/../../libs/PHPMailer/PHPMailer.php';
require __DIR__ . '/../../libs/PHPMailer/SMTP.php';
require __DIR__ . '/../../libs/PHPMailer/Exception.php';
require __DIR__ . '/../../libs/PHPMailer/PHPMailer.php';
require __DIR__ . '/../../libs/PHPMailer/SMTP.php';
require __DIR__ . '/../../libs/PHPMailer/Exception.php';
$mail = new PHPMailer(true);
$mail->isSMTP();
$mail->Host = $smtpAddress;
$mail->SMTPAuth = true;
$mail->Username = $smtpUsername;
$mail->Password = $smtpPassword;
$mail->SMTPSecure = $encryption;
$mail->Port = $smtpPort;
$mail->setFrom($fromEmail);
$mail = new PHPMailer(true);
$mail->isSMTP();
$mail->Host = $smtpAddress;
$mail->SMTPAuth = true;
$mail->Username = $smtpUsername;
$mail->Password = $smtpPassword;
$mail->SMTPSecure = $encryption;
$mail->Port = $smtpPort;
$mail->setFrom($fromEmail);
try {
foreach ($rows as $user) {
$mail->addAddress($user['email']);
$mail->isHTML(true);
$mail->Subject = 'Wallos - Reset Password';
$mail->Body = '<img src="' . $server_url . '/images/siteicons/blue/wallos.png" alt="Logo" />
try {
foreach ($rows as $user) {
$mail->addAddress($user['email']);
$mail->isHTML(true);
$mail->Subject = 'Wallos - Reset Password';
$mail->Body = '<img src="' . $server_url . '/images/siteicons/blue/wallos.png" alt="Logo" />
<br>
A password reset was requested for your account.
<br>
Please click the following link to reset your password: <a href="' . $server_url . '/passwordreset.php?email=' . $user['email'] . '&token=' . $user['token'] . '">Reset Password</a>';
$mail->send();
$query = "UPDATE password_resets SET email_sent = 1 WHERE id = :id";
$stmt = $db->prepare($query);
$stmt->bindParam(':id', $user['id'], SQLITE3_INTEGER);
$stmt->execute();
$mail->send();
$mail->clearAddresses();
$query = "UPDATE password_resets SET email_sent = 1 WHERE id = :id";
$stmt = $db->prepare($query);
$stmt->bindParam(':id', $user['id'], SQLITE3_INTEGER);
$stmt->execute();
echo "Password reset email sent to " . $user['email'] . "<br>";
$mail->clearAddresses();
echo "Password reset email sent to " . $user['email'] . "<br>";
}
} catch (Exception $e) {
echo "Message could not be sent. Mailer Error: {$mail->ErrorInfo} <br>";
}
} else {
// There are no SMTP settings
exit();
} catch (Exception $e) {
echo "Message could not be sent. Mailer Error: {$mail->ErrorInfo} <br>";
}
} else {
// There are no password reset emails to be sent
// There are no SMTP settings
exit();
}
} else {
// There are no password reset emails to be sent
exit();
}
?>

View File

@@ -1,85 +1,85 @@
<?php
use PHPMailer\PHPMailer\PHPMailer;
use PHPMailer\PHPMailer\SMTP;
use PHPMailer\PHPMailer\Exception;
use PHPMailer\PHPMailer\PHPMailer;
use PHPMailer\PHPMailer\SMTP;
use PHPMailer\PHPMailer\Exception;
require_once __DIR__ . '/../../includes/connect_endpoint_crontabs.php';
require_once __DIR__ . '/../../includes/connect_endpoint_crontabs.php';
$query = "SELECT * FROM admin";
$stmt = $db->prepare($query);
$result = $stmt->execute();
$admin = $result->fetchArray(SQLITE3_ASSOC);
$query = "SELECT * FROM admin";
$stmt = $db->prepare($query);
$result = $stmt->execute();
$admin = $result->fetchArray(SQLITE3_ASSOC);
if ($admin['require_email_verification'] == 0) {
die("Email verification is not required.");
}
if ($admin['require_email_verification'] == 0) {
die("Email verification is not required.");
}
$query = "SELECT * FROM email_verification WHERE email_sent = 0";
$stmt = $db->prepare($query);
$result = $stmt->execute();
$query = "SELECT * FROM email_verification WHERE email_sent = 0";
$stmt = $db->prepare($query);
$result = $stmt->execute();
$rows = [];
while ($row = $result->fetchArray(SQLITE3_ASSOC)) {
$rows[] = $row;
}
$rows = [];
while ($row = $result->fetchArray(SQLITE3_ASSOC)) {
$rows[] = $row;
}
if ($rows) {
if ($admin['smtp_address'] && $admin['smtp_port'] && $admin['smtp_username'] && $admin['smtp_password'] && $admin['encryption']) {
// There are SMTP settings
$smtpAddress = $admin['smtp_address'];
$smtpPort = $admin['smtp_port'];
$smtpUsername = $admin['smtp_username'];
$smtpPassword = $admin['smtp_password'];
$fromEmail = empty($admin['from_email']) ? 'wallos@wallosapp.com' : $admin['from_email'];
$encryption = $admin['encryption'];
$server_url = $admin['server_url'];
if ($rows) {
if ($admin['smtp_address'] && $admin['smtp_port'] && $admin['smtp_username'] && $admin['smtp_password'] && $admin['encryption']) {
// There are SMTP settings
$smtpAddress = $admin['smtp_address'];
$smtpPort = $admin['smtp_port'];
$smtpUsername = $admin['smtp_username'];
$smtpPassword = $admin['smtp_password'];
$fromEmail = empty($admin['from_email']) ? 'wallos@wallosapp.com' : $admin['from_email'];
$encryption = $admin['encryption'];
$server_url = $admin['server_url'];
require __DIR__ . '/../../libs/PHPMailer/PHPMailer.php';
require __DIR__ . '/../../libs/PHPMailer/SMTP.php';
require __DIR__ . '/../../libs/PHPMailer/Exception.php';
require __DIR__ . '/../../libs/PHPMailer/PHPMailer.php';
require __DIR__ . '/../../libs/PHPMailer/SMTP.php';
require __DIR__ . '/../../libs/PHPMailer/Exception.php';
$mail = new PHPMailer(true);
$mail->isSMTP();
$mail->Host = $smtpAddress;
$mail->SMTPAuth = true;
$mail->Username = $smtpUsername;
$mail->Password = $smtpPassword;
$mail->SMTPSecure = $encryption;
$mail->Port = $smtpPort;
$mail->setFrom($fromEmail);
$mail = new PHPMailer(true);
$mail->isSMTP();
$mail->Host = $smtpAddress;
$mail->SMTPAuth = true;
$mail->Username = $smtpUsername;
$mail->Password = $smtpPassword;
$mail->SMTPSecure = $encryption;
$mail->Port = $smtpPort;
$mail->setFrom($fromEmail);
try {
foreach ($rows as $user) {
$mail->addAddress($user['email']);
$mail->isHTML(true);
$mail->Subject = 'Wallos - Email Verification';
$mail->Body = '<img src="' . $server_url . '/images/siteicons/blue/wallos.png" alt="Logo" />
try {
foreach ($rows as $user) {
$mail->addAddress($user['email']);
$mail->isHTML(true);
$mail->Subject = 'Wallos - Email Verification';
$mail->Body = '<img src="' . $server_url . '/images/siteicons/blue/wallos.png" alt="Logo" />
<br>
Registration on Wallos was successful.
<br>
Please click the following link to verify your email: <a href="' . $server_url . '/verifyemail.php?email=' . $user['email'] . '&token=' . $user['token'] . '">Verify Email</a>';
$mail->send();
$query = "UPDATE email_verification SET email_sent = 1 WHERE id = :id";
$stmt = $db->prepare($query);
$stmt->bindParam(':id', $user['id'], SQLITE3_INTEGER);
$stmt->execute();
$mail->send();
$mail->clearAddresses();
$query = "UPDATE email_verification SET email_sent = 1 WHERE id = :id";
$stmt = $db->prepare($query);
$stmt->bindParam(':id', $user['id'], SQLITE3_INTEGER);
$stmt->execute();
echo "Verification email sent to " . $user['email'] . "<br>";
}
} catch (Exception $e) {
echo "Message could not be sent. Mailer Error: {$mail->ErrorInfo}";
$mail->clearAddresses();
echo "Verification email sent to " . $user['email'] . "<br>";
}
} else {
// There are no SMTP settings
exit();
} catch (Exception $e) {
echo "Message could not be sent. Mailer Error: {$mail->ErrorInfo}";
}
} else {
// There are no verification emails to be sent
// There are no SMTP settings
exit();
}
} else {
// There are no verification emails to be sent
exit();
}
?>

View File

@@ -1,104 +1,104 @@
<?php
require_once __DIR__ . '/../../includes/connect_endpoint_crontabs.php';
require_once __DIR__ . '/../../includes/connect_endpoint_crontabs.php';
// Get all user ids
// Get all user ids
$query = "SELECT id, username FROM user";
$query = "SELECT id, username FROM user";
$stmt = $db->prepare($query);
$usersToUpdateExchange = $stmt->execute();
while ($userToUpdateExchange = $usersToUpdateExchange->fetchArray(SQLITE3_ASSOC)) {
$userId = $userToUpdateExchange['id'];
echo "For user: " . $userToUpdateExchange['username'] . "<br />";
$query = "SELECT api_key, provider FROM fixer WHERE user_id = :userId";
$stmt = $db->prepare($query);
$usersToUpdateExchange = $stmt->execute();
$stmt->bindParam(':userId', $userId, SQLITE3_INTEGER);
$result = $stmt->execute();
while ($userToUpdateExchange = $usersToUpdateExchange->fetchArray(SQLITE3_ASSOC)) {
$userId = $userToUpdateExchange['id'];
echo "For user: " . $userToUpdateExchange['username'] . "<br />";
if ($result) {
$row = $result->fetchArray(SQLITE3_ASSOC);
$query = "SELECT api_key, provider FROM fixer WHERE user_id = :userId";
$stmt = $db->prepare($query);
$stmt->bindParam(':userId', $userId, SQLITE3_INTEGER);
$result = $stmt->execute();
if ($row) {
$apiKey = $row['api_key'];
$provider = $row['provider'];
if ($result) {
$codes = "";
$query = "SELECT id, name, symbol, code FROM currencies WHERE user_id = :userId";
$stmt = $db->prepare($query);
$stmt->bindParam(':userId', $userId, SQLITE3_INTEGER);
$result = $stmt->execute();
while ($row = $result->fetchArray(SQLITE3_ASSOC)) {
$codes .= $row['code'] . ",";
}
$codes = rtrim($codes, ',');
$query = "SELECT u.main_currency, c.code FROM user u LEFT JOIN currencies c ON u.main_currency = c.id WHERE u.id = :userId";
$stmt = $db->prepare($query);
$stmt->bindParam(':userId', $userId, SQLITE3_INTEGER);
$result = $stmt->execute();
$row = $result->fetchArray(SQLITE3_ASSOC);
if ($row) {
$apiKey = $row['api_key'];
$provider = $row['provider'];
$mainCurrencyCode = $row['code'];
$mainCurrencyId = $row['main_currency'];
$codes = "";
$query = "SELECT id, name, symbol, code FROM currencies WHERE user_id = :userId";
$stmt = $db->prepare($query);
$stmt->bindParam(':userId', $userId, SQLITE3_INTEGER);
$result = $stmt->execute();
while ($row = $result->fetchArray(SQLITE3_ASSOC)) {
$codes .= $row['code'].",";
}
$codes = rtrim($codes, ',');
$query = "SELECT u.main_currency, c.code FROM user u LEFT JOIN currencies c ON u.main_currency = c.id WHERE u.id = :userId";
$stmt = $db->prepare($query);
$stmt->bindParam(':userId', $userId, SQLITE3_INTEGER);
$result = $stmt->execute();
$row = $result->fetchArray(SQLITE3_ASSOC);
$mainCurrencyCode = $row['code'];
$mainCurrencyId = $row['main_currency'];
if ($provider === 1) {
$api_url = "https://api.apilayer.com/fixer/latest?base=EUR&symbols=" . $codes;
$context = stream_context_create([
'http' => [
'method' => 'GET',
'header' => 'apikey: ' . $apiKey,
]
]);
$response = file_get_contents($api_url, false, $context);
} else {
$api_url = "http://data.fixer.io/api/latest?access_key=". $apiKey . "&base=EUR&symbols=" . $codes;
$response = file_get_contents($api_url);
}
$apiData = json_decode($response, true);
$mainCurrencyToEUR = $apiData['rates'][$mainCurrencyCode];
if ($apiData !== null && isset($apiData['rates'])) {
foreach ($apiData['rates'] as $currencyCode => $rate) {
if ($currencyCode === $mainCurrencyCode) {
$exchangeRate = 1.0;
} else {
$exchangeRate = $rate / $mainCurrencyToEUR;
}
$updateQuery = "UPDATE currencies SET rate = :rate WHERE code = :code";
$updateStmt = $db->prepare($updateQuery);
$updateStmt->bindParam(':rate', $exchangeRate, SQLITE3_TEXT);
$updateStmt->bindParam(':code', $currencyCode, SQLITE3_TEXT);
$updateResult = $updateStmt->execute();
if (!$updateResult) {
echo "Error updating rate for currency: $currencyCode <br />";
}
}
$currentDate = new DateTime();
$formattedDate = $currentDate->format('Y-m-d');
$deleteQuery = "DELETE FROM last_exchange_update WHERE user_id = :userId";
$deleteStmt = $db->prepare($deleteQuery);
$deleteResult = $deleteStmt->execute();
$query = "INSERT INTO last_exchange_update (date, user_id) VALUES (:formattedDate, :userId)";
$stmt = $db->prepare($query);
$stmt->bindParam(':formattedDate', $formattedDate, SQLITE3_TEXT);
$stmt->bindParam(':userId', $userId, SQLITE3_INTEGER);
$result = $stmt->execute();
echo "Rates updated successfully!<br />";
}
if ($provider === 1) {
$api_url = "https://api.apilayer.com/fixer/latest?base=EUR&symbols=" . $codes;
$context = stream_context_create([
'http' => [
'method' => 'GET',
'header' => 'apikey: ' . $apiKey,
]
]);
$response = file_get_contents($api_url, false, $context);
} else {
echo "Exchange rates update skipped. No fixer.io api key provided<br />";
$apiKey = null;
$api_url = "http://data.fixer.io/api/latest?access_key=" . $apiKey . "&base=EUR&symbols=" . $codes;
$response = file_get_contents($api_url);
}
$apiData = json_decode($response, true);
$mainCurrencyToEUR = $apiData['rates'][$mainCurrencyCode];
if ($apiData !== null && isset($apiData['rates'])) {
foreach ($apiData['rates'] as $currencyCode => $rate) {
if ($currencyCode === $mainCurrencyCode) {
$exchangeRate = 1.0;
} else {
$exchangeRate = $rate / $mainCurrencyToEUR;
}
$updateQuery = "UPDATE currencies SET rate = :rate WHERE code = :code";
$updateStmt = $db->prepare($updateQuery);
$updateStmt->bindParam(':rate', $exchangeRate, SQLITE3_TEXT);
$updateStmt->bindParam(':code', $currencyCode, SQLITE3_TEXT);
$updateResult = $updateStmt->execute();
if (!$updateResult) {
echo "Error updating rate for currency: $currencyCode <br />";
}
}
$currentDate = new DateTime();
$formattedDate = $currentDate->format('Y-m-d');
$deleteQuery = "DELETE FROM last_exchange_update WHERE user_id = :userId";
$deleteStmt = $db->prepare($deleteQuery);
$deleteResult = $deleteStmt->execute();
$query = "INSERT INTO last_exchange_update (date, user_id) VALUES (:formattedDate, :userId)";
$stmt = $db->prepare($query);
$stmt->bindParam(':formattedDate', $formattedDate, SQLITE3_TEXT);
$stmt->bindParam(':userId', $userId, SQLITE3_INTEGER);
$result = $stmt->execute();
echo "Rates updated successfully!<br />";
}
} else {
echo "Exchange rates update skipped. No fixer.io api key provided<br />";
$apiKey = null;
}
} else {
echo "Exchange rates update skipped. No fixer.io api key provided<br />";
$apiKey = null;
}
$db->close();
}
$db->close();
?>

View File

@@ -1,66 +1,66 @@
<?php
require_once __DIR__ . '/../../includes/connect_endpoint_crontabs.php';
require_once __DIR__ . '/../../includes/connect_endpoint_crontabs.php';
$currentDate = new DateTime();
$currentDateString = $currentDate->format('Y-m-d');
$currentDate = new DateTime();
$currentDateString = $currentDate->format('Y-m-d');
$cycles = array();
$query = "SELECT * FROM cycles";
$result = $db->query($query);
while ($row = $result->fetchArray(SQLITE3_ASSOC)) {
$cycleId = $row['id'];
$cycles[$cycleId] = $row;
$cycles = array();
$query = "SELECT * FROM cycles";
$result = $db->query($query);
while ($row = $result->fetchArray(SQLITE3_ASSOC)) {
$cycleId = $row['id'];
$cycles[$cycleId] = $row;
}
$query = "SELECT id, next_payment, frequency, cycle FROM subscriptions WHERE next_payment < :currentDate";
$stmt = $db->prepare($query);
$stmt->bindValue(':currentDate', $currentDate->format('Y-m-d'));
$result = $stmt->execute();
while ($row = $result->fetchArray(SQLITE3_ASSOC)) {
$subscriptionId = $row['id'];
$nextPaymentDate = new DateTime($row['next_payment']);
$frequency = $row['frequency'];
$cycle = $cycles[$row['cycle']]['name'];
// Calculate the interval to add based on the cycle
$intervalSpec = "P";
if ($cycle == 'Daily') {
$intervalSpec .= "{$frequency}D";
} elseif ($cycle === 'Weekly') {
$intervalSpec .= "{$frequency}W";
} elseif ($cycle === 'Monthly') {
$intervalSpec .= "{$frequency}M";
} elseif ($cycle === 'Yearly') {
$intervalSpec .= "{$frequency}Y";
}
$query = "SELECT id, next_payment, frequency, cycle FROM subscriptions WHERE next_payment < :currentDate";
$stmt = $db->prepare($query);
$stmt->bindValue(':currentDate', $currentDate->format('Y-m-d'));
$result = $stmt->execute();
$interval = new DateInterval($intervalSpec);
while ($row = $result->fetchArray(SQLITE3_ASSOC)) {
$subscriptionId = $row['id'];
$nextPaymentDate = new DateTime($row['next_payment']);
$frequency = $row['frequency'];
$cycle = $cycles[$row['cycle']]['name'];
// Calculate the interval to add based on the cycle
$intervalSpec = "P";
if ($cycle == 'Daily') {
$intervalSpec .= "{$frequency}D";
} elseif ($cycle === 'Weekly') {
$intervalSpec .= "{$frequency}W";
} elseif ($cycle === 'Monthly') {
$intervalSpec .= "{$frequency}M";
} elseif ($cycle === 'Yearly') {
$intervalSpec .= "{$frequency}Y";
}
$interval = new DateInterval($intervalSpec);
// Add intervals until the next payment date is in the future
while ($nextPaymentDate < $currentDate) {
$nextPaymentDate->add($interval);
}
// Update the subscription's next_payment date
$updateQuery = "UPDATE subscriptions SET next_payment = :nextPaymentDate WHERE id = :subscriptionId";
$updateStmt = $db->prepare($updateQuery);
$updateStmt->bindValue(':nextPaymentDate', $nextPaymentDate->format('Y-m-d'));
$updateStmt->bindValue(':subscriptionId', $subscriptionId);
$updateStmt->execute();
// Add intervals until the next payment date is in the future
while ($nextPaymentDate < $currentDate) {
$nextPaymentDate->add($interval);
}
$formattedDate = $currentDate->format('Y-m-d');
// Update the subscription's next_payment date
$updateQuery = "UPDATE subscriptions SET next_payment = :nextPaymentDate WHERE id = :subscriptionId";
$updateStmt = $db->prepare($updateQuery);
$updateStmt->bindValue(':nextPaymentDate', $nextPaymentDate->format('Y-m-d'));
$updateStmt->bindValue(':subscriptionId', $subscriptionId);
$updateStmt->execute();
}
$deleteQuery = "DELETE FROM last_update_next_payment_date";
$deleteStmt = $db->prepare($deleteQuery);
$deleteResult = $deleteStmt->execute();
$formattedDate = $currentDate->format('Y-m-d');
$query = "INSERT INTO last_update_next_payment_date (date) VALUES (:formattedDate)";
$stmt = $db->prepare($query);
$stmt->bindParam(':formattedDate', $currentDateString, SQLITE3_TEXT);
$result = $stmt->execute();
$deleteQuery = "DELETE FROM last_update_next_payment_date";
$deleteStmt = $db->prepare($deleteQuery);
$deleteResult = $deleteStmt->execute();
echo "Updated next payment dates";
$query = "INSERT INTO last_update_next_payment_date (date) VALUES (:formattedDate)";
$stmt = $db->prepare($query);
$stmt->bindParam(':formattedDate', $currentDateString, SQLITE3_TEXT);
$result = $stmt->execute();
echo "Updated next payment dates";
?>

View File

@@ -3,25 +3,25 @@ require_once '../../includes/connect_endpoint.php';
require_once '../../includes/inputvalidation.php';
if (isset($_SESSION['loggedin']) && $_SESSION['loggedin'] === true) {
$currencyName = "Currency";
$currencySymbol = "$";
$currencyCode = "CODE";
$currencyRate = 1;
$sqlInsert = "INSERT INTO currencies (name, symbol, code, rate, user_id) VALUES (:name, :symbol, :code, :rate, :userId)";
$stmtInsert = $db->prepare($sqlInsert);
$stmtInsert->bindParam(':name', $currencyName, SQLITE3_TEXT);
$stmtInsert->bindParam(':symbol', $currencySymbol, SQLITE3_TEXT);
$stmtInsert->bindParam(':code', $currencyCode, SQLITE3_TEXT);
$stmtInsert->bindParam(':rate', $currencyRate, SQLITE3_TEXT);
$stmtInsert->bindParam(':userId', $userId, SQLITE3_INTEGER);
$resultInsert = $stmtInsert->execute();
if ($resultInsert) {
$currencyId = $db->lastInsertRowID();
echo $currencyId;
} else {
echo translate('error_adding_currency', $i18n);
}
$currencyName = "Currency";
$currencySymbol = "$";
$currencyCode = "CODE";
$currencyRate = 1;
$sqlInsert = "INSERT INTO currencies (name, symbol, code, rate, user_id) VALUES (:name, :symbol, :code, :rate, :userId)";
$stmtInsert = $db->prepare($sqlInsert);
$stmtInsert->bindParam(':name', $currencyName, SQLITE3_TEXT);
$stmtInsert->bindParam(':symbol', $currencySymbol, SQLITE3_TEXT);
$stmtInsert->bindParam(':code', $currencyCode, SQLITE3_TEXT);
$stmtInsert->bindParam(':rate', $currencyRate, SQLITE3_TEXT);
$stmtInsert->bindParam(':userId', $userId, SQLITE3_INTEGER);
$resultInsert = $stmtInsert->execute();
if ($resultInsert) {
$currencyId = $db->lastInsertRowID();
echo $currencyId;
} else {
echo translate('error_adding_currency', $i18n);
}
} else {
$response = [
"success" => false,
@@ -30,4 +30,4 @@ if (isset($_SESSION['loggedin']) && $_SESSION['loggedin'] === true) {
echo json_encode($response);
}
?>
?>

View File

@@ -16,7 +16,7 @@ if (isset($_SESSION['loggedin']) && $_SESSION['loggedin'] === true) {
$stmtInsert->bindParam(':rate', $currencyRate, SQLITE3_TEXT);
$stmtInsert->bindParam(':userId', $userId, SQLITE3_INTEGER);
$resultInsert = $stmtInsert->execute();
if ($resultInsert) {
$currencyId = $db->lastInsertRowID();
echo $currencyId;
@@ -126,4 +126,4 @@ if (isset($_SESSION['loggedin']) && $_SESSION['loggedin'] === true) {
echo json_encode($response);
}
?>
?>

View File

@@ -45,4 +45,4 @@ if (isset($_SESSION['loggedin']) && $_SESSION['loggedin'] === true) {
echo json_encode($response);
}
?>
?>

View File

@@ -1,59 +1,59 @@
<?php
require_once '../../includes/connect_endpoint.php';
if (isset($_SESSION['loggedin']) && $_SESSION['loggedin'] === true) {
if ($_SERVER["REQUEST_METHOD"] === "POST") {
$newApiKey = isset($_POST["api_key"]) ? trim($_POST["api_key"]) : "";
$provider = isset($_POST["provider"]) ? $_POST["provider"] : 0;
require_once '../../includes/connect_endpoint.php';
$removeOldKey = "DELETE FROM fixer WHERE user_id = :userId";
$stmt = $db->prepare($removeOldKey);
$stmt->bindParam(":userId", $userId, SQLITE3_INTEGER);
$stmt->execute();
if (isset($_SESSION['loggedin']) && $_SESSION['loggedin'] === true) {
if ($_SERVER["REQUEST_METHOD"] === "POST") {
$newApiKey = isset($_POST["api_key"]) ? trim($_POST["api_key"]) : "";
$provider = isset($_POST["provider"]) ? $_POST["provider"] : 0;
if ($provider == 1) {
$testKeyUrl = "https://api.apilayer.com/fixer/latest?base=USD&symbols=EUR";
$context = stream_context_create([
'http' => [
'method' => 'GET',
'header' => 'apikey: ' . $newApiKey,
]
]);
$response = file_get_contents($testKeyUrl, false, $context);
} else {
$testKeyUrl = "http://data.fixer.io/api/latest?access_key=$newApiKey";
$response = file_get_contents($testKeyUrl);
}
$apiData = json_decode($response, true);
if ($apiData['success'] && $apiData['success'] == 1) {
if (!empty($newApiKey)) {
$insertNewKey = "INSERT INTO fixer (api_key, provider, user_id) VALUES (:api_key, :provider, :userId)";
$stmt = $db->prepare($insertNewKey);
$stmt->bindParam(":api_key", $newApiKey, SQLITE3_TEXT);
$stmt->bindParam(":provider", $provider, SQLITE3_INTEGER);
$stmt->bindParam(":userId", $userId, SQLITE3_INTEGER);
$result = $stmt->execute();
if ($result) {
echo json_encode(["success" => true, "message" => translate('api_key_saved', $i18n)]);
} else {
$response = [
"success" => false,
"message" => translate('failed_to_store_api_key', $i18n)
];
echo json_encode($response);
}
$removeOldKey = "DELETE FROM fixer WHERE user_id = :userId";
$stmt = $db->prepare($removeOldKey);
$stmt->bindParam(":userId", $userId, SQLITE3_INTEGER);
$stmt->execute();
if ($provider == 1) {
$testKeyUrl = "https://api.apilayer.com/fixer/latest?base=USD&symbols=EUR";
$context = stream_context_create([
'http' => [
'method' => 'GET',
'header' => 'apikey: ' . $newApiKey,
]
]);
$response = file_get_contents($testKeyUrl, false, $context);
} else {
$testKeyUrl = "http://data.fixer.io/api/latest?access_key=$newApiKey";
$response = file_get_contents($testKeyUrl);
}
$apiData = json_decode($response, true);
if ($apiData['success'] && $apiData['success'] == 1) {
if (!empty($newApiKey)) {
$insertNewKey = "INSERT INTO fixer (api_key, provider, user_id) VALUES (:api_key, :provider, :userId)";
$stmt = $db->prepare($insertNewKey);
$stmt->bindParam(":api_key", $newApiKey, SQLITE3_TEXT);
$stmt->bindParam(":provider", $provider, SQLITE3_INTEGER);
$stmt->bindParam(":userId", $userId, SQLITE3_INTEGER);
$result = $stmt->execute();
if ($result) {
echo json_encode(["success" => true, "message" => translate('api_key_saved', $i18n)]);
} else {
echo json_encode(["success" => true, "message" => translate('apy_key_saved', $i18n)]);
$response = [
"success" => false,
"message" => translate('failed_to_store_api_key', $i18n)
];
echo json_encode($response);
}
} else {
$response = [
"success" => false,
"message" => translate('invalid_api_key', $i18n)
];
echo json_encode($response);
echo json_encode(["success" => true, "message" => translate('apy_key_saved', $i18n)]);
}
} else {
$response = [
"success" => false,
"message" => translate('invalid_api_key', $i18n)
];
echo json_encode($response);
}
}
}
?>

View File

@@ -67,4 +67,4 @@ if (isset($_SESSION['loggedin']) && $_SESSION['loggedin'] === true) {
echo json_encode($response);
}
?>
?>

View File

@@ -18,7 +18,7 @@ if (isset($_GET['force']) && $_GET['force'] === "true") {
$currentDateString = $currentDate->format('Y-m-d');
$shouldUpdate = $lastUpdateDateString < $currentDateString;
}
if (!$shouldUpdate) {
echo "Rates are current, no need to update.";
exit;
@@ -30,7 +30,7 @@ $result = $db->query($query);
if ($result) {
$row = $result->fetchArray(SQLITE3_ASSOC);
if ($row) {
$apiKey = $row['api_key'];
$provider = $row['provider'];
@@ -41,7 +41,7 @@ if ($result) {
$stmt->bindParam(':userId', $userId, SQLITE3_INTEGER);
$result = $stmt->execute();
while ($row = $result->fetchArray(SQLITE3_ASSOC)) {
$codes .= $row['code'].",";
$codes .= $row['code'] . ",";
}
$codes = rtrim($codes, ',');
$query = "SELECT u.main_currency, c.code FROM user u LEFT JOIN currencies c ON u.main_currency = c.id WHERE u.id = :userId";
@@ -62,7 +62,7 @@ if ($result) {
]);
$response = file_get_contents($api_url, false, $context);
} else {
$api_url = "http://data.fixer.io/api/latest?access_key=". $apiKey . "&base=EUR&symbols=" . $codes;
$api_url = "http://data.fixer.io/api/latest?access_key=" . $apiKey . "&base=EUR&symbols=" . $codes;
$response = file_get_contents($api_url);
}

View File

@@ -8,21 +8,23 @@ if (!isset($_SESSION['loggedin']) || $_SESSION['loggedin'] !== true) {
]));
}
function addFolderToZip($dir, $zipArchive, $zipdir = ''){
function addFolderToZip($dir, $zipArchive, $zipdir = '')
{
if (is_dir($dir)) {
if ($dh = opendir($dir)) {
//Add the directory
if(!empty($zipdir)) $zipArchive->addEmptyDir($zipdir);
if (!empty($zipdir))
$zipArchive->addEmptyDir($zipdir);
while (($file = readdir($dh)) !== false) {
// Skip '.' and '..'
if ($file == "." || $file == "..") {
continue;
}
//If it's a folder, run the function again!
if(is_dir($dir . $file)){
if (is_dir($dir . $file)) {
$newdir = $dir . $file . '/';
addFolderToZip($newdir, $zipArchive, $zipdir . $file . '/');
}else{
} else {
//Add the files
$zipArchive->addFile($dir . $file, $zipdir . $file);
}
@@ -40,7 +42,7 @@ $zip = new ZipArchive();
$filename = "backup_" . uniqid() . ".zip";
$zipname = "../../.tmp/" . $filename;
if ($zip->open($zipname, ZipArchive::CREATE)!==TRUE) {
if ($zip->open($zipname, ZipArchive::CREATE) !== TRUE) {
die(json_encode([
"success" => false,
"message" => translate('cannot_open_zip', $i18n)

View File

@@ -42,8 +42,8 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') {
$di = new RecursiveDirectoryIterator($dir, FilesystemIterator::SKIP_DOTS);
$ri = new RecursiveIteratorIterator($di, RecursiveIteratorIterator::CHILD_FIRST);
foreach ( $ri as $file ) {
if ( $file->isDir() ) {
foreach ($ri as $file) {
if ($file->isDir()) {
rmdir($file->getPathname());
} else {
unlink($file->getPathname());
@@ -67,12 +67,12 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') {
}
}
}
$files = new RecursiveIteratorIterator(
new RecursiveDirectoryIterator('../../.tmp', RecursiveDirectoryIterator::SKIP_DOTS),
RecursiveIteratorIterator::CHILD_FIRST
);
foreach ($files as $fileinfo) {
$removeFunction = ($fileinfo->isDir() ? 'rmdir' : 'unlink');
$removeFunction($fileinfo->getRealPath());

View File

@@ -1,5 +1,6 @@
<?php
function errorHandler($severity, $message, $file, $line) {
function errorHandler($severity, $message, $file, $line)
{
throw new ErrorException($message, 0, $severity, $file, $line);
}
@@ -19,8 +20,8 @@ try {
$completedMigrations = [];
$migrationTableExists = $db
->query('SELECT name FROM sqlite_master WHERE type="table" AND name="migrations"')
->fetchArray(SQLITE3_ASSOC) !== false;
->query('SELECT name FROM sqlite_master WHERE type="table" AND name="migrations"')
->fetchArray(SQLITE3_ASSOC) !== false;
if ($migrationTableExists) {
$migrationQuery = $db->query('SELECT migration FROM migrations');
@@ -34,11 +35,11 @@ if (count($allMigrations) == 0) {
$allMigrations = glob('../../migrations/*.php');
}
$allMigrations = array_map(function($migration) {
$allMigrations = array_map(function ($migration) {
return str_replace('../../', '', $migration);
}, $allMigrations);
$completedMigrations = array_map(function($migration) {
$completedMigrations = array_map(function ($migration) {
return str_replace('../../', '', $migration);
}, $completedMigrations);

View File

@@ -40,8 +40,8 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') {
$di = new RecursiveDirectoryIterator($dir, FilesystemIterator::SKIP_DOTS);
$ri = new RecursiveIteratorIterator($di, RecursiveIteratorIterator::CHILD_FIRST);
foreach ( $ri as $file ) {
if ( $file->isDir() ) {
foreach ($ri as $file) {
if ($file->isDir()) {
rmdir($file->getPathname());
} else {
unlink($file->getPathname());
@@ -70,12 +70,12 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') {
new RecursiveDirectoryIterator('../../.tmp', RecursiveDirectoryIterator::SKIP_DOTS),
RecursiveIteratorIterator::CHILD_FIRST
);
foreach ($files as $fileinfo) {
$removeFunction = ($fileinfo->isDir() ? 'rmdir' : 'unlink');
$removeFunction($fileinfo->getRealPath());
}
echo json_encode([
"success" => true,
"message" => translate("success", $i18n)

View File

@@ -10,7 +10,7 @@ if (isset($_SESSION['loggedin']) && $_SESSION['loggedin'] === true) {
$stmtInsert->bindParam(':name', $householdName, SQLITE3_TEXT);
$stmtInsert->bindParam(':userId', $userId, SQLITE3_INTEGER);
$resultInsert = $stmtInsert->execute();
if ($resultInsert) {
$householdId = $db->lastInsertRowID();
$response = [
@@ -110,4 +110,4 @@ if (isset($_SESSION['loggedin']) && $_SESSION['loggedin'] === true) {
echo translate('error', $i18n);
}
?>
?>

View File

@@ -1,83 +1,84 @@
<?php
if (isset($_GET['search'])) {
$searchTerm = urlencode($_GET['search'] . " logo");
if (isset($_GET['search'])) {
$searchTerm = urlencode($_GET['search'] . " logo");
$url = "https://www.google.com/search?q={$searchTerm}&tbm=isch&tbs=iar:xw,ift:png";
$backupUrl = "https://search.brave.com/search?q={$searchTerm}";
$url = "https://www.google.com/search?q={$searchTerm}&tbm=isch&tbs=iar:xw,ift:png";
$backupUrl = "https://search.brave.com/search?q={$searchTerm}";
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
// Convert all environment variable keys to lowercase
$envVars = array_change_key_case($_SERVER, CASE_LOWER);
// Check for http_proxy or https_proxy environment variables
$httpProxy = isset($envVars['http_proxy']) ? $envVars['http_proxy'] : null;
$httpsProxy = isset($envVars['https_proxy']) ? $envVars['https_proxy'] : null;
if (!empty($httpProxy)) {
curl_setopt($ch, CURLOPT_PROXY, $httpProxy);
} elseif (!empty($httpsProxy)) {
curl_setopt($ch, CURLOPT_PROXY, $httpsProxy);
}
$response = curl_exec($ch);
if ($response === false) {
// If cURL fails to access google images, use brave image search as a backup
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_URL, $backupUrl);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
// Convert all environment variable keys to lowercase
$envVars = array_change_key_case($_SERVER, CASE_LOWER);
// Check for http_proxy or https_proxy environment variables
$httpProxy = isset($envVars['http_proxy']) ? $envVars['http_proxy'] : null;
$httpsProxy = isset($envVars['https_proxy']) ? $envVars['https_proxy'] : null;
if (!empty($httpProxy)) {
curl_setopt($ch, CURLOPT_PROXY, $httpProxy);
} elseif (!empty($httpsProxy)) {
curl_setopt($ch, CURLOPT_PROXY, $httpsProxy);
}
$response = curl_exec($ch);
if ($response === false) {
// If cURL fails to access google images, use brave image search as a backup
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $backupUrl);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
$envVars = array_change_key_case($_SERVER, CASE_LOWER);
$httpProxy = isset($envVars['http_proxy']) ? $envVars['http_proxy'] : null;
$httpsProxy = isset($envVars['https_proxy']) ? $envVars['https_proxy'] : null;
if (!empty($httpProxy)) {
curl_setopt($ch, CURLOPT_PROXY, $httpProxy);
} elseif (!empty($httpsProxy)) {
curl_setopt($ch, CURLOPT_PROXY, $httpsProxy);
}
$response = curl_exec($ch);
if ($response === false) {
echo json_encode(['error' => 'Failed to fetch data from Google.']);
} else {
$imageUrls = extractImageUrlsFromPage($response);
header('Content-Type: application/json');
echo json_encode(['imageUrls' => $imageUrls]);
}
echo json_encode(['error' => 'Failed to fetch data from Google.']);
} else {
// Parse the HTML response to extract image URLs
$imageUrls = extractImageUrlsFromPage($response);
// Pass the image URLs to the client
header('Content-Type: application/json');
echo json_encode(['imageUrls' => $imageUrls]);
}
curl_close($ch);
} else {
echo json_encode(['error' => 'Invalid request.']);
// Parse the HTML response to extract image URLs
$imageUrls = extractImageUrlsFromPage($response);
// Pass the image URLs to the client
header('Content-Type: application/json');
echo json_encode(['imageUrls' => $imageUrls]);
}
function extractImageUrlsFromPage($html) {
$imageUrls = [];
curl_close($ch);
} else {
echo json_encode(['error' => 'Invalid request.']);
}
$doc = new DOMDocument();
@$doc->loadHTML($html);
function extractImageUrlsFromPage($html)
{
$imageUrls = [];
$imgTags = $doc->getElementsByTagName('img');
foreach ($imgTags as $imgTag) {
$src = $imgTag->getAttribute('src');
if (!strstr($imgTag->getAttribute('class'), "favicon") && !strstr($imgTag->getAttribute('class'), "logo")) {
if (filter_var($src, FILTER_VALIDATE_URL)) {
$imageUrls[] = $src;
}
$doc = new DOMDocument();
@$doc->loadHTML($html);
$imgTags = $doc->getElementsByTagName('img');
foreach ($imgTags as $imgTag) {
$src = $imgTag->getAttribute('src');
if (!strstr($imgTag->getAttribute('class'), "favicon") && !strstr($imgTag->getAttribute('class'), "logo")) {
if (filter_var($src, FILTER_VALIDATE_URL)) {
$imageUrls[] = $src;
}
}
return $imageUrls;
}
?>
return $imageUrls;
}
?>

View File

@@ -1,77 +1,77 @@
<?php
require_once '../../includes/connect_endpoint.php';
require_once '../../includes/connect_endpoint.php';
if (!isset($_SESSION['loggedin']) || $_SESSION['loggedin'] !== true) {
die(json_encode([
if (!isset($_SESSION['loggedin']) || $_SESSION['loggedin'] !== true) {
die(json_encode([
"success" => false,
"message" => translate('session_expired', $i18n)
]));
}
if ($_SERVER["REQUEST_METHOD"] === "POST") {
$postData = file_get_contents("php://input");
$data = json_decode($postData, true);
if (
!isset($data["url"]) || $data["url"] == ""
) {
$response = [
"success" => false,
"message" => translate('session_expired', $i18n)
]));
}
"message" => translate('fill_mandatory_fields', $i18n)
];
echo json_encode($response);
} else {
$enabled = $data["enabled"];
$webhook_url = $data["url"];
$bot_username = $data["bot_username"];
$bot_avatar_url = $data["bot_avatar"];
if ($_SERVER["REQUEST_METHOD"] === "POST") {
$postData = file_get_contents("php://input");
$data = json_decode($postData, true);
$query = "SELECT COUNT(*) FROM discord_notifications WHERE user_id = :userId";
$stmt = $db->prepare($query);
$stmt->bindParam(":userId", $userId, SQLITE3_INTEGER);
$result = $stmt->execute();
if (
!isset($data["url"]) || $data["url"] == ""
) {
if ($result === false) {
$response = [
"success" => false,
"message" => translate('fill_mandatory_fields', $i18n)
"message" => translate('error_saving_notifications', $i18n)
];
echo json_encode($response);
} else {
$enabled = $data["enabled"];
$webhook_url = $data["url"];
$bot_username = $data["bot_username"];
$bot_avatar_url = $data["bot_avatar"];
$row = $result->fetchArray();
$count = $row[0];
if ($count == 0) {
$query = "INSERT INTO discord_notifications (enabled, webhook_url, bot_username, bot_avatar_url, user_id)
VALUES (:enabled, :webhook_url, :bot_username, :bot_avatar_url, :userId)";
} else {
$query = "UPDATE discord_notifications
SET enabled = :enabled, webhook_url = :webhook_url, bot_username = :bot_username, bot_avatar_url = :bot_avatar_url
WHERE user_id = :userId";
}
$query = "SELECT COUNT(*) FROM discord_notifications WHERE user_id = :userId";
$stmt = $db->prepare($query);
$stmt->bindParam(":userId", $userId, SQLITE3_INTEGER);
$result = $stmt->execute();
if ($result === false) {
$stmt->bindValue(':enabled', $enabled, SQLITE3_INTEGER);
$stmt->bindValue(':webhook_url', $webhook_url, SQLITE3_TEXT);
$stmt->bindValue(':bot_username', $bot_username, SQLITE3_TEXT);
$stmt->bindValue(':bot_avatar_url', $bot_avatar_url, SQLITE3_TEXT);
$stmt->bindValue(':userId', $userId, SQLITE3_INTEGER);
if ($stmt->execute()) {
$response = [
"success" => true,
"message" => translate('notifications_settings_saved', $i18n)
];
echo json_encode($response);
} else {
$response = [
"success" => false,
"message" => translate('error_saving_notifications', $i18n)
];
echo json_encode($response);
} else {
$row = $result->fetchArray();
$count = $row[0];
if ($count == 0) {
$query = "INSERT INTO discord_notifications (enabled, webhook_url, bot_username, bot_avatar_url, user_id)
VALUES (:enabled, :webhook_url, :bot_username, :bot_avatar_url, :userId)";
} else {
$query = "UPDATE discord_notifications
SET enabled = :enabled, webhook_url = :webhook_url, bot_username = :bot_username, bot_avatar_url = :bot_avatar_url
WHERE user_id = :userId";
}
$stmt = $db->prepare($query);
$stmt->bindValue(':enabled', $enabled, SQLITE3_INTEGER);
$stmt->bindValue(':webhook_url', $webhook_url, SQLITE3_TEXT);
$stmt->bindValue(':bot_username', $bot_username, SQLITE3_TEXT);
$stmt->bindValue(':bot_avatar_url', $bot_avatar_url, SQLITE3_TEXT);
$stmt->bindValue(':userId', $userId, SQLITE3_INTEGER);
if ($stmt->execute()) {
$response = [
"success" => true,
"message" => translate('notifications_settings_saved', $i18n)
];
echo json_encode($response);
} else {
$response = [
"success" => false,
"message" => translate('error_saving_notifications', $i18n)
];
echo json_encode($response);
}
}
}
}
}
?>

View File

@@ -1,87 +1,87 @@
<?php
require_once '../../includes/connect_endpoint.php';
require_once '../../includes/connect_endpoint.php';
if (!isset($_SESSION['loggedin']) || $_SESSION['loggedin'] !== true) {
die(json_encode([
if (!isset($_SESSION['loggedin']) || $_SESSION['loggedin'] !== true) {
die(json_encode([
"success" => false,
"message" => translate('session_expired', $i18n)
]));
}
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,
"message" => translate('session_expired', $i18n)
]));
}
"message" => translate('fill_mandatory_fields', $i18n)
];
echo json_encode($response);
} else {
$enabled = $data["enabled"];
$smtpAddress = $data["smtpaddress"];
$smtpPort = $data["smtpport"];
$encryption = "tls";
if (isset($data["encryption"])) {
$encryption = $data["encryption"];
}
$smtpUsername = $data["smtpusername"];
$smtpPassword = $data["smtppassword"];
$fromEmail = $data["fromemail"];
if ($_SERVER["REQUEST_METHOD"] === "POST") {
$postData = file_get_contents("php://input");
$data = json_decode($postData, true);
$query = "SELECT COUNT(*) FROM email_notifications WHERE user_id = :userId";
$stmt = $db->prepare($query);
$stmt->bindParam(":userId", $userId, SQLITE3_INTEGER);
$result = $stmt->execute();
if (
!isset($data["smtpaddress"]) || $data["smtpaddress"] == "" ||
!isset($data["smtpport"]) || $data["smtpport"] == "" ||
!isset($data["smtpusername"]) || $data["smtpusername"] == "" ||
!isset($data["smtppassword"]) || $data["smtppassword"] == ""
) {
if ($result === false) {
$response = [
"success" => false,
"message" => translate('fill_mandatory_fields', $i18n)
"message" => translate('error_saving_notifications', $i18n)
];
echo json_encode($response);
} else {
$enabled = $data["enabled"];
$smtpAddress = $data["smtpaddress"];
$smtpPort = $data["smtpport"];
$encryption = "tls";
if (isset($data["encryption"])) {
$encryption = $data["encryption"];
$row = $result->fetchArray();
$count = $row[0];
if ($count == 0) {
$query = "INSERT INTO email_notifications (enabled, smtp_address, smtp_port, smtp_username, smtp_password, from_email, encryption, user_id)
VALUES (:enabled, :smtpAddress, :smtpPort, :smtpUsername, :smtpPassword, :fromEmail, :encryption, :userId)";
} else {
$query = "UPDATE email_notifications
SET enabled = :enabled, smtp_address = :smtpAddress, smtp_port = :smtpPort,
smtp_username = :smtpUsername, smtp_password = :smtpPassword, from_email = :fromEmail, encryption = :encryption WHERE user_id = :userId";
}
$smtpUsername = $data["smtpusername"];
$smtpPassword = $data["smtppassword"];
$fromEmail = $data["fromemail"];
$query = "SELECT COUNT(*) FROM email_notifications WHERE user_id = :userId";
$stmt = $db->prepare($query);
$stmt->bindParam(":userId", $userId, SQLITE3_INTEGER);
$result = $stmt->execute();
if ($result === false) {
$stmt->bindValue(':enabled', $enabled, 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);
$stmt->bindValue(':fromEmail', $fromEmail, SQLITE3_TEXT);
$stmt->bindValue(':encryption', $encryption, SQLITE3_TEXT);
$stmt->bindValue(':userId', $userId, SQLITE3_INTEGER);
if ($stmt->execute()) {
$response = [
"success" => true,
"message" => translate('notifications_settings_saved', $i18n)
];
echo json_encode($response);
} else {
$response = [
"success" => false,
"message" => translate('error_saving_notifications', $i18n)
];
echo json_encode($response);
} else {
$row = $result->fetchArray();
$count = $row[0];
if ($count == 0) {
$query = "INSERT INTO email_notifications (enabled, smtp_address, smtp_port, smtp_username, smtp_password, from_email, encryption, user_id)
VALUES (:enabled, :smtpAddress, :smtpPort, :smtpUsername, :smtpPassword, :fromEmail, :encryption, :userId)";
} else {
$query = "UPDATE email_notifications
SET enabled = :enabled, smtp_address = :smtpAddress, smtp_port = :smtpPort,
smtp_username = :smtpUsername, smtp_password = :smtpPassword, from_email = :fromEmail, encryption = :encryption WHERE user_id = :userId";
}
$stmt = $db->prepare($query);
$stmt->bindValue(':enabled', $enabled, 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);
$stmt->bindValue(':fromEmail', $fromEmail, SQLITE3_TEXT);
$stmt->bindValue(':encryption', $encryption, SQLITE3_TEXT);
$stmt->bindValue(':userId', $userId, SQLITE3_INTEGER);
if ($stmt->execute()) {
$response = [
"success" => true,
"message" => translate('notifications_settings_saved', $i18n)
];
echo json_encode($response);
} else {
$response = [
"success" => false,
"message" => translate('error_saving_notifications', $i18n)
];
echo json_encode($response);
}
}
}
}
}
?>

View File

@@ -1,73 +1,73 @@
<?php
require_once '../../includes/connect_endpoint.php';
require_once '../../includes/connect_endpoint.php';
if (!isset($_SESSION['loggedin']) || $_SESSION['loggedin'] !== true) {
die(json_encode([
if (!isset($_SESSION['loggedin']) || $_SESSION['loggedin'] !== true) {
die(json_encode([
"success" => false,
"message" => translate('session_expired', $i18n)
]));
}
if ($_SERVER["REQUEST_METHOD"] === "POST") {
$postData = file_get_contents("php://input");
$data = json_decode($postData, true);
if (
!isset($data["gotify_url"]) || $data["gotify_url"] == "" ||
!isset($data["token"]) || $data["token"] == ""
) {
$response = [
"success" => false,
"message" => translate('session_expired', $i18n)
]));
}
"message" => translate('fill_mandatory_fields', $i18n)
];
echo json_encode($response);
} else {
$enabled = $data["enabled"];
$url = $data["gotify_url"];
$token = $data["token"];
if ($_SERVER["REQUEST_METHOD"] === "POST") {
$postData = file_get_contents("php://input");
$data = json_decode($postData, true);
$query = "SELECT COUNT(*) FROM gotify_notifications WHERE user_id = :userId";
$stmt = $db->prepare($query);
$stmt->bindParam(":userId", $userId, SQLITE3_INTEGER);
$result = $stmt->execute();
if (
!isset($data["gotify_url"]) || $data["gotify_url"] == "" ||
!isset($data["token"]) || $data["token"] == ""
) {
if ($result === false) {
$response = [
"success" => false,
"message" => translate('fill_mandatory_fields', $i18n)
"message" => translate('error_saving_notifications', $i18n)
];
echo json_encode($response);
} else {
$enabled = $data["enabled"];
$url = $data["gotify_url"];
$token = $data["token"];
$row = $result->fetchArray();
$count = $row[0];
if ($count == 0) {
$query = "INSERT INTO gotify_notifications (enabled, url, token, user_id)
VALUES (:enabled, :url, :token, :userId)";
} else {
$query = "UPDATE gotify_notifications
SET enabled = :enabled, url = :url, token = :token WHERE user_id = :userId";
}
$query = "SELECT COUNT(*) FROM gotify_notifications WHERE user_id = :userId";
$stmt = $db->prepare($query);
$stmt->bindParam(":userId", $userId, SQLITE3_INTEGER);
$result = $stmt->execute();
if ($result === false) {
$stmt->bindValue(':enabled', $enabled, SQLITE3_INTEGER);
$stmt->bindValue(':url', $url, SQLITE3_TEXT);
$stmt->bindValue(':token', $token, SQLITE3_TEXT);
$stmt->bindValue(':userId', $userId, SQLITE3_INTEGER);
if ($stmt->execute()) {
$response = [
"success" => true,
"message" => translate('notifications_settings_saved', $i18n)
];
echo json_encode($response);
} else {
$response = [
"success" => false,
"message" => translate('error_saving_notifications', $i18n)
];
echo json_encode($response);
} else {
$row = $result->fetchArray();
$count = $row[0];
if ($count == 0) {
$query = "INSERT INTO gotify_notifications (enabled, url, token, user_id)
VALUES (:enabled, :url, :token, :userId)";
} else {
$query = "UPDATE gotify_notifications
SET enabled = :enabled, url = :url, token = :token WHERE user_id = :userId";
}
$stmt = $db->prepare($query);
$stmt->bindValue(':enabled', $enabled, SQLITE3_INTEGER);
$stmt->bindValue(':url', $url, SQLITE3_TEXT);
$stmt->bindValue(':token', $token, SQLITE3_TEXT);
$stmt->bindValue(':userId', $userId, SQLITE3_INTEGER);
if ($stmt->execute()) {
$response = [
"success" => true,
"message" => translate('notifications_settings_saved', $i18n)
];
echo json_encode($response);
} else {
$response = [
"success" => false,
"message" => translate('error_saving_notifications', $i18n)
];
echo json_encode($response);
}
}
}
}
}
?>

View File

@@ -1,71 +1,71 @@
<?php
require_once '../../includes/connect_endpoint.php';
require_once '../../includes/connect_endpoint.php';
if (!isset($_SESSION['loggedin']) || $_SESSION['loggedin'] !== true) {
die(json_encode([
if (!isset($_SESSION['loggedin']) || $_SESSION['loggedin'] !== true) {
die(json_encode([
"success" => false,
"message" => translate('session_expired', $i18n)
]));
}
if ($_SERVER["REQUEST_METHOD"] === "POST") {
$postData = file_get_contents("php://input");
$data = json_decode($postData, true);
if (!isset($data["days"]) || $data['days'] == "") {
$response = [
"success" => false,
"message" => translate('session_expired', $i18n)
]));
}
"message" => translate('fill_mandatory_fields', $i18n)
];
echo json_encode($response);
} else {
$days = $data["days"];
$query = "SELECT COUNT(*) FROM notification_settings WHERE user_id = :userId";
$stmt = $db->prepare($query);
$stmt->bindParam(":userId", $userId, SQLITE3_INTEGER);
$result = $stmt->execute();
if ($_SERVER["REQUEST_METHOD"] === "POST") {
$postData = file_get_contents("php://input");
$data = json_decode($postData, true);
if (!isset($data["days"]) || $data['days'] == "") {
if ($result === false) {
$response = [
"success" => false,
"message" => translate('fill_mandatory_fields', $i18n)
"message" => translate('error_saving_notifications', $i18n)
];
echo json_encode($response);
} else {
$days = $data["days"];
$query = "SELECT COUNT(*) FROM notification_settings WHERE user_id = :userId";
$row = $result->fetchArray();
$count = $row[0];
if ($count == 0) {
$query = "INSERT INTO notification_settings (days, user_id)
VALUES (:days, :userId)";
} else {
$query = "UPDATE notification_settings SET days = :days WHERE user_id = :userId";
}
$stmt = $db->prepare($query);
$stmt->bindParam(":userId", $userId, SQLITE3_INTEGER);
$result = $stmt->execute();
if ($result === false) {
$stmt->bindValue(':days', $days, SQLITE3_INTEGER);
$stmt->bindValue(':userId', $userId, SQLITE3_INTEGER);
if ($stmt->execute()) {
$response = [
"success" => true,
"message" => translate('notifications_settings_saved', $i18n)
];
echo json_encode($response);
} else {
$response = [
"success" => false,
"message" => translate('error_saving_notifications', $i18n)
];
echo json_encode($response);
} else {
$row = $result->fetchArray();
$count = $row[0];
if ($count == 0) {
$query = "INSERT INTO notification_settings (days, user_id)
VALUES (:days, :userId)";
} else {
$query = "UPDATE notification_settings SET days = :days WHERE user_id = :userId";
}
$stmt = $db->prepare($query);
$stmt->bindValue(':days', $days, SQLITE3_INTEGER);
$stmt->bindValue(':userId', $userId, SQLITE3_INTEGER);
if ($stmt->execute()) {
$response = [
"success" => true,
"message" => translate('notifications_settings_saved', $i18n)
];
echo json_encode($response);
} else {
$response = [
"success" => false,
"message" => translate('error_saving_notifications', $i18n)
];
echo json_encode($response);
}
}
}
} else {
$response = [
"success" => false,
"message" => "Invalid request method"
];
echo json_encode($response);
exit();
}
}
} else {
$response = [
"success" => false,
"message" => "Invalid request method"
];
echo json_encode($response);
exit();
}

View File

@@ -1,84 +1,84 @@
<?php
require_once '../../includes/connect_endpoint.php';
require_once '../../includes/connect_endpoint.php';
if (!isset($_SESSION['loggedin']) || $_SESSION['loggedin'] !== true) {
die(json_encode([
if (!isset($_SESSION['loggedin']) || $_SESSION['loggedin'] !== true) {
die(json_encode([
"success" => false,
"message" => translate('session_expired', $i18n)
]));
}
if ($_SERVER["REQUEST_METHOD"] === "POST") {
$postData = file_get_contents("php://input");
$data = json_decode($postData, true);
if (
!isset($data["topic"]) || $data["topic"] == "" ||
!isset($data["host"]) || $data["host"] == ""
) {
$response = [
"success" => false,
"message" => translate('session_expired', $i18n)
]));
}
"message" => translate('fill_mandatory_fields', $i18n)
];
echo json_encode($response);
} else {
$enabled = $data["enabled"];
$host = $data["host"];
$topic = $data["topic"];
$headers = $data["headers"];
if ($_SERVER["REQUEST_METHOD"] === "POST") {
$postData = file_get_contents("php://input");
$data = json_decode($postData, true);
$query = "SELECT COUNT(*) FROM ntfy_notifications WHERE user_id = :userId";
$stmt = $db->prepare($query);
$stmt->bindParam(":userId", $userId, SQLITE3_INTEGER);
$result = $stmt->execute();
if (
!isset($data["topic"]) || $data["topic"] == "" ||
!isset($data["host"]) || $data["host"] == ""
) {
if ($result === false) {
$response = [
"success" => false,
"message" => translate('fill_mandatory_fields', $i18n)
"message" => translate('error_saving_notifications', $i18n)
];
echo json_encode($response);
} else {
$enabled = $data["enabled"];
$host = $data["host"];
$topic = $data["topic"];
$headers = $data["headers"];
$row = $result->fetchArray();
$count = $row[0];
if ($count == 0) {
$query = "INSERT INTO ntfy_notifications (enabled, host, topic, headers, user_id)
VALUES (:enabled, :host, :topic, :headers, :userId)";
} else {
$query = "UPDATE ntfy_notifications
SET enabled = :enabled, host = :host, topic = :topic, headers = :headers WHERE user_id = :userId";
}
$query = "SELECT COUNT(*) FROM ntfy_notifications WHERE user_id = :userId";
$stmt = $db->prepare($query);
$stmt->bindParam(":userId", $userId, SQLITE3_INTEGER);
$result = $stmt->execute();
$stmt->bindValue(':enabled', $enabled, SQLITE3_INTEGER);
$stmt->bindValue(':host', $host, SQLITE3_TEXT);
$stmt->bindValue(':topic', $topic, SQLITE3_TEXT);
$stmt->bindValue(':headers', $headers, SQLITE3_TEXT);
$stmt->bindValue(':userId', $userId, SQLITE3_INTEGER);
if ($result === false) {
if ($stmt->execute()) {
$response = [
"success" => true,
"message" => translate('notifications_settings_saved', $i18n)
];
echo json_encode($response);
} else {
$response = [
"success" => false,
"message" => translate('error_saving_notifications', $i18n)
];
echo json_encode($response);
} else {
$row = $result->fetchArray();
$count = $row[0];
if ($count == 0) {
$query = "INSERT INTO ntfy_notifications (enabled, host, topic, headers, user_id)
VALUES (:enabled, :host, :topic, :headers, :userId)";
} else {
$query = "UPDATE ntfy_notifications
SET enabled = :enabled, host = :host, topic = :topic, headers = :headers WHERE user_id = :userId";
}
$stmt = $db->prepare($query);
$stmt->bindValue(':enabled', $enabled, SQLITE3_INTEGER);
$stmt->bindValue(':host', $host, SQLITE3_TEXT);
$stmt->bindValue(':topic', $topic, SQLITE3_TEXT);
$stmt->bindValue(':headers', $headers, SQLITE3_TEXT);
$stmt->bindValue(':userId', $userId, SQLITE3_INTEGER);
if ($stmt->execute()) {
$response = [
"success" => true,
"message" => translate('notifications_settings_saved', $i18n)
];
echo json_encode($response);
} else {
$response = [
"success" => false,
"message" => translate('error_saving_notifications', $i18n)
];
echo json_encode($response);
}
}
}
}
} else {
$response = [
"success" => false,
"message" => translate('invalid_request_method', $i18n)
];
echo json_encode($response);
}
?>
} else {
$response = [
"success" => false,
"message" => translate('invalid_request_method', $i18n)
];
echo json_encode($response);
}
?>

View File

@@ -1,81 +1,81 @@
<?php
require_once '../../includes/connect_endpoint.php';
require_once '../../includes/connect_endpoint.php';
if (!isset($_SESSION['loggedin']) || $_SESSION['loggedin'] !== true) {
die(json_encode([
if (!isset($_SESSION['loggedin']) || $_SESSION['loggedin'] !== true) {
die(json_encode([
"success" => false,
"message" => translate('session_expired', $i18n)
]));
}
if ($_SERVER["REQUEST_METHOD"] === "POST") {
$postData = file_get_contents("php://input");
$data = json_decode($postData, true);
if (
!isset($data["user_key"]) || $data["user_key"] == "" ||
!isset($data["token"]) || $data["token"] == ""
) {
$response = [
"success" => false,
"message" => translate('session_expired', $i18n)
]));
}
"message" => translate('fill_mandatory_fields', $i18n)
];
echo json_encode($response);
} else {
$enabled = $data["enabled"];
$user_key = $data["user_key"];
$token = $data["token"];
if ($_SERVER["REQUEST_METHOD"] === "POST") {
$postData = file_get_contents("php://input");
$data = json_decode($postData, true);
$query = "SELECT COUNT(*) FROM pushover_notifications WHERE user_id = :userId";
$stmt = $db->prepare($query);
$stmt->bindParam(":userId", $userId, SQLITE3_INTEGER);
$result = $stmt->execute();
if (
!isset($data["user_key"]) || $data["user_key"] == "" ||
!isset($data["token"]) || $data["token"] == ""
) {
if ($result === false) {
$response = [
"success" => false,
"message" => translate('fill_mandatory_fields', $i18n)
"message" => translate('error_saving_notifications', $i18n)
];
echo json_encode($response);
} else {
$enabled = $data["enabled"];
$user_key = $data["user_key"];
$token = $data["token"];
$row = $result->fetchArray();
$count = $row[0];
if ($count == 0) {
$query = "INSERT INTO pushover_notifications (enabled, user_key, token, user_id)
VALUES (:enabled, :user_key, :token, :userId)";
} else {
$query = "UPDATE pushover_notifications
SET enabled = :enabled, user_key = :user_key, token = :token, user_id = :userId";
}
$query = "SELECT COUNT(*) FROM pushover_notifications WHERE user_id = :userId";
$stmt = $db->prepare($query);
$stmt->bindParam(":userId", $userId, SQLITE3_INTEGER);
$result = $stmt->execute();
if ($result === false) {
$stmt->bindValue(':enabled', $enabled, SQLITE3_INTEGER);
$stmt->bindValue(':user_key', $user_key, SQLITE3_TEXT);
$stmt->bindValue(':token', $token, SQLITE3_TEXT);
$stmt->bindValue(':userId', $userId, SQLITE3_INTEGER);
if ($stmt->execute()) {
$response = [
"success" => true,
"message" => translate('notifications_settings_saved', $i18n)
];
echo json_encode($response);
} else {
$response = [
"success" => false,
"message" => translate('error_saving_notifications', $i18n)
];
echo json_encode($response);
} else {
$row = $result->fetchArray();
$count = $row[0];
if ($count == 0) {
$query = "INSERT INTO pushover_notifications (enabled, user_key, token, user_id)
VALUES (:enabled, :user_key, :token, :userId)";
} else {
$query = "UPDATE pushover_notifications
SET enabled = :enabled, user_key = :user_key, token = :token, user_id = :userId";
}
$stmt = $db->prepare($query);
$stmt->bindValue(':enabled', $enabled, SQLITE3_INTEGER);
$stmt->bindValue(':user_key', $user_key, SQLITE3_TEXT);
$stmt->bindValue(':token', $token, SQLITE3_TEXT);
$stmt->bindValue(':userId', $userId, SQLITE3_INTEGER);
if ($stmt->execute()) {
$response = [
"success" => true,
"message" => translate('notifications_settings_saved', $i18n)
];
echo json_encode($response);
} else {
$response = [
"success" => false,
"message" => translate('error_saving_notifications', $i18n)
];
echo json_encode($response);
}
}
}
} else {
$response = [
"success" => false,
"message" => translate('invalid_request_method', $i18n)
];
echo json_encode($response);
}
} else {
$response = [
"success" => false,
"message" => translate('invalid_request_method', $i18n)
];
echo json_encode($response);
}
?>

View File

@@ -1,73 +1,73 @@
<?php
require_once '../../includes/connect_endpoint.php';
require_once '../../includes/connect_endpoint.php';
if (!isset($_SESSION['loggedin']) || $_SESSION['loggedin'] !== true) {
die(json_encode([
if (!isset($_SESSION['loggedin']) || $_SESSION['loggedin'] !== true) {
die(json_encode([
"success" => false,
"message" => translate('session_expired', $i18n)
]));
}
if ($_SERVER["REQUEST_METHOD"] === "POST") {
$postData = file_get_contents("php://input");
$data = json_decode($postData, true);
if (
!isset($data["bot_token"]) || $data["bot_token"] == "" ||
!isset($data["chat_id"]) || $data["chat_id"] == ""
) {
$response = [
"success" => false,
"message" => translate('session_expired', $i18n)
]));
}
"message" => translate('fill_mandatory_fields', $i18n)
];
echo json_encode($response);
} else {
$enabled = $data["enabled"];
$bot_token = $data["bot_token"];
$chat_id = $data["chat_id"];
if ($_SERVER["REQUEST_METHOD"] === "POST") {
$postData = file_get_contents("php://input");
$data = json_decode($postData, true);
$query = "SELECT COUNT(*) FROM telegram_notifications WHERE user_id = :userId";
$stmt = $db->prepare($query);
$stmt->bindParam(":userId", $userId, SQLITE3_INTEGER);
$result = $stmt->execute();
if (
!isset($data["bot_token"]) || $data["bot_token"] == "" ||
!isset($data["chat_id"]) || $data["chat_id"] == ""
) {
if ($result === false) {
$response = [
"success" => false,
"message" => translate('fill_mandatory_fields', $i18n)
"message" => translate('error_saving_notifications', $i18n)
];
echo json_encode($response);
} else {
$enabled = $data["enabled"];
$bot_token = $data["bot_token"];
$chat_id = $data["chat_id"];
$row = $result->fetchArray();
$count = $row[0];
if ($count == 0) {
$query = "INSERT INTO telegram_notifications (enabled, bot_token, chat_id, user_id)
VALUES (:enabled, :bot_token, :chat_id, :userId)";
} else {
$query = "UPDATE telegram_notifications
SET enabled = :enabled, bot_token = :bot_token, chat_id = :chat_id WHERE user_id = :userId";
}
$query = "SELECT COUNT(*) FROM telegram_notifications WHERE user_id = :userId";
$stmt = $db->prepare($query);
$stmt->bindParam(":userId", $userId, SQLITE3_INTEGER);
$result = $stmt->execute();
if ($result === false) {
$stmt->bindValue(':enabled', $enabled, SQLITE3_INTEGER);
$stmt->bindValue(':bot_token', $bot_token, SQLITE3_TEXT);
$stmt->bindValue(':chat_id', $chat_id, SQLITE3_TEXT);
$stmt->bindValue(':userId', $userId, SQLITE3_INTEGER);
if ($stmt->execute()) {
$response = [
"success" => true,
"message" => translate('notifications_settings_saved', $i18n)
];
echo json_encode($response);
} else {
$response = [
"success" => false,
"message" => translate('error_saving_notifications', $i18n)
];
echo json_encode($response);
} else {
$row = $result->fetchArray();
$count = $row[0];
if ($count == 0) {
$query = "INSERT INTO telegram_notifications (enabled, bot_token, chat_id, user_id)
VALUES (:enabled, :bot_token, :chat_id, :userId)";
} else {
$query = "UPDATE telegram_notifications
SET enabled = :enabled, bot_token = :bot_token, chat_id = :chat_id WHERE user_id = :userId";
}
$stmt = $db->prepare($query);
$stmt->bindValue(':enabled', $enabled, SQLITE3_INTEGER);
$stmt->bindValue(':bot_token', $bot_token, SQLITE3_TEXT);
$stmt->bindValue(':chat_id', $chat_id, SQLITE3_TEXT);
$stmt->bindValue(':userId', $userId, SQLITE3_INTEGER);
if ($stmt->execute()) {
$response = [
"success" => true,
"message" => translate('notifications_settings_saved', $i18n)
];
echo json_encode($response);
} else {
$response = [
"success" => false,
"message" => translate('error_saving_notifications', $i18n)
];
echo json_encode($response);
}
}
}
}
}
?>

View File

@@ -1,75 +1,75 @@
<?php
require_once '../../includes/connect_endpoint.php';
require_once '../../includes/connect_endpoint.php';
if (!isset($_SESSION['loggedin']) || $_SESSION['loggedin'] !== true) {
die(json_encode([
if (!isset($_SESSION['loggedin']) || $_SESSION['loggedin'] !== true) {
die(json_encode([
"success" => false,
"message" => translate('session_expired', $i18n)
]));
}
if ($_SERVER["REQUEST_METHOD"] === "POST") {
$postData = file_get_contents("php://input");
$data = json_decode($postData, true);
if (
!isset($data["webhook_url"]) || $data["webhook_url"] == "" ||
!isset($data["payload"]) || $data["payload"] == ""
) {
$response = [
"success" => false,
"message" => translate('session_expired', $i18n)
]));
}
"message" => translate('fill_mandatory_fields', $i18n)
];
echo json_encode($response);
} else {
$enabled = $data["enabled"];
$url = $data["webhook_url"];
$headers = $data["headers"];
$payload = $data["payload"];
if ($_SERVER["REQUEST_METHOD"] === "POST") {
$postData = file_get_contents("php://input");
$data = json_decode($postData, true);
$query = "SELECT COUNT(*) FROM webhook_notifications WHERE user_id = :userId";
$stmt = $db->prepare($query);
$stmt->bindParam(":userId", $userId, SQLITE3_INTEGER);
$result = $stmt->execute();
if (
!isset($data["webhook_url"]) || $data["webhook_url"] == "" ||
!isset($data["payload"]) || $data["payload"] == ""
) {
if ($result === false) {
$response = [
"success" => false,
"message" => translate('fill_mandatory_fields', $i18n)
"message" => translate('error_saving_notifications', $i18n)
];
echo json_encode($response);
} else {
$enabled = $data["enabled"];
$url = $data["webhook_url"];
$headers = $data["headers"];
$payload = $data["payload"];
$row = $result->fetchArray();
$count = $row[0];
if ($count == 0) {
$query = "INSERT INTO webhook_notifications (enabled, url, headers, payload, user_id)
VALUES (:enabled, :url, :headers, :payload, :userId)";
} else {
$query = "UPDATE webhook_notifications
SET enabled = :enabled, url = :url, headers = :headers, payload = :payload WHERE user_id = :userId";
}
$query = "SELECT COUNT(*) FROM webhook_notifications WHERE user_id = :userId";
$stmt = $db->prepare($query);
$stmt->bindParam(":userId", $userId, SQLITE3_INTEGER);
$result = $stmt->execute();
if ($result === false) {
$stmt->bindValue(':enabled', $enabled, SQLITE3_INTEGER);
$stmt->bindValue(':url', $url, SQLITE3_TEXT);
$stmt->bindValue(':headers', $headers, SQLITE3_TEXT);
$stmt->bindValue(':payload', $payload, SQLITE3_TEXT);
$stmt->bindValue(':userId', $userId, SQLITE3_INTEGER);
if ($stmt->execute()) {
$response = [
"success" => true,
"message" => translate('notifications_settings_saved', $i18n)
];
echo json_encode($response);
} else {
$response = [
"success" => false,
"message" => translate('error_saving_notifications', $i18n)
];
echo json_encode($response);
} else {
$row = $result->fetchArray();
$count = $row[0];
if ($count == 0) {
$query = "INSERT INTO webhook_notifications (enabled, url, headers, payload, user_id)
VALUES (:enabled, :url, :headers, :payload, :userId)";
} else {
$query = "UPDATE webhook_notifications
SET enabled = :enabled, url = :url, headers = :headers, payload = :payload WHERE user_id = :userId";
}
$stmt = $db->prepare($query);
$stmt->bindValue(':enabled', $enabled, SQLITE3_INTEGER);
$stmt->bindValue(':url', $url, SQLITE3_TEXT);
$stmt->bindValue(':headers', $headers, SQLITE3_TEXT);
$stmt->bindValue(':payload', $payload, SQLITE3_TEXT);
$stmt->bindValue(':userId', $userId, SQLITE3_INTEGER);
if ($stmt->execute()) {
$response = [
"success" => true,
"message" => translate('notifications_settings_saved', $i18n)
];
echo json_encode($response);
} else {
$response = [
"success" => false,
"message" => translate('error_saving_notifications', $i18n)
];
echo json_encode($response);
}
}
}
}
}
?>

View File

@@ -40,17 +40,17 @@ if ($_SERVER["REQUEST_METHOD"] === "POST") {
]
]
];
if (!empty($bot_username)) {
$postfields['username'] = $bot_username;
}
if (!empty($bot_avatar_url)) {
$postfields['avatar_url'] = $bot_avatar_url;
}
$ch = curl_init();
// Set the URL and other options
curl_setopt($ch, CURLOPT_URL, $webhook_url);
curl_setopt($ch, CURLOPT_POST, 1);

View File

@@ -45,7 +45,7 @@ if ($_SERVER["REQUEST_METHOD"] === "POST") {
$fromEmail = $data["fromemail"] ? $data['fromemail'] : "wallos@wallosapp.com";
$mail = new PHPMailer(true);
$mail->CharSet="UTF-8";
$mail->CharSet = "UTF-8";
$mail->isSMTP();
$mail->Host = $smtpAddress;
@@ -83,4 +83,4 @@ if ($_SERVER["REQUEST_METHOD"] === "POST") {
}
}
?>
?>

View File

@@ -28,7 +28,7 @@ if ($_SERVER["REQUEST_METHOD"] === "POST") {
$priority = 5;
$url = $data["gotify_url"];
$token = $data["token"];
$token = $data["token"];
$ch = curl_init();

View File

@@ -26,9 +26,9 @@ if ($_SERVER["REQUEST_METHOD"] === "POST") {
$host = rtrim($data["host"], '/');
$topic = $data["topic"];
$headers = json_decode($data["headers"], true);
$customheaders = array_map(function($key, $value) {
$customheaders = array_map(function ($key, $value) {
return "$key: $value";
}, array_keys($headers), $headers);
}, array_keys($headers), $headers);
$url = "$host/$topic";

View File

@@ -46,7 +46,7 @@ if ($_SERVER["REQUEST_METHOD"] === "POST") {
// Execute the request
$response = curl_exec($ch);
// Close the cURL session
curl_close($ch);

View File

@@ -1,217 +1,222 @@
<?php
error_reporting(E_ERROR | E_PARSE);
require_once '../../includes/connect_endpoint.php';
require_once '../../includes/inputvalidation.php';
require_once '../../includes/getsettings.php';
error_reporting(E_ERROR | E_PARSE);
require_once '../../includes/connect_endpoint.php';
require_once '../../includes/inputvalidation.php';
require_once '../../includes/getsettings.php';
function sanitizeFilename($filename) {
$filename = preg_replace("/[^a-zA-Z0-9\s]/", "", $filename);
$filename = str_replace(" ", "-", $filename);
$filename = str_replace(".", "", $filename);
return $filename;
}
function sanitizeFilename($filename)
{
$filename = preg_replace("/[^a-zA-Z0-9\s]/", "", $filename);
$filename = str_replace(" ", "-", $filename);
$filename = str_replace(".", "", $filename);
return $filename;
}
function validateFileExtension($fileExtension) {
$allowedExtensions = ['png', 'jpg', 'jpeg', 'gif', 'jtif', 'webp'];
return in_array($fileExtension, $allowedExtensions);
}
function validateFileExtension($fileExtension)
{
$allowedExtensions = ['png', 'jpg', 'jpeg', 'gif', 'jtif', 'webp'];
return in_array($fileExtension, $allowedExtensions);
}
function getLogoFromUrl($url, $uploadDir, $name) {
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
$imageData = curl_exec($ch);
if ($imageData !== false) {
$timestamp = time();
$fileName = $timestamp . '-payments-' . sanitizeFilename($name) . '.png';
$uploadDir = '../../images/uploads/logos/';
$uploadFile = $uploadDir . $fileName;
if (saveLogo($imageData, $uploadFile, $name)) {
return $fileName;
} else {
echo translate('error_fetching_image', $i18n) . ": " . curl_error($ch);
return "";
}
function getLogoFromUrl($url, $uploadDir, $name, $i18n, $settings)
{
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
$imageData = curl_exec($ch);
if ($imageData !== false) {
$timestamp = time();
$fileName = $timestamp . '-payments-' . sanitizeFilename($name) . '.png';
$uploadDir = '../../images/uploads/logos/';
$uploadFile = $uploadDir . $fileName;
if (saveLogo($imageData, $uploadFile, $name, $settings)) {
curl_close($ch);
return $fileName;
} else {
curl_close($ch);
echo translate('error_fetching_image', $i18n) . ": " . curl_error($ch);
return "";
}
}
function saveLogo($imageData, $uploadFile, $name) {
$image = imagecreatefromstring($imageData);
$removeBackground = isset($settings['removeBackground']) && $settings['removeBackground'] === 'true';
if ($image !== false) {
$tempFile = tempnam(sys_get_temp_dir(), 'logo');
imagepng($image, $tempFile);
imagedestroy($image);
$imagick = new Imagick($tempFile);
if ($removeBackground) {
$fuzz = Imagick::getQuantum() * 0.1; // 10%
$imagick->transparentPaintImage("rgb(247, 247, 247)", 0, $fuzz, false);
}
$imagick->setImageFormat('png');
$imagick->writeImage($uploadFile);
$imagick->clear();
$imagick->destroy();
unlink($tempFile);
return true;
} else {
return false;
}
}
function resizeAndUploadLogo($uploadedFile, $uploadDir, $name) {
$targetWidth = 70;
$targetHeight = 48;
$timestamp = time();
$originalFileName = $uploadedFile['name'];
$fileExtension = pathinfo($originalFileName, PATHINFO_EXTENSION);
$fileExtension = validateFileExtension($fileExtension) ? $fileExtension : 'png';
$fileName = $timestamp . '-payments-' . sanitizeFilename($name) . '.' . $fileExtension;
$uploadFile = $uploadDir . $fileName;
if (move_uploaded_file($uploadedFile['tmp_name'], $uploadFile)) {
$fileInfo = getimagesize($uploadFile);
if ($fileInfo !== false) {
$width = $fileInfo[0];
$height = $fileInfo[1];
// Load the image based on its format
if ($fileExtension === 'png') {
$image = imagecreatefrompng($uploadFile);
} elseif ($fileExtension === 'jpg' || $fileExtension === 'jpeg') {
$image = imagecreatefromjpeg($uploadFile);
} elseif ($fileExtension === 'gif') {
$image = imagecreatefromgif($uploadFile);
} elseif ($fileExtension === 'webp') {
$image = imagecreatefromwebp($uploadFile);
} else {
// Handle other image formats as needed
return "";
}
// Enable alpha channel (transparency) for PNG images
if ($fileExtension === 'png') {
imagesavealpha($image, true);
}
$newWidth = $width;
$newHeight = $height;
if ($width > $targetWidth) {
$newWidth = $targetWidth;
$newHeight = ($targetWidth / $width) * $height;
}
if ($newHeight > $targetHeight) {
$newWidth = ($targetHeight / $newHeight) * $newWidth;
$newHeight = $targetHeight;
}
$resizedImage = imagecreatetruecolor($newWidth, $newHeight);
imagesavealpha($resizedImage, true);
$transparency = imagecolorallocatealpha($resizedImage, 0, 0, 0, 127);
imagefill($resizedImage, 0, 0, $transparency);
imagecopyresampled($resizedImage, $image, 0, 0, 0, 0, $newWidth, $newHeight, $width, $height);
if ($fileExtension === 'png') {
imagepng($resizedImage, $uploadFile);
} elseif ($fileExtension === 'jpg' || $fileExtension === 'jpeg') {
imagejpeg($resizedImage, $uploadFile);
} elseif ($fileExtension === 'gif') {
imagegif($resizedImage, $uploadFile);
} elseif ($fileExtension === 'webp') {
imagewebp($resizedImage, $uploadFile);
} else {
return "";
}
imagedestroy($image);
imagedestroy($resizedImage);
return $fileName;
}
}
} else {
echo translate('error_fetching_image', $i18n) . ": " . curl_error($ch);
return "";
}
}
if (isset($_SESSION['loggedin']) && $_SESSION['loggedin'] === true) {
if ($_SERVER["REQUEST_METHOD"] === "POST") {
$enabled = 1;
$name = validate($_POST["paymentname"]);
$iconUrl = validate($_POST['icon-url']);
function saveLogo($imageData, $uploadFile, $name, $settings)
{
$image = imagecreatefromstring($imageData);
$removeBackground = isset($settings['removeBackground']) && $settings['removeBackground'] === 'true';
if ($image !== false) {
$tempFile = tempnam(sys_get_temp_dir(), 'logo');
imagepng($image, $tempFile);
imagedestroy($image);
if ($name === "" || ($iconUrl === "" && empty($_FILES['paymenticon']['name']))) {
$response = [
"success" => false,
"errorMessage" => translate('fill_all_fields', $i18n)
];
echo json_encode($response);
exit();
}
$imagick = new Imagick($tempFile);
if ($removeBackground) {
$fuzz = Imagick::getQuantum() * 0.1; // 10%
$imagick->transparentPaintImage("rgb(247, 247, 247)", 0, $fuzz, false);
}
$imagick->setImageFormat('png');
$imagick->writeImage($uploadFile);
$icon = "";
$imagick->clear();
$imagick->destroy();
unlink($tempFile);
if($iconUrl !== "") {
$icon = getLogoFromUrl($iconUrl, '../../images/uploads/logos/', $name);
return true;
} else {
return false;
}
}
function resizeAndUploadLogo($uploadedFile, $uploadDir, $name)
{
$targetWidth = 70;
$targetHeight = 48;
$timestamp = time();
$originalFileName = $uploadedFile['name'];
$fileExtension = pathinfo($originalFileName, PATHINFO_EXTENSION);
$fileExtension = validateFileExtension($fileExtension) ? $fileExtension : 'png';
$fileName = $timestamp . '-payments-' . sanitizeFilename($name) . '.' . $fileExtension;
$uploadFile = $uploadDir . $fileName;
if (move_uploaded_file($uploadedFile['tmp_name'], $uploadFile)) {
$fileInfo = getimagesize($uploadFile);
if ($fileInfo !== false) {
$width = $fileInfo[0];
$height = $fileInfo[1];
// Load the image based on its format
if ($fileExtension === 'png') {
$image = imagecreatefrompng($uploadFile);
} elseif ($fileExtension === 'jpg' || $fileExtension === 'jpeg') {
$image = imagecreatefromjpeg($uploadFile);
} elseif ($fileExtension === 'gif') {
$image = imagecreatefromgif($uploadFile);
} elseif ($fileExtension === 'webp') {
$image = imagecreatefromwebp($uploadFile);
} else {
if (!empty($_FILES['paymenticon']['name'])) {
$fileType = mime_content_type($_FILES['paymenticon']['tmp_name']);
if (strpos($fileType, 'image') === false) {
$response = [
"success" => false,
"errorMessage" => translate('fill_all_fields', $i18n)
];
echo json_encode($response);
exit();
}
$icon = resizeAndUploadLogo($_FILES['paymenticon'], '../../images/uploads/logos/', $name);
}
// Handle other image formats as needed
return "";
}
// Get the maximum existing ID
$stmt = $db->prepare("SELECT MAX(id) as maxID FROM payment_methods");
$result = $stmt->execute();
$row = $result->fetchArray(SQLITE3_ASSOC);
$maxID = $row['maxID'];
// Enable alpha channel (transparency) for PNG images
if ($fileExtension === 'png') {
imagesavealpha($image, true);
}
// Ensure the new ID is greater than 31
$newID = max($maxID + 1, 32);
$newWidth = $width;
$newHeight = $height;
// Insert the new record with the new ID
$sql = "INSERT INTO payment_methods (id, name, icon, enabled, user_id) VALUES (:id, :name, :icon, :enabled, :userId)";
$stmt = $db->prepare($sql);
if ($width > $targetWidth) {
$newWidth = $targetWidth;
$newHeight = ($targetWidth / $width) * $height;
}
$stmt->bindParam(':id', $newID, SQLITE3_INTEGER);
$stmt->bindParam(':name', $name, SQLITE3_TEXT);
$stmt->bindParam(':icon', $icon, SQLITE3_TEXT);
$stmt->bindParam(':enabled', $enabled, SQLITE3_INTEGER);
$stmt->bindParam(':userId', $userId, SQLITE3_INTEGER);
if ($newHeight > $targetHeight) {
$newWidth = ($targetHeight / $newHeight) * $newWidth;
$newHeight = $targetHeight;
}
if ($stmt->execute()) {
$success['success'] = true;
$success['message'] = translate('payment_method_added_successfuly', $i18n);
$json = json_encode($success);
header('Content-Type: application/json');
echo $json;
exit();
$resizedImage = imagecreatetruecolor($newWidth, $newHeight);
imagesavealpha($resizedImage, true);
$transparency = imagecolorallocatealpha($resizedImage, 0, 0, 0, 127);
imagefill($resizedImage, 0, 0, $transparency);
imagecopyresampled($resizedImage, $image, 0, 0, 0, 0, $newWidth, $newHeight, $width, $height);
if ($fileExtension === 'png') {
imagepng($resizedImage, $uploadFile);
} elseif ($fileExtension === 'jpg' || $fileExtension === 'jpeg') {
imagejpeg($resizedImage, $uploadFile);
} elseif ($fileExtension === 'gif') {
imagegif($resizedImage, $uploadFile);
} elseif ($fileExtension === 'webp') {
imagewebp($resizedImage, $uploadFile);
} else {
echo translate('error', $i18n) . ": " . $db->lastErrorMsg();
return "";
}
imagedestroy($image);
imagedestroy($resizedImage);
return $fileName;
}
}
$db->close();
return "";
}
if (isset($_SESSION['loggedin']) && $_SESSION['loggedin'] === true) {
if ($_SERVER["REQUEST_METHOD"] === "POST") {
$enabled = 1;
$name = validate($_POST["paymentname"]);
$iconUrl = validate($_POST['icon-url']);
if ($name === "" || ($iconUrl === "" && empty($_FILES['paymenticon']['name']))) {
$response = [
"success" => false,
"errorMessage" => translate('fill_all_fields', $i18n)
];
echo json_encode($response);
exit();
}
$icon = "";
if ($iconUrl !== "") {
$icon = getLogoFromUrl($iconUrl, '../../images/uploads/logos/', $name, $i18n, $settings);
} else {
if (!empty($_FILES['paymenticon']['name'])) {
$fileType = mime_content_type($_FILES['paymenticon']['tmp_name']);
if (strpos($fileType, 'image') === false) {
$response = [
"success" => false,
"errorMessage" => translate('fill_all_fields', $i18n)
];
echo json_encode($response);
exit();
}
$icon = resizeAndUploadLogo($_FILES['paymenticon'], '../../images/uploads/logos/', $name);
}
}
// Get the maximum existing ID
$stmt = $db->prepare("SELECT MAX(id) as maxID FROM payment_methods");
$result = $stmt->execute();
$row = $result->fetchArray(SQLITE3_ASSOC);
$maxID = $row['maxID'];
// Ensure the new ID is greater than 31
$newID = max($maxID + 1, 32);
// Insert the new record with the new ID
$sql = "INSERT INTO payment_methods (id, name, icon, enabled, user_id) VALUES (:id, :name, :icon, :enabled, :userId)";
$stmt = $db->prepare($sql);
$stmt->bindParam(':id', $newID, SQLITE3_INTEGER);
$stmt->bindParam(':name', $name, SQLITE3_TEXT);
$stmt->bindParam(':icon', $icon, SQLITE3_TEXT);
$stmt->bindParam(':enabled', $enabled, SQLITE3_INTEGER);
$stmt->bindParam(':userId', $userId, SQLITE3_INTEGER);
if ($stmt->execute()) {
$success['success'] = true;
$success['message'] = translate('payment_method_added_successfuly', $i18n);
$json = json_encode($success);
header('Content-Type: application/json');
echo $json;
exit();
} else {
echo translate('error', $i18n) . ": " . $db->lastErrorMsg();
}
}
}
$db->close();
?>

View File

@@ -27,4 +27,4 @@ if (isset($_SESSION['loggedin']) && $_SESSION['loggedin'] === true) {
}
$db->close();
?>
?>

View File

@@ -6,12 +6,12 @@ if (isset($_SESSION['loggedin']) && $_SESSION['loggedin'] === true) {
$paymentsInUseQuery = $db->prepare('SELECT id FROM payment_methods WHERE id IN (SELECT DISTINCT payment_method_id FROM subscriptions) AND user_id = :userId');
$paymentsInUseQuery->bindParam(':userId', $userId, SQLITE3_INTEGER);
$result = $paymentsInUseQuery->execute();
$paymentsInUse = [];
while ($row = $result->fetchArray(SQLITE3_ASSOC)) {
$paymentsInUse[] = $row['id'];
}
$sql = "SELECT * FROM payment_methods WHERE user_id = :userId";
$stmt = $db->prepare($sql);
$stmt->bindParam(':userId', $userId, SQLITE3_INTEGER);
@@ -20,7 +20,7 @@ if (isset($_SESSION['loggedin']) && $_SESSION['loggedin'] === true) {
if ($result) {
$payments = array();
while ($row = $result->fetchArray(SQLITE3_ASSOC)) {
$payments[] = $row;
$payments[] = $row;
}
} else {
http_response_code(500);
@@ -32,26 +32,25 @@ if (isset($_SESSION['loggedin']) && $_SESSION['loggedin'] === true) {
$paymentIconFolder = (strpos($payment['icon'], 'images/uploads/icons/') !== false) ? "" : "images/uploads/logos/";
$inUse = in_array($payment['id'], $paymentsInUse);
?>
<div class="payments-payment"
data-enabled="<?= $payment['enabled']; ?>"
data-in-use="<?= $inUse ? 'yes' : 'no' ?>"
data-paymentid="<?= $payment['id'] ?>"
title="<?= $inUse ? translate('cant_delete_payment_method_in_use', $i18n) : ($payment['enabled'] ? translate('disable', $i18n) : translate('enable', $i18n)) ?>"
onClick="togglePayment(<?= $payment['id'] ?>)">
<img src="<?= $paymentIconFolder.$payment['icon'] ?>" alt="Logo" />
<span class="payment-name">
<?= $payment['name'] ?>
</span>
<?php
if (!$inUse) {
?>
<div class="delete-payment-method" title="<?= translate('delete', $i18n) ?>" data-paymentid="<?= $payment['id'] ?>" onclick="deletePaymentMethod(<?= $payment['id'] ?>)">
x
</div>
<?php
}
<div class="payments-payment" data-enabled="<?= $payment['enabled']; ?>" data-in-use="<?= $inUse ? 'yes' : 'no' ?>"
data-paymentid="<?= $payment['id'] ?>"
title="<?= $inUse ? translate('cant_delete_payment_method_in_use', $i18n) : ($payment['enabled'] ? translate('disable', $i18n) : translate('enable', $i18n)) ?>"
onClick="togglePayment(<?= $payment['id'] ?>)">
<img src="<?= $paymentIconFolder . $payment['icon'] ?>" alt="Logo" />
<span class="payment-name">
<?= $payment['name'] ?>
</span>
<?php
if (!$inUse) {
?>
</div>
<div class="delete-payment-method" title="<?= translate('delete', $i18n) ?>" data-paymentid="<?= $payment['id'] ?>"
onclick="deletePaymentMethod(<?= $payment['id'] ?>)">
x
</div>
<?php
}
?>
</div>
<?php
}
} else {

View File

@@ -51,5 +51,5 @@ if ($resultUpdate) {
die(json_encode([
"success" => false,
"message" => tranlate('failed_update_payment', $i18n)
"message" => translate('failed_update_payment', $i18n)
]));

View File

@@ -1,83 +1,84 @@
<?php
if (isset($_GET['search'])) {
$searchTerm = urlencode($_GET['search'] . " logo");
if (isset($_GET['search'])) {
$searchTerm = urlencode($_GET['search'] . " logo");
$url = "https://www.google.com/search?q={$searchTerm}&tbm=isch";
$backupUrl = "https://search.brave.com/search?q={$searchTerm}";
$url = "https://www.google.com/search?q={$searchTerm}&tbm=isch";
$backupUrl = "https://search.brave.com/search?q={$searchTerm}";
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
// Convert all environment variable keys to lowercase
$envVars = array_change_key_case($_SERVER, CASE_LOWER);
// Check for http_proxy or https_proxy environment variables
$httpProxy = isset($envVars['http_proxy']) ? $envVars['http_proxy'] : null;
$httpsProxy = isset($envVars['https_proxy']) ? $envVars['https_proxy'] : null;
if (!empty($httpProxy)) {
curl_setopt($ch, CURLOPT_PROXY, $httpProxy);
} elseif (!empty($httpsProxy)) {
curl_setopt($ch, CURLOPT_PROXY, $httpsProxy);
}
$response = curl_exec($ch);
if ($response === false) {
// If cURL fails to access google images, use brave image search as a backup
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_URL, $backupUrl);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
// Convert all environment variable keys to lowercase
$envVars = array_change_key_case($_SERVER, CASE_LOWER);
// Check for http_proxy or https_proxy environment variables
$httpProxy = isset($envVars['http_proxy']) ? $envVars['http_proxy'] : null;
$httpsProxy = isset($envVars['https_proxy']) ? $envVars['https_proxy'] : null;
if (!empty($httpProxy)) {
curl_setopt($ch, CURLOPT_PROXY, $httpProxy);
} elseif (!empty($httpsProxy)) {
curl_setopt($ch, CURLOPT_PROXY, $httpsProxy);
}
$response = curl_exec($ch);
if ($response === false) {
// If cURL fails to access google images, use brave image search as a backup
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $backupUrl);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
$envVars = array_change_key_case($_SERVER, CASE_LOWER);
$httpProxy = isset($envVars['http_proxy']) ? $envVars['http_proxy'] : null;
$httpsProxy = isset($envVars['https_proxy']) ? $envVars['https_proxy'] : null;
if (!empty($httpProxy)) {
curl_setopt($ch, CURLOPT_PROXY, $httpProxy);
} elseif (!empty($httpsProxy)) {
curl_setopt($ch, CURLOPT_PROXY, $httpsProxy);
}
$response = curl_exec($ch);
if ($response === false) {
echo json_encode(['error' => 'Failed to fetch data from Google.']);
} else {
$imageUrls = extractImageUrlsFromPage($response);
header('Content-Type: application/json');
echo json_encode(['imageUrls' => $imageUrls]);
}
echo json_encode(['error' => 'Failed to fetch data from Google.']);
} else {
// Parse the HTML response to extract image URLs
$imageUrls = extractImageUrlsFromPage($response);
// Pass the image URLs to the client
header('Content-Type: application/json');
echo json_encode(['imageUrls' => $imageUrls]);
}
curl_close($ch);
} else {
echo json_encode(['error' => 'Invalid request.']);
// Parse the HTML response to extract image URLs
$imageUrls = extractImageUrlsFromPage($response);
// Pass the image URLs to the client
header('Content-Type: application/json');
echo json_encode(['imageUrls' => $imageUrls]);
}
function extractImageUrlsFromPage($html) {
$imageUrls = [];
curl_close($ch);
} else {
echo json_encode(['error' => 'Invalid request.']);
}
$doc = new DOMDocument();
@$doc->loadHTML($html);
function extractImageUrlsFromPage($html)
{
$imageUrls = [];
$imgTags = $doc->getElementsByTagName('img');
foreach ($imgTags as $imgTag) {
$src = $imgTag->getAttribute('src');
if (!strstr($imgTag->getAttribute('class'), "favicon") && !strstr($imgTag->getAttribute('class'), "logo")) {
if (filter_var($src, FILTER_VALIDATE_URL)) {
$imageUrls[] = $src;
}
$doc = new DOMDocument();
@$doc->loadHTML($html);
$imgTags = $doc->getElementsByTagName('img');
foreach ($imgTags as $imgTag) {
$src = $imgTag->getAttribute('src');
if (!strstr($imgTag->getAttribute('class'), "favicon") && !strstr($imgTag->getAttribute('class'), "logo")) {
if (filter_var($src, FILTER_VALIDATE_URL)) {
$imageUrls[] = $src;
}
}
return $imageUrls;
}
return $imageUrls;
}
?>

View File

@@ -20,7 +20,7 @@ if (isset($_SESSION['loggedin']) && $_SESSION['loggedin'] === true) {
"success" => true,
"message" => translate("sort_order_saved", $i18n)
];
echo json_encode($response);
echo json_encode($response);
} else {
$response = [
"success" => false,

View File

@@ -1,35 +1,35 @@
<?php
require_once '../../includes/connect_endpoint.php';
if (!isset($_SESSION['loggedin']) || $_SESSION['loggedin'] !== true) {
require_once '../../includes/connect_endpoint.php';
if (!isset($_SESSION['loggedin']) || $_SESSION['loggedin'] !== true) {
die(json_encode([
"success" => false,
"message" => translate('session_expired', $i18n)
]));
}
if ($_SERVER["REQUEST_METHOD"] === "POST") {
$postData = file_get_contents("php://input");
$data = json_decode($postData, true);
$color = $data['color'];
$stmt = $db->prepare('UPDATE settings SET color_theme = :color WHERE user_id = :userId');
$stmt->bindParam(':color', $color, SQLITE3_TEXT);
$stmt->bindParam(':userId', $userId, SQLITE3_INTEGER);
if ($stmt->execute()) {
die(json_encode([
"success" => true,
"message" => translate("success", $i18n)
]));
} else {
die(json_encode([
"success" => false,
"message" => translate('session_expired', $i18n)
"message" => translate("error", $i18n)
]));
}
if ($_SERVER["REQUEST_METHOD"] === "POST") {
$postData = file_get_contents("php://input");
$data = json_decode($postData, true);
$color = $data['color'];
$stmt = $db->prepare('UPDATE settings SET color_theme = :color WHERE user_id = :userId');
$stmt->bindParam(':color', $color, SQLITE3_TEXT);
$stmt->bindParam(':userId', $userId, SQLITE3_INTEGER);
if ($stmt->execute()) {
die(json_encode([
"success" => true,
"message" => translate("success", $i18n)
]));
} else {
die(json_encode([
"success" => false,
"message" => translate("error", $i18n)
]));
}
}
}
?>

View File

@@ -11,7 +11,7 @@ if (!isset($_SESSION['loggedin']) || $_SESSION['loggedin'] !== true) {
if ($_SERVER["REQUEST_METHOD"] === "POST") {
$postData = file_get_contents("php://input");
$data = json_decode($postData, true);
$convert_currency = $data['value'];
$stmt = $db->prepare('UPDATE settings SET convert_currency = :convert_currency WHERE user_id = :userId');

View File

@@ -1,42 +1,42 @@
<?php
require_once '../../includes/connect_endpoint.php';
require_once '../../includes/connect_endpoint.php';
if (!isset($_SESSION['loggedin']) || $_SESSION['loggedin'] !== true) {
if (!isset($_SESSION['loggedin']) || $_SESSION['loggedin'] !== true) {
die(json_encode([
"success" => false,
"message" => translate('session_expired', $i18n)
]));
}
if ($_SERVER["REQUEST_METHOD"] === "POST") {
$postData = file_get_contents("php://input");
$data = json_decode($postData, true);
$main_color = $data['mainColor'];
$accent_color = $data['accentColor'];
$hover_color = $data['hoverColor'];
$stmt = $db->prepare('DELETE FROM custom_colors');
$stmt->execute();
$stmt = $db->prepare('INSERT INTO custom_colors (main_color, accent_color, hover_color, user_id) VALUES (:main_color, :accent_color, :hover_color, :userId)');
$stmt->bindParam(':main_color', $main_color, SQLITE3_TEXT);
$stmt->bindParam(':accent_color', $accent_color, SQLITE3_TEXT);
$stmt->bindParam(':hover_color', $hover_color, SQLITE3_TEXT);
$stmt->bindParam(':userId', $userId, SQLITE3_INTEGER);
if ($stmt->execute()) {
die(json_encode([
"success" => true,
"message" => translate("success", $i18n)
]));
} else {
die(json_encode([
"success" => false,
"message" => translate('session_expired', $i18n)
"message" => translate("error", $i18n)
]));
}
if ($_SERVER["REQUEST_METHOD"] === "POST") {
$postData = file_get_contents("php://input");
$data = json_decode($postData, true);
$main_color = $data['mainColor'];
$accent_color = $data['accentColor'];
$hover_color = $data['hoverColor'];
$stmt = $db->prepare('DELETE FROM custom_colors');
$stmt->execute();
$stmt = $db->prepare('INSERT INTO custom_colors (main_color, accent_color, hover_color, user_id) VALUES (:main_color, :accent_color, :hover_color, :userId)');
$stmt->bindParam(':main_color', $main_color, SQLITE3_TEXT);
$stmt->bindParam(':accent_color', $accent_color, SQLITE3_TEXT);
$stmt->bindParam(':hover_color', $hover_color, SQLITE3_TEXT);
$stmt->bindParam(':userId', $userId, SQLITE3_INTEGER);
if ($stmt->execute()) {
die(json_encode([
"success" => true,
"message" => translate("success", $i18n)
]));
} else {
die(json_encode([
"success" => false,
"message" => translate("error", $i18n)
]));
}
}
}
?>

View File

@@ -11,7 +11,7 @@ if (!isset($_SESSION['loggedin']) || $_SESSION['loggedin'] !== true) {
if ($_SERVER["REQUEST_METHOD"] === "POST") {
$postData = file_get_contents("php://input");
$data = json_decode($postData, true);
$hide_disabled = $data['value'];
$stmt = $db->prepare('UPDATE settings SET hide_disabled = :hide_disabled WHERE user_id = :userId');

View File

@@ -11,7 +11,7 @@ if (!isset($_SESSION['loggedin']) || $_SESSION['loggedin'] !== true) {
if ($_SERVER["REQUEST_METHOD"] === "POST") {
$postData = file_get_contents("php://input");
$data = json_decode($postData, true);
$monthly_price = $data['value'];
$stmt = $db->prepare('UPDATE settings SET monthly_price = :monthly_price WHERE user_id = :userId');

View File

@@ -11,7 +11,7 @@ if (!isset($_SESSION['loggedin']) || $_SESSION['loggedin'] !== true) {
if ($_SERVER["REQUEST_METHOD"] === "POST") {
$postData = file_get_contents("php://input");
$data = json_decode($postData, true);
$remove_background = $data['value'];
$stmt = $db->prepare('UPDATE settings SET remove_background = :remove_background WHERE user_id = :userId');

View File

@@ -1,29 +1,29 @@
<?php
require_once '../../includes/connect_endpoint.php';
if (!isset($_SESSION['loggedin']) || $_SESSION['loggedin'] !== true) {
require_once '../../includes/connect_endpoint.php';
if (!isset($_SESSION['loggedin']) || $_SESSION['loggedin'] !== true) {
die(json_encode([
"success" => false,
"message" => translate('session_expired', $i18n)
]));
}
if ($_SERVER["REQUEST_METHOD"] === "DELETE") {
$stmt = $db->prepare('DELETE FROM custom_colors WHERE user_id = :userId');
$stmt->bindParam(':userId', $userId, SQLITE3_INTEGER);
if ($stmt->execute()) {
die(json_encode([
"success" => true,
"message" => translate("success", $i18n)
]));
} else {
die(json_encode([
"success" => false,
"message" => translate('session_expired', $i18n)
"message" => translate("error", $i18n)
]));
}
if ($_SERVER["REQUEST_METHOD"] === "DELETE") {
$stmt = $db->prepare('DELETE FROM custom_colors WHERE user_id = :userId');
$stmt->bindParam(':userId', $userId, SQLITE3_INTEGER);
if ($stmt->execute()) {
die(json_encode([
"success" => true,
"message" => translate("success", $i18n)
]));
} else {
die(json_encode([
"success" => false,
"message" => translate("error", $i18n)
]));
}
}
}
?>

View File

@@ -11,7 +11,7 @@ if (!isset($_SESSION['loggedin']) || $_SESSION['loggedin'] !== true) {
if ($_SERVER["REQUEST_METHOD"] === "POST") {
$postData = file_get_contents("php://input");
$data = json_decode($postData, true);
$theme = $data['theme'];
$stmt = $db->prepare('UPDATE settings SET dark_theme = :theme WHERE user_id = :userId');

View File

@@ -1,240 +1,246 @@
<?php
error_reporting(E_ERROR | E_PARSE);
require_once '../../includes/connect_endpoint.php';
require_once '../../includes/inputvalidation.php';
require_once '../../includes/getsettings.php';
error_reporting(E_ERROR | E_PARSE);
require_once '../../includes/connect_endpoint.php';
require_once '../../includes/inputvalidation.php';
require_once '../../includes/getsettings.php';
function sanitizeFilename($filename) {
$filename = preg_replace("/[^a-zA-Z0-9\s]/", "", $filename);
$filename = str_replace(" ", "-", $filename);
$filename = str_replace(".", "", $filename);
return $filename;
}
function sanitizeFilename($filename)
{
$filename = preg_replace("/[^a-zA-Z0-9\s]/", "", $filename);
$filename = str_replace(" ", "-", $filename);
$filename = str_replace(".", "", $filename);
return $filename;
}
function validateFileExtension($fileExtension) {
$allowedExtensions = ['png', 'jpg', 'jpeg', 'gif', 'webp'];
return in_array($fileExtension, $allowedExtensions);
}
function validateFileExtension($fileExtension)
{
$allowedExtensions = ['png', 'jpg', 'jpeg', 'gif', 'webp'];
return in_array($fileExtension, $allowedExtensions);
}
function getLogoFromUrl($url, $uploadDir, $name, $settings) {
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
$imageData = curl_exec($ch);
if ($imageData !== false) {
$timestamp = time();
$fileName = $timestamp . '-' . sanitizeFilename($name) . '.png';
$uploadDir = '../../images/uploads/logos/';
$uploadFile = $uploadDir . $fileName;
if (saveLogo($imageData, $uploadFile, $name, $settings)) {
return $fileName;
} else {
echo translate('error_fetching_image', $i18n) . ": " . curl_error($ch);
return "";
}
function getLogoFromUrl($url, $uploadDir, $name, $settings, $i18n)
{
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
$imageData = curl_exec($ch);
if ($imageData !== false) {
$timestamp = time();
$fileName = $timestamp . '-' . sanitizeFilename($name) . '.png';
$uploadDir = '../../images/uploads/logos/';
$uploadFile = $uploadDir . $fileName;
if (saveLogo($imageData, $uploadFile, $name, $settings)) {
curl_close($ch);
return $fileName;
} else {
curl_close($ch);
echo translate('error_fetching_image', $i18n) . ": " . curl_error($ch);
return "";
}
}
function saveLogo($imageData, $uploadFile, $name, $settings) {
$image = imagecreatefromstring($imageData);
$removeBackground = isset($settings['removeBackground']) && $settings['removeBackground'] === 'true';
if ($image !== false) {
$tempFile = tempnam(sys_get_temp_dir(), 'logo');
imagepng($image, $tempFile);
imagedestroy($image);
$imagick = new Imagick($tempFile);
if ($removeBackground) {
$fuzz = Imagick::getQuantum() * 0.1; // 10%
$imagick->transparentPaintImage("rgb(247, 247, 247)", 0, $fuzz, false);
}
$imagick->setImageFormat('png');
$imagick->writeImage($uploadFile);
$imagick->clear();
$imagick->destroy();
unlink($tempFile);
return true;
} else {
return false;
}
}
function resizeAndUploadLogo($uploadedFile, $uploadDir, $name, $settings) {
$targetWidth = 135;
$targetHeight = 42;
$timestamp = time();
$originalFileName = $uploadedFile['name'];
$fileExtension = pathinfo($originalFileName, PATHINFO_EXTENSION);
$fileExtension = validateFileExtension($fileExtension) ? $fileExtension : 'png';
$fileName = $timestamp . '-' . sanitizeFilename($name) . '.' . $fileExtension;
$uploadFile = $uploadDir . $fileName;
if (move_uploaded_file($uploadedFile['tmp_name'], $uploadFile)) {
$fileInfo = getimagesize($uploadFile);
if ($fileInfo !== false) {
$width = $fileInfo[0];
$height = $fileInfo[1];
// Load the image based on its format
if ($fileExtension === 'png') {
$image = imagecreatefrompng($uploadFile);
} elseif ($fileExtension === 'jpg' || $fileExtension === 'jpeg') {
$image = imagecreatefromjpeg($uploadFile);
} elseif ($fileExtension === 'gif') {
$image = imagecreatefromgif($uploadFile);
} elseif ($fileExtension === 'webp') {
$image = imagecreatefromwebp($uploadFile);
} else {
// Handle other image formats as needed
return "";
}
// Enable alpha channel (transparency) for PNG images
if ($fileExtension === 'png') {
imagesavealpha($image, true);
}
$newWidth = $width;
$newHeight = $height;
if ($width > $targetWidth) {
$newWidth = $targetWidth;
$newHeight = ($targetWidth / $width) * $height;
}
if ($newHeight > $targetHeight) {
$newWidth = ($targetHeight / $newHeight) * $newWidth;
$newHeight = $targetHeight;
}
$resizedImage = imagecreatetruecolor($newWidth, $newHeight);
imagesavealpha($resizedImage, true);
$transparency = imagecolorallocatealpha($resizedImage, 0, 0, 0, 127);
imagefill($resizedImage, 0, 0, $transparency);
imagecopyresampled($resizedImage, $image, 0, 0, 0, 0, $newWidth, $newHeight, $width, $height);
if ($fileExtension === 'png') {
imagepng($resizedImage, $uploadFile);
} elseif ($fileExtension === 'jpg' || $fileExtension === 'jpeg') {
imagejpeg($resizedImage, $uploadFile);
} elseif ($fileExtension === 'gif') {
imagegif($resizedImage, $uploadFile);
} elseif ($fileExtension === 'webp') {
imagewebp($resizedImage, $uploadFile);
} else {
return "";
}
imagedestroy($image);
imagedestroy($resizedImage);
return $fileName;
}
}
} else {
echo translate('error_fetching_image', $i18n) . ": " . curl_error($ch);
return "";
}
}
if (isset($_SESSION['loggedin']) && $_SESSION['loggedin'] === true) {
if ($_SERVER["REQUEST_METHOD"] === "POST") {
$isEdit = isset($_POST['id']) && $_POST['id'] != "";
$name = validate($_POST["name"]);
$price = $_POST['price'];
$currencyId = $_POST["currency_id"];
$frequency = $_POST["frequency"];
$cycle = $_POST["cycle"];
$nextPayment = $_POST["next_payment"];
$paymentMethodId = $_POST["payment_method_id"];
$payerUserId = $_POST["payer_user_id"];
$categoryId = $_POST['category_id'];
$notes = validate($_POST["notes"]);
$url = validate($_POST['url']);
$logoUrl = validate($_POST['logo-url']);
$logo = "";
$notify = isset($_POST['notifications']) ? true : false;
$notifyDaysBefore = $_POST['notify_days_before'];
$inactive = isset($_POST['inactive']) ? true : false;
function saveLogo($imageData, $uploadFile, $name, $settings)
{
$image = imagecreatefromstring($imageData);
$removeBackground = isset($settings['removeBackground']) && $settings['removeBackground'] === 'true';
if ($image !== false) {
$tempFile = tempnam(sys_get_temp_dir(), 'logo');
imagepng($image, $tempFile);
imagedestroy($image);
if($logoUrl !== "") {
$logo = getLogoFromUrl($logoUrl, '../../images/uploads/logos/', $name, $settings);
$imagick = new Imagick($tempFile);
if ($removeBackground) {
$fuzz = Imagick::getQuantum() * 0.1; // 10%
$imagick->transparentPaintImage("rgb(247, 247, 247)", 0, $fuzz, false);
}
$imagick->setImageFormat('png');
$imagick->writeImage($uploadFile);
$imagick->clear();
$imagick->destroy();
unlink($tempFile);
return true;
} else {
return false;
}
}
function resizeAndUploadLogo($uploadedFile, $uploadDir, $name, $settings)
{
$targetWidth = 135;
$targetHeight = 42;
$timestamp = time();
$originalFileName = $uploadedFile['name'];
$fileExtension = pathinfo($originalFileName, PATHINFO_EXTENSION);
$fileExtension = validateFileExtension($fileExtension) ? $fileExtension : 'png';
$fileName = $timestamp . '-' . sanitizeFilename($name) . '.' . $fileExtension;
$uploadFile = $uploadDir . $fileName;
if (move_uploaded_file($uploadedFile['tmp_name'], $uploadFile)) {
$fileInfo = getimagesize($uploadFile);
if ($fileInfo !== false) {
$width = $fileInfo[0];
$height = $fileInfo[1];
// Load the image based on its format
if ($fileExtension === 'png') {
$image = imagecreatefrompng($uploadFile);
} elseif ($fileExtension === 'jpg' || $fileExtension === 'jpeg') {
$image = imagecreatefromjpeg($uploadFile);
} elseif ($fileExtension === 'gif') {
$image = imagecreatefromgif($uploadFile);
} elseif ($fileExtension === 'webp') {
$image = imagecreatefromwebp($uploadFile);
} else {
if (!empty($_FILES['logo']['name'])) {
$fileType = mime_content_type($_FILES['logo']['tmp_name']);
if (strpos($fileType, 'image') === false) {
echo translate("fill_all_fields", $i18n);
exit();
}
$logo = resizeAndUploadLogo($_FILES['logo'], '../../images/uploads/logos/', $name, $settings);
}
// Handle other image formats as needed
return "";
}
if (!$isEdit) {
$sql = "INSERT INTO subscriptions (name, logo, price, currency_id, next_payment, cycle, frequency, notes,
// Enable alpha channel (transparency) for PNG images
if ($fileExtension === 'png') {
imagesavealpha($image, true);
}
$newWidth = $width;
$newHeight = $height;
if ($width > $targetWidth) {
$newWidth = $targetWidth;
$newHeight = ($targetWidth / $width) * $height;
}
if ($newHeight > $targetHeight) {
$newWidth = ($targetHeight / $newHeight) * $newWidth;
$newHeight = $targetHeight;
}
$resizedImage = imagecreatetruecolor($newWidth, $newHeight);
imagesavealpha($resizedImage, true);
$transparency = imagecolorallocatealpha($resizedImage, 0, 0, 0, 127);
imagefill($resizedImage, 0, 0, $transparency);
imagecopyresampled($resizedImage, $image, 0, 0, 0, 0, $newWidth, $newHeight, $width, $height);
if ($fileExtension === 'png') {
imagepng($resizedImage, $uploadFile);
} elseif ($fileExtension === 'jpg' || $fileExtension === 'jpeg') {
imagejpeg($resizedImage, $uploadFile);
} elseif ($fileExtension === 'gif') {
imagegif($resizedImage, $uploadFile);
} elseif ($fileExtension === 'webp') {
imagewebp($resizedImage, $uploadFile);
} else {
return "";
}
imagedestroy($image);
imagedestroy($resizedImage);
return $fileName;
}
}
return "";
}
if (isset($_SESSION['loggedin']) && $_SESSION['loggedin'] === true) {
if ($_SERVER["REQUEST_METHOD"] === "POST") {
$isEdit = isset($_POST['id']) && $_POST['id'] != "";
$name = validate($_POST["name"]);
$price = $_POST['price'];
$currencyId = $_POST["currency_id"];
$frequency = $_POST["frequency"];
$cycle = $_POST["cycle"];
$nextPayment = $_POST["next_payment"];
$paymentMethodId = $_POST["payment_method_id"];
$payerUserId = $_POST["payer_user_id"];
$categoryId = $_POST['category_id'];
$notes = validate($_POST["notes"]);
$url = validate($_POST['url']);
$logoUrl = validate($_POST['logo-url']);
$logo = "";
$notify = isset($_POST['notifications']) ? true : false;
$notifyDaysBefore = $_POST['notify_days_before'];
$inactive = isset($_POST['inactive']) ? true : false;
if ($logoUrl !== "") {
$logo = getLogoFromUrl($logoUrl, '../../images/uploads/logos/', $name, $settings, $i18n);
} else {
if (!empty($_FILES['logo']['name'])) {
$fileType = mime_content_type($_FILES['logo']['tmp_name']);
if (strpos($fileType, 'image') === false) {
echo translate("fill_all_fields", $i18n);
exit();
}
$logo = resizeAndUploadLogo($_FILES['logo'], '../../images/uploads/logos/', $name, $settings);
}
}
if (!$isEdit) {
$sql = "INSERT INTO subscriptions (name, logo, price, currency_id, next_payment, cycle, frequency, notes,
payment_method_id, payer_user_id, category_id, notify, inactive, url, notify_days_before, user_id)
VALUES (:name, :logo, :price, :currencyId, :nextPayment, :cycle, :frequency, :notes,
:paymentMethodId, :payerUserId, :categoryId, :notify, :inactive, :url, :notifyDaysBefore, :userId)";
} else {
$id = $_POST['id'];
if ($logo != "") {
$sql = "UPDATE subscriptions SET name = :name, logo = :logo, price = :price, currency_id = :currencyId,
} else {
$id = $_POST['id'];
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, notify = :notify, inactive = :inactive,
url = :url, notify_days_before = :notifyDaysBefore WHERE id = :id AND user_id = :userId";
} else {
$sql = "UPDATE subscriptions SET name = :name, price = :price, currency_id = :currencyId, next_payment = :nextPayment,
} 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, notify = :notify, inactive = :inactive, url = :url,notify_days_before = :notifyDaysBefore
WHERE id = :id AND user_id = :userId";
}
}
$stmt = $db->prepare($sql);
if ($isEdit) {
$stmt->bindParam(':id', $id, SQLITE3_INTEGER);
}
$stmt->bindParam(':name', $name, SQLITE3_TEXT);
if ($logo != "") {
$stmt->bindParam(':logo', $logo, SQLITE3_TEXT);
}
$stmt->bindParam(':price', $price, SQLITE3_FLOAT);
$stmt->bindParam(':currencyId', $currencyId, SQLITE3_INTEGER);
$stmt->bindParam(':nextPayment', $nextPayment, SQLITE3_TEXT);
$stmt->bindParam(':cycle', $cycle, SQLITE3_INTEGER);
$stmt->bindParam(':frequency', $frequency, SQLITE3_INTEGER);
$stmt->bindParam(':notes', $notes, SQLITE3_TEXT);
$stmt->bindParam(':paymentMethodId', $paymentMethodId, SQLITE3_INTEGER);
$stmt->bindParam(':payerUserId', $payerUserId, SQLITE3_INTEGER);
$stmt->bindParam(':categoryId', $categoryId, SQLITE3_INTEGER);
$stmt->bindParam(':notify', $notify, SQLITE3_INTEGER);
$stmt->bindParam(':inactive', $inactive, SQLITE3_INTEGER);
$stmt->bindParam(':url', $url, SQLITE3_TEXT);
$stmt->bindParam(':notifyDaysBefore', $notifyDaysBefore, SQLITE3_INTEGER);
$stmt->bindParam(':userId', $userId, SQLITE3_INTEGER);
if ($stmt->execute()) {
$success['status'] = "Success";
$text = $isEdit ? "updated" : "added";
$success['message'] = translate('subscription_' . $text . '_successfuly', $i18n);
$json = json_encode($success);
header('Content-Type: application/json');
echo $json;
exit();
} else {
echo translate('error', $i18n) . ": " . $db->lastErrorMsg();
}
}
$stmt = $db->prepare($sql);
if ($isEdit) {
$stmt->bindParam(':id', $id, SQLITE3_INTEGER);
}
$stmt->bindParam(':name', $name, SQLITE3_TEXT);
if ($logo != "") {
$stmt->bindParam(':logo', $logo, SQLITE3_TEXT);
}
$stmt->bindParam(':price', $price, SQLITE3_FLOAT);
$stmt->bindParam(':currencyId', $currencyId, SQLITE3_INTEGER);
$stmt->bindParam(':nextPayment', $nextPayment, SQLITE3_TEXT);
$stmt->bindParam(':cycle', $cycle, SQLITE3_INTEGER);
$stmt->bindParam(':frequency', $frequency, SQLITE3_INTEGER);
$stmt->bindParam(':notes', $notes, SQLITE3_TEXT);
$stmt->bindParam(':paymentMethodId', $paymentMethodId, SQLITE3_INTEGER);
$stmt->bindParam(':payerUserId', $payerUserId, SQLITE3_INTEGER);
$stmt->bindParam(':categoryId', $categoryId, SQLITE3_INTEGER);
$stmt->bindParam(':notify', $notify, SQLITE3_INTEGER);
$stmt->bindParam(':inactive', $inactive, SQLITE3_INTEGER);
$stmt->bindParam(':url', $url, SQLITE3_TEXT);
$stmt->bindParam(':notifyDaysBefore', $notifyDaysBefore, SQLITE3_INTEGER);
$stmt->bindParam(':userId', $userId, SQLITE3_INTEGER);
if ($stmt->execute()) {
$success['status'] = "Success";
$text = $isEdit ? "updated" : "added";
$success['message'] = translate('subscription_' . $text . '_successfuly', $i18n);
$json = json_encode($success);
header('Content-Type: application/json');
echo $json;
exit();
} else {
echo translate('error', $i18n) . ": " . $db->lastErrorMsg();
}
}
$db->close();
?>
}
$db->close();
?>

View File

@@ -1,44 +1,44 @@
<?php
require_once '../../includes/connect_endpoint.php';
if (isset($_SESSION['loggedin']) && $_SESSION['loggedin'] === true) {
if (isset($_GET['id']) && $_GET['id'] != "") {
$subscriptionId = intval($_GET['id']);
$query = "SELECT * FROM subscriptions WHERE id = :subscriptionId AND user_id = :userId";
$stmt = $db->prepare($query);
$stmt->bindParam(':subscriptionId', $subscriptionId, SQLITE3_INTEGER);
$stmt->bindParam(':userId', $userId, SQLITE3_INTEGER);
$result = $stmt->execute();
require_once '../../includes/connect_endpoint.php';
$subscriptionData = array();
if (isset($_SESSION['loggedin']) && $_SESSION['loggedin'] === true) {
if (isset($_GET['id']) && $_GET['id'] != "") {
$subscriptionId = intval($_GET['id']);
$query = "SELECT * FROM subscriptions WHERE id = :subscriptionId AND user_id = :userId";
$stmt = $db->prepare($query);
$stmt->bindParam(':subscriptionId', $subscriptionId, SQLITE3_INTEGER);
$stmt->bindParam(':userId', $userId, SQLITE3_INTEGER);
$result = $stmt->execute();
if ($row = $result->fetchArray(SQLITE3_ASSOC)) {
$subscriptionData['id'] = $subscriptionId;
$subscriptionData['name'] = htmlspecialchars_decode($row['name'] ?? "");
$subscriptionData['logo'] = $row['logo'];
$subscriptionData['price'] = $row['price'];
$subscriptionData['currency_id'] = $row['currency_id'];
$subscriptionData['next_payment'] = $row['next_payment'];
$subscriptionData['frequency'] = $row['frequency'];
$subscriptionData['cycle'] = $row['cycle'];
$subscriptionData['notes'] = htmlspecialchars_decode($row['notes'] ?? "");
$subscriptionData['payment_method_id'] = $row['payment_method_id'];
$subscriptionData['payer_user_id'] = $row['payer_user_id'];
$subscriptionData['category_id'] = $row['category_id'];
$subscriptionData['notify'] = $row['notify'];
$subscriptionData['inactive'] = $row['inactive'];
$subscriptionData['url'] = htmlspecialchars_decode($row['url'] ?? "");
$subscriptionData['notify_days_before'] = $row['notify_days_before'];
$subscriptionData = array();
$subscriptionJson = json_encode($subscriptionData);
header('Content-Type: application/json');
echo $subscriptionJson;
} else {
echo translate('error', $i18n);
}
if ($row = $result->fetchArray(SQLITE3_ASSOC)) {
$subscriptionData['id'] = $subscriptionId;
$subscriptionData['name'] = htmlspecialchars_decode($row['name'] ?? "");
$subscriptionData['logo'] = $row['logo'];
$subscriptionData['price'] = $row['price'];
$subscriptionData['currency_id'] = $row['currency_id'];
$subscriptionData['next_payment'] = $row['next_payment'];
$subscriptionData['frequency'] = $row['frequency'];
$subscriptionData['cycle'] = $row['cycle'];
$subscriptionData['notes'] = htmlspecialchars_decode($row['notes'] ?? "");
$subscriptionData['payment_method_id'] = $row['payment_method_id'];
$subscriptionData['payer_user_id'] = $row['payer_user_id'];
$subscriptionData['category_id'] = $row['category_id'];
$subscriptionData['notify'] = $row['notify'];
$subscriptionData['inactive'] = $row['inactive'];
$subscriptionData['url'] = htmlspecialchars_decode($row['url'] ?? "");
$subscriptionData['notify_days_before'] = $row['notify_days_before'];
$subscriptionJson = json_encode($subscriptionData);
header('Content-Type: application/json');
echo $subscriptionJson;
} else {
echo translate('error', $i18n);
}
} else {
echo translate('error', $i18n);
}
$db->close();
}
$db->close();
?>

View File

@@ -31,7 +31,7 @@ if ($_SERVER["REQUEST_METHOD"] === "POST") {
if ($subscription) {
// get payer name from household object
$subscription['payer_user'] = $members[$subscription['payer_user_id']]['name'];
$subscription['payer_user'] = $members[$subscription['payer_user_id']]['name'];
$subscription['category'] = $categories[$subscription['category_id']]['name'];
$subscription['payment_method'] = $payment_methods[$subscription['payment_method_id']]['name'];
$subscription['currency'] = $currencies[$subscription['currency_id']]['symbol'];

View File

@@ -1,128 +1,128 @@
<?php
require_once '../../includes/connect_endpoint.php';
require_once '../../includes/connect_endpoint.php';
require_once '../../includes/currency_formatter.php';
require_once '../../includes/getdbkeys.php';
require_once '../../includes/currency_formatter.php';
require_once '../../includes/getdbkeys.php';
include_once '../../includes/list_subscriptions.php';
include_once '../../includes/list_subscriptions.php';
require_once '../../includes/getsettings.php';
require_once '../../includes/getsettings.php';
$theme = "light";
if (isset($settings['theme'])) {
$theme = $settings['theme'];
$theme = "light";
if (isset($settings['theme'])) {
$theme = $settings['theme'];
}
$colorTheme = "blue";
if (isset($settings['color_theme'])) {
$colorTheme = $settings['color_theme'];
}
if (isset($_SESSION['loggedin']) && $_SESSION['loggedin'] === true) {
$sort = "next_payment";
$order = "ASC";
$sql = "SELECT * FROM subscriptions ORDER BY next_payment ASC, inactive ASC";
if (isset($_COOKIE['sortOrder']) && $_COOKIE['sortOrder'] != "") {
$sort = $_COOKIE['sortOrder'];
$allowedSortCriteria = ['name', 'id', 'next_payment', 'price', 'payer_user_id', 'category_id', 'payment_method_id'];
if ($sort == "price" || $sort == "id") {
$order = "DESC";
}
$colorTheme = "blue";
if (isset($settings['color_theme'])) {
$colorTheme = $settings['color_theme'];
if (!in_array($sort, $allowedSortCriteria)) {
$sort = "next_payment";
}
}
if (isset($_SESSION['loggedin']) && $_SESSION['loggedin'] === true) {
$sort = "next_payment";
$order = "ASC";
$sql = "SELECT * FROM subscriptions ORDER BY next_payment ASC, inactive ASC";
if (isset($_COOKIE['sortOrder']) && $_COOKIE['sortOrder'] != "") {
$sort = $_COOKIE['sortOrder'];
$allowedSortCriteria = ['name', 'id', 'next_payment', 'price', 'payer_user_id', 'category_id', 'payment_method_id'];
if ($sort == "price" || $sort == "id") {
$order = "DESC";
}
if (!in_array($sort, $allowedSortCriteria)) {
$sort = "next_payment";
}
}
$params = array();
$sql = "SELECT * FROM subscriptions WHERE user_id = :userId";
$params = array();
$sql = "SELECT * FROM subscriptions WHERE user_id = :userId";
if (isset($_GET['category']) && $_GET['category'] != "") {
$sql .= " AND category_id = :category";
$params[':category'] = $_GET['category'];
}
if (isset($_GET['category']) && $_GET['category'] != "") {
$sql .= " AND category_id = :category";
$params[':category'] = $_GET['category'];
}
if (isset($_GET['payment']) && $_GET['payment'] != "") {
$sql .= " AND payment_method_id = :payment";
$params[':payment'] = $_GET['payment'];
}
if (isset($_GET['payment']) && $_GET['payment'] != "") {
$sql .= " AND payment_method_id = :payment";
$params[':payment'] = $_GET['payment'];
}
if (isset($_GET['member']) && $_GET['member'] != "") {
$sql .= " AND payer_user_id = :member";
$params[':member'] = $_GET['member'];
}
if (isset($_GET['member']) && $_GET['member'] != "") {
$sql .= " AND payer_user_id = :member";
$params[':member'] = $_GET['member'];
}
$sql .= " ORDER BY $sort $order, inactive ASC";
$sql .= " ORDER BY $sort $order, inactive ASC";
$stmt = $db->prepare($sql);
$stmt->bindValue(':userId', $userId, SQLITE3_INTEGER);
$stmt = $db->prepare($sql);
$stmt->bindValue(':userId', $userId, SQLITE3_INTEGER);
foreach ($params as $key => $value) {
$stmt->bindValue($key, $value);
}
foreach ($params as $key => $value) {
$stmt->bindValue($key, $value);
}
$result = $stmt->execute();
if ($result) {
$subscriptions = array();
while ($row = $result->fetchArray(SQLITE3_ASSOC)) {
$subscriptions[] = $row;
}
}
$defaultLogo = $theme == "light" ? "images/siteicons/" . $colorTheme . "/wallos.png" : "images/siteicons/" . $colorTheme . "/walloswhite.png";
foreach ($subscriptions as $subscription) {
if ($subscription['inactive'] == 1 && isset($settings['hideDisabledSubscriptions']) && $settings['hideDisabledSubscriptions'] === 'true') {
continue;
}
$id = $subscription['id'];
$print[$id]['id'] = $id;
$print[$id]['logo'] = $subscription['logo'] != "" ? "images/uploads/logos/".$subscription['logo'] : $defaultLogo;
$print[$id]['name'] = htmlspecialchars_decode($subscription['name'] ?? "");
$cycle = $subscription['cycle'];
$frequency = $subscription['frequency'];
$print[$id]['billing_cycle'] = getBillingCycle($cycle, $frequency, $i18n);
$paymentMethodId = $subscription['payment_method_id'];
$print[$id]['currency_code'] = $currencies[$subscription['currency_id']]['code'];
$currencyId = $subscription['currency_id'];
$print[$id]['next_payment'] = date('M d, Y', strtotime($subscription['next_payment']));
$paymentIconFolder = (strpos($payment_methods[$paymentMethodId]['icon'], 'images/uploads/icons/') !== false) ? "" : "images/uploads/logos/";
$print[$id]['payment_method_icon'] = $paymentIconFolder . $payment_methods[$paymentMethodId]['icon'];
$print[$id]['payment_method_name'] = $payment_methods[$paymentMethodId]['name'];
$print[$id]['payment_method_id'] = $paymentMethodId;
$print[$id]['category_id'] = $subscription['category_id'];
$print[$id]['payer_user_id'] = $subscription['payer_user_id'];
$print[$id]['price'] = floatval($subscription['price']);
$print[$id]['inactive'] = $subscription['inactive'];
$print[$id]['url'] = htmlspecialchars_decode($subscription['url'] ?? "");
$print[$id]['notes'] = htmlspecialchars_decode($subscription['notes'] ?? "");
if (isset($settings['convertCurrency']) && $settings['convertCurrency'] === 'true' && $currencyId != $mainCurrencyId) {
$print[$id]['price'] = getPriceConverted($print[$id]['price'], $currencyId, $db);
$print[$id]['currency_code'] = $currencies[$mainCurrencyId]['code'];
}
if (isset($settings['showMonthlyPrice']) && $settings['showMonthlyPrice'] === 'true') {
$print[$id]['price'] = getPricePerMonth($cycle, $frequency, $print[$id]['price']);
}
}
if (isset($print)) {
printSubscriptions($print, $sort, $categories, $members, $i18n, $colorTheme);
}
if (count($subscriptions) == 0) {
?>
<div class="no-matching-subscriptions">
<p>
<?= translate('no_matching_subscriptions', $i18n) ?>
</p>
<button class="button" onClick="clearFilters()">
<span clasS="fa-solid fa-minus-circle"></span>
<?= translate('clear_filters', $i18n) ?>
</button>
<img src="images/siteimages/empty.png" alt="<?= translate('empty_page', $i18n) ?>" />
</div>
<?php
}
$result = $stmt->execute();
if ($result) {
$subscriptions = array();
while ($row = $result->fetchArray(SQLITE3_ASSOC)) {
$subscriptions[] = $row;
}
}
$db->close();
$defaultLogo = $theme == "light" ? "images/siteicons/" . $colorTheme . "/wallos.png" : "images/siteicons/" . $colorTheme . "/walloswhite.png";
foreach ($subscriptions as $subscription) {
if ($subscription['inactive'] == 1 && isset($settings['hideDisabledSubscriptions']) && $settings['hideDisabledSubscriptions'] === 'true') {
continue;
}
$id = $subscription['id'];
$print[$id]['id'] = $id;
$print[$id]['logo'] = $subscription['logo'] != "" ? "images/uploads/logos/" . $subscription['logo'] : $defaultLogo;
$print[$id]['name'] = htmlspecialchars_decode($subscription['name'] ?? "");
$cycle = $subscription['cycle'];
$frequency = $subscription['frequency'];
$print[$id]['billing_cycle'] = getBillingCycle($cycle, $frequency, $i18n);
$paymentMethodId = $subscription['payment_method_id'];
$print[$id]['currency_code'] = $currencies[$subscription['currency_id']]['code'];
$currencyId = $subscription['currency_id'];
$print[$id]['next_payment'] = date('M d, Y', strtotime($subscription['next_payment']));
$paymentIconFolder = (strpos($payment_methods[$paymentMethodId]['icon'], 'images/uploads/icons/') !== false) ? "" : "images/uploads/logos/";
$print[$id]['payment_method_icon'] = $paymentIconFolder . $payment_methods[$paymentMethodId]['icon'];
$print[$id]['payment_method_name'] = $payment_methods[$paymentMethodId]['name'];
$print[$id]['payment_method_id'] = $paymentMethodId;
$print[$id]['category_id'] = $subscription['category_id'];
$print[$id]['payer_user_id'] = $subscription['payer_user_id'];
$print[$id]['price'] = floatval($subscription['price']);
$print[$id]['inactive'] = $subscription['inactive'];
$print[$id]['url'] = htmlspecialchars_decode($subscription['url'] ?? "");
$print[$id]['notes'] = htmlspecialchars_decode($subscription['notes'] ?? "");
if (isset($settings['convertCurrency']) && $settings['convertCurrency'] === 'true' && $currencyId != $mainCurrencyId) {
$print[$id]['price'] = getPriceConverted($print[$id]['price'], $currencyId, $db);
$print[$id]['currency_code'] = $currencies[$mainCurrencyId]['code'];
}
if (isset($settings['showMonthlyPrice']) && $settings['showMonthlyPrice'] === 'true') {
$print[$id]['price'] = getPricePerMonth($cycle, $frequency, $print[$id]['price']);
}
}
if (isset($print)) {
printSubscriptions($print, $sort, $categories, $members, $i18n, $colorTheme);
}
if (count($subscriptions) == 0) {
?>
<div class="no-matching-subscriptions">
<p>
<?= translate('no_matching_subscriptions', $i18n) ?>
</p>
<button class="button" onClick="clearFilters()">
<span clasS="fa-solid fa-minus-circle"></span>
<?= translate('clear_filters', $i18n) ?>
</button>
<img src="images/siteimages/empty.png" alt="<?= translate('empty_page', $i18n) ?>" />
</div>
<?php
}
}
$db->close();
?>

View File

@@ -1,38 +1,38 @@
<?php
require_once '../../includes/connect_endpoint.php';
require_once '../../includes/connect_endpoint.php';
if (!isset($_SESSION['loggedin']) || $_SESSION['loggedin'] !== true) {
die(json_encode([
"success" => false,
"message" => translate('session_expired', $i18n)
]));
}
if (!isset($_SESSION['loggedin']) || $_SESSION['loggedin'] !== true) {
die(json_encode([
"success" => false,
"message" => translate('session_expired', $i18n)
]));
}
$input = json_decode(file_get_contents('php://input'), true);
if (isset($input['avatar'])) {
$avatar = "images/uploads/logos/avatars/".$input['avatar'];
$sql = "SELECT avatar FROM user WHERE id = :userId";
$stmt = $db->prepare($sql);
$stmt->bindValue(':userId', $userId, SQLITE3_INTEGER);
$result = $stmt->execute();
$userAvatar = $result->fetchArray(SQLITE3_ASSOC)['avatar'];
$input = json_decode(file_get_contents('php://input'), true);
if (isset($input['avatar'])) {
$avatar = "images/uploads/logos/avatars/" . $input['avatar'];
$sql = "SELECT avatar FROM user WHERE id = :userId";
$stmt = $db->prepare($sql);
$stmt->bindValue(':userId', $userId, SQLITE3_INTEGER);
$result = $stmt->execute();
$userAvatar = $result->fetchArray(SQLITE3_ASSOC)['avatar'];
// Check if $avatar matches the avatar in the user table
if ($avatar === $userAvatar) {
echo json_encode(array("success" => false));
} else {
// The avatars do not match
$filePath = "../../" . $avatar;
// Check if $avatar matches the avatar in the user table
if ($avatar === $userAvatar) {
echo json_encode(array("success" => false));
} else {
// The avatars do not match
$filePath = "../../" . $avatar;
if (file_exists($filePath)) {
unlink($filePath);
echo json_encode(array("success" => true, "message" => translate("success", $i18n)));
} else {
echo json_encode(array("success" => false, "message" => translate("error", $i18n)));
}
}
} else {
echo json_encode(array("success" => false, "message" => translate("error", $i18n)));
}
} else {
echo json_encode(array("success" => false, "message" => translate("error", $i18n)));
}
?>

View File

@@ -1,256 +1,254 @@
<?php
require_once '../../includes/connect_endpoint.php';
require_once '../../includes/inputvalidation.php';
require_once '../../includes/connect_endpoint.php';
require_once '../../includes/inputvalidation.php';
function update_exchange_rate($db) {
$query = "SELECT api_key, provider FROM fixer WHERE user_id = :userId";
$stmt = $db->prepare($query);
$stmt->bindParam(':userId', $userId, SQLITE3_INTEGER);
$result = $stmt->execute();
function update_exchange_rate($db, $userId)
{
$query = "SELECT api_key, provider FROM fixer WHERE user_id = :userId";
$stmt = $db->prepare($query);
$stmt->bindParam(':userId', $userId, SQLITE3_INTEGER);
$result = $stmt->execute();
if ($result) {
if ($result) {
$row = $result->fetchArray(SQLITE3_ASSOC);
if ($row) {
$apiKey = $row['api_key'];
$provider = $row['provider'];
$codes = "";
$query = "SELECT id, name, symbol, code FROM currencies";
$result = $db->query($query);
while ($row = $result->fetchArray(SQLITE3_ASSOC)) {
$codes .= $row['code'] . ",";
}
$codes = rtrim($codes, ',');
$query = "SELECT u.main_currency, c.code FROM user u LEFT JOIN currencies c ON u.main_currency = c.id WHERE u.id = :userId";
$stmt = $db->prepare($query);
$stmt->bindParam(':userId', $userId, SQLITE3_INTEGER);
$result = $stmt->execute();
$row = $result->fetchArray(SQLITE3_ASSOC);
if ($row) {
$apiKey = $row['api_key'];
$provider = $row['provider'];
$mainCurrencyCode = $row['code'];
$mainCurrencyId = $row['main_currency'];
$codes = "";
$query = "SELECT id, name, symbol, code FROM currencies";
$result = $db->query($query);
while ($row = $result->fetchArray(SQLITE3_ASSOC)) {
$codes .= $row['code'].",";
if ($provider === 1) {
$api_url = "https://api.apilayer.com/fixer/latest?base=EUR&symbols=" . $codes;
$context = stream_context_create([
'http' => [
'method' => 'GET',
'header' => 'apikey: ' . $apiKey,
]
]);
$response = file_get_contents($api_url, false, $context);
} else {
$api_url = "http://data.fixer.io/api/latest?access_key=" . $apiKey . "&base=EUR&symbols=" . $codes;
$response = file_get_contents($api_url);
}
$apiData = json_decode($response, true);
$mainCurrencyToEUR = $apiData['rates'][$mainCurrencyCode];
if ($apiData !== null && isset($apiData['rates'])) {
foreach ($apiData['rates'] as $currencyCode => $rate) {
if ($currencyCode === $mainCurrencyCode) {
$exchangeRate = 1.0;
} else {
$exchangeRate = $rate / $mainCurrencyToEUR;
}
$updateQuery = "UPDATE currencies SET rate = :rate WHERE code = :code AND user_id = :userId";
$updateStmt = $db->prepare($updateQuery);
$updateStmt->bindParam(':rate', $exchangeRate, SQLITE3_TEXT);
$updateStmt->bindParam(':code', $currencyCode, SQLITE3_TEXT);
$updateStmt->bindParam(':userId', $userId, SQLITE3_INTEGER);
$updateResult = $updateStmt->execute();
}
$codes = rtrim($codes, ',');
$currentDate = new DateTime();
$formattedDate = $currentDate->format('Y-m-d');
$query = "SELECT u.main_currency, c.code FROM user u LEFT JOIN currencies c ON u.main_currency = c.id WHERE u.id = :userId";
$query = "SELECT * FROM last_exchange_update WHERE user_id = :userId";
$stmt = $db->prepare($query);
$stmt->bindParam(':userId', $userId, SQLITE3_INTEGER);
$result = $stmt->execute();
$row = $result->fetchArray(SQLITE3_ASSOC);
$mainCurrencyCode = $row['code'];
$mainCurrencyId = $row['main_currency'];
if ($provider === 1) {
$api_url = "https://api.apilayer.com/fixer/latest?base=EUR&symbols=" . $codes;
$context = stream_context_create([
'http' => [
'method' => 'GET',
'header' => 'apikey: ' . $apiKey,
]
]);
$response = file_get_contents($api_url, false, $context);
if ($row) {
$query = "UPDATE last_exchange_update SET date = :formattedDate WHERE user_id = :userId";
} else {
$api_url = "http://data.fixer.io/api/latest?access_key=". $apiKey . "&base=EUR&symbols=" . $codes;
$response = file_get_contents($api_url);
$query = "INSERT INTO last_exchange_update (date, user_id) VALUES (:formattedDate, :userId)";
}
$apiData = json_decode($response, true);
$stmt = $db->prepare($query);
$stmt->bindParam(':formattedDate', $formattedDate, SQLITE3_TEXT);
$stmt->bindParam(':userId', $userId, SQLITE3_INTEGER);
$resutl = $stmt->execute();
$mainCurrencyToEUR = $apiData['rates'][$mainCurrencyCode];
if ($apiData !== null && isset($apiData['rates'])) {
foreach ($apiData['rates'] as $currencyCode => $rate) {
if ($currencyCode === $mainCurrencyCode) {
$exchangeRate = 1.0;
} else {
$exchangeRate = $rate / $mainCurrencyToEUR;
}
$updateQuery = "UPDATE currencies SET rate = :rate WHERE code = :code AND user_id = :userId";
$updateStmt = $db->prepare($updateQuery);
$updateStmt->bindParam(':rate', $exchangeRate, SQLITE3_TEXT);
$updateStmt->bindParam(':code', $currencyCode, SQLITE3_TEXT);
$updateStmt->bindParam(':userId', $userId, SQLITE3_INTEGER);
$updateResult = $updateStmt->execute();
}
$currentDate = new DateTime();
$formattedDate = $currentDate->format('Y-m-d');
$query = "SELECT * FROM last_exchange_update WHERE user_id = :userId";
$stmt = $db->prepare($query);
$stmt->bindParam(':userId', $userId, SQLITE3_INTEGER);
$result = $stmt->execute();
$row = $result->fetchArray(SQLITE3_ASSOC);
if ($row) {
$query = "UPDATE last_exchange_update SET date = :formattedDate WHERE user_id = :userId";
} else {
$query = "INSERT INTO last_exchange_update (date, user_id) VALUES (:formattedDate, :userId)";
}
$stmt = $db->prepare($query);
$stmt->bindParam(':formattedDate', $formattedDate, SQLITE3_TEXT);
$stmt->bindParam(':userId', $userId, SQLITE3_INTEGER);
$resutl = $stmt->execute();
$db->close();
}
}
}
}
$query = "SELECT main_currency FROM user WHERE id = :userId";
$stmt = $db->prepare($query);
$stmt->bindParam(':userId', $userId, SQLITE3_INTEGER);
$result = $stmt->execute();
$row = $result->fetchArray(SQLITE3_ASSOC);
$mainCurrencyId = $row['main_currency'];
function sanitizeFilename($filename) {
$filename = preg_replace("/[^a-zA-Z0-9\s]/", "", $filename);
$filename = str_replace(" ", "-", $filename);
$filename = str_replace(".", "", $filename);
return $filename;
}
function validateFileExtension($fileExtension) {
$allowedExtensions = ['png', 'jpg', 'jpeg', 'gif', 'jtif', 'webp'];
return in_array($fileExtension, $allowedExtensions);
}
function resizeAndUploadAvatar($uploadedFile, $uploadDir, $name) {
$targetWidth = 80;
$targetHeight = 80;
$timestamp = time();
$originalFileName = $uploadedFile['name'];
$fileExtension = strtolower(pathinfo($originalFileName, PATHINFO_EXTENSION));
$fileExtension = validateFileExtension($fileExtension) ? $fileExtension : 'png';
$fileName = $timestamp . '-avatars-' . sanitizeFilename($name) . '.' . $fileExtension;
$uploadFile = $uploadDir . $fileName;
if (move_uploaded_file($uploadedFile['tmp_name'], $uploadFile)) {
$fileInfo = getimagesize($uploadFile);
if ($fileInfo !== false) {
$width = $fileInfo[0];
$height = $fileInfo[1];
// Load the image based on its format
if ($fileExtension === 'png') {
$image = imagecreatefrompng($uploadFile);
} elseif ($fileExtension === 'jpg' || $fileExtension === 'jpeg') {
$image = imagecreatefromjpeg($uploadFile);
} elseif ($fileExtension === 'gif') {
$image = imagecreatefromgif($uploadFile);
} elseif ($fileExtension === 'webp') {
$image = imagecreatefromwebp($uploadFile);
} else {
// Handle other image formats as needed
return "";
}
// Enable alpha channel (transparency) for PNG images
if ($fileExtension === 'png') {
imagesavealpha($image, true);
}
$newWidth = $width;
$newHeight = $height;
if ($width > $targetWidth) {
$newWidth = $targetWidth;
$newHeight = ($targetWidth / $width) * $height;
}
if ($newHeight > $targetHeight) {
$newWidth = ($targetHeight / $newHeight) * $newWidth;
$newHeight = $targetHeight;
}
$resizedImage = imagecreatetruecolor($newWidth, $newHeight);
imagesavealpha($resizedImage, true);
$transparency = imagecolorallocatealpha($resizedImage, 0, 0, 0, 127);
imagefill($resizedImage, 0, 0, $transparency);
imagecopyresampled($resizedImage, $image, 0, 0, 0, 0, $newWidth, $newHeight, $width, $height);
if ($fileExtension === 'png') {
imagepng($resizedImage, $uploadFile);
} elseif ($fileExtension === 'jpg' || $fileExtension === 'jpeg') {
imagejpeg($resizedImage, $uploadFile);
} elseif ($fileExtension === 'gif') {
imagegif($resizedImage, $uploadFile);
} elseif ($fileExtension === 'webp') {
imagewebp($resizedImage, $uploadFile);
} else {
return "";
}
imagedestroy($image);
imagedestroy($resizedImage);
return "images/uploads/logos/avatars/".$fileName;
$db->close();
}
}
return "";
}
}
if (isset($_SESSION['username']) && isset($_POST['email']) && $_POST['email'] !== ""
&& isset($_POST['avatar']) && $_POST['avatar'] !== ""
&& isset($_POST['main_currency']) && $_POST['main_currency'] !== ""
&& isset($_POST['language']) && $_POST['language'] !== "") {
$email = validate($_POST['email']);
$query = "SELECT email FROM user WHERE id = :user_id";
$stmt = $db->prepare($query);
$stmt->bindValue(':user_id', $userId, SQLITE3_TEXT);
$result = $stmt->execute();
$user = $result->fetchArray(SQLITE3_ASSOC);
$oldEmail = $user['email'];
$query = "SELECT main_currency FROM user WHERE id = :userId";
$stmt = $db->prepare($query);
$stmt->bindParam(':userId', $userId, SQLITE3_INTEGER);
$result = $stmt->execute();
$row = $result->fetchArray(SQLITE3_ASSOC);
$mainCurrencyId = $row['main_currency'];
if ($oldEmail != $email) {
$query = "SELECT email FROM user WHERE email = :email AND id != :userId";
$stmt = $db->prepare($query);
$stmt->bindValue(':email', $email, SQLITE3_TEXT);
$stmt->bindValue(':userId', $userId, SQLITE3_INTEGER);
$result = $stmt->execute();
$otherUser = $result->fetchArray(SQLITE3_ASSOC);
if ($otherUser) {
$response = [
"success" => false,
"errorMessage" => translate('email_exists', $i18n)
];
echo json_encode($response);
exit();
}
}
function sanitizeFilename($filename)
{
$filename = preg_replace("/[^a-zA-Z0-9\s]/", "", $filename);
$filename = str_replace(" ", "-", $filename);
$filename = str_replace(".", "", $filename);
return $filename;
}
$avatar = $_POST['avatar'];
$main_currency = $_POST['main_currency'];
$language = $_POST['language'];
function validateFileExtension($fileExtension)
{
$allowedExtensions = ['png', 'jpg', 'jpeg', 'gif', 'jtif', 'webp'];
return in_array($fileExtension, $allowedExtensions);
}
if (! empty($_FILES['profile_pic']["name"])) {
$file = $_FILES['profile_pic'];
function resizeAndUploadAvatar($uploadedFile, $uploadDir, $name)
{
$targetWidth = 80;
$targetHeight = 80;
$fileType = mime_content_type($_FILES['profile_pic']['tmp_name']);
if (strpos($fileType, 'image') === false) {
$response = [
"success" => false,
"errorMessage" => translate('fill_all_fields', $i18n)
];
echo json_encode($response);
exit();
}
$name = $file['name'];
$avatar = resizeAndUploadAvatar($_FILES['profile_pic'], '../../images/uploads/logos/avatars/', $name);
}
$timestamp = time();
$originalFileName = $uploadedFile['name'];
$fileExtension = strtolower(pathinfo($originalFileName, PATHINFO_EXTENSION));
$fileExtension = validateFileExtension($fileExtension) ? $fileExtension : 'png';
$fileName = $timestamp . '-avatars-' . sanitizeFilename($name) . '.' . $fileExtension;
$uploadFile = $uploadDir . $fileName;
if (isset($_POST['password']) && $_POST['password'] != "") {
$password = $_POST['password'];
if (isset($_POST['confirm_password'])) {
$confirm = $_POST['confirm_password'];
if ($password != $confirm) {
$response = [
"success" => false,
"errorMessage" => translate('passwords_dont_match', $i18n)
];
echo json_encode($response);
exit();
}
if (move_uploaded_file($uploadedFile['tmp_name'], $uploadFile)) {
$fileInfo = getimagesize($uploadFile);
if ($fileInfo !== false) {
$width = $fileInfo[0];
$height = $fileInfo[1];
// Load the image based on its format
if ($fileExtension === 'png') {
$image = imagecreatefrompng($uploadFile);
} elseif ($fileExtension === 'jpg' || $fileExtension === 'jpeg') {
$image = imagecreatefromjpeg($uploadFile);
} elseif ($fileExtension === 'gif') {
$image = imagecreatefromgif($uploadFile);
} elseif ($fileExtension === 'webp') {
$image = imagecreatefromwebp($uploadFile);
} else {
// Handle other image formats as needed
return "";
}
// Enable alpha channel (transparency) for PNG images
if ($fileExtension === 'png') {
imagesavealpha($image, true);
}
$newWidth = $width;
$newHeight = $height;
if ($width > $targetWidth) {
$newWidth = $targetWidth;
$newHeight = ($targetWidth / $width) * $height;
}
if ($newHeight > $targetHeight) {
$newWidth = ($targetHeight / $newHeight) * $newWidth;
$newHeight = $targetHeight;
}
$resizedImage = imagecreatetruecolor($newWidth, $newHeight);
imagesavealpha($resizedImage, true);
$transparency = imagecolorallocatealpha($resizedImage, 0, 0, 0, 127);
imagefill($resizedImage, 0, 0, $transparency);
imagecopyresampled($resizedImage, $image, 0, 0, 0, 0, $newWidth, $newHeight, $width, $height);
if ($fileExtension === 'png') {
imagepng($resizedImage, $uploadFile);
} elseif ($fileExtension === 'jpg' || $fileExtension === 'jpeg') {
imagejpeg($resizedImage, $uploadFile);
} elseif ($fileExtension === 'gif') {
imagegif($resizedImage, $uploadFile);
} elseif ($fileExtension === 'webp') {
imagewebp($resizedImage, $uploadFile);
} else {
return "";
}
imagedestroy($image);
imagedestroy($resizedImage);
return "images/uploads/logos/avatars/" . $fileName;
}
}
return "";
}
if (
isset($_SESSION['username']) && isset($_POST['email']) && $_POST['email'] !== ""
&& isset($_POST['avatar']) && $_POST['avatar'] !== ""
&& isset($_POST['main_currency']) && $_POST['main_currency'] !== ""
&& isset($_POST['language']) && $_POST['language'] !== ""
) {
$email = validate($_POST['email']);
$query = "SELECT email FROM user WHERE id = :user_id";
$stmt = $db->prepare($query);
$stmt->bindValue(':user_id', $userId, SQLITE3_TEXT);
$result = $stmt->execute();
$user = $result->fetchArray(SQLITE3_ASSOC);
$oldEmail = $user['email'];
if ($oldEmail != $email) {
$query = "SELECT email FROM user WHERE email = :email AND id != :userId";
$stmt = $db->prepare($query);
$stmt->bindValue(':email', $email, SQLITE3_TEXT);
$stmt->bindValue(':userId', $userId, SQLITE3_INTEGER);
$result = $stmt->execute();
$otherUser = $result->fetchArray(SQLITE3_ASSOC);
if ($otherUser) {
$response = [
"success" => false,
"errorMessage" => translate('email_exists', $i18n)
];
echo json_encode($response);
exit();
}
}
$avatar = $_POST['avatar'];
$main_currency = $_POST['main_currency'];
$language = $_POST['language'];
if (!empty($_FILES['profile_pic']["name"])) {
$file = $_FILES['profile_pic'];
$fileType = mime_content_type($_FILES['profile_pic']['tmp_name']);
if (strpos($fileType, 'image') === false) {
$response = [
"success" => false,
"errorMessage" => translate('fill_all_fields', $i18n)
];
echo json_encode($response);
exit();
}
$name = $file['name'];
$avatar = resizeAndUploadAvatar($_FILES['profile_pic'], '../../images/uploads/logos/avatars/', $name);
}
if (isset($_POST['password']) && $_POST['password'] != "") {
$password = $_POST['password'];
if (isset($_POST['confirm_password'])) {
$confirm = $_POST['confirm_password'];
if ($password != $confirm) {
$response = [
"success" => false,
"errorMessage" => translate('passwords_dont_match', $i18n)
@@ -258,64 +256,72 @@
echo json_encode($response);
exit();
}
}
if (isset($_POST['password']) && $_POST['password'] != "") {
$sql = "UPDATE user SET avatar = :avatar, email = :email, password = :password, main_currency = :main_currency, language = :language WHERE id = :userId";
} else {
$sql = "UPDATE user SET avatar = :avatar, email = :email, main_currency = :main_currency, language = :language WHERE id = :userId";
}
$stmt = $db->prepare($sql);
$stmt->bindParam(':avatar', $avatar, SQLITE3_TEXT);
$stmt->bindParam(':email', $email, SQLITE3_TEXT);
$stmt->bindParam(':main_currency', $main_currency, SQLITE3_INTEGER);
$stmt->bindParam(':language', $language, SQLITE3_TEXT);
$stmt->bindParam(':userId', $userId, SQLITE3_INTEGER);
if (isset($_POST['password']) && $_POST['password'] != "") {
$hashedPassword = password_hash($password, PASSWORD_DEFAULT);
$stmt->bindParam(':password', $hashedPassword, SQLITE3_TEXT);
}
$result = $stmt->execute();
if ($result) {
$cookieExpire = time() + (30 * 24 * 60 * 60);
$oldLanguage = isset($_COOKIE['language']) ? $_COOKIE['language'] : "en";
$root = str_replace('/endpoints/user', '', dirname($_SERVER['PHP_SELF']));
$root = $root == '' ? '/' : $root;
setcookie('language', $language, $cookieExpire, $root);
$_SESSION['avatar'] = $avatar;
$_SESSION['main_currency'] = $main_currency;
if ($main_currency != $mainCurrencyId) {
update_exchange_rate($db);
}
$reload = $oldLanguage != $language;
$response = [
"success" => true,
"message" => translate('user_details_saved', $i18n),
"reload" => $reload
];
echo json_encode($response);
} else {
$response = [
"success" => false,
"errorMessage" => translate('error_updating_user_data', $i18n)
"errorMessage" => translate('passwords_dont_match', $i18n)
];
echo json_encode($response);
exit();
}
}
if (isset($_POST['password']) && $_POST['password'] != "") {
$sql = "UPDATE user SET avatar = :avatar, email = :email, password = :password, main_currency = :main_currency, language = :language WHERE id = :userId";
} else {
$sql = "UPDATE user SET avatar = :avatar, email = :email, main_currency = :main_currency, language = :language WHERE id = :userId";
}
$stmt = $db->prepare($sql);
$stmt->bindParam(':avatar', $avatar, SQLITE3_TEXT);
$stmt->bindParam(':email', $email, SQLITE3_TEXT);
$stmt->bindParam(':main_currency', $main_currency, SQLITE3_INTEGER);
$stmt->bindParam(':language', $language, SQLITE3_TEXT);
$stmt->bindParam(':userId', $userId, SQLITE3_INTEGER);
if (isset($_POST['password']) && $_POST['password'] != "") {
$hashedPassword = password_hash($password, PASSWORD_DEFAULT);
$stmt->bindParam(':password', $hashedPassword, SQLITE3_TEXT);
}
$result = $stmt->execute();
if ($result) {
$cookieExpire = time() + (30 * 24 * 60 * 60);
$oldLanguage = isset($_COOKIE['language']) ? $_COOKIE['language'] : "en";
$root = str_replace('/endpoints/user', '', dirname($_SERVER['PHP_SELF']));
$root = $root == '' ? '/' : $root;
setcookie('language', $language, $cookieExpire, $root);
$_SESSION['avatar'] = $avatar;
$_SESSION['main_currency'] = $main_currency;
if ($main_currency != $mainCurrencyId) {
update_exchange_rate($db, $userId);
}
exit();
$reload = $oldLanguage != $language;
$response = [
"success" => true,
"message" => translate('user_details_saved', $i18n),
"reload" => $reload
];
echo json_encode($response);
} else {
$response = [
"success" => false,
"errorMessage" => translate('fill_all_fields', $i18n)
"errorMessage" => translate('error_updating_user_data', $i18n)
];
echo json_encode($response);
exit();
}
?>
exit();
} else {
$response = [
"success" => false,
"errorMessage" => translate('fill_all_fields', $i18n)
];
echo json_encode($response);
exit();
}
?>

View File

@@ -1,90 +1,90 @@
<?php
session_start();
if (isset($_SESSION['loggedin']) && $_SESSION['loggedin'] === true) {
$username = $_SESSION['username'];
$main_currency = $_SESSION['main_currency'];
session_start();
if (isset($_SESSION['loggedin']) && $_SESSION['loggedin'] === true) {
$username = $_SESSION['username'];
$main_currency = $_SESSION['main_currency'];
$sql = "SELECT * FROM user WHERE username = :username";
$stmt = $db->prepare($sql);
$stmt->bindValue(':username', $username, SQLITE3_TEXT);
$result = $stmt->execute();
$userData = $result->fetchArray(SQLITE3_ASSOC);
$userId = $userData['id'];
if ($userData === false) {
header('Location: logout.php');
exit();
} else {
$_SESSION['userId'] = $userData['id'];
}
if ($userData['avatar'] == "") {
$userData['avatar'] = "0";
}
} else {
if (isset($_COOKIE['wallos_login'])) {
$cookie = explode('|', $_COOKIE['wallos_login'], 3);
$username = $cookie[0];
$token = $cookie[1];
$main_currency = $cookie[2];
$sql = "SELECT * FROM user WHERE username = :username";
$stmt = $db->prepare($sql);
$stmt->bindValue(':username', $username, SQLITE3_TEXT);
$result = $stmt->execute();
$userData = $result->fetchArray(SQLITE3_ASSOC);
$userId = $userData['id'];
if ($userData === false) {
header('Location: logout.php');
exit();
} else {
$_SESSION['userId'] = $userData['id'];
}
if ($userData['avatar'] == "") {
$userData['avatar'] = "0";
}
} else {
if (isset($_COOKIE['wallos_login'])) {
$cookie = explode('|', $_COOKIE['wallos_login'], 3);
$username = $cookie[0];
$token = $cookie[1];
$main_currency = $cookie[2];
$sql = "SELECT * FROM user WHERE username = :username";
$stmt = $db->prepare($sql);
$stmt->bindValue(':username', $username, SQLITE3_TEXT);
$result = $stmt->execute();
if ($result) {
$userData = $result->fetchArray(SQLITE3_ASSOC);
if (!isset($userData['id'])) {
$db->close();
header("Location: logout.php");
exit();
}
if ($userData['avatar'] == "") {
$userData['avatar'] = "0";
}
$userId = $userData['id'];
$main_currency = $userData['main_currency'];
$adminQuery = "SELECT login_disabled FROM admin";
$adminResult = $db->query($adminQuery);
$adminRow = $adminResult->fetchArray(SQLITE3_ASSOC);
if ($adminRow['login_disabled'] == 1) {
$sql = "SELECT * FROM login_tokens WHERE user_id = :userId";
$stmt = $db->prepare($sql);
$stmt->bindParam(':userId', $userId, SQLITE3_TEXT);
} else {
$sql = "SELECT * FROM login_tokens WHERE user_id = :userId AND token = :token";
$stmt = $db->prepare($sql);
$stmt->bindParam(':userId', $userId, SQLITE3_TEXT);
$stmt->bindParam(':token', $token, SQLITE3_TEXT);
}
$result = $stmt->execute();
$row = $result->fetchArray(SQLITE3_ASSOC);
if ($row != false) {
$_SESSION['username'] = $username;
$_SESSION['token'] = $token;
$_SESSION['loggedin'] = true;
$_SESSION['main_currency'] = $main_currency;
$_SESSION['userId'] = $userId;
} else {
$db->close();
header("Location: logout.php");
exit();
}
} else {
if ($result) {
$userData = $result->fetchArray(SQLITE3_ASSOC);
if (!isset($userData['id'])) {
$db->close();
header("Location: logout.php");
exit();
}
if ($userData['avatar'] == "") {
$userData['avatar'] = "0";
}
$userId = $userData['id'];
$main_currency = $userData['main_currency'];
$adminQuery = "SELECT login_disabled FROM admin";
$adminResult = $db->query($adminQuery);
$adminRow = $adminResult->fetchArray(SQLITE3_ASSOC);
if ($adminRow['login_disabled'] == 1) {
$sql = "SELECT * FROM login_tokens WHERE user_id = :userId";
$stmt = $db->prepare($sql);
$stmt->bindParam(':userId', $userId, SQLITE3_TEXT);
} else {
$sql = "SELECT * FROM login_tokens WHERE user_id = :userId AND token = :token";
$stmt = $db->prepare($sql);
$stmt->bindParam(':userId', $userId, SQLITE3_TEXT);
$stmt->bindParam(':token', $token, SQLITE3_TEXT);
}
$result = $stmt->execute();
$row = $result->fetchArray(SQLITE3_ASSOC);
if ($row != false) {
$_SESSION['username'] = $username;
$_SESSION['token'] = $token;
$_SESSION['loggedin'] = true;
$_SESSION['main_currency'] = $main_currency;
$_SESSION['userId'] = $userId;
} else {
$db->close();
header("Location: logout.php");
exit();
}
} else {
$db->close();
header("Location: login.php");
header("Location: logout.php");
exit();
}
} else {
$db->close();
header("Location: login.php");
exit();
}
}
?>

View File

@@ -1,6 +1,6 @@
<?php
$query = "SELECT COUNT(*) as count FROM user";
$result = $db->query($query);
$row = $result->fetchArray(SQLITE3_ASSOC);
$userCount = $row['count'];
$query = "SELECT COUNT(*) as count FROM user";
$result = $db->query($query);
$row = $result->fetchArray(SQLITE3_ASSOC);
$userCount = $row['count'];
?>

View File

@@ -25,10 +25,11 @@
</div>
<?php
if (isset($db)) {
$db->close();
}
if (isset($db)) {
$db->close();
}
?>
</body>
</body>
</html>

View File

@@ -8,8 +8,20 @@ $result = $stmt->execute();
$settings = $result->fetchArray(SQLITE3_ASSOC);
if ($settings) {
$cookieExpire = time() + (30 * 24 * 60 * 60);
setcookie('theme', $settings['dark_theme'] ? 'dark': 'light', $cookieExpire);
$settings['theme'] = $settings['dark_theme'] ? 'dark': 'light';
$themeMapping = array(0 => 'light', 1 => 'dark', 2 => 'automatic');
$themeKey = isset($settings['dark_theme']) ? $settings['dark_theme'] : 2;
$themeValue = $themeMapping[$themeKey];
setcookie('theme', $themeValue, $cookieExpire);
$settings['update_theme_setttings'] = false;
if (isset($_COOKIE['inUseTheme']) && $settings['dark_theme'] == 2) {
$inUseTheme = $_COOKIE['inUseTheme'];
$settings['theme'] = $inUseTheme;
} else {
$settings['theme'] = $themeValue;
}
if ($themeValue == "automatic") {
$settings['update_theme_setttings'] = true;
}
$settings['color_theme'] = $settings['color_theme'] ? $settings['color_theme'] : "blue";
$settings['showMonthlyPrice'] = $settings['monthly_price'] ? 'true': 'false';
$settings['convertCurrency'] = $settings['convert_currency'] ? 'true': 'false';

View File

@@ -18,11 +18,16 @@
exit();
}
$theme = "light";
$theme = "automatic";
if (isset($settings['theme'])) {
$theme = $settings['theme'];
}
$updateThemeSettings = false;
if (isset($settings['update_theme_setttings'])) {
$updateThemeSettings = $settings['update_theme_setttings'];
}
$colorTheme = "blue";
if (isset($settings['color_theme'])) {
$colorTheme = $settings['color_theme'];
@@ -37,13 +42,13 @@
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
<title>Wallos - Subscription Tracker</title>
<meta name="theme-color" content="<?= $theme == "light" ? "#FFFFFF" : "#222222" ?>"/>
<meta name="theme-color" content="<?= $theme == "light" ? "#FFFFFF" : "#222222" ?>" id="theme-color"/>
<link rel="icon" type="image/png" href="images/icon/favicon.ico" sizes="16x16">
<link rel="apple-touch-icon" sizes="180x180" href="images/icon/apple-touch-icon.png">
<link rel="manifest" href="manifest.json" crossorigin="use-credentials">
<link rel="stylesheet" href="styles/theme.css?<?= $version ?>">
<link rel="stylesheet" href="styles/styles.css?<?= $version ?>">
<link rel="stylesheet" href="styles/dark-theme.css?<?= $version ?>" id="dark-theme" <?= $theme == "light" ? "disabled" : "" ?>>
<link rel="stylesheet" href="styles/dark-theme.css?<?= $version ?>" id="dark-theme" <?= $theme != "dark" ? "disabled" : "" ?>>
<link rel="stylesheet" href="styles/themes/red.css?<?= $version ?>" id="red-theme" <?= $colorTheme != "red" ? "disabled" : "" ?>>
<link rel="stylesheet" href="styles/themes/green.css?<?= $version ?>" id="green-theme" <?= $colorTheme != "green" ? "disabled" : "" ?>>
<link rel="stylesheet" href="styles/themes/yellow.css?<?= $version ?>" id="yellow-theme" <?= $colorTheme != "yellow" ? "disabled" : "" ?>>
@@ -54,6 +59,7 @@
<script type="text/javascript" src="scripts/common.js?<?= $version ?>"></script>
<script type="text/javascript">
window.theme = "<?= $theme ?>";
window.update_theme_settings = "<?= $updateThemeSettings ?>";
window.lang = "<?=$lang ?>";
window.colorTheme = "<?= $colorTheme ?>";
</script>

View File

@@ -77,8 +77,6 @@ $i18n = [
"payment_every" => "Zahlung alle",
"frequency" => "Abrechnungsfrequenz",
"cycle" => "Zeitraum",
"next_payment" => "Nächste Zahlung",
"payment_method" => "Zahlungsmethode",
"no_category" => "Keine Kategorie",
"paid_by" => "Gezahlt durch",
"url" => "URL",
@@ -180,7 +178,7 @@ $i18n = [
"theme_settings" => "Themen-Einstellungen",
"custom_colors" => "Benutzerdefinierte Farben",
"dark_theme" => "Dark Theme",
"switch_theme" => "Light / Dark Theme umschalten",
"automatic"=> "Automatisch",
"calculate_monthly_price" => "Berechne und zeige monatlichen Preis für alle Abonnements an",
"convert_prices" => "Preise immer in meine Hauptwährung umrechnen und darin anzeigen (langsamer)",
"hide_disabled_subscriptions" => "Deaktivierte Abonnements verstecken",

View File

@@ -77,8 +77,6 @@ $i18n = [
"payment_every" => "Πληρωμή κάθε",
"frequency" => "Συχνότητα",
"cycle" => "Κύκλος",
"next_payment" => "Επόμενη πληρωμή",
"payment_method" => "Τρόπος πληρωμής",
"no_category" => "Καμία κατηγορία",
"paid_by" => "Πληρώνεται από",
"url" => "URL",
@@ -180,7 +178,7 @@ $i18n = [
"theme_settings" => "Ρυθμίσεις θέματος",
"custom_colors" => "Προσαρμοσμένα χρώματα",
"dark_theme" => "Dark Theme",
"switch_theme" => "Διακόπτης Light / Dark Theme",
"automatic"=> "Αυτόματο",
"calculate_monthly_price" => "Υπολογισμός και εμφάνιση της μηνιαίας τιμής για όλες τις συνδρομές",
"convert_prices" => "Πάντα να μετατρέπει και να εμφανίζει τις τιμές στο κύριο νόμισμά μου (πιο αργό)",
"hide_disabled_subscriptions" => "Απόκρυψη απενεργοποιημένων συνδρομών",

View File

@@ -77,8 +77,6 @@ $i18n = [
"payment_every" => "Payment every",
"frequency" => "Frequency",
"cycle" => "Cycle",
"next_payment" => "Next Payment",
"payment_method" => "Payment Method",
"no_category" => "No category",
"paid_by" => "Paid by",
"url" => "URL",
@@ -180,7 +178,7 @@ $i18n = [
"theme_settings" => "Theme Settings",
"custom_colors" => "Custom Colors",
"dark_theme" => "Dark Theme",
"switch_theme" => "Switch Light / Dark Theme",
"automatic"=> "Automatic",
"calculate_monthly_price" => "Calculate and show monthly price for all subscriptions",
"convert_prices" => "Always convert and show prices on my main currency (slower)",
"hide_disabled_subscriptions" => "Hide disabled subscriptions",

View File

@@ -77,8 +77,6 @@ $i18n = [
"payment_every" => "Pago cada",
"frequency" => "Frecuencia",
"cycle" => "Ciclo",
"next_payment" => "Próximo Pago",
"payment_method" => "Método de Pago",
"no_category" => "Sin categoría",
"paid_by" => "Pagado por",
"url" => "URL",
@@ -180,7 +178,7 @@ $i18n = [
"theme_settings" => "Configuración de Tema",
"custom_collors" => "Colores Personalizados",
"dark_theme" => "Tema Oscuro",
"switch_theme" => "Cambiar entre Tema Claro / Oscuro",
"automatic"=> "Automático",
"calculate_monthly_price" => "Calcular y mostrar el precio mensual de todas las suscripciones",
"convert_prices" => "Convertir y mostrar siempre los precios en mi moneda principal (más lento)",
"hide_disabled_subscriptions" => "Ocultar suscripciones desactivadas",

View File

@@ -77,8 +77,6 @@ $i18n = [
"payment_every" => "Paiement tous les",
"frequency" => "Fréquence",
"cycle" => "Cycle",
"next_payment" => "Prochain paiement",
"payment_method" => "Méthode de paiement",
"no_category" => "Pas de catégorie",
"paid_by" => "Payé par",
"url" => "URL",
@@ -180,7 +178,7 @@ $i18n = [
"theme_settings" => "Paramètres de thème",
"custom_colors" => "Couleurs personnalisées",
"dark_theme" => "Thème sombre",
"switch_theme" => "Basculer entre le thème clair et sombre",
"automatic"=> "Automatique",
"calculate_monthly_price" => "Calculer et afficher le prix mensuel pour tous les abonnements",
"convert_prices" => "Convertir toujours et afficher les prix dans ma devise principale (plus lent)",
"hide_disabled_subscriptions" => "Masquer les abonnements désactivés",

View File

@@ -9,7 +9,8 @@ if (isset($_COOKIE['language'])) {
}
}
function translate($text, $translations) {
function translate($text, $translations)
{
if (array_key_exists($text, $translations)) {
return $translations[$text];
} else {

View File

@@ -186,7 +186,7 @@ $i18n = [
"theme_settings" => 'Impostazioni del tema',
"custom_colors" => 'Colori personalizzati',
"dark_theme" => 'Tema scuro',
'switch_theme' => 'Cambia tema chiaro/scuro',
"automatic" => "Automatico",
'calculate_monthly_price' => 'Calcola e mostra il prezzo mensile per tutti gli abbonamenti',
'convert_prices' => 'Converti sempre e mostra i prezzi nella mia valuta principale (più lento)',
"hide_disabled_subscriptions" => 'Nascondi gli abbonamenti disattivati',

View File

@@ -77,8 +77,6 @@ $i18n = [
"payment_every" => "支払い頻度",
"frequency" => "頻度",
"cycle" => "サイクル",
"next_payment" => "次回支払い",
"payment_method" => "支払い方法",
"no_category" => "カテゴリなし",
"paid_by" => "支払い元",
"url" => "URL",
@@ -180,7 +178,7 @@ $i18n = [
"theme_settings" => "テーマ設定",
"custom_colors" => "カスタムカラー",
"dark_theme" => "ダークテーマ",
"switch_theme" => "ライト/ダーク テーマの切り替え",
"automatic"=> "自動",
"calculate_monthly_price" => "すべての定期購入の月額料金を計算して表示する",
"convert_prices" => "常にメイン通貨で価格を換算して表示する (遅い)",
"hide_disabled_subscriptions" => "無効な定期購入を非表示にする",

View File

@@ -77,8 +77,6 @@ $i18n = [
"payment_every" => "지불 빈도",
"frequency" => "빈도",
"cycle" => "주기",
"next_payment" => "다음 결제",
"payment_method" => "결제 방법",
"no_category" => "카테고리 없음",
"paid_by" => "결제하는 사람",
"url" => "URL",
@@ -181,7 +179,7 @@ $i18n = [
"theme_settings" => "테마 설정",
"custom_colors" => "커스텀 색상",
"dark_theme" => "다크 테마",
"switch_theme" => "라이트/다크 테마 전환",
"automatic"=> "자동",
"calculate_monthly_price" => "모든 구독에 대한 월별 요금을 계산하고 표시",
"convert_prices" => "항상 기본 통화로 가격을 환산하고 표시 (느림)",
"hide_disabled_subscriptions" => "비활성화된 구독 숨기기",

View File

@@ -1,26 +1,26 @@
<?php
// File Name => Language Name
$languages = [
// English first
"en" => ["name" => "English", "dir" => "ltr"],
// Remaining sorted alphabetically by language code
"de" => ["name" => "Deutsch", "dir" => "ltr"],
"el" => ["name" => "Ελληνικά", "dir" => "ltr"],
"es" => ["name" => "Español", "dir" => "ltr"],
"fr" => ["name" => "Français", "dir" => "ltr"],
"it" => ["name" => "Italiano", "dir" => "ltr"],
"jp" => ["name" => "日本語", "dir" => "ltr"],
"ko" => ["name" => "한국어", "dir" => "ltr"],
"pl" => ["name" => "Polski", "dir" => "ltr"],
"pt" => ["name" => "Português", "dir" => "ltr"],
"pt_br" => ["name" => "Português Brasileiro", "dir" => "ltr"],
"ru" => ["name" => "Русский", "dir" => "ltr"],
"sl" => ["name" => "Slovenščina", "dir" => "ltr"],
"sr_lat" => ["name" => "Srpski", "dir" => "ltr"],
"sr" => ["name" => "Српски", "dir" => "ltr"],
"tr" => ["name" => "Türkçe", "dir" => "ltr"],
"zh_cn" => ["name" => "简体中文", "dir" => "ltr"],
"zh_tw" => ["name" => "繁體中文", "dir" => "ltr"],
]
?>
// File Name => Language Name
$languages = [
// English first
"en" => ["name" => "English", "dir" => "ltr"],
// Remaining sorted alphabetically by language code
"de" => ["name" => "Deutsch", "dir" => "ltr"],
"el" => ["name" => "Ελληνικά", "dir" => "ltr"],
"es" => ["name" => "Español", "dir" => "ltr"],
"fr" => ["name" => "Français", "dir" => "ltr"],
"it" => ["name" => "Italiano", "dir" => "ltr"],
"jp" => ["name" => "日本語", "dir" => "ltr"],
"ko" => ["name" => "한국어", "dir" => "ltr"],
"pl" => ["name" => "Polski", "dir" => "ltr"],
"pt" => ["name" => "Português", "dir" => "ltr"],
"pt_br" => ["name" => "Português Brasileiro", "dir" => "ltr"],
"ru" => ["name" => "Русский", "dir" => "ltr"],
"sl" => ["name" => "Slovenščina", "dir" => "ltr"],
"sr_lat" => ["name" => "Srpski", "dir" => "ltr"],
"sr" => ["name" => "Српски", "dir" => "ltr"],
"tr" => ["name" => "Türkçe", "dir" => "ltr"],
"zh_cn" => ["name" => "简体中文", "dir" => "ltr"],
"zh_tw" => ["name" => "繁體中文", "dir" => "ltr"],
]
?>

View File

@@ -77,8 +77,6 @@ $i18n = [
"payment_every" => "Płatność co",
"frequency" => "Częstotliwość",
"cycle" => "Cykl",
"next_payment" => "Następna płatność",
"payment_method" => "Metoda płatności",
"no_category" => "Brak kategorii",
"paid_by" => "Zapłacone przez",
"url" => "URL",
@@ -180,7 +178,7 @@ $i18n = [
"theme_settings" => "Ustawienia motywu",
"custom_colors" => "Kolory niestandardowe",
"dark_theme" => "Przełącz na jasny/ciemny motyw",
"switch_theme" => "Przełącz na jasny/ciemny motyw",
"automatic"=> "Automatycznie",
"calculate_monthly_price" => "Oblicz i pokaż miesięczną cenę wszystkich subskrypcji",
"convert_prices" => "Zawsze przeliczaj i pokazuj ceny w mojej głównej walucie (wolniej)",
"hide_disabled_subscriptions" => "Ukryj wyłączone subskrypcje",

View File

@@ -77,8 +77,6 @@ $i18n = [
"payment_every" => "Pagamento a cada",
"frequency" => "Frequencia",
"Cycle" => "Ciclo",
"next_payment" => "Próximo Pagamento",
"payment_method" => "Método de Pagamento",
"no_category" => "Sem categoria",
"paid_by" => "Pago por",
"url" => "URL",
@@ -180,7 +178,7 @@ $i18n = [
"theme_settings" => "Definições de Tema",
"custom_colors" => "Cores Personalizadas",
"dark_theme" => "Tema Escuro",
"switch_theme" => "Trocar Tema Claro / Escuro",
"automatic"=> "Automático",
"calculate_monthly_price" => "Calcular e mostrar preço mensal para todas as subscrições",
"convert_prices" => "Converter e mostrar todas as subscrições na moeda principal (mais lento)",
"hide_disabled_subscriptions" => "Esconder subscrições desactivadas",

View File

@@ -178,7 +178,7 @@ $i18n = [
"theme_settings" => "Configurações de tema",
"custom_colors" => "Cores personalizadas",
"dark_theme" => "Tema Escuro",
"switch_theme" => "Alternar entre tema Claro / Escuro",
"automatic" => "Automático",
"calculate_monthly_price" => "Calcular e exibir o custo mensal para todas as assinaturas",
"convert_prices" => "Sempre converter e exibir preços na moeda principal (mais lento)",
"hide_disabled_subscriptions" => "Ocultar assinaturas desativadas",

View File

@@ -77,8 +77,6 @@ $i18n = [
"payment_every" => "Оплата каждые",
"frequency" => "Частота",
"cycle" => "Цикл",
"next_payment" => "Следующий платеж",
"payment_method" => "Способ оплаты",
"no_category" => "Нет категории",
"paid_by" => "Оплачивает",
"url" => "URL",
@@ -180,7 +178,7 @@ $i18n = [
"theme_settings" => "Настройки темы",
"custom_colors" => "Пользовательские цвета",
"dark_theme" => "Темная тема",
"switch_theme" => "Переключить светлую/темную тему",
"automatic"=> "Автоматически",
"calculate_monthly_price" => "Рассчитать и показать ежемесячную цену для всех подписок",
"convert_prices" => "Всегда конвертировать и показывать цены в моей основной валюте (медленнее)",
"hide_disabled_subscriptions" => "Скрыть отключенные подписки",

View File

@@ -77,8 +77,6 @@ $i18n = [
"payment_every" => "Plačilo vsakih",
"frequency" => "Ponavljanje",
"cycle" => "cikel",
"next_payment" => "Naslednje plačilo",
"payment_method" => "Način plačila",
"no_category" => "Brez kategorije",
"paid_by" => "Plačal",
"url" => "URL",
@@ -180,7 +178,7 @@ $i18n = [
"theme_settings" => "Nastavitve teme",
"custom_colors" => "Barve po meri",
"dark_theme" => "Temna tema",
"switch_theme" => "Preklop med svetlo/temno temo",
"automatic"=> "Samodejno",
"calculate_monthly_price" => "Izračunaj in prikaži mesečno ceno za vse naročnine",
"convert_prices" => "Vedno pretvori in prikaži cene v moji glavni valuti (počasneje)",
"hide_disabled_subscriptions" => "Skrij onemogočene naročnine",

View File

@@ -77,8 +77,6 @@ $i18n = [
"payment_every" => "Плаћање сваког",
"frequency" => "Фреквенција",
"cycle" => "Циклус",
"next_payment" => "Следећа уплата",
"payment_method" => "Начин плаћања",
"no_category" => "Без категорије",
"paid_by" => "Плаћено од",
"url" => "URL",
@@ -179,7 +177,7 @@ $i18n = [
"theme_settings" => "Подешавања теме",
"custom_colors" => "Прилагођене боје",
"dark_theme" => "Тамна тема",
"switch_theme" => "Промени светлу / тамну тему",
"automatic"=> "Аутоматски",
"calculate_monthly_price" => "Израчунајте и прикажите месечну цену за све претплате",
"convert_prices" => "Увек конвертујте и прикажите цене на мојој главној валути (спорије)",
"hide_disabled_subscriptions" => "Сакриј онемогућене претплате",

View File

@@ -77,8 +77,6 @@ $i18n = [
"payment_every" => "Plaćanje svakog",
"frequency" => "Frekvencija",
"cycle" => "Ciklus",
"next_payment" => "Sledeća uplata",
"payment_method" => "Način plaćanja",
"no_category" => "Bez kategorije",
"paid_by" => "Plaćeno od strane",
"url" => "URL",
@@ -180,7 +178,7 @@ $i18n = [
"theme_settings" => "Podešavanja teme",
"custom_colors" => "Prilagođene boje",
"dark_theme" => "Tamna tema",
"switch_theme" => "Promeni svetli / tamni temu",
"automatic"=> "Automatski",
"calculate_monthly_price" => "Izračunaj i prikaži mesečnu cenu za sve pretplate",
"convert_prices" => "Uvek konvertuj i prikaži cene u mojoj glavnoj valuti (sporije)",
"hide_disabled_subscriptions" => "Sakrij onemogućene pretplate",

View File

@@ -77,8 +77,6 @@ $i18n = [
"payment_every" => "Ödeme Sıklığı",
"frequency" => "Frekans",
"cycle" => "Döngü",
"next_payment" => "Sonraki Ödeme",
"payment_method" => "Ödeme Yöntemi",
"no_category" => "Kategori yok",
"paid_by" => "Ödeyen",
"url" => "URL",
@@ -181,6 +179,7 @@ $i18n = [
"custom_colors" => "Özel Renkler",
"dark_theme" => "Koyu Temayı",
"switch_theme" => "ık / Koyu Temayı Değiştir",
"automatic"=> "Otomatik",
"calculate_monthly_price" => "Tüm aboneliklerin aylık fiyatını hesaplayın ve gösterin",
"convert_prices" => "Fiyatları her zaman ana para birimimde dönüştürün ve gösterin (daha yavaş)",
"hide_disabled_subscriptions" => "Devre dışı bırakılan abonelikleri gizle",

View File

@@ -82,8 +82,6 @@ $i18n = [
"payment_every" => "支付频率",
"frequency" => "频率",
"cycle" => "周期",
"next_payment" => "下次支付",
"payment_method" => "支付方式",
"no_category" => "无分类",
"paid_by" => "付款人",
"url" => "链接",
@@ -188,7 +186,7 @@ $i18n = [
"theme_settings" => "主题设置",
"custom_colors" => "自定义颜色",
"dark_theme" => "深色主题",
"switch_theme" => "切换浅色/深色主题",
"automatic"=> "自动",
"calculate_monthly_price" => "计算并显示所有订阅的月价格",
"convert_prices" => "始终按我的主要货币转换和显示价格(较慢)",
"hide_disabled_subscriptions" => "隐藏已停用的订阅",

View File

@@ -77,8 +77,6 @@ $i18n = [
"payment_every" => "付款頻率",
"frequency" => "頻率",
"cycle" => "週期",
"next_payment" => "下次付款",
"payment_method" => "付款方式",
"no_category" => "無分類",
"paid_by" => "付款人",
"url" => "連結",
@@ -180,7 +178,7 @@ $i18n = [
"theme_settings" => "主題設定",
"custom_colors" => "自訂顏色",
"dark_theme" => "深色主題",
"switch_theme" => "切換淺色/深色主題",
"automatic"=> "自動",
"calculate_monthly_price" => "計算並顯示所有訂閱的每月價格",
"convert_prices" => "始終按照我的主要貨幣單位轉換和顯示價格(較慢)",
"hide_disabled_subscriptions" => "隱藏已停用的訂閱",

View File

@@ -1,6 +1,7 @@
<?php
function validate($value) {
function validate($value)
{
$value = trim($value);
$value = stripslashes($value);
$value = htmlspecialchars($value);

View File

@@ -6,16 +6,12 @@
switch ($cycle) {
case 1:
return $frequency == 1 ? translate('Daily', $i18n) : $frequency . " " . translate('days', $i18n);
break;
case 2:
return $frequency == 1 ? translate('Weekly', $i18n) : $frequency . " " . translate('weeks', $i18n);
break;
case 3:
return $frequency == 1 ? translate('Monthly', $i18n) : $frequency . " " . translate('months', $i18n);
break;
case 4:
return $frequency == 1 ? translate('Yearly', $i18n) : $frequency . " " . translate('years', $i18n);
break;
}
}
@@ -24,19 +20,15 @@
case 1:
$numberOfPaymentsPerMonth = (30 / $frequency);
return $price * $numberOfPaymentsPerMonth;
break;
case 2:
$numberOfPaymentsPerMonth = (4.35 / $frequency);
return $price * $numberOfPaymentsPerMonth;
break;
case 3:
$numberOfPaymentsPerMonth = (1 / $frequency);
return $price * $numberOfPaymentsPerMonth;
break;
case 4:
$numberOfMonths = (12 * $frequency);
return $price / $numberOfMonths;
break;
}
}

View File

@@ -1,3 +1,3 @@
<?php
$version = "v2.7.0";
?>
$version = "v2.8.0";
?>

692
index.php
View File

@@ -1,372 +1,392 @@
<?php
require_once 'includes/header.php';
require_once 'includes/getdbkeys.php';
require_once 'includes/header.php';
require_once 'includes/getdbkeys.php';
include_once 'includes/list_subscriptions.php';
include_once 'includes/list_subscriptions.php';
$sort = "next_payment";
$sql = "SELECT * FROM subscriptions WHERE user_id = :userId ORDER BY next_payment ASC, inactive ASC";
if (isset($_COOKIE['sortOrder']) && $_COOKIE['sortOrder'] != "") {
$sort = $_COOKIE['sortOrder'];
$allowedSortCriteria = ['name', 'id', 'next_payment', 'price', 'payer_user_id', 'category_id', 'payment_method_id'];
$order = "ASC";
if ($sort == "price" || $sort == "id") {
$order = "DESC";
}
if (in_array($sort, $allowedSortCriteria)) {
$sql = "SELECT * FROM subscriptions WHERE user_id = :userId ORDER BY $sort $order, inactive ASC";
}
$sort = "next_payment";
$sql = "SELECT * FROM subscriptions WHERE user_id = :userId ORDER BY next_payment ASC, inactive ASC";
if (isset($_COOKIE['sortOrder']) && $_COOKIE['sortOrder'] != "") {
$sort = $_COOKIE['sortOrder'];
$allowedSortCriteria = ['name', 'id', 'next_payment', 'price', 'payer_user_id', 'category_id', 'payment_method_id'];
$order = "ASC";
if ($sort == "price" || $sort == "id") {
$order = "DESC";
}
$stmt = $db->prepare($sql);
$stmt->bindValue(':userId', $userId, SQLITE3_INTEGER);
$result = $stmt->execute();
if ($result) {
$subscriptions = array();
while ($row = $result->fetchArray(SQLITE3_ASSOC)) {
$subscriptions[] = $row;
}
if (in_array($sort, $allowedSortCriteria)) {
$sql = "SELECT * FROM subscriptions WHERE user_id = :userId ORDER BY $sort $order, inactive ASC";
}
}
$headerClass = count($subscriptions) > 0 ? "main-actions" : "main-actions hidden";
$defaultLogo = $theme == "light" ? "images/siteicons/" . $colorTheme . "/wallos.png" : "images/siteicons/" . $colorTheme . "/walloswhite.png";
$stmt = $db->prepare($sql);
$stmt->bindValue(':userId', $userId, SQLITE3_INTEGER);
$result = $stmt->execute();
if ($result) {
$subscriptions = array();
while ($row = $result->fetchArray(SQLITE3_ASSOC)) {
$subscriptions[] = $row;
}
}
$headerClass = count($subscriptions) > 0 ? "main-actions" : "main-actions hidden";
$defaultLogo = $theme == "light" ? "images/siteicons/" . $colorTheme . "/wallos.png" : "images/siteicons/" . $colorTheme . "/walloswhite.png";
?>
<style>
.logo-preview:after {
content: '<?= translate('upload_logo', $i18n) ?>';
}
</style>
<section class="contain">
<header class="<?= $headerClass ?>" id="main-actions">
<button class="button" onClick="addSubscription()">
<i class="fa-solid fa-circle-plus"></i>
<?= translate('new_subscription', $i18n) ?>
</button>
<div class="top-actions">
<div class="search">
<input type="text" autocomplete="off" name="search" id="search" placeholder="<?= translate('search', $i18n) ?>" onkeyup="searchSubscriptions()" />
<span class="fa-solid fa-magnifying-glass search-icon"></span>
</div>
<style>
.logo-preview:after {
content: '<?= translate('upload_logo', $i18n) ?>';
}
</style>
<section class="contain">
<header class="<?= $headerClass ?>" id="main-actions">
<button class="button" onClick="addSubscription()">
<i class="fa-solid fa-circle-plus"></i>
<?= translate('new_subscription', $i18n) ?>
</button>
<div class="top-actions">
<div class="search">
<input type="text" autocomplete="off" name="search" id="search" placeholder="<?= translate('search', $i18n) ?>"
onkeyup="searchSubscriptions()" />
<span class="fa-solid fa-magnifying-glass search-icon"></span>
</div>
<div class="filtermenu on-dashboard">
<button class="button secondary-button" id="filtermenu-button" title="<?= translate("filter", $i18n) ?>">
<i class="fa-solid fa-filter"></i>
</button>
<div class="filtermenu-content">
<?php
if (count($members) > 1) {
?>
<div class="filtermenu-submenu">
<div class="filter-title" onClick="toggleSubMenu('member')"><?= translate("member", $i18n) ?></div>
<div class="filtermenu-submenu-content" id="filter-member">
<?php
foreach ($members as $member) {
$selectedClass = '';
if (isset($_GET['member']) && $_GET['member'] == $member['id']) {
$selectedClass = 'selected';
}
?>
<div class="filter-item <?= $selectedClass ?>" data-memberid="<?= $member['id'] ?>"><?= $member['name'] ?></div>
<?php
}
?>
<div class="filtermenu on-dashboard">
<button class="button secondary-button" id="filtermenu-button" title="<?= translate("filter", $i18n) ?>">
<i class="fa-solid fa-filter"></i>
</button>
<div class="filtermenu-content">
<?php
if (count($members) > 1) {
?>
<div class="filtermenu-submenu">
<div class="filter-title" onClick="toggleSubMenu('member')"><?= translate("member", $i18n) ?></div>
<div class="filtermenu-submenu-content" id="filter-member">
<?php
foreach ($members as $member) {
$selectedClass = '';
if (isset($_GET['member']) && $_GET['member'] == $member['id']) {
$selectedClass = 'selected';
}
?>
<div class="filter-item <?= $selectedClass ?>" data-memberid="<?= $member['id'] ?>"><?= $member['name'] ?>
</div>
</div>
<?php
<?php
}
?>
<?php
if (count($categories) > 1) {
?>
<div class="filtermenu-submenu">
<div class="filter-title" onClick="toggleSubMenu('category')"><?= translate("category", $i18n) ?></div>
<div class="filtermenu-submenu-content" id="filter-category">
<?php
foreach ($categories as $category) {
if ($category['name'] == "No category") {
$category['name'] = translate("no_category", $i18n);
}
$selectedClass = '';
if (isset($_GET['category']) && $_GET['category'] == $category['id']) {
$selectedClass = 'selected';
}
?>
<div class="filter-item <?= $selectedClass ?>" data-categoryid="<?= $category['id'] ?>"><?= $category['name'] ?></div>
<?php
}
?>
</div>
</div>
<?php
}
?>
<?php
if (count($payment_methods) > 1) {
?>
<div class="filtermenu-submenu">
<div class="filter-title" onClick="toggleSubMenu('payment')"><?= translate("payment_method", $i18n) ?></div>
<div class="filtermenu-submenu-content" id="filter-payment">
<?php
foreach ($payment_methods as $payment) {
$selectedClass = '';
if (isset($_GET['payment']) && $_GET['payment'] == $payment['id']) {
$selectedClass = 'selected';
}
?>
<div class="filter-item <?= $selectedClass ?>" data-paymentid="<?= $payment['id'] ?>"><?= $payment['name'] ?></div>
<?php
}
?>
</div>
</div>
<?php
}
?>
<div class="filtermenu-submenu hide" id="clear-filters">
<div class="filter-title filter-clear" onClick="clearFilters()">
<i class="fa-solid fa-times-circle"></i> <?= translate("clear", $i18n) ?>
</div>
?>
</div>
</div>
</div>
<div class="sort-container">
<button class="button secondary-button" value="Sort" onClick="toggleSortOptions()" id="sort-button" title="<?= translate('sort', $i18n) ?>">
<i class="fa-solid fa-arrow-down-wide-short"></i>
</button>
<div class="sort-options" id="sort-options">
<ul>
<li <?= $sort == "name" ? 'class="selected"' : "" ?> onClick="setSortOption('name')" id="sort-name"><?= translate('name', $i18n) ?></li>
<li <?= $sort == "id" ? 'class="selected"' : "" ?> onClick="setSortOption('id')" id="sort-id"><?= translate('last_added', $i18n) ?></li>
<li <?= $sort == "price" ? 'class="selected"' : "" ?> onClick="setSortOption('price')" id="sort-price"><?= translate('price', $i18n) ?></li>
<li <?= $sort == "next_payment" ? 'class="selected"' : "" ?> onClick="setSortOption('next_payment')" id="sort-next_payment"><?= translate('next_payment', $i18n) ?></li>
<li <?= $sort == "payer_user_id" ? 'class="selected"' : "" ?> onClick="setSortOption('payer_user_id')" id="sort-payer_user_id"><?= translate('member', $i18n) ?></li>
<li <?= $sort == "category_id" ? 'class="selected"' : "" ?> onClick="setSortOption('category_id')" id="sort-category_id"><?= translate('category', $i18n) ?></li>
<li <?= $sort == "payment_method_id" ? 'class="selected"' : "" ?> onClick="setSortOption('payment_method_id')" id="sort-payment_method_id"><?= translate('payment_method', $i18n) ?></li>
</ul>
<?php
}
?>
<?php
if (count($categories) > 1) {
?>
<div class="filtermenu-submenu">
<div class="filter-title" onClick="toggleSubMenu('category')"><?= translate("category", $i18n) ?></div>
<div class="filtermenu-submenu-content" id="filter-category">
<?php
foreach ($categories as $category) {
if ($category['name'] == "No category") {
$category['name'] = translate("no_category", $i18n);
}
$selectedClass = '';
if (isset($_GET['category']) && $_GET['category'] == $category['id']) {
$selectedClass = 'selected';
}
?>
<div class="filter-item <?= $selectedClass ?>" data-categoryid="<?= $category['id'] ?>">
<?= $category['name'] ?></div>
<?php
}
?>
</div>
</div>
<?php
}
?>
<?php
if (count($payment_methods) > 1) {
?>
<div class="filtermenu-submenu">
<div class="filter-title" onClick="toggleSubMenu('payment')"><?= translate("payment_method", $i18n) ?></div>
<div class="filtermenu-submenu-content" id="filter-payment">
<?php
foreach ($payment_methods as $payment) {
$selectedClass = '';
if (isset($_GET['payment']) && $_GET['payment'] == $payment['id']) {
$selectedClass = 'selected';
}
?>
<div class="filter-item <?= $selectedClass ?>" data-paymentid="<?= $payment['id'] ?>">
<?= $payment['name'] ?></div>
<?php
}
?>
</div>
</div>
<?php
}
?>
<div class="filtermenu-submenu hide" id="clear-filters">
<div class="filter-title filter-clear" onClick="clearFilters()">
<i class="fa-solid fa-times-circle"></i> <?= translate("clear", $i18n) ?>
</div>
</div>
</div>
</header>
<div class="subscriptions" id="subscriptions">
<?php
foreach ($subscriptions as $subscription) {
if ($subscription['inactive'] == 1 && isset($settings['hideDisabledSubscriptions']) && $settings['hideDisabledSubscriptions'] === 'true') {
continue;
}
$id = $subscription['id'];
$print[$id]['id'] = $id;
$print[$id]['logo'] = $subscription['logo'] != "" ? "images/uploads/logos/".$subscription['logo'] : $defaultLogo;
$print[$id]['name']= $subscription['name'];
$cycle = $subscription['cycle'];
$frequency = $subscription['frequency'];
$print[$id]['billing_cycle'] = getBillingCycle($cycle, $frequency, $i18n);
$paymentMethodId = $subscription['payment_method_id'];
$print[$id]['currency_code'] = $currencies[$subscription['currency_id']]['code'];
$currencyId = $subscription['currency_id'];
$print[$id]['next_payment'] = date('M d, Y', strtotime($subscription['next_payment']));
$paymentIconFolder = (strpos($payment_methods[$paymentMethodId]['icon'], 'images/uploads/icons/') !== false) ? "" : "images/uploads/logos/";
$print[$id]['payment_method_icon'] = $paymentIconFolder . $payment_methods[$paymentMethodId]['icon'];
$print[$id]['payment_method_name'] = $payment_methods[$paymentMethodId]['name'];
$print[$id]['payment_method_id'] = $paymentMethodId;
$print[$id]['category_id'] = $subscription['category_id'];
$print[$id]['payer_user_id'] = $subscription['payer_user_id'];
$print[$id]['price'] = floatval($subscription['price']);
$print[$id]['inactive'] = $subscription['inactive'];
$print[$id]['url'] = $subscription['url'];
$print[$id]['notes'] = $subscription['notes'];
if (isset($settings['convertCurrency']) && $settings['convertCurrency'] === 'true' && $currencyId != $mainCurrencyId) {
$print[$id]['price'] = getPriceConverted($print[$id]['price'], $currencyId, $db);
$print[$id]['currency_code'] = $currencies[$mainCurrencyId]['code'];
}
if (isset($settings['showMonthlyPrice']) && $settings['showMonthlyPrice'] === 'true') {
$print[$id]['price'] = getPricePerMonth($cycle, $frequency, $print[$id]['price']);
}
}
if (isset($print)) {
printSubscriptions($print, $sort, $categories, $members, $i18n, $colorTheme);
}
$db->close();
if (count($subscriptions) == 0) {
?>
<div class="empty-page">
<img src="images/siteimages/empty.png" alt="<?= translate('empty_page', $i18n) ?>" />
<p>
<?= translate('no_subscriptions_yet', $i18n) ?>
</p>
<button class="button" onClick="addSubscription()">
<i class="fa-solid fa-circle-plus"></i>
<?= translate('add_first_subscription', $i18n) ?>
</button>
</div>
<?php
}
?>
</div>
<section class="subscription-form" id="subscription-form">
<header>
<h3 id="form-title"><?= translate('add_subscription', $i18n) ?></h3>
<span class="fa-solid fa-xmark close-form" onClick="closeAddSubscription()"></span>
</header>
<form action="endpoints/subscription/add.php" method="post" id="subs-form">
<div class="form-group-inline">
<input type="text" id="name" name="name" placeholder="<?= translate('subscription_name', $i18n) ?>" onchange="setSearchButtonStatus()" onkeypress="this.onchange();" onpaste="this.onchange();" oninput="this.onchange();" required>
<label for="logo" class="logo-preview">
<img src="" alt="<?= translate('logo_preview', $i18n) ?>" id="form-logo">
</label>
<input type="file" id="logo" name="logo" accept="image/jpeg, image/png, image/gif, image/webp" onchange="handleFileSelect(event)" class="hidden-input">
<input type="hidden" id="logo-url" name="logo-url">
<div id="logo-search-button" class="image-button medium disabled" title="<?= translate('search_logo', $i18n) ?>" onClick="searchLogo()">
<img src="images/siteicons/<?= $colorTheme ?>/websearch.png">
</div>
<input type="hidden" id="id" name="id">
<div id="logo-search-results" class="logo-search">
<header>
<?= translate('web_search', $i18n) ?>
<span class="fa-solid fa-xmark close-logo-search" onClick="closeLogoSearch()"></span>
</header>
<div id="logo-search-images"></div>
</div>
</div>
<div class="sort-container">
<button class="button secondary-button" value="Sort" onClick="toggleSortOptions()" id="sort-button"
title="<?= translate('sort', $i18n) ?>">
<i class="fa-solid fa-arrow-down-wide-short"></i>
</button>
<div class="sort-options" id="sort-options">
<ul>
<li <?= $sort == "name" ? 'class="selected"' : "" ?> onClick="setSortOption('name')" id="sort-name">
<?= translate('name', $i18n) ?></li>
<li <?= $sort == "id" ? 'class="selected"' : "" ?> onClick="setSortOption('id')" id="sort-id">
<?= translate('last_added', $i18n) ?></li>
<li <?= $sort == "price" ? 'class="selected"' : "" ?> onClick="setSortOption('price')" id="sort-price">
<?= translate('price', $i18n) ?></li>
<li <?= $sort == "next_payment" ? 'class="selected"' : "" ?> onClick="setSortOption('next_payment')"
id="sort-next_payment"><?= translate('next_payment', $i18n) ?></li>
<li <?= $sort == "payer_user_id" ? 'class="selected"' : "" ?> onClick="setSortOption('payer_user_id')"
id="sort-payer_user_id"><?= translate('member', $i18n) ?></li>
<li <?= $sort == "category_id" ? 'class="selected"' : "" ?> onClick="setSortOption('category_id')"
id="sort-category_id"><?= translate('category', $i18n) ?></li>
<li <?= $sort == "payment_method_id" ? 'class="selected"' : "" ?> onClick="setSortOption('payment_method_id')"
id="sort-payment_method_id"><?= translate('payment_method', $i18n) ?></li>
</ul>
</div>
</div>
</div>
</header>
<div class="subscriptions" id="subscriptions">
<?php
foreach ($subscriptions as $subscription) {
if ($subscription['inactive'] == 1 && isset($settings['hideDisabledSubscriptions']) && $settings['hideDisabledSubscriptions'] === 'true') {
continue;
}
$id = $subscription['id'];
$print[$id]['id'] = $id;
$print[$id]['logo'] = $subscription['logo'] != "" ? "images/uploads/logos/" . $subscription['logo'] : $defaultLogo;
$print[$id]['name'] = $subscription['name'];
$cycle = $subscription['cycle'];
$frequency = $subscription['frequency'];
$print[$id]['billing_cycle'] = getBillingCycle($cycle, $frequency, $i18n);
$paymentMethodId = $subscription['payment_method_id'];
$print[$id]['currency_code'] = $currencies[$subscription['currency_id']]['code'];
$currencyId = $subscription['currency_id'];
$print[$id]['next_payment'] = date('M d, Y', strtotime($subscription['next_payment']));
$paymentIconFolder = (strpos($payment_methods[$paymentMethodId]['icon'], 'images/uploads/icons/') !== false) ? "" : "images/uploads/logos/";
$print[$id]['payment_method_icon'] = $paymentIconFolder . $payment_methods[$paymentMethodId]['icon'];
$print[$id]['payment_method_name'] = $payment_methods[$paymentMethodId]['name'];
$print[$id]['payment_method_id'] = $paymentMethodId;
$print[$id]['category_id'] = $subscription['category_id'];
$print[$id]['payer_user_id'] = $subscription['payer_user_id'];
$print[$id]['price'] = floatval($subscription['price']);
$print[$id]['inactive'] = $subscription['inactive'];
$print[$id]['url'] = $subscription['url'];
$print[$id]['notes'] = $subscription['notes'];
<div class="form-group-inline">
<input type="number" step="0.01" id="price" name="price" placeholder="<?= translate('price', $i18n) ?>" required>
<select id="currency" name="currency_id" placeholder="<?= translate('add_subscription', $i18n) ?>">
<?php
foreach ($currencies as $currency) {
$selected = ($currency['id'] == $main_currency) ? 'selected' : '';
?>
<option value="<?= $currency['id'] ?>" <?= $selected ?>><?= $currency['name'] ?></option>
<?php
}
?>
</select>
</div>
<div class="form-group">
if (isset($settings['convertCurrency']) && $settings['convertCurrency'] === 'true' && $currencyId != $mainCurrencyId) {
$print[$id]['price'] = getPriceConverted($print[$id]['price'], $currencyId, $db);
$print[$id]['currency_code'] = $currencies[$mainCurrencyId]['code'];
}
if (isset($settings['showMonthlyPrice']) && $settings['showMonthlyPrice'] === 'true') {
$print[$id]['price'] = getPricePerMonth($cycle, $frequency, $print[$id]['price']);
}
}
if (isset($print)) {
printSubscriptions($print, $sort, $categories, $members, $i18n, $colorTheme);
}
$db->close();
if (count($subscriptions) == 0) {
?>
<div class="empty-page">
<img src="images/siteimages/empty.png" alt="<?= translate('empty_page', $i18n) ?>" />
<p>
<?= translate('no_subscriptions_yet', $i18n) ?>
</p>
<button class="button" onClick="addSubscription()">
<i class="fa-solid fa-circle-plus"></i>
<?= translate('add_first_subscription', $i18n) ?>
</button>
</div>
<?php
}
?>
</div>
<section class="subscription-form" id="subscription-form">
<header>
<h3 id="form-title"><?= translate('add_subscription', $i18n) ?></h3>
<span class="fa-solid fa-xmark close-form" onClick="closeAddSubscription()"></span>
</header>
<form action="endpoints/subscription/add.php" method="post" id="subs-form">
<div class="form-group-inline">
<input type="text" id="name" name="name" placeholder="<?= translate('subscription_name', $i18n) ?>"
onchange="setSearchButtonStatus()" onkeypress="this.onchange();" onpaste="this.onchange();"
oninput="this.onchange();" required>
<label for="logo" class="logo-preview">
<img src="" alt="<?= translate('logo_preview', $i18n) ?>" id="form-logo">
</label>
<input type="file" id="logo" name="logo" accept="image/jpeg, image/png, image/gif, image/webp"
onchange="handleFileSelect(event)" class="hidden-input">
<input type="hidden" id="logo-url" name="logo-url">
<div id="logo-search-button" class="image-button medium disabled" title="<?= translate('search_logo', $i18n) ?>"
onClick="searchLogo()">
<img src="images/siteicons/<?= $colorTheme ?>/websearch.png">
</div>
<input type="hidden" id="id" name="id">
<div id="logo-search-results" class="logo-search">
<header>
<?= translate('web_search', $i18n) ?>
<span class="fa-solid fa-xmark close-logo-search" onClick="closeLogoSearch()"></span>
</header>
<div id="logo-search-images"></div>
</div>
</div>
<div class="form-group-inline">
<input type="number" step="0.01" id="price" name="price" placeholder="<?= translate('price', $i18n) ?>"
required>
<select id="currency" name="currency_id" placeholder="<?= translate('add_subscription', $i18n) ?>">
<?php
foreach ($currencies as $currency) {
$selected = ($currency['id'] == $main_currency) ? 'selected' : '';
?>
<option value="<?= $currency['id'] ?>" <?= $selected ?>><?= $currency['name'] ?></option>
<?php
}
?>
</select>
</div>
<div class="form-group">
<div class="inline">
<div class="split66">
<label for="cycle"><?= translate('payment_every', $i18n) ?></label>
<div class="inline">
<div class="split66">
<label for="cycle"><?= translate('payment_every', $i18n) ?></label>
<div class="inline">
<select id="frequency" name="frequency" placeholder="<?= translate('frequency', $i18n) ?>">
<?php
for ($i = 1; $i <= 366; $i++) {
<select id="frequency" name="frequency" placeholder="<?= translate('frequency', $i18n) ?>">
<?php
for ($i = 1; $i <= 366; $i++) {
?>
<option value="<?= $i ?>"><?= $i ?></option>
<option value="<?= $i ?>"><?= $i ?></option>
<?php
}
}
?>
</select>
<select id="cycle" name="cycle" placeholder="Cycle">
<?php
foreach ($cycles as $cycle) {
?>
</select>
<select id="cycle" name="cycle" placeholder="Cycle">
<option value="<?= $cycle['id'] ?>" <?= $cycle['id'] == 3 ? "selected" : "" ?>>
<?= translate(strtolower($cycle['name']), $i18n) ?></option>
<?php
foreach ($cycles as $cycle) {
?>
<option value="<?= $cycle['id'] ?>" <?= $cycle['id'] == 3 ? "selected" : "" ?>><?= translate(strtolower($cycle['name']), $i18n) ?></option>
<?php
}
?>
</select>
</div>
</div>
<div class="split33">
<label for="next_payment"><?= translate('next_payment', $i18n) ?></label>
<input type="date" id="next_payment" name="next_payment" required>
</div>
}
?>
</select>
</div>
</div>
<div class="form-group-inline">
<input type="checkbox" id="notifications" name="notifications" onchange="toggleNotificationDays()">
<label for="notifications"><?= translate('enable_notifications', $i18n) ?></label>
<div class="split33">
<label for="next_payment"><?= translate('next_payment', $i18n) ?></label>
<input type="date" id="next_payment" name="next_payment" required>
</div>
</div>
</div>
<div class="form-group">
<label for="notify_days_before"><?= translate('notify_me', $i18n) ?></label>
<select id="notify_days_before" name="notify_days_before" disabled>
<option value="0"><?= translate('default_value_from_settings', $i18n) ?></option>
<option value="1">1 <?= translate('day_before', $i18n) ?></option>
<?php
for ($i = 2; $i <= 90; $i++) {
?>
<option value="<?= $i ?>"><?= $i ?> <?= translate('days_before', $i18n) ?></option>
<?php
}
?>
</select>
</div>
<div class="form-group-inline">
<input type="checkbox" id="notifications" name="notifications" onchange="toggleNotificationDays()">
<label for="notifications"><?= translate('enable_notifications', $i18n) ?></label>
</div>
<div class="form-group">
<label for="payment_method"><?= translate('payment_method', $i18n) ?></label>
<select id="payment_method" name="payment_method_id">
<?php
foreach ($payment_methods as $payment) {
?>
<option value="<?= $payment['id'] ?>">
<?= $payment['name'] ?>
</option>
<?php
}
?>
</select>
</div>
<div class="form-group">
<label for="notify_days_before"><?= translate('notify_me', $i18n) ?></label>
<select id="notify_days_before" name="notify_days_before" disabled>
<option value="0"><?= translate('default_value_from_settings', $i18n) ?></option>
<option value="1">1 <?= translate('day_before', $i18n) ?></option>
<?php
for ($i = 2; $i <= 90; $i++) {
?>
<option value="<?= $i ?>"><?= $i ?> <?= translate('days_before', $i18n) ?></option>
<?php
}
?>
</select>
</div>
<div class="form-group">
<label for="category"><?= translate('category', $i18n) ?></label>
<select id="category" name="category_id">
<?php
foreach ($categories as $category) {
?>
<option value="<?= $category['id'] ?>">
<?= $category['name'] ?>
</option>
<?php
}
?>
</select>
</div>
<div class="form-group">
<label for="payment_method"><?= translate('payment_method', $i18n) ?></label>
<select id="payment_method" name="payment_method_id">
<?php
foreach ($payment_methods as $payment) {
?>
<option value="<?= $payment['id'] ?>">
<?= $payment['name'] ?>
</option>
<?php
}
?>
</select>
</div>
<div class="form-group">
<label for="payer_user"><?= translate('paid_by', $i18n) ?></label>
<select id="payer_user" name="payer_user_id">
<?php
foreach ($members as $member) {
?>
<option value="<?= $member['id'] ?>"><?= $member['name'] ?></option>
<?php
}
?>
</select>
</div>
<div class="form-group">
<label for="category"><?= translate('category', $i18n) ?></label>
<select id="category" name="category_id">
<?php
foreach ($categories as $category) {
?>
<option value="<?= $category['id'] ?>">
<?= $category['name'] ?>
</option>
<?php
}
?>
</select>
</div>
<div class="form-group">
<input type="text" id="url" name="url" placeholder="<?= translate('url', $i18n) ?>">
</div>
<div class="form-group">
<input type="text" id="notes" name="notes" placeholder="<?= translate('notes', $i18n) ?>">
</div>
<div class="form-group">
<label for="payer_user"><?= translate('paid_by', $i18n) ?></label>
<select id="payer_user" name="payer_user_id">
<?php
foreach ($members as $member) {
?>
<option value="<?= $member['id'] ?>"><?= $member['name'] ?></option>
<?php
}
?>
</select>
</div>
<div class="form-group-inline">
<input type="checkbox" id="inactive" name="inactive">
<label for="inactive"><?= translate('inactive', $i18n) ?></label>
</div>
<div class="form-group">
<input type="text" id="url" name="url" placeholder="<?= translate('url', $i18n) ?>">
</div>
<div class="buttons">
<input type="button" value="<?= translate('delete', $i18n) ?>" class="warning-button left thin" id="deletesub" style="display: none">
<input type="button" value="<?= translate('cancel', $i18n) ?>" class="secondary-button thin" onClick="closeAddSubscription()">
<input type="submit" value="<?= translate('save', $i18n) ?>" class="thin" id="save-button">
</div>
</form>
</section>
</section>
<script src="scripts/dashboard.js?<?= $version ?>"></script>
<div class="form-group">
<input type="text" id="notes" name="notes" placeholder="<?= translate('notes', $i18n) ?>">
</div>
<div class="form-group-inline">
<input type="checkbox" id="inactive" name="inactive">
<label for="inactive"><?= translate('inactive', $i18n) ?></label>
</div>
<div class="buttons">
<input type="button" value="<?= translate('delete', $i18n) ?>" class="warning-button left thin" id="deletesub"
style="display: none">
<input type="button" value="<?= translate('cancel', $i18n) ?>" class="secondary-button thin"
onClick="closeAddSubscription()">
<input type="submit" value="<?= translate('save', $i18n) ?>" class="thin" id="save-button">
</div>
</form>
</section>
</section>
<script src="scripts/dashboard.js?<?= $version ?>"></script>
<?php
require_once 'includes/footer.php';
?>
require_once 'includes/footer.php';
?>

126
login.php
View File

@@ -18,14 +18,14 @@ if (isset($_SESSION['loggedin']) && $_SESSION['loggedin'] === true) {
$db->close();
header("Location: .");
exit();
}
}
// Check if login is disabled
$adminQuery = "SELECT login_disabled FROM admin";
$adminResult = $db->query($adminQuery);
$adminRow = $adminResult->fetchArray(SQLITE3_ASSOC);
if ($adminRow['login_disabled'] == 1) {
$query = "SELECT id, username, main_currency, language FROM user WHERE id = :id";
$stmt = $db->prepare($query);
$stmt->bindValue(':id', 1, SQLITE3_INTEGER);
@@ -57,7 +57,7 @@ if ($adminRow['login_disabled'] == 1) {
$stmt = $db->prepare($query);
$result = $stmt->execute();
$settings = $result->fetchArray(SQLITE3_ASSOC);
setcookie('colorTheme', $settings['color_theme'], $cookieExpire);
setcookie('colorTheme', $settings['color_theme'], $cookieExpire);
$cookieValue = $username . "|" . "abc123ABC" . "|" . $main_currency;
setcookie('wallos_login', $cookieValue, $cookieExpire);
@@ -69,8 +69,11 @@ if ($adminRow['login_disabled'] == 1) {
$theme = "light";
$updateThemeSettings = false;
if (isset($_COOKIE['theme'])) {
$theme = $_COOKIE['theme'];
} else {
$updateThemeSettings = true;
}
$colorTheme = "blue";
@@ -123,7 +126,7 @@ if (isset($_POST['username']) && isset($_POST['password'])) {
$result = $stmt->execute();
$settings = $result->fetchArray(SQLITE3_ASSOC);
setcookie('colorTheme', $settings['color_theme'], $cookieExpire);
$token = bin2hex(random_bytes(32));
$addLoginTokens = "INSERT INTO login_tokens (user_id, token) VALUES (:userId, :token)";
$addLoginTokensStmt = $db->prepare($addLoginTokens);
@@ -138,7 +141,7 @@ if (isset($_POST['username']) && isset($_POST['password'])) {
header("Location: .");
exit();
}
} else {
$loginFailed = true;
}
@@ -175,10 +178,11 @@ if ($adminRow['smtp_address'] != "" && $adminRow['server_url'] != "") {
?>
<!DOCTYPE html>
<html dir="<?= $languages[$lang]['dir'] ?>">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
<meta name="theme-color" content="<?= $theme == "light" ? "#FFFFFF" : "#222222" ?>"/>
<meta name="theme-color" content="<?= $theme == "light" ? "#FFFFFF" : "#222222" ?>" id="theme-color" />
<title>Wallos - Subscription Tracker</title>
<link rel="icon" type="image/png" href="images/icon/favicon.ico" sizes="16x16">
<link rel="apple-touch-icon" sizes="180x180" href="images/icon/apple-touch-icon.png">
@@ -191,17 +195,25 @@ if ($adminRow['smtp_address'] != "" && $adminRow['server_url'] != "") {
<link rel="stylesheet" href="styles/font-awesome.min.css">
<link rel="stylesheet" href="styles/barlow.css">
<link rel="stylesheet" href="styles/login-dark-theme.css?<?= $version ?>" id="dark-theme" <?= $theme == "light" ? "disabled" : "" ?>>
<script type="text/javascript">
window.update_theme_settings = "<?= $updateThemeSettings ?>";
window.color_theme = "<?= $colorTheme ?>";
</script>
<script type="text/javascript" src="scripts/login.js?<?= $version ?>"></script>
</head>
<body class="<?= $languages[$lang]['dir'] ?>">
<div class="content">
<section class="container">
<header>
<?php
if ($theme == "light") {
?> <img src="images/siteicons/<?= $colorTheme ?>/wallos.png" alt="Wallos Logo" title="Wallos - Subscription Tracker" width="215" /> <?php
} else {
?> <img src="images/siteicons/<?= $colorTheme ?>/walloswhite.png" alt="Wallos Logo" title="Wallos - Subscription Tracker" width="215" /> <?php
}
<?php
if ($theme == "light") {
?> <img src="images/siteicons/<?= $colorTheme ?>/wallos.png" alt="Wallos Logo"
title="Wallos - Subscription Tracker" width="215" id="wallos-logo" /> <?php
} else {
?> <img src="images/siteicons/<?= $colorTheme ?>/walloswhite.png" alt="Wallos Logo"
title="Wallos - Subscription Tracker" width="215" id="wallos-logo" /> <?php
}
?>
<p>
<?= translate('please_login', $i18n) ?>
@@ -224,62 +236,65 @@ if ($adminRow['smtp_address'] != "" && $adminRow['server_url'] != "") {
<input type="submit" value="<?= translate('login', $i18n) ?>">
</div>
<?php
if ($loginFailed) {
?>
<ul class="error-box">
if ($loginFailed) {
?>
<ul class="error-box">
<?php
if ($userEmailWaitingVerification) {
?>
<li><i class="fa-solid fa-triangle-exclamation"></i><?= translate('user_email_waiting_verification', $i18n) ?></li>
<?php
} else {
?>
<li><i class="fa-solid fa-triangle-exclamation"></i><?= translate('login_failed', $i18n) ?></li>
<?php
}
if ($userEmailWaitingVerification) {
?>
<li><i
class="fa-solid fa-triangle-exclamation"></i><?= translate('user_email_waiting_verification', $i18n) ?>
</li>
<?php
} else {
?>
<li><i class="fa-solid fa-triangle-exclamation"></i><?= translate('login_failed', $i18n) ?></li>
<?php
}
?>
</ul>
</ul>
<?php
}
if ($hasSuccessMessage) {
?>
<ul class="success-box">
<?php
}
if ($hasSuccessMessage) {
?>
<ul class="success-box">
<?php
if (isset($_GET['validated']) && $_GET['validated'] == "true") {
?>
<li><i class="fa-solid fa-check"></i><?= translate('email_verified', $i18n) ?></li>
<?php
} else if (isset($_GET['registered']) && $_GET['registered']) {
?>
if (isset($_GET['validated']) && $_GET['validated'] == "true") {
?>
<li><i class="fa-solid fa-check"></i><?= translate('email_verified', $i18n) ?></li>
<?php
} else if (isset($_GET['registered']) && $_GET['registered']) {
?>
<li><i class="fa-solid fa-check"></i><?= translate('registration_successful', $i18n) ?></li>
<?php
if (isset($_GET['requireValidation']) && $_GET['requireValidation'] == true) {
?>
<li><?= translate('user_email_waiting_verification', $i18n) ?></li>
<?php
<?php
}
}
}
?>
</ul>
<?php
}
</ul>
<?php
}
if ($resetPasswordEnabled) {
?>
<div class="login-form-link">
<a href="passwordreset.php"><?= translate('forgot_password', $i18n) ?></a>
</div>
<?php
}
if ($resetPasswordEnabled) {
?>
<div class="login-form-link">
<a href="passwordreset.php"><?= translate('forgot_password', $i18n) ?></a>
</div>
<?php
}
?>
<?php
if ($registrations) {
?>
<div class="separator">
<input type="button" class="secondary-button" onclick="openRegitrationPage()" value="<?= translate('register', $i18n) ?>"></input>
</div>
<?php
}
if ($registrations) {
?>
<div class="separator">
<input type="button" class="secondary-button" onclick="openRegitrationPage()"
value="<?= translate('register', $i18n) ?>"></input>
</div>
<?php
}
?>
</form>
</section>
@@ -290,4 +305,5 @@ if ($adminRow['smtp_address'] != "" && $adminRow['server_url'] != "") {
}
</script>
</body>
</html>

View File

@@ -1,54 +1,56 @@
<!DOCTYPE html>
<html>
<head>
<title>Subscription Logos</title>
<script type="text/javascript">
document.addEventListener("DOMContentLoaded", function () {
const searchForm = document.getElementById("search-form");
const imageResults = document.getElementById("image-results");
const searchForm = document.getElementById("search-form");
const imageResults = document.getElementById("image-results");
searchForm.addEventListener("submit", function (e) {
e.preventDefault();
searchForm.addEventListener("submit", function (e) {
e.preventDefault();
const searchTerm = document.getElementById("search").value.trim();
if (searchTerm === "") {
alert("Please enter a search term.");
return;
}
// Use the proxy to perform a Google image search
const proxyUrl = `endpoints/logos/search.php?search=${searchTerm}`;
// Send an AJAX request to the proxy
fetch(proxyUrl)
.then(response => response.json())
.then(data => {
if (data.imageUrls) {
// Display the image sources from the PHP response.
displayImageResults(data.imageUrls);
} else if (data.error) {
console.error(data.error);
const searchTerm = document.getElementById("search").value.trim();
if (searchTerm === "") {
alert("Please enter a search term.");
return;
}
})
.catch(error => {
console.error("Error fetching image results:", error);
// Use the proxy to perform a Google image search
const proxyUrl = `endpoints/logos/search.php?search=${searchTerm}`;
// Send an AJAX request to the proxy
fetch(proxyUrl)
.then(response => response.json())
.then(data => {
if (data.imageUrls) {
// Display the image sources from the PHP response.
displayImageResults(data.imageUrls);
} else if (data.error) {
console.error(data.error);
}
})
.catch(error => {
console.error("Error fetching image results:", error);
});
});
});
function displayImageResults(imageSources) {
// Clear previous results
imageResults.innerHTML = "";
function displayImageResults(imageSources) {
// Clear previous results
imageResults.innerHTML = "";
// Display the image sources as image elements
imageSources.forEach(src => {
const img = document.createElement("img");
img.src = src;
imageResults.appendChild(img);
// Display the image sources as image elements
imageSources.forEach(src => {
const img = document.createElement("img");
img.src = src;
imageResults.appendChild(img);
});
}
});
}
});
</script>
</head>
<body>
<form id="search-form">
<input type="text" name="search" id="search">
@@ -58,4 +60,5 @@
<!-- Image results will be displayed here -->
</div>
</body>
</html>

View File

@@ -1,20 +1,20 @@
<?php
require_once 'includes/connect.php';
session_start();
// get token from cookie to remove from DB
if (isset($_SESSION['token'])) {
$token = $_SESSION['token'];
$sql = "DELETE FROM login_tokens WHERE token = :token AND user_id = :userId";
$stmt = $db->prepare($sql);
$stmt->bindParam(':token', $token, SQLITE3_TEXT);
$stmt->bindParam(':userId', $userId, SQLITE3_INTEGER);
$stmt->execute();
}
$_SESSION = array();
session_destroy();
$cookieExpire = time() - 3600;
setcookie('wallos_login', '', $cookieExpire);
$db->close();
header("Location: .");
exit();
require_once 'includes/connect.php';
session_start();
// get token from cookie to remove from DB
if (isset($_SESSION['token'])) {
$token = $_SESSION['token'];
$sql = "DELETE FROM login_tokens WHERE token = :token AND user_id = :userId";
$stmt = $db->prepare($sql);
$stmt->bindParam(':token', $token, SQLITE3_TEXT);
$stmt->bindParam(':userId', $userId, SQLITE3_INTEGER);
$stmt->execute();
}
$_SESSION = array();
session_destroy();
$cookieExpire = time() - 3600;
setcookie('wallos_login', '', $cookieExpire);
$db->close();
header("Location: .");
exit();
?>

View File

@@ -14,7 +14,7 @@ if (isset($_SESSION['loggedin']) && $_SESSION['loggedin'] === true) {
$db->close();
header("Location: .");
exit();
}
}
$requestMode = true;
$resetMode = false;
@@ -104,10 +104,11 @@ if (isset($_POST['password']) && $_POST['password'] != "" && isset($_POST['confi
?>
<!DOCTYPE html>
<html dir="<?= $languages[$lang]['dir'] ?>">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
<meta name="theme-color" content="<?= $theme == "light" ? "#FFFFFF" : "#222222" ?>"/>
<meta name="theme-color" content="<?= $theme == "light" ? "#FFFFFF" : "#222222" ?>" />
<title>Wallos - Subscription Tracker</title>
<link rel="icon" type="image/png" href="images/icon/favicon.ico" sizes="16x16">
<link rel="apple-touch-icon" sizes="180x180" href="images/icon/apple-touch-icon.png">
@@ -121,16 +122,19 @@ if (isset($_POST['password']) && $_POST['password'] != "" && isset($_POST['confi
<link rel="stylesheet" href="styles/barlow.css">
<link rel="stylesheet" href="styles/login-dark-theme.css?<?= $version ?>" id="dark-theme" <?= $theme == "light" ? "disabled" : "" ?>>
</head>
<body class="<?= $languages[$lang]['dir'] ?>">
<div class="content">
<section class="container">
<header>
<?php
if ($theme == "light") {
?> <img src="images/siteicons/<?= $colorTheme ?>/wallos.png" alt="Wallos Logo" title="Wallos - Subscription Tracker" width="215" /> <?php
} else {
?> <img src="images/siteicons/<?= $colorTheme ?>/walloswhite.png" alt="Wallos Logo" title="Wallos - Subscription Tracker" width="215" /> <?php
}
<?php
if ($theme == "light") {
?> <img src="images/siteicons/<?= $colorTheme ?>/wallos.png" alt="Wallos Logo"
title="Wallos - Subscription Tracker" width="215" /> <?php
} else {
?> <img src="images/siteicons/<?= $colorTheme ?>/walloswhite.png" alt="Wallos Logo"
title="Wallos - Subscription Tracker" width="215" /> <?php
}
?>
<p>
<?= translate('reset_password', $i18n) ?>
@@ -138,8 +142,8 @@ if (isset($_POST['password']) && $_POST['password'] != "" && isset($_POST['confi
</header>
<form action="passwordreset.php?submit=true" method="post">
<?php
if ($requestMode) {
if (!$hideForm) {
if ($requestMode) {
if (!$hideForm) {
?>
<div class="form-group">
<label for="email"><?= translate('email', $i18n) ?>:</label>
@@ -149,24 +153,24 @@ if (isset($_POST['password']) && $_POST['password'] != "" && isset($_POST['confi
<input type="submit" value="<?= translate('reset_password', $i18n) ?>">
</div>
<?php
}
if ($hasSuccessMessage) {
?>
<ul class="success-box">
<li><i class="fa-solid fa-check"></i><?= translate('reset_sent_check_email', $i18n) ?></li>
</ul>
<?php
}
if ($hasErrorMessage) {
?>
<ul class="error-box">
<li><i class="fa-solid fa-triangle-exclamation"></i><?= translate('error', $i18n) ?></li>
</ul>
<?php
}
}
if ($resetMode) {
if (!$hideForm) {
if ($hasSuccessMessage) {
?>
<ul class="success-box">
<li><i class="fa-solid fa-check"></i><?= translate('reset_sent_check_email', $i18n) ?></li>
</ul>
<?php
}
if ($hasErrorMessage) {
?>
<ul class="error-box">
<li><i class="fa-solid fa-triangle-exclamation"></i><?= translate('error', $i18n) ?></li>
</ul>
<?php
}
}
if ($resetMode) {
if (!$hideForm) {
?>
<div class="form-group">
<input type="hidden" name="token" value="<?= $token ?>">
@@ -182,30 +186,31 @@ if (isset($_POST['password']) && $_POST['password'] != "" && isset($_POST['confi
<input type="submit" value="<?= translate('reset_password', $i18n) ?>">
</div>
<?php
}
if ($hasErrorMessage) {
if ($passwordsMismatch) {
?>
<ul class="error-box">
<li><i class="fa-solid fa-triangle-exclamation"></i><?= translate('passwords_dont_match', $i18n) ?></li>
</ul>
<?php
} else {
?>
<ul class="error-box">
<li><i class="fa-solid fa-triangle-exclamation"></i><?= translate('error', $i18n) ?></li>
</ul>
<?php
}
}
if ($hasSuccessMessage) {
}
if ($hasErrorMessage) {
if ($passwordsMismatch) {
?>
<ul class="success-box">
<li><i class="fa-solid fa-check"></i><?= translate('password_reset_successful', $i18n) ?></li>
<ul class="error-box">
<li><i class="fa-solid fa-triangle-exclamation"></i><?= translate('passwords_dont_match', $i18n) ?>
</li>
</ul>
<?php
} else {
?>
<ul class="error-box">
<li><i class="fa-solid fa-triangle-exclamation"></i><?= translate('error', $i18n) ?></li>
</ul>
<?php
}
}
if ($hasSuccessMessage) {
?>
<ul class="success-box">
<li><i class="fa-solid fa-check"></i><?= translate('password_reset_successful', $i18n) ?></li>
</ul>
<?php
}
}
?>
<div class="login-form-link">
<a href="login.php"><?= translate('login', $i18n) ?></a>
@@ -219,6 +224,7 @@ if (isset($_POST['password']) && $_POST['password'] != "" && isset($_POST['confi
}
</script>
</body>
</html>
?>

View File

@@ -8,7 +8,8 @@ require_once 'includes/i18n/' . $lang . '.php';
require_once 'includes/version.php';
function validate($value) {
function validate($value)
{
$value = trim($value);
$value = stripslashes($value);
$value = htmlspecialchars($value);
@@ -43,8 +44,11 @@ if ($userCount > 0) {
$theme = "light";
$updateThemeSettings = false;
if (isset($_COOKIE['theme'])) {
$theme = $_COOKIE['theme'];
} else {
$updateThemeSettings = true;
}
$colorTheme = "blue";
@@ -282,150 +286,163 @@ if (isset($_POST['username'])) {
$requireValidation = true;
}
}
$db->close();
header("Location: login.php?registered=true&requireValidation=$requireValidation");
exit();
} else {
$registrationFailed = true;
$registrationFailed = true;
}
}
}
}
?>
<!DOCTYPE html>
<html dir="<?= $languages[$lang]['dir'] ?>">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
<meta name="theme-color" content="<?= $theme == "light" ? "#FFFFFF" : "#222222" ?>"/>
<title>Wallos - Subscription Tracker</title>
<link rel="icon" type="image/png" href="images/icon/favicon.ico" sizes="16x16">
<link rel="apple-touch-icon" sizes="180x180" href="images/icon/apple-touch-icon.png">
<link rel="manifest" href="manifest.json">
<link rel="stylesheet" href="styles/theme.css?<?= $version ?>">
<link rel="stylesheet" href="styles/login.css?<?= $version ?>">
<link rel="stylesheet" href="styles/themes/red.css?<?= $version ?>" id="red-theme" <?= $colorTheme != "red" ? "disabled" : "" ?>>
<link rel="stylesheet" href="styles/themes/green.css?<?= $version ?>" id="green-theme" <?= $colorTheme != "green" ? "disabled" : "" ?>>
<link rel="stylesheet" href="styles/themes/yellow.css?<?= $version ?>" id="yellow-theme" <?= $colorTheme != "yellow" ? "disabled" : "" ?>>
<link rel="stylesheet" href="styles/login-dark-theme.css?<?= $version ?>" id="dark-theme" <?= $theme == "light" ? "disabled" : "" ?>>
<link rel="stylesheet" href="styles/font-awesome.min.css">
<link rel="stylesheet" href="styles/barlow.css">
<script type="text/javascript" src="scripts/registration.js?<?= $version ?>"></script>
</head>
<body class="<?= $languages[$lang]['dir'] ?>">
<div class="content">
<section class="container">
<header>
<?php
if ($theme == "light") {
?> <img src="images/siteicons/<?= $colorTheme ?>/wallos.png" alt="Wallos Logo" title="Wallos - Subscription Tracker" width="215" /> <?php
} else {
?> <img src="images/siteicons/<?= $colorTheme ?>/walloswhite.png" alt="Wallos Logo" title="Wallos - Subscription Tracker" width="215" /> <?php
}
?>
<p>
<?= translate('create_account', $i18n) ?>
</p>
</header>
<form action="registration.php" method="post">
<div class="form-group">
<label for="username"><?= translate('username', $i18n) ?>:</label>
<input type="text" id="username" name="username" required>
</div>
<div class="form-group">
<label for="email"><?= translate('email', $i18n) ?>:</label>
<input type="email" id="email" name="email" required>
</div>
<div class="form-group">
<label for="password"><?= translate('password', $i18n) ?>:</label>
<input type="password" id="password" name="password" required>
</div>
<div class="form-group">
<label for="confirm_password"><?= translate('confirm_password', $i18n) ?>:</label>
<input type="password" id="confirm_password" name="confirm_password" required>
</div>
<div class="form-group">
<label for="currency"><?= translate('main_currency', $i18n) ?>:</label>
<select id="currency" name="main_currency" placeholder="Currency">
<?php
foreach ($currencies as $currency) {
?>
<option value="<?= $currency['code'] ?>"><?= $currency['name'] ?></option>
<?php
}
?>
</select>
</div>
<div class="form-group">
<label for="language"><?= translate('language', $i18n) ?>:</label>
<select id="language" name="language" placeholder="Language" onchange="changeLanguage(this.value)">
<?php
foreach ($languages as $code => $language) {
$selected = ($code === $lang) ? 'selected' : '';
?>
<option value="<?= $code ?>" <?= $selected ?>><?= $language['name'] ?></option>
<?php
}
?>
</select>
</div>
<?php
if ($hasErrors) {
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
<meta name="theme-color" content="<?= $theme == "light" ? "#FFFFFF" : "#222222" ?>" id="theme-color" />
<title>Wallos - Subscription Tracker</title>
<link rel="icon" type="image/png" href="images/icon/favicon.ico" sizes="16x16">
<link rel="apple-touch-icon" sizes="180x180" href="images/icon/apple-touch-icon.png">
<link rel="manifest" href="manifest.json">
<link rel="stylesheet" href="styles/theme.css?<?= $version ?>">
<link rel="stylesheet" href="styles/login.css?<?= $version ?>">
<link rel="stylesheet" href="styles/themes/red.css?<?= $version ?>" id="red-theme" <?= $colorTheme != "red" ? "disabled" : "" ?>>
<link rel="stylesheet" href="styles/themes/green.css?<?= $version ?>" id="green-theme" <?= $colorTheme != "green" ? "disabled" : "" ?>>
<link rel="stylesheet" href="styles/themes/yellow.css?<?= $version ?>" id="yellow-theme" <?= $colorTheme != "yellow" ? "disabled" : "" ?>>
<link rel="stylesheet" href="styles/login-dark-theme.css?<?= $version ?>" id="dark-theme" <?= $theme == "light" ? "disabled" : "" ?>>
<link rel="stylesheet" href="styles/font-awesome.min.css">
<link rel="stylesheet" href="styles/barlow.css">
<script type="text/javascript">
window.update_theme_settings = "<?= $updateThemeSettings ?>";
window.colorTheme = "<?= $colorTheme ?>";
</script>
<script type="text/javascript" src="scripts/registration.js?<?= $version ?>"></script>
</head>
<body class="<?= $languages[$lang]['dir'] ?>">
<div class="content">
<section class="container">
<header>
<?php
if ($theme == "light") {
?> <img src="images/siteicons/<?= $colorTheme ?>/wallos.png" alt="Wallos Logo"
title="Wallos - Subscription Tracker" width="215" id="wallos-logo" /> <?php
} else {
?> <img src="images/siteicons/<?= $colorTheme ?>/walloswhite.png" alt="Wallos Logo"
title="Wallos - Subscription Tracker" width="215" id="wallos-logo" /> <?php
}
?>
<p>
<?= translate('create_account', $i18n) ?>
</p>
</header>
<form action="registration.php" method="post">
<div class="form-group">
<label for="username"><?= translate('username', $i18n) ?>:</label>
<input type="text" id="username" name="username" required>
</div>
<div class="form-group">
<label for="email"><?= translate('email', $i18n) ?>:</label>
<input type="email" id="email" name="email" required>
</div>
<div class="form-group">
<label for="password"><?= translate('password', $i18n) ?>:</label>
<input type="password" id="password" name="password" required>
</div>
<div class="form-group">
<label for="confirm_password"><?= translate('confirm_password', $i18n) ?>:</label>
<input type="password" id="confirm_password" name="confirm_password" required>
</div>
<div class="form-group">
<label for="currency"><?= translate('main_currency', $i18n) ?>:</label>
<select id="currency" name="main_currency" placeholder="Currency">
<?php
foreach ($currencies as $currency) {
?>
<ul class="error-box">
<?php
if ($passwordMismatch) {
?>
<li><i class="fa-solid fa-triangle-exclamation"></i><?= translate('passwords_dont_match', $i18n) ?></li>
<?php
}
<option value="<?= $currency['code'] ?>"><?= $currency['name'] ?></option>
<?php
}
?>
</select>
</div>
<div class="form-group">
<label for="language"><?= translate('language', $i18n) ?>:</label>
<select id="language" name="language" placeholder="Language" onchange="changeLanguage(this.value)">
<?php
foreach ($languages as $code => $language) {
$selected = ($code === $lang) ? 'selected' : '';
?>
<?php
if ($usernameExists) {
?>
<li><i class="fa-solid fa-triangle-exclamation"></i><?= translate('username_exists', $i18n) ?></li>
<?php
}
?>
<?php
if ($emailExists) {
?>
<li><i class="fa-solid fa-triangle-exclamation"></i><?= translate('email_exists', $i18n) ?></li>
<?php
}
?>
<?php
if ($registrationFailed) {
?>
<li><i class="fa-solid fa-triangle-exclamation"></i><?= translate('registration_failed', $i18n) ?></li>
<?php
}
?>
</ul>
<option value="<?= $code ?>" <?= $selected ?>><?= $language['name'] ?></option>
<?php
}
?>
<div class="form-group">
<input type="submit" value="<?= translate('register', $i18n) ?>">
</div>
</form>
<?php
if ($userCount == 0) {
?>
<div class="separator">
<input type="button" class="secondary-button" value="<?= translate('restore_database', $i18n) ?>" id="restoreDB" onClick="openRestoreDBFileSelect()" />
<input type="file" name="restoreDBFile" id="restoreDBFile" style="display: none;" onChange="restoreDB()" accept=".zip">
</div>
</select>
</div>
<?php
if ($hasErrors) {
?>
<ul class="error-box">
<?php
}
?>
</section>
</div>
<?php
require_once 'includes/footer.php';
?>
</body>
if ($passwordMismatch) {
?>
<li><i class="fa-solid fa-triangle-exclamation"></i><?= translate('passwords_dont_match', $i18n) ?>
</li>
<?php
}
?>
<?php
if ($usernameExists) {
?>
<li><i class="fa-solid fa-triangle-exclamation"></i><?= translate('username_exists', $i18n) ?></li>
<?php
}
?>
<?php
if ($emailExists) {
?>
<li><i class="fa-solid fa-triangle-exclamation"></i><?= translate('email_exists', $i18n) ?></li>
<?php
}
?>
<?php
if ($registrationFailed) {
?>
<li><i class="fa-solid fa-triangle-exclamation"></i><?= translate('registration_failed', $i18n) ?>
</li>
<?php
}
?>
</ul>
<?php
}
?>
<div class="form-group">
<input type="submit" value="<?= translate('register', $i18n) ?>">
</div>
</form>
<?php
if ($userCount == 0) {
?>
<div class="separator">
<input type="button" class="secondary-button" value="<?= translate('restore_database', $i18n) ?>"
id="restoreDB" onClick="openRestoreDBFileSelect()" />
<input type="file" name="restoreDBFile" id="restoreDBFile" style="display: none;" onChange="restoreDB()"
accept=".zip">
</div>
<?php
}
?>
</section>
</div>
<?php
require_once 'includes/footer.php';
?>
</body>
</html>

View File

@@ -1,86 +1,97 @@
let isDropdownOpen = false;
function toggleDropdown() {
const dropdown = document.querySelector('.dropdown');
dropdown.classList.toggle('is-open');
isDropdownOpen = !isDropdownOpen;
const dropdown = document.querySelector('.dropdown');
dropdown.classList.toggle('is-open');
isDropdownOpen = !isDropdownOpen;
}
function showErrorMessage(message) {
const toast = document.querySelector(".toast#errorToast");
(closeIcon = document.querySelector(".close-error")),
const toast = document.querySelector(".toast#errorToast");
(closeIcon = document.querySelector(".close-error")),
(errorMessage = document.querySelector(".errorMessage")),
(progress = document.querySelector(".progress.error"));
let timer1, timer2;
errorMessage.textContent = message;
toast.classList.add("active");
progress.classList.add("active");
timer1 = setTimeout(() => {
toast.classList.remove("active");
closeIcon.removeEventListener("click", () => {});
}, 5000);
timer2 = setTimeout(() => {
let timer1, timer2;
errorMessage.textContent = message;
toast.classList.add("active");
progress.classList.add("active");
timer1 = setTimeout(() => {
toast.classList.remove("active");
closeIcon.removeEventListener("click", () => { });
}, 5000);
timer2 = setTimeout(() => {
progress.classList.remove("active");
}, 5300);
closeIcon.addEventListener("click", () => {
toast.classList.remove("active");
setTimeout(() => {
progress.classList.remove("active");
}, 5300);
closeIcon.addEventListener("click", () => {
toast.classList.remove("active");
setTimeout(() => {
progress.classList.remove("active");
}, 300);
clearTimeout(timer1);
clearTimeout(timer2);
closeIcon.removeEventListener("click", () => {});
});
}, 300);
clearTimeout(timer1);
clearTimeout(timer2);
closeIcon.removeEventListener("click", () => { });
});
}
function showSuccessMessage(message) {
const toast = document.querySelector(".toast#successToast");
(closeIcon = document.querySelector(".close-success")),
const toast = document.querySelector(".toast#successToast");
(closeIcon = document.querySelector(".close-success")),
(successMessage = document.querySelector(".successMessage")),
(progress = document.querySelector(".progress.success"));
let timer1, timer2;
successMessage.textContent = message;
toast.classList.add("active");
progress.classList.add("active");
timer1 = setTimeout(() => {
toast.classList.remove("active");
closeIcon.removeEventListener("click", () => {});
}, 5000);
timer2 = setTimeout(() => {
let timer1, timer2;
successMessage.textContent = message;
toast.classList.add("active");
progress.classList.add("active");
timer1 = setTimeout(() => {
toast.classList.remove("active");
closeIcon.removeEventListener("click", () => { });
}, 5000);
timer2 = setTimeout(() => {
progress.classList.remove("active");
}, 5300);
closeIcon.addEventListener("click", () => {
toast.classList.remove("active");
setTimeout(() => {
progress.classList.remove("active");
}, 5300);
closeIcon.addEventListener("click", () => {
toast.classList.remove("active");
setTimeout(() => {
progress.classList.remove("active");
}, 300);
clearTimeout(timer1);
clearTimeout(timer2);
closeIcon.removeEventListener("click", () => {});
});
}, 300);
clearTimeout(timer1);
clearTimeout(timer2);
closeIcon.removeEventListener("click", () => { });
});
}
document.addEventListener('DOMContentLoaded', function() {
document.addEventListener('DOMContentLoaded', function () {
document.addEventListener('mousedown', function(event) {
var dropdown = document.querySelector('.dropdown');
var dropdownContent = document.querySelector('.dropdown-content');
if (window.update_theme_settings) {
const prefersDarkMode = window.matchMedia('(prefers-color-scheme: dark)').matches;
const themePreference = prefersDarkMode ? 'dark' : 'light';
const darkThemeCss = document.querySelector("#dark-theme");
darkThemeCss.disabled = themePreference === 'light';
document.body.className = themePreference;
document.cookie = `inUseTheme=${themePreference}; expires=Fri, 31 Dec 9999 23:59:59 GMT`;
const themeColorMetaTag = document.querySelector('meta[name="theme-color"]');
themeColorMetaTag.setAttribute('content', themePreference === 'dark' ? '#222222' : '#FFFFFF');
}
if (!dropdown.contains(event.target) && isDropdownOpen) {
dropdown.classList.remove('is-open');
isDropdownOpen = false;
}
});
document.addEventListener('mousedown', function (event) {
var dropdown = document.querySelector('.dropdown');
var dropdownContent = document.querySelector('.dropdown-content');
document.querySelector('.dropdown-content').addEventListener('focus', function() {
isDropdownOpen = true;
});
if (!dropdown.contains(event.target) && isDropdownOpen) {
dropdown.classList.remove('is-open');
isDropdownOpen = false;
}
});
document.querySelector('.dropdown-content').addEventListener('focus', function () {
isDropdownOpen = true;
});
});

18
scripts/login.js Normal file
View File

@@ -0,0 +1,18 @@
document.addEventListener('DOMContentLoaded', function () {
if (window.update_theme_settings) {
const prefersDarkMode = window.matchMedia('(prefers-color-scheme: dark)').matches;
const themePreference = prefersDarkMode ? 'dark' : 'light';
const darkThemeCss = document.querySelector("#dark-theme");
darkThemeCss.disabled = themePreference === 'light';
document.body.className = themePreference;
const themeColorMetaTag = document.querySelector('meta[name="theme-color"]');
themeColorMetaTag.setAttribute('content', themePreference === 'dark' ? '#222222' : '#FFFFFF');
const logoImage = document.querySelector('#wallos-logo');
const imageName = themePreference === 'dark' ? 'walloswhite' : 'wallos';
const colorTheme = window.color_theme ?? 'blue';
logoImage.src = `images/siteicons/${colorTheme}/${imageName}.png`;
}
});

View File

@@ -157,8 +157,25 @@ function restoreDB() {
.catch(error => showErrorMessage('Error:', error));
}
function checkThemeNeedsUpdate() {
if (window.update_theme_settings) {
const prefersDarkMode = window.matchMedia('(prefers-color-scheme: dark)').matches;
const themePreference = prefersDarkMode ? 'dark' : 'light';
const darkThemeCss = document.querySelector("#dark-theme");
darkThemeCss.disabled = themePreference === 'light';
document.body.className = themePreference;
const themeColorMetaTag = document.querySelector('meta[name="theme-color"]');
themeColorMetaTag.setAttribute('content', themePreference === 'dark' ? '#222222' : '#FFFFFF');
const logoImage = document.querySelector('#wallos-logo');
const imageName = themePreference === 'dark' ? 'walloswhite' : 'wallos';
const colorTheme = window.color_theme ?? 'blue';
logoImage.src = `images/siteicons/${colorTheme}/${imageName}.png`;
}
}
window.onload = function () {
restoreFormFields();
removeFromStorage();
runDatabaseMigration();
checkThemeNeedsUpdate();
};

View File

@@ -903,6 +903,65 @@ function switchTheme() {
});
}
function setDarkTheme(theme) {
const darkThemeRadio = document.querySelector("#theme-dark");
const lightThemeRadio = document.querySelector("#theme-light");
const automaticThemeRadio = document.querySelector("#theme-automatic");
const darkThemeCss = document.querySelector("#dark-theme");
const themes = {0: 'light', 1: 'dark', 2: 'automatic'};
const themeValue = themes[theme];
const prefersDarkMode = window.matchMedia('(prefers-color-scheme: dark)').matches;
darkThemeRadio.disabled = true;
lightThemeRadio.disabled = true;
automaticThemeRadio.disabled = true;
fetch('endpoints/settings/theme.php', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({theme: theme})
})
.then(response => response.json())
.then(data => {
if (data.success) {
darkThemeRadio.disabled = false;
lightThemeRadio.disabled = false;
automaticThemeRadio.disabled = false;
document.cookie = `theme=${themeValue}; expires=Fri, 31 Dec 9999 23:59:59 GMT`;
if (theme == 0) {
darkThemeCss.disabled = true;
document.body.className = 'light';
}
if (theme == 1) {
darkThemeCss.disabled = false;
document.body.className = 'dark';
}
if (theme == 2) {
darkThemeCss.disabled = !prefersDarkMode;
document.body.className = prefersDarkMode ? 'dark' : 'light';
document.cookie = `inUseTheme=${prefersDarkMode ? 'dark' : 'light'}; expires=Fri, 31 Dec 9999 23:59:59 GMT`;
}
showSuccessMessage(data.message);
} else {
showErrorMessage(data.errorMessage);
darkThemeRadio.disabled = false;
lightThemeRadio.disabled = false;
automaticThemeRadio.disabled = false;
}
}).catch(error => {
darkThemeRadio.disabled = false;
lightThemeRadio.disabled = false;
automaticThemeRadio.disabled = false;
});
}
function storeSettingsOnDB(endpoint, value) {
fetch('endpoints/settings/' + endpoint + '.php', {
method: 'POST',

View File

@@ -31,6 +31,7 @@ self.addEventListener('install', function(event) {
'scripts/settings.js',
'scripts/notifications.js',
'scripts/registration.js',
'scripts/login.js',
'scripts/admin.js',
'scripts/calendar.js',
'scripts/i18n/en.js',

View File

File diff suppressed because it is too large Load Diff

538
stats.php
View File

@@ -1,43 +1,41 @@
<?php
require_once 'includes/header.php';
require_once 'includes/header.php';
function getPricePerMonth($cycle, $frequency, $price) {
switch ($cycle) {
function getPricePerMonth($cycle, $frequency, $price)
{
switch ($cycle) {
case 1:
$numberOfPaymentsPerMonth = (30 / $frequency);
return $price * $numberOfPaymentsPerMonth;
break;
$numberOfPaymentsPerMonth = (30 / $frequency);
return $price * $numberOfPaymentsPerMonth;
case 2:
$numberOfPaymentsPerMonth = (4.35 / $frequency);
return $price * $numberOfPaymentsPerMonth;
break;
$numberOfPaymentsPerMonth = (4.35 / $frequency);
return $price * $numberOfPaymentsPerMonth;
case 3:
$numberOfPaymentsPerMonth = (1 / $frequency);
return $price * $numberOfPaymentsPerMonth;
break;
$numberOfPaymentsPerMonth = (1 / $frequency);
return $price * $numberOfPaymentsPerMonth;
case 4:
$numberOfMonths = (12 * $frequency);
return $price / $numberOfMonths;
break;
}
}
}
function getPriceConverted($price, $currency, $database, $userId) {
$query = "SELECT rate FROM currencies WHERE id = :currency AND user_id = :userId";
$stmt = $database->prepare($query);
$stmt->bindParam(':currency', $currency, SQLITE3_INTEGER);
$stmt->bindParam(':userId', $userId, SQLITE3_INTEGER);
$result = $stmt->execute();
$exchangeRate = $result->fetchArray(SQLITE3_ASSOC);
if ($exchangeRate === false) {
return $price;
} else {
$fromRate = $exchangeRate['rate'];
return $price / $fromRate;
}
function getPriceConverted($price, $currency, $database, $userId)
{
$query = "SELECT rate FROM currencies WHERE id = :currency AND user_id = :userId";
$stmt = $database->prepare($query);
$stmt->bindParam(':currency', $currency, SQLITE3_INTEGER);
$stmt->bindParam(':userId', $userId, SQLITE3_INTEGER);
$result = $stmt->execute();
$exchangeRate = $result->fetchArray(SQLITE3_ASSOC);
if ($exchangeRate === false) {
return $price;
} else {
$fromRate = $exchangeRate['rate'];
return $price / $fromRate;
}
}
//Get household members
$members = array();
@@ -46,10 +44,10 @@ $stmt = $db->prepare($query);
$stmt->bindValue(':userId', $userId, SQLITE3_INTEGER);
$result = $stmt->execute();
while ($row = $result->fetchArray(SQLITE3_ASSOC)) {
$memberId = $row['id'];
$members[$memberId] = $row;
$memberCost[$memberId]['cost'] = 0;
$memberCost[$memberId]['name'] = $row['name'];
$memberId = $row['id'];
$members[$memberId] = $row;
$memberCost[$memberId]['cost'] = 0;
$memberCost[$memberId]['name'] = $row['name'];
}
// Get categories
@@ -59,10 +57,10 @@ $stmt = $db->prepare($query);
$stmt->bindValue(':userId', $userId, SQLITE3_INTEGER);
$result = $stmt->execute();
while ($row = $result->fetchArray(SQLITE3_ASSOC)) {
$categoryId = $row['id'];
$categories[$categoryId] = $row;
$categoryCost[$categoryId]['cost'] = 0;
$categoryCost[$categoryId]['name'] = $row['name'];
$categoryId = $row['id'];
$categories[$categoryId] = $row;
$categoryCost[$categoryId]['cost'] = 0;
$categoryCost[$categoryId]['name'] = $row['name'];
}
// Get payment methods
@@ -72,10 +70,10 @@ $stmt = $db->prepare($query);
$stmt->bindValue(':userId', $userId, SQLITE3_INTEGER);
$result = $stmt->execute();
while ($row = $result->fetchArray(SQLITE3_ASSOC)) {
$paymentMethodId = $row['id'];
$paymentMethodCount[$paymentMethodId] = $row;
$paymentMethodCount[$paymentMethodId]['count'] = 0;
$paymentMethodCount[$paymentMethodId]['name'] = $row['name'];
$paymentMethodId = $row['id'];
$paymentMethodCount[$paymentMethodId] = $row;
$paymentMethodCount[$paymentMethodId]['count'] = 0;
$paymentMethodCount[$paymentMethodId]['name'] = $row['name'];
}
// Get code of main currency to display on statistics
@@ -104,35 +102,35 @@ $conditions = [];
$params = [];
if (isset($_GET['member'])) {
$conditions[] = "payer_user_id = :member";
$params[':member'] = $_GET['member'];
$statsSubtitleParts[] = $members[$_GET['member']]['name'];
$conditions[] = "payer_user_id = :member";
$params[':member'] = $_GET['member'];
$statsSubtitleParts[] = $members[$_GET['member']]['name'];
}
if (isset($_GET['category'])) {
$conditions[] = "category_id = :category";
$params[':category'] = $_GET['category'];
$statsSubtitleParts[] = $categories[$_GET['category']]['name'] == "No category" ? translate("no_category", $i18n) : $categories[$_GET['category']]['name'];
$conditions[] = "category_id = :category";
$params[':category'] = $_GET['category'];
$statsSubtitleParts[] = $categories[$_GET['category']]['name'] == "No category" ? translate("no_category", $i18n) : $categories[$_GET['category']]['name'];
}
if (isset($_GET['payment'])) {
$conditions[] = "payment_method_id = :payment";
$params[':payment'] = $_GET['payment'];
$statsSubtitleParts[] = $paymentMethodCount[$_GET['payment']]['name'];
$conditions[] = "payment_method_id = :payment";
$params[':payment'] = $_GET['payment'];
$statsSubtitleParts[] = $paymentMethodCount[$_GET['payment']]['name'];
}
$conditions[] = "user_id = :userId";
$params[':userId'] = $userId;
if (!empty($conditions)) {
$query .= " WHERE " . implode(' AND ', $conditions);
$query .= " WHERE " . implode(' AND ', $conditions);
}
$stmt = $db->prepare($query);
$statsSubtitle = !empty($statsSubtitleParts) ? '(' . implode(', ', $statsSubtitleParts) . ')' : "";
foreach ($params as $key => $value) {
$stmt->bindValue($key, $value, SQLITE3_INTEGER);
$stmt->bindValue($key, $value, SQLITE3_INTEGER);
}
$result = $stmt->execute();
@@ -172,20 +170,20 @@ if ($result) {
$nextPaymentDate = DateTime::createFromFormat('Y-m-d', trim($next_payment));
$tomorrow = new DateTime('tomorrow');
$endOfMonth = new DateTime('last day of this month');
if ($nextPaymentDate >= $tomorrow && $nextPaymentDate <= $endOfMonth) {
$timesToPay = 1;
$daysInMonth = $endOfMonth->diff($tomorrow)->days + 1;
$daysRemaining = $endOfMonth->diff($nextPaymentDate)->days + 1;
if ($cycle == 1) {
$timesToPay = $daysRemaining / $frequency;
}
if ($cycle == 2) {
$weeksInMonth = ceil($daysInMonth / 7);
$weeksRemaining = ceil($daysRemaining / 7);
$timesToPay = $weeksRemaining / $frequency;
}
$amountDueThisMonth += $originalSubscriptionPrice * $timesToPay;
$timesToPay = 1;
$daysInMonth = $endOfMonth->diff($tomorrow)->days + 1;
$daysRemaining = $endOfMonth->diff($nextPaymentDate)->days + 1;
if ($cycle == 1) {
$timesToPay = $daysRemaining / $frequency;
}
if ($cycle == 2) {
$weeksInMonth = ceil($daysInMonth / 7);
$weeksRemaining = ceil($daysRemaining / 7);
$timesToPay = $weeksRemaining / $frequency;
}
$amountDueThisMonth += $originalSubscriptionPrice * $timesToPay;
}
} else {
$inactiveSubscriptions++;
@@ -193,10 +191,10 @@ if ($result) {
}
}
// Calculate yearly price
$totalCostPerYear = $totalCostPerMonth * 12;
// Calculate average subscription monthly cost
if ($activeSubscriptions > 0) {
$averageSubscriptionCost = $totalCostPerMonth / $activeSubscriptions;
@@ -209,7 +207,7 @@ if ($result) {
$averageSubscriptionCost = 0;
}
}
if (isset($userData['budget']) && $userData['budget'] > 0) {
$budget = $userData['budget'];
$budgetLeft = $budget - $totalCostPerMonth;
@@ -219,7 +217,7 @@ if (isset($userData['budget']) && $userData['budget'] > 0) {
if ($totalCostPerMonth > $budget) {
$overBudgetAmount = $totalCostPerMonth - $budget;
}
}
}
$numberOfElements = 6;
?>
@@ -235,89 +233,92 @@ $numberOfElements = 6;
</button>
<div class="filtermenu-content">
<?php
if (count($members) > 1) {
?>
if (count($members) > 1) {
?>
<div class="filtermenu-submenu">
<div class="filter-title" onClick="toggleSubMenu('member')"><?= translate("member", $i18n) ?></div>
<div class="filtermenu-submenu-content" id="filter-member">
<?php
foreach ($members as $member) {
$selectedClass = '';
if (isset($_GET['member']) && $_GET['member'] == $member['id']) {
$selectedClass = 'selected';
}
?>
<div class="filter-item <?= $selectedClass ?>" data-memberid="<?= $member['id'] ?>"><?= $member['name'] ?></div>
<?php
foreach ($members as $member) {
$selectedClass = '';
if (isset($_GET['member']) && $_GET['member'] == $member['id']) {
$selectedClass = 'selected';
}
?>
<div class="filter-item <?= $selectedClass ?>" data-memberid="<?= $member['id'] ?>"><?= $member['name'] ?>
</div>
<?php
}
?>
</div>
</div>
<?php
}
<?php
}
?>
<?php
if (count($categories) > 1) {
?>
if (count($categories) > 1) {
?>
<div class="filtermenu-submenu">
<div class="filter-title" onClick="toggleSubMenu('category')"><?= translate("category", $i18n) ?></div>
<div class="filtermenu-submenu-content" id="filter-category">
<?php
foreach ($categories as $category) {
if ($category['name'] == "No category") {
$category['name'] = translate("no_category", $i18n);
}
$selectedClass = '';
if (isset($_GET['category']) && $_GET['category'] == $category['id']) {
$selectedClass = 'selected';
}
?>
<div class="filter-item <?= $selectedClass ?>" data-categoryid="<?= $category['id'] ?>"><?= $category['name'] ?></div>
<?php
foreach ($categories as $category) {
if ($category['name'] == "No category") {
$category['name'] = translate("no_category", $i18n);
}
$selectedClass = '';
if (isset($_GET['category']) && $_GET['category'] == $category['id']) {
$selectedClass = 'selected';
}
?>
<div class="filter-item <?= $selectedClass ?>" data-categoryid="<?= $category['id'] ?>">
<?= $category['name'] ?></div>
<?php
}
?>
</div>
</div>
<?php
}
<?php
}
?>
<?php
if (count($paymentMethodCount) > 1) {
?>
if (count($paymentMethodCount) > 1) {
?>
<div class="filtermenu-submenu">
<div class="filter-title" onClick="toggleSubMenu('payment')"><?= translate("payment_method", $i18n) ?></div>
<div class="filtermenu-submenu-content" id="filter-payment">
<?php
foreach ($paymentMethodCount as $payment) {
$selectedClass = '';
if (isset($_GET['payment']) && $_GET['payment'] == $payment['id']) {
$selectedClass = 'selected';
}
?>
<div class="filter-item <?= $selectedClass ?>" data-paymentid="<?= $payment['id'] ?>"><?= $payment['name'] ?></div>
<?php
foreach ($paymentMethodCount as $payment) {
$selectedClass = '';
if (isset($_GET['payment']) && $_GET['payment'] == $payment['id']) {
$selectedClass = 'selected';
}
?>
<div class="filter-item <?= $selectedClass ?>" data-paymentid="<?= $payment['id'] ?>">
<?= $payment['name'] ?></div>
<?php
}
?>
</div>
</div>
<?php
}
<?php
}
?>
<?php
if (isset($_GET['member']) || isset($_GET['category']) || isset($_GET['payment'])) {
?>
<div class="filtermenu-submenu">
<div class="filter-title filter-clear" onClick="clearFilters()">
<i class="fa-solid fa-times-circle"></i> <?= translate("clear", $i18n) ?>
</div>
</div>
<?php
}
if (isset($_GET['member']) || isset($_GET['category']) || isset($_GET['payment'])) {
?>
<div class="filtermenu-submenu">
<div class="filter-title filter-clear" onClick="clearFilters()">
<i class="fa-solid fa-times-circle"></i> <?= translate("clear", $i18n) ?>
</div>
</div>
<?php
}
?>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="statistics">
<div class="statistic">
@@ -340,17 +341,18 @@ $numberOfElements = 6;
<span><?= CurrencyFormatter::format($mostExpensiveSubscription['price'], $code) ?></span>
<div class="title"><?= translate('most_expensive', $i18n) ?></div>
<?php
if (isset($mostExpensiveSubscription['logo']) && $mostExpensiveSubscription['logo'] != '') {
?>
<div class="subtitle">
<img src="images/uploads/logos/<?= $mostExpensiveSubscription['logo'] ?>" alt="<?= $mostExpensiveSubscription['name'] ?>" title="<?= $mostExpensiveSubscription['name'] ?>" />
</div>
<?php
} else if (isset($mostExpensiveSubscription['name']) && $mostExpensiveSubscription['name'] != ''){
?>
<div class="subtitle"><?= $mostExpensiveSubscription['name'] ?></div>
<?php
}
if (isset($mostExpensiveSubscription['logo']) && $mostExpensiveSubscription['logo'] != '') {
?>
<div class="subtitle">
<img src="images/uploads/logos/<?= $mostExpensiveSubscription['logo'] ?>"
alt="<?= $mostExpensiveSubscription['name'] ?>" title="<?= $mostExpensiveSubscription['name'] ?>" />
</div>
<?php
} else if (isset($mostExpensiveSubscription['name']) && $mostExpensiveSubscription['name'] != '') {
?>
<div class="subtitle"><?= $mostExpensiveSubscription['name'] ?></div>
<?php
}
?>
</div>
<div class="statistic">
@@ -358,161 +360,161 @@ $numberOfElements = 6;
<div class="title"><?= translate('amount_due', $i18n) ?></div>
</div>
<?php
if (isset($budgetUsed)) {
$numberOfElements += 1;
?>
<div class="statistic">
<span><?= number_format($budgetUsed, 2) ?>%</span>
<div class="title"><?= translate('percentage_budget_used', $i18n) ?></div>
</div>
<?php
}
if (isset($budgetLeft)) {
$numberOfElements += 1;
?>
<div class="statistic">
<span><?= CurrencyFormatter::format($budgetLeft, $code) ?></span>
<div class="title"><?= translate('budget_remaining', $i18n) ?></div>
</div>
<?php
}
if (isset($overBudgetAmount)) {
$numberOfElements += 1;
?>
<div class="statistic">
<span><?= CurrencyFormatter::format($overBudgetAmount, $code) ?></span>
<div class="title"><?= translate('amount_over_budget', $i18n) ?></div>
</div>
<?php
}
if ($inactiveSubscriptions > 0) {
$numberOfElements += 3;
?>
<div class="statistic">
<span><?= $inactiveSubscriptions ?></span>
<div class="title"><?= translate('inactive_subscriptions', $i18n) ?></div>
</div>
<div class="statistic">
<span><?= CurrencyFormatter::format($totalSavingsPerMonth, $code) ?></span>
<div class="title"><?= translate('monthly_savings', $i18n) ?></div>
</div>
<div class="statistic">
<span><?= CurrencyFormatter::format($totalSavingsPerMonth * 12, $code) ?></span>
<div class="title"><?= translate('yearly_savings', $i18n) ?></div>
</div>
<?php
}
if (isset($budgetUsed)) {
$numberOfElements += 1;
?>
<div class="statistic">
<span><?= number_format($budgetUsed, 2) ?>%</span>
<div class="title"><?= translate('percentage_budget_used', $i18n) ?></div>
</div>
<?php
}
if (isset($budgetLeft)) {
$numberOfElements += 1;
?>
<div class="statistic">
<span><?= CurrencyFormatter::format($budgetLeft, $code) ?></span>
<div class="title"><?= translate('budget_remaining', $i18n) ?></div>
</div>
<?php
}
if (isset($overBudgetAmount)) {
$numberOfElements += 1;
?>
<div class="statistic">
<span><?= CurrencyFormatter::format($overBudgetAmount, $code) ?></span>
<div class="title"><?= translate('amount_over_budget', $i18n) ?></div>
</div>
<?php
}
if ($inactiveSubscriptions > 0) {
$numberOfElements += 3;
?>
<div class="statistic">
<span><?= $inactiveSubscriptions ?></span>
<div class="title"><?= translate('inactive_subscriptions', $i18n) ?></div>
</div>
<div class="statistic">
<span><?= CurrencyFormatter::format($totalSavingsPerMonth, $code) ?></span>
<div class="title"><?= translate('monthly_savings', $i18n) ?></div>
</div>
<div class="statistic">
<span><?= CurrencyFormatter::format($totalSavingsPerMonth * 12, $code) ?></span>
<div class="title"><?= translate('yearly_savings', $i18n) ?></div>
</div>
<?php
}
if (($numberOfElements + 1) % 3 == 0) {
?>
<div class="statistic empty"></div>
<?php
}
?>
if (($numberOfElements + 1) % 3 == 0) {
?>
<div class="statistic empty"></div>
<?php
}
?>
</div>
<?php
$categoryDataPoints = [];
if (isset($categoryCost)) {
foreach ($categoryCost as $category) {
if ($category['cost'] != 0) {
$categoryDataPoints[] = [
"label" => $category['name'],
"y" => $category["cost"],
];
}
}
}
$showCategoryCostGraph = count($categoryDataPoints) > 1;
$memberDataPoints = [];
if (isset($memberCost)) {
foreach ($memberCost as $member) {
if ($member['cost'] != 0) {
$memberDataPoints[] = [
"label" => $member['name'],
"y" => $member["cost"],
];
}
}
}
$showMemberCostGraph = count($memberDataPoints) > 1;
$paymentMethodDataPoints = [];
foreach ($paymentMethodCount as $paymentMethod) {
if ($paymentMethod['count'] != 0) {
$paymentMethodDataPoints[] = [
"label" => $paymentMethod['name'],
"y" => $paymentMethod["count"],
$categoryDataPoints = [];
if (isset($categoryCost)) {
foreach ($categoryCost as $category) {
if ($category['cost'] != 0) {
$categoryDataPoints[] = [
"label" => $category['name'],
"y" => $category["cost"],
];
}
}
}
$showPaymentMethodCountGraph = count($paymentMethodDataPoints) > 1;
if ($showCategoryCostGraph || $showMemberCostGraph || $showPaymentMethodCountGraph) {
?>
<h2><?= translate('split_views', $i18n) ?></h2>
<div class="graphs">
<?php
if ($showMemberCostGraph) {
?>
<section class="graph">
<header>
<?= translate('household_split', $i18n) ?>
<div class="sub-header">(<?= translate('monthly_cost', $i18n) ?>)</div>
</header>
<canvas id="memberSplitChart"></canvas>
</section>
<?php
}
if ($showCategoryCostGraph) {
?>
<section class="graph">
<header>
<?= translate('category_split', $i18n) ?>
<div class="sub-header">(<?= translate('monthly_cost', $i18n) ?>)</div>
</header>
<canvas id="categorySplitChart" style="height: 370px; width: 100%;"></canvas>
</section>
<?php
}
$showCategoryCostGraph = count($categoryDataPoints) > 1;
if ($showPaymentMethodCountGraph) {
?>
<section class="graph">
<header>
<?= translate('payment_method_split', $i18n) ?>
</header>
<canvas id="paymentMethidSplitChart" style="height: 370px; width: 100%;"></canvas>
</section>
<?php
}
$memberDataPoints = [];
if (isset($memberCost)) {
foreach ($memberCost as $member) {
if ($member['cost'] != 0) {
$memberDataPoints[] = [
"label" => $member['name'],
"y" => $member["cost"],
];
?>
</div>
<?php
}
}
?>
</section>
<?php
}
$showMemberCostGraph = count($memberDataPoints) > 1;
$paymentMethodDataPoints = [];
foreach ($paymentMethodCount as $paymentMethod) {
if ($paymentMethod['count'] != 0) {
$paymentMethodDataPoints[] = [
"label" => $paymentMethod['name'],
"y" => $paymentMethod["count"],
];
}
}
$showPaymentMethodCountGraph = count($paymentMethodDataPoints) > 1;
if ($showCategoryCostGraph || $showMemberCostGraph || $showPaymentMethodCountGraph) {
?>
<script src="scripts/libs/chart.js"></script>
<script type="text/javascript">
window.onload = function() {
loadGraph("categorySplitChart", <?php echo json_encode($categoryDataPoints, JSON_NUMERIC_CHECK); ?>, "<?= $code ?>", <?= $showCategoryCostGraph ?>);
loadGraph("memberSplitChart", <?php echo json_encode($memberDataPoints, JSON_NUMERIC_CHECK); ?>, "<?= $code ?>", <?= $showMemberCostGraph ?>);
loadGraph("paymentMethidSplitChart", <?php echo json_encode($paymentMethodDataPoints, JSON_NUMERIC_CHECK); ?>, "", <?= $showPaymentMethodCountGraph ?>);
<h2><?= translate('split_views', $i18n) ?></h2>
<div class="graphs">
<?php
if ($showMemberCostGraph) {
?>
<section class="graph">
<header>
<?= translate('household_split', $i18n) ?>
<div class="sub-header">(<?= translate('monthly_cost', $i18n) ?>)</div>
</header>
<canvas id="memberSplitChart"></canvas>
</section>
<?php
}
</script>
if ($showCategoryCostGraph) {
?>
<section class="graph">
<header>
<?= translate('category_split', $i18n) ?>
<div class="sub-header">(<?= translate('monthly_cost', $i18n) ?>)</div>
</header>
<canvas id="categorySplitChart" style="height: 370px; width: 100%;"></canvas>
</section>
<?php
}
if ($showPaymentMethodCountGraph) {
?>
<section class="graph">
<header>
<?= translate('payment_method_split', $i18n) ?>
</header>
<canvas id="paymentMethidSplitChart" style="height: 370px; width: 100%;"></canvas>
</section>
<?php
}
?>
</div>
<?php
}
?>
</section>
<?php
if ($showCategoryCostGraph || $showMemberCostGraph || $showPaymentMethodCountGraph) {
?>
<script src="scripts/libs/chart.js"></script>
<script type="text/javascript">
window.onload = function () {
loadGraph("categorySplitChart", <?php echo json_encode($categoryDataPoints, JSON_NUMERIC_CHECK); ?>, "<?= $code ?>", <?= $showCategoryCostGraph ?>);
loadGraph("memberSplitChart", <?php echo json_encode($memberDataPoints, JSON_NUMERIC_CHECK); ?>, "<?= $code ?>", <?= $showMemberCostGraph ?>);
loadGraph("paymentMethidSplitChart", <?php echo json_encode($paymentMethodDataPoints, JSON_NUMERIC_CHECK); ?>, "", <?= $showPaymentMethodCountGraph ?>);
}
</script>
<?php
}
?>
<script src="scripts/stats.js?<?= $version ?>"></script>
<?php
require_once 'includes/footer.php';
require_once 'includes/footer.php';
?>

View File

@@ -2094,4 +2094,8 @@ textarea.thin {
.subscription-modal img {
max-width: 135px;
}
.capitalize {
text-transform: capitalize;
}

Some files were not shown because too many files have changed in this diff Show More