added DB functions

This commit is contained in:
eclipse 2025-03-02 19:50:47 +01:00
parent cfb6879b32
commit 973d4b0345
4 changed files with 113 additions and 36 deletions

View File

@ -1,31 +1,56 @@
<?php
// inspired by https://www.mailgun.com/blog/email/double-opt-in-with-php-mailgun/
$statusCode = 'HTTP/1.1 303 See Other';
require(dirname(__FILE__) . '/settings.php');
$successURL = '/newsletter/confirmed.html';
$errorURL = '/newsletter/confirm-error.html';
// return TRUE when successful, message string on failure
// e.g. Adresse schon vorhanden, Datenbank-Fehler, was noch?
function AddSubscriberToDB($recipientAddress) {
global $db;
echo 'ah jup';
// Adds new subscriber to database. Returns an error message on failure, TRUE on success.
function AddSubscriberToDB($subscriberAddress, $subscriberName = NULL) {
global $general;
try {
$pdo = getPDO();
// create table if it doesn't exist already
$query = $pdo->prepare($general['sql']['create_table']);
if ( ! $query->execute() ) {
error_log('Datenbankfehler beim Prüfen/Erzeugen der Tabelle.');
return "Ein Fehler ist aufgetreten.";
}
// check if record exists
$query = $pdo->prepare($general['sql']['read_record']);
if ( ! $query->execute([':e' => $subscriberAddress]) ) {
error_log("Datenbankfehler: Adresscheck für Emailadresse {$subscriberAddress} ergab einen Fehler.");
return 'Datenbankfehler.';
}
if ( $query->fetch() ) {
error_log("Datenbankfehler: Emailadresse {$subscriberAddress} ist bereits eingetragen.");
return "Emailadresse ist bereits eingetragen.";
}
// create record
$query = $pdo->prepare($general['sql']['create_record']);
if ( ( ! $query->execute([':e' => $subscriberAddress, ':n' => $subscriberName]) ) or ( $query->fetch() ) ) {
error_log("Datenbankfehler: Einfügen von Emailadresse {$subscriberAddress} ergab einen Fehler.");
return 'Datenbankfehler.';
}
} catch(\PDOException $e) {
error_log("Datenbankfehler: {$e->getMessage()}");
return $e->getMessage();
}
return TRUE;
}
function CheckConfirmationHash($confEmail, $confCode) {
global $general;
return (md5($confEmail . $general['uniqueKey']) === $confCode);
}
require(dirname(__FILE__) . '/settings.php');
if (isset($_GET['c']) && isset($_GET['e'])) {
$c = filter_var($_GET['c'], FILTER_SANITIZE_STRING);
$e = filter_var($_GET['e'], FILTER_SANITIZE_STRING);
if (CheckConfirmationHash($e, $c)) {
if ( GetConfirmationHash($e) === $c ) {
$result = AddSubscriberToDB($e);
if ($result == TRUE) {
if ($result === TRUE) {
GracefulExit($successURL, 'Bestätigung erfolgt: Newsletter-Anmeldung bestätigt');
} elseif (gettype($result == 'string')) {
GracefulExit($errorURL, "Bestätigung fehlgeschlagen: {$result}");

View File

@ -11,16 +11,28 @@ require $dname . '/SMTP.php';
// general constants
$general = [
// 'domain' => 'tobias-radloff.de',
// site domain (used for building confirmation links)
/* 'domain' => 'tobias-radloff.de', */
'domain' => 'localhost',
// string concatenated with email address to create a non-recreatable md5 hash
'uniqueKey' => '***REMOVED***', // works like password salt
// file name of confirm script
'confirmScript' => '/confirm.php',
'statusCode' => 'HTTP/1.1 303 See Other'
// status code to be used when redirection to success or error page
'statusCode' => 'HTTP/1.1 303 See Other',
// array of SQL statements used
'sql' => [
'create_table' => 'CREATE TABLE IF NOT EXISTS subscribers (id INTEGER PRIMARY KEY, email TEXT NOT NULL UNIQUE, name TEXT);',
'create_record' => 'INSERT INTO subscribers(email, name) VALUES(:e, :n);',
'read_record' => 'SELECT 1 FROM subscribers WHERE email = :e;',
'update_record' => '',
'delete_record' => 'DELETE FROM subscribers WHERE email = :e;'
]
];
// complete site URL
$general['siteURL'] = 'https://' . $general['domain'];
// smtp info
// SMTP server information
$smtp = [
'host' => '***REMOVED***
'port' => 587,
@ -31,28 +43,47 @@ $smtp = [
'fromName' => 'Tobias Radloffs Newsletter',
];
// body of confirmation email
$bodyConfirmation = [
'Hallo!',
'Bitte bestätige die Anmeldung für meinen Newsletter, indem du auf den folgenden Link klickst:',
'%Placeholder%', // placeholder
'%Placeholder%',
'Bis bald und viele Grüße, Tobias'
];
// mail contents
// contents of confirmation email
$mailConfirmation = [
'subject' => 'Newsletter-Anmeldung bestaetigen',
'bodyHTML' => '<p>' . implode('</p><p>', $bodyConfirmation) . '</p>',
'bodyText' => implode("\n\n", $bodyConfirmation)
];
// DB constants
// database information
$db = [
'sqlite' => [
'dsn' => 'sqlite:../newsletter.sqlite',
],
'mysql' => [
'dsn' => '',
'host' => '',
'port' => '',
'username' => '',
'password' => ''
]
];
function GetConfirmationHash($confEmail) {
global $general;
return md5($confEmail . $general['uniqueKey'] );
}
// connects to database and returns PDO object
function getPDO($dbType = 'sqlite') {
global $db;
return new \PDO($db[$dbType]['dsn']);
}
// Sends an email to single recipient with subject and body specified in an array. Returns an error message on failure, TRUE on success.
function SendEmail($recipientAddress, $mailContents, $link = NULL) {
global $general, $smtp;
@ -92,6 +123,7 @@ function SendEmail($recipientAddress, $mailContents, $link = NULL) {
}
}
// redirects to specified URL via GET request and conveys an optional message
function GracefulExit($location, $message = NULL) {
global $general;
header($general['statusCode']);

View File

@ -6,20 +6,15 @@ $errorURL = '/newsletter/subscribe-error.html';
require(dirname(__FILE__) . '/settings.php');
function MakeConfirmationHash($confEmail, $confCode) {
return md5($confEmail . $confCode);
}
if (isset($_POST['email'])) {
$email = filter_var(trim($_POST['email'], FILTER_SANITIZE_STRING));
error_log("Email ist: {$email}");
if (filter_var($email, FILTER_VALIDATE_EMAIL)) {
$hashedUnique = MakeConfirmationHash($email, $general['uniqueKey']);
$confirmQuery = http_build_query(['c' => $hashedUnique, 'e' => $email]);
$confirmQuery = http_build_query(['c' => GetConfirmationHash($email), 'e' => $email]);
$confirmLink = $general['siteURL'] . $general['confirmScript'] . "?" . $confirmQuery;
$result = SendEmail($email, $mailConfirmation, $confirmLink);
if ( $result == TRUE ) {
if ( $result === TRUE ) {
GracefulExit($successURL, 'Anmeldung wird fortgesetzt: Email mit Bestätigungslink wurde versandt.');
} else {
GracefulExit($errorURL, 'Anmeldung fehlgeschlagen: Fehler beim Versenden der Bestätigungs-Email.');

View File

@ -7,14 +7,39 @@ $errorURL = '/newsletter/unsubscribe-error.html';
function RemoveSubscriberFromDB($subscriberAddress) {
error_log("removing subscriber {$subscriberAddress} from DB ...");
global $general;
try {
$pdo = getPDO();
// make sure record exists
$query = $pdo->prepare($general['sql']['read_record']);
if ( ! $query->execute([':e' => $subscriberAddress]) ) {
error_log("Datenbankfehler: Adresscheck für {$subscriberAddress} ergab einen Fehler.");
return 'Datenbankfehler.';
}
if ( ! $query->fetch() ) {
error_log("Datenbankfehler: Emailadresse {$subscriberAddress} nicht in Datenbank vorhanden.");
return "Emailadresse nicht bekannt.";
}
// delete record
$query = $pdo->prepare($general['sql']['delete_record']);
if ( ! $query->execute([':e' => $subscriberAddress])) {
error_log("Datenbankfehler: Löschen von Emailadresse {$subscriberAddress} ergab einen Fehler.");
return 'Fehler beim Löschen des Datenbankeintrags.';
}
} catch(\PDOException $e) {
error_log("Datenbankfehler: {$e->getMessage()}");
return $e->getMessage();
}
return TRUE;
}
if (isset($_GET['e'])) {
$e = filter_var($_GET["e"], FILTER_SANITIZE_STRING);
$result = RemoveSubscriberFromDB($e);
if ($result == TRUE) {
if ($result === TRUE) {
GracefulExit($successURL, "Abmeldung für {$e} erfolgreich.");
} elseif (gettype($result == 'string')) {
GracefulExit($errorURL, "Abmeldung fehlgeschlagen: {$result}");