newsletter signup api (#45)

This commit is contained in:
DrMaxNix 2024-02-04 20:40:40 +01:00
parent 2fc9af74cf
commit c4a0b1772a
5 changed files with 172 additions and 5 deletions

2
.dat/.gitignore vendored Normal file
View File

@ -0,0 +1,2 @@
*
!.gitignore

View File

@ -0,0 +1,56 @@
<?php
declare(strict_types = 1);
namespace Kimendisch\Sbgg_Jetzt;
use Flake\Error;
// DECODE REQUEST //
// get json string
$json_body = file_get_contents("php://input");
if(strlen($json_body) <= 0){
http_response_code(400);
echo("malformed request body");
die();
}
// try decoding json
$request = json_decode($json_body, true);
if(json_last_error() != JSON_ERROR_NONE){
http_response_code(400);
echo("malformed request body");
die();
}
// VALIDATE VALUES //
// mail address
$mail_address = $request["mail_address"] ?? "";
if(!is_string($mail_address)){
http_response_code(400);
echo("invalid mail address");
die();
}
if(!preg_match("/^[a-zA-Z0-9\.\-\_\+]+@([a-z0-9\-]+\.)+[a-z0-9\-]{2,}$/", $mail_address)){
http_response_code(400);
echo("invalid mail address");
die();
}
// language
$language = $request["language"] ?? "";
if(!in_array($language, ["de", "en"])){
http_response_code(400);
echo("invalid language");
die();
}
// ADD TO MAILING LIST //
Newsletter::subscribe(mail_address: $mail_address, language: $language);
// POSITIVE RESPONSE //
http_response_code(200);
echo(json_encode([
"success" => true
]));
?>

View File

@ -5,6 +5,7 @@
// DEPENDENCIES //
// used extensions
static::$ext[] = "dat";
static::$ext[] = "request";
static::$ext[] = "lang";
static::$ext[] = "page";
@ -25,6 +26,8 @@
// pages
static::$route["sbgg.jetzt"] = [
["path" => "", "target" => "page/start"],
["path" => ":lang", "target" => "page/start"]
["path" => ":lang", "target" => "page/start"],
["path" => "api/newsletter/subscribe", "target" => "api/newsletter/subscribe.php"]
];
?>

View File

@ -187,13 +187,41 @@ async function newsletter_submit(){
// SEND API REQUEST //
/**/setTimeout(function(){
var xhr = new XMLHttpRequest();
xhr.open("POST", "/api/newsletter/subscribe", true);
xhr.setRequestHeader("Content-Type", "application/json");
xhr.send(JSON.stringify({
mail_address: mail_address,
language: language
}));
xhr.onload = function(){
let success = true;
// validate http status code
if(xhr.status !== 200) success = false;
// check response
if(success){
let response = null;
try {
response = JSON.parse(xhr.response);
} catch(e){}
if(typeof response !== "object") success = false;
if(success && response === null) success = false;
if(success && response.success !== true) success = false;
}
// positive feedback
newsletter_feedback_wait.classList.add("gone");
newsletter_feedback_success.classList.remove("hidden", "gone");
if(success){
newsletter_feedback_wait.classList.add("gone");
newsletter_feedback_success.classList.remove("hidden", "gone");
return;
}
// negative feedback
newsletter_feedback_wait.classList.add("gone");
newsletter_feedback_failure.classList.remove("hidden", "gone");
/**/}, 700);
}
}

78
src/newsletter.php Normal file
View File

@ -0,0 +1,78 @@
<?php
declare(strict_types = 1);
namespace Kimendisch\Sbgg_Jetzt;
use Flake\Dat;
use Flake\Id64;
class Newsletter {
/**
* Add a new mail address to the mailing list.
*
* @param string $mail_address Recipient mail address.
* @param string $language Desired newsletter language.
*/
public static function subscribe(string $mail_address, string $language): void {
// OPEN DATABASE //
// acquire runlock
$old_ignore_user_abort = (bool)ignore_user_abort(true);
// obtain handle
$newsletter_db = new Dat("./.dat/newsletter", Dat::MODE_READ_WRITE);
// MAYBE INITIALIZE DATABASE //
if(!is_array($newsletter_db->get("list"))){
// initialize as empty array
$newsletter_db->set("list", []);
}
// UPDATE DATABASE //
$entry_key = ["list", $mail_address];
// generate unsubscribe key
$unsubscribe_key = Id64::new(length: 16);
// only allow new entries
$is_new = ($newsletter_db->get($entry_key) === null);
// maybe add to database
if($is_new){
$newsletter_db->set($entry_key, [
"unsubscribe_key" => $unsubscribe_key,
"language" => $language
]);
}
// FINALIZE //
// close database
$newsletter_db->write_close();
if($is_new){
// send welcome mail
self::send_welcome_mail(mail_address: $mail_address);
} else {
// fake delay
//*/ TODO
}
// release runlock
ignore_user_abort($old_ignore_user_abort);
}
/**
* HELPER: Send welcome mail to new recipient.
*
* @param string $mail_address Recipient mail address.
*/
private static function send_welcome_mail(string $mail_address): void {
/**/print_r(["send_welcome_mail" => $mail_address]);
//*/ TODO
}
}
?>