✨ admin area newsletter send all (#45)
This commit is contained in:
parent
3d4d3bd373
commit
eeada3aa41
1
meta.php
1
meta.php
|
@ -48,5 +48,6 @@
|
|||
["path" => "admin/newsletter/:content", "target" => "page/admin/newsletter/content.php"],
|
||||
|
||||
["path" => "admin/newsletter/api/send-one", "target" => "page/admin/newsletter/api/send_one.php"],
|
||||
["path" => "admin/newsletter/api/send-all", "target" => "page/admin/newsletter/api/send_all.php"],
|
||||
];
|
||||
?>
|
||||
|
|
|
@ -0,0 +1,61 @@
|
|||
<?php
|
||||
declare(strict_types = 1);
|
||||
namespace Kimendisch\Sbgg_Jetzt;
|
||||
use Flake\Csrf;
|
||||
|
||||
// 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 //
|
||||
// csrf token
|
||||
Csrf::check(token: $request["csrf_token"] ?? "");
|
||||
|
||||
// content name
|
||||
$content_name = $request["content_name"] ?? "";
|
||||
if(!is_string($content_name)){
|
||||
http_response_code(400);
|
||||
echo("invalid content name");
|
||||
die();
|
||||
}
|
||||
if(!preg_match("/^\d{4}-\d{2}-\d{2}(-[a-z0-9]+)+$/", $content_name)){
|
||||
http_response_code(400);
|
||||
echo("invalid content name");
|
||||
die();
|
||||
}
|
||||
|
||||
|
||||
// TRY SENDING //
|
||||
// make sure session isn't locked
|
||||
if(extension_loaded("session")) session_write_close();
|
||||
|
||||
// send
|
||||
if(!Newsletter::send_all(content_name: $content_name)){
|
||||
http_response_code(200);
|
||||
echo(json_encode([
|
||||
"success" => false
|
||||
]));
|
||||
die();
|
||||
}
|
||||
|
||||
|
||||
// POSITIVE RESPONSE //
|
||||
http_response_code(200);
|
||||
echo(json_encode([
|
||||
"success" => true
|
||||
]));
|
||||
?>
|
|
@ -72,6 +72,7 @@
|
|||
Page::css("./page/start/style.css");
|
||||
Page::js(__DIR__ . "/iframe_magic.js");
|
||||
Page::js(__DIR__ . "/send_one.js");
|
||||
Page::js(__DIR__ . "/send_all.js");
|
||||
|
||||
Page::font("ubuntu");
|
||||
Page::font("tabler");
|
||||
|
@ -171,6 +172,49 @@
|
|||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="box danger">
|
||||
<span class="title">Send All (<?= Newsletter::member_count() ?>)</span>
|
||||
|
||||
<div id="newsletter-send-all-form-container" class="form-container">
|
||||
<div id="newsletter-send-all-form" class="form">
|
||||
<div class="key-value-pair">
|
||||
<div class="key">
|
||||
<span class="ti ti-shield"></span>
|
||||
</div>
|
||||
<div class="value-list">
|
||||
<span id="newsletter-send-all-form-safe-code" class="value select-none"> </span>
|
||||
<div class="inputwrapper">
|
||||
<input id="newsletter-send-all-form-safe-code-repeat" class="value" type="text" name="safe_code" placeholder="Safe Code" autocomplete="off" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<input id="newsletter-send-all-form-content-name" type="hidden" value="<?= $content_name ?>" />
|
||||
<input id="newsletter-send-all-form-csrf-token" type="hidden" value="<?= Csrf::token() ?>" />
|
||||
|
||||
<button id="newsletter-send-all-form-submit" class="button primary">
|
||||
<span class="text">Send All</span>
|
||||
<span class="icon ti ti-chevron-right"></span>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div id="newsletter-send-all-form-feedback" class="form-feedback gone">
|
||||
<div id="newsletter-send-all-form-feedback-wait" class="form-feedback-wait centertext gone">
|
||||
<span class="icon spinning ti ti-loader-2"></span>
|
||||
<span class="text">Sending</span>
|
||||
</div>
|
||||
<div id="newsletter-send-all-form-feedback-success" class="form-feedback-success centertext gone">
|
||||
<span class="icon ti ti-check"></span>
|
||||
<span class="text">Successfully sent</span>
|
||||
</div>
|
||||
<div id="newsletter-send-all-form-feedback-failure" class="form-feedback-failure centertext gone">
|
||||
<span class="icon ti ti-x"></span>
|
||||
<span class="text">Sending failed</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -0,0 +1,190 @@
|
|||
"use strict";
|
||||
|
||||
let newsletter_send_all_form;
|
||||
let newsletter_send_all_safe_code;
|
||||
let newsletter_send_all_input_safe_code_repeat;
|
||||
let newsletter_send_all_input_content_name;
|
||||
let newsletter_send_all_input_csrf_token;
|
||||
let newsletter_send_all_input_submit;
|
||||
let newsletter_send_all_feedback;
|
||||
let newsletter_send_all_feedback_wait;
|
||||
let newsletter_send_all_feedback_success;
|
||||
let newsletter_send_all_feedback_failure;
|
||||
|
||||
let newsletter_send_all_valid_safe_code = false;
|
||||
|
||||
window.addEventListener("load", function(){
|
||||
// STORE ELEMENTS //
|
||||
newsletter_send_all_form = document.getElementById("newsletter-send-all-form");
|
||||
newsletter_send_all_safe_code = document.getElementById("newsletter-send-all-form-safe-code");
|
||||
newsletter_send_all_input_safe_code_repeat = document.getElementById("newsletter-send-all-form-safe-code-repeat");
|
||||
newsletter_send_all_input_content_name = document.getElementById("newsletter-send-all-form-content-name");
|
||||
newsletter_send_all_input_csrf_token = document.getElementById("newsletter-send-all-form-csrf-token");
|
||||
newsletter_send_all_input_submit = document.getElementById("newsletter-send-all-form-submit");
|
||||
newsletter_send_all_feedback = document.getElementById("newsletter-send-all-form-feedback");
|
||||
newsletter_send_all_feedback_wait = document.getElementById("newsletter-send-all-form-feedback-wait");
|
||||
newsletter_send_all_feedback_success = document.getElementById("newsletter-send-all-form-feedback-success");
|
||||
newsletter_send_all_feedback_failure = document.getElementById("newsletter-send-all-form-feedback-failure");
|
||||
|
||||
|
||||
// INITIALIZE INPUTS //
|
||||
newsletter_send_all_init_safe_code();
|
||||
newsletter_send_all_init_safe_code_repeat();
|
||||
newsletter_send_all_init_submit();
|
||||
});
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* HELPER: Initialize safe code text.
|
||||
*/
|
||||
async function newsletter_send_all_init_safe_code(){
|
||||
// POPULATE WITH RANDOM NUMBER //
|
||||
newsletter_send_all_safe_code.textContent = Math.random().toString().slice(2, 6);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* HELPER: Initialize safe code repeat input.
|
||||
*/
|
||||
async function newsletter_send_all_init_safe_code_repeat(){
|
||||
// REGISTER INPUT HANDLER //
|
||||
newsletter_send_all_input_safe_code_repeat.addEventListener("input", newsletter_send_all_update_safe_code_repeat);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* HELPER: Initialize submit button input.
|
||||
*/
|
||||
async function newsletter_send_all_init_submit(){
|
||||
// REGISTER CLICK HANDLER //
|
||||
newsletter_send_all_input_submit.addEventListener("click", newsletter_send_all_submit);
|
||||
|
||||
|
||||
// UPDATE STATE //
|
||||
newsletter_send_all_update_submit();
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* CALLBACK: Update safe code repeat state.
|
||||
*/
|
||||
async function newsletter_send_all_update_safe_code_repeat(){
|
||||
// VALIDATE INPUT //
|
||||
// load values
|
||||
let should = newsletter_send_all_safe_code.textContent;
|
||||
let is = newsletter_send_all_input_safe_code_repeat.value;
|
||||
/**/console.log({is: is, should: should});
|
||||
|
||||
// compare
|
||||
newsletter_send_all_valid_safe_code = (is === should);
|
||||
|
||||
|
||||
// UPDATE VALIDITY INDICATOR //
|
||||
// get element
|
||||
let validity_indicator = newsletter_send_all_input_safe_code_repeat.parentElement;
|
||||
|
||||
// reset state
|
||||
validity_indicator.classList.remove("valid", "invalid");
|
||||
|
||||
// set state
|
||||
if(newsletter_send_all_valid_safe_code){
|
||||
validity_indicator.classList.add("valid");
|
||||
} else {
|
||||
validity_indicator.classList.add("invalid");
|
||||
}
|
||||
|
||||
|
||||
// UPDATE SUBMIT BUTTON //
|
||||
newsletter_send_all_update_submit();
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* HELPER: Update submit button state.
|
||||
*/
|
||||
async function newsletter_send_all_update_submit(){
|
||||
// DISABLE //
|
||||
newsletter_send_all_input_submit.classList.add("disabled");
|
||||
|
||||
|
||||
// MAYBE ENABLE //
|
||||
if(newsletter_send_all_valid_safe_code){
|
||||
newsletter_send_all_input_submit.classList.remove("disabled");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* CALLBACK: Maybe submit the form.
|
||||
*/
|
||||
async function newsletter_send_all_submit(){
|
||||
// MAKE SURE ALL INPUTS ARE VALID //
|
||||
if(!newsletter_send_all_valid_safe_code) return;
|
||||
|
||||
|
||||
// SHOW WAIT FEEDBACK //
|
||||
newsletter_send_all_feedback.classList.remove("hidden", "gone");
|
||||
newsletter_send_all_form.classList.add("hidden");
|
||||
newsletter_send_all_feedback_wait.classList.remove("hidden", "gone");
|
||||
|
||||
|
||||
// COLLECT VALUES //
|
||||
// content name
|
||||
let content_name = newsletter_send_all_input_content_name.value;
|
||||
|
||||
// csrf token
|
||||
let csrf_token = newsletter_send_all_input_csrf_token.value;
|
||||
|
||||
|
||||
// SEND API REQUEST //
|
||||
var xhr = new XMLHttpRequest();
|
||||
xhr.open("POST", "/admin/newsletter/api/send-all", true);
|
||||
xhr.setRequestHeader("Content-Type", "application/json");
|
||||
xhr.send(JSON.stringify({
|
||||
content_name: content_name,
|
||||
csrf_token: csrf_token
|
||||
}));
|
||||
|
||||
xhr.onload = function(){
|
||||
let success = true;
|
||||
|
||||
// validate http status code
|
||||
if(xhr.status !== 200) success = false;
|
||||
|
||||
// check response
|
||||
let response = null;
|
||||
if(success){
|
||||
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
|
||||
if(success){
|
||||
newsletter_send_all_feedback_wait.classList.add("gone");
|
||||
newsletter_send_all_feedback_success.classList.remove("hidden", "gone");
|
||||
return;
|
||||
}
|
||||
|
||||
// negative feedback: no member
|
||||
if(response !== null && (response.reason ?? "") === "no_member"){
|
||||
newsletter_send_all_feedback_wait.classList.add("gone");
|
||||
newsletter_send_all_feedback_failure_no_member.classList.remove("hidden", "gone");
|
||||
return;
|
||||
}
|
||||
|
||||
// negative feedback: default
|
||||
newsletter_send_all_feedback_wait.classList.add("gone");
|
||||
newsletter_send_all_feedback_failure.classList.remove("hidden", "gone");
|
||||
}
|
||||
}
|
|
@ -1,35 +1,35 @@
|
|||
"use strict";
|
||||
|
||||
let newsletter_form;
|
||||
let newsletter_input_mail_address;
|
||||
let newsletter_input_content_name;
|
||||
let newsletter_input_csrf_token;
|
||||
let newsletter_input_submit;
|
||||
let newsletter_feedback;
|
||||
let newsletter_feedback_wait;
|
||||
let newsletter_feedback_success;
|
||||
let newsletter_feedback_failure;
|
||||
let newsletter_feedback_failure_no_member;
|
||||
let newsletter_send_one_form;
|
||||
let newsletter_send_one_input_mail_address;
|
||||
let newsletter_send_one_input_content_name;
|
||||
let newsletter_send_one_input_csrf_token;
|
||||
let newsletter_send_one_input_submit;
|
||||
let newsletter_send_one_feedback;
|
||||
let newsletter_send_one_feedback_wait;
|
||||
let newsletter_send_one_feedback_success;
|
||||
let newsletter_send_one_feedback_failure;
|
||||
let newsletter_send_one_feedback_failure_no_member;
|
||||
|
||||
let newsletter_valid_mail_address = false;
|
||||
let newsletter_send_one_valid_mail_address = false;
|
||||
|
||||
window.addEventListener("load", function(){
|
||||
// STORE ELEMENTS //
|
||||
newsletter_form = document.getElementById("newsletter-send-one-form");
|
||||
newsletter_input_mail_address = document.getElementById("newsletter-send-one-form-mail-address");
|
||||
newsletter_input_content_name = document.getElementById("newsletter-send-one-form-content-name");
|
||||
newsletter_input_csrf_token = document.getElementById("newsletter-send-one-form-csrf-token");
|
||||
newsletter_input_submit = document.getElementById("newsletter-send-one-form-submit");
|
||||
newsletter_feedback = document.getElementById("newsletter-send-one-form-feedback");
|
||||
newsletter_feedback_wait = document.getElementById("newsletter-send-one-form-feedback-wait");
|
||||
newsletter_feedback_success = document.getElementById("newsletter-send-one-form-feedback-success");
|
||||
newsletter_feedback_failure = document.getElementById("newsletter-send-one-form-feedback-failure");
|
||||
newsletter_feedback_failure_no_member = document.getElementById("newsletter-send-one-form-feedback-failure-no-member");
|
||||
newsletter_send_one_form = document.getElementById("newsletter-send-one-form");
|
||||
newsletter_send_one_input_mail_address = document.getElementById("newsletter-send-one-form-mail-address");
|
||||
newsletter_send_one_input_content_name = document.getElementById("newsletter-send-one-form-content-name");
|
||||
newsletter_send_one_input_csrf_token = document.getElementById("newsletter-send-one-form-csrf-token");
|
||||
newsletter_send_one_input_submit = document.getElementById("newsletter-send-one-form-submit");
|
||||
newsletter_send_one_feedback = document.getElementById("newsletter-send-one-form-feedback");
|
||||
newsletter_send_one_feedback_wait = document.getElementById("newsletter-send-one-form-feedback-wait");
|
||||
newsletter_send_one_feedback_success = document.getElementById("newsletter-send-one-form-feedback-success");
|
||||
newsletter_send_one_feedback_failure = document.getElementById("newsletter-send-one-form-feedback-failure");
|
||||
newsletter_send_one_feedback_failure_no_member = document.getElementById("newsletter-send-one-form-feedback-failure-no-member");
|
||||
|
||||
|
||||
// INITIALIZE INPUTS //
|
||||
newsletter_init_mail_address();
|
||||
newsletter_init_submit();
|
||||
newsletter_send_one_init_mail_address();
|
||||
newsletter_send_one_init_submit();
|
||||
});
|
||||
|
||||
|
||||
|
@ -37,9 +37,9 @@ window.addEventListener("load", function(){
|
|||
/**
|
||||
* HELPER: Initialize mail address input.
|
||||
*/
|
||||
async function newsletter_init_mail_address(){
|
||||
async function newsletter_send_one_init_mail_address(){
|
||||
// REGISTER INPUT HANDLER //
|
||||
newsletter_input_mail_address.addEventListener("input", newsletter_update_mail_address);
|
||||
newsletter_send_one_input_mail_address.addEventListener("input", newsletter_send_one_update_mail_address);
|
||||
}
|
||||
|
||||
|
||||
|
@ -47,13 +47,13 @@ async function newsletter_init_mail_address(){
|
|||
/**
|
||||
* HELPER: Initialize submit button input.
|
||||
*/
|
||||
async function newsletter_init_submit(){
|
||||
async function newsletter_send_one_init_submit(){
|
||||
// REGISTER CLICK HANDLER //
|
||||
newsletter_input_submit.addEventListener("click", newsletter_submit);
|
||||
newsletter_send_one_input_submit.addEventListener("click", newsletter_send_one_submit);
|
||||
|
||||
|
||||
// UPDATE STATE //
|
||||
newsletter_update_submit();
|
||||
newsletter_send_one_update_submit();
|
||||
}
|
||||
|
||||
|
||||
|
@ -61,24 +61,24 @@ async function newsletter_init_submit(){
|
|||
/**
|
||||
* CALLBACK: Update mail address state.
|
||||
*/
|
||||
async function newsletter_update_mail_address(){
|
||||
async function newsletter_send_one_update_mail_address(){
|
||||
// VALIDATE INPUT //
|
||||
// load value
|
||||
let value = newsletter_input_mail_address.value;
|
||||
let value = newsletter_send_one_input_mail_address.value;
|
||||
|
||||
// check against regex
|
||||
newsletter_valid_mail_address = (value.match(/^[a-zA-Z0-9\.\-\_\+]+@([a-z0-9\-]+\.)+[a-z0-9\-]{2,}$/) !== null);
|
||||
newsletter_send_one_valid_mail_address = (value.match(/^[a-zA-Z0-9\.\-\_\+]+@([a-z0-9\-]+\.)+[a-z0-9\-]{2,}$/) !== null);
|
||||
|
||||
|
||||
// UPDATE VALIDITY INDICATOR //
|
||||
// get element
|
||||
let validity_indicator = newsletter_input_mail_address.parentElement;
|
||||
let validity_indicator = newsletter_send_one_input_mail_address.parentElement;
|
||||
|
||||
// reset state
|
||||
validity_indicator.classList.remove("valid", "invalid");
|
||||
|
||||
// set state
|
||||
if(newsletter_valid_mail_address){
|
||||
if(newsletter_send_one_valid_mail_address){
|
||||
validity_indicator.classList.add("valid");
|
||||
} else {
|
||||
validity_indicator.classList.add("invalid");
|
||||
|
@ -86,7 +86,7 @@ async function newsletter_update_mail_address(){
|
|||
|
||||
|
||||
// UPDATE SUBMIT BUTTON //
|
||||
newsletter_update_submit();
|
||||
newsletter_send_one_update_submit();
|
||||
}
|
||||
|
||||
|
||||
|
@ -94,14 +94,14 @@ async function newsletter_update_mail_address(){
|
|||
/**
|
||||
* HELPER: Update submit button state.
|
||||
*/
|
||||
async function newsletter_update_submit(){
|
||||
async function newsletter_send_one_update_submit(){
|
||||
// DISABLE //
|
||||
newsletter_input_submit.classList.add("disabled");
|
||||
newsletter_send_one_input_submit.classList.add("disabled");
|
||||
|
||||
|
||||
// MAYBE ENABLE //
|
||||
if(newsletter_valid_mail_address){
|
||||
newsletter_input_submit.classList.remove("disabled");
|
||||
if(newsletter_send_one_valid_mail_address){
|
||||
newsletter_send_one_input_submit.classList.remove("disabled");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -110,26 +110,26 @@ async function newsletter_update_submit(){
|
|||
/**
|
||||
* CALLBACK: Maybe submit the form.
|
||||
*/
|
||||
async function newsletter_submit(){
|
||||
async function newsletter_send_one_submit(){
|
||||
// MAKE SURE ALL INPUTS ARE VALID //
|
||||
if(!newsletter_valid_mail_address) return;
|
||||
if(!newsletter_send_one_valid_mail_address) return;
|
||||
|
||||
|
||||
// SHOW WAIT FEEDBACK //
|
||||
newsletter_feedback.classList.remove("hidden", "gone");
|
||||
newsletter_form.classList.add("hidden");
|
||||
newsletter_feedback_wait.classList.remove("hidden", "gone");
|
||||
newsletter_send_one_feedback.classList.remove("hidden", "gone");
|
||||
newsletter_send_one_form.classList.add("hidden");
|
||||
newsletter_send_one_feedback_wait.classList.remove("hidden", "gone");
|
||||
|
||||
|
||||
// COLLECT VALUES //
|
||||
// mail address
|
||||
let mail_address = newsletter_input_mail_address.value;
|
||||
let mail_address = newsletter_send_one_input_mail_address.value;
|
||||
|
||||
// content name
|
||||
let content_name = newsletter_input_content_name.value;
|
||||
let content_name = newsletter_send_one_input_content_name.value;
|
||||
|
||||
// csrf token
|
||||
let csrf_token = newsletter_input_csrf_token.value;
|
||||
let csrf_token = newsletter_send_one_input_csrf_token.value;
|
||||
|
||||
|
||||
// SEND API REQUEST //
|
||||
|
@ -162,20 +162,20 @@ async function newsletter_submit(){
|
|||
|
||||
// positive feedback
|
||||
if(success){
|
||||
newsletter_feedback_wait.classList.add("gone");
|
||||
newsletter_feedback_success.classList.remove("hidden", "gone");
|
||||
newsletter_send_one_feedback_wait.classList.add("gone");
|
||||
newsletter_send_one_feedback_success.classList.remove("hidden", "gone");
|
||||
return;
|
||||
}
|
||||
|
||||
// negative feedback: no member
|
||||
if(response !== null && (response.reason ?? "") === "no_member"){
|
||||
newsletter_feedback_wait.classList.add("gone");
|
||||
newsletter_feedback_failure_no_member.classList.remove("hidden", "gone");
|
||||
newsletter_send_one_feedback_wait.classList.add("gone");
|
||||
newsletter_send_one_feedback_failure_no_member.classList.remove("hidden", "gone");
|
||||
return;
|
||||
}
|
||||
|
||||
// negative feedback: default
|
||||
newsletter_feedback_wait.classList.add("gone");
|
||||
newsletter_feedback_failure.classList.remove("hidden", "gone");
|
||||
newsletter_send_one_feedback_wait.classList.add("gone");
|
||||
newsletter_send_one_feedback_failure.classList.remove("hidden", "gone");
|
||||
}
|
||||
}
|
||||
|
|
|
@ -133,6 +133,12 @@ span.inline {
|
|||
display: none !important;
|
||||
}
|
||||
|
||||
.select-none {
|
||||
-webkit-user-select: none;
|
||||
-ms-user-select: none;
|
||||
user-select: none;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -290,6 +296,14 @@ span.inline {
|
|||
.box.important {
|
||||
border: 0.5rem solid var(--theme);
|
||||
}
|
||||
.box.danger {
|
||||
border: 0.5rem solid var(--color-red);
|
||||
}
|
||||
.box.danger * {
|
||||
--theme: var(--color-red);
|
||||
--theme-light: var(--color-red-light);
|
||||
--theme-dark: var(--color-red-dark);
|
||||
}
|
||||
a.box:hover {
|
||||
background-color: var(--color-gray-dark-dark);
|
||||
}
|
||||
|
|
|
@ -369,6 +369,31 @@
|
|||
|
||||
|
||||
|
||||
/**
|
||||
* Determine number of members.
|
||||
*
|
||||
* @return int Number of members in newsletter list.
|
||||
*/
|
||||
public static function member_count(): int {
|
||||
// LOAD LIST FROM DATABASE //
|
||||
// open
|
||||
$old_ignore_user_abort = (bool)ignore_user_abort(true);
|
||||
$newsletter_db = new Dat("./.dat/newsletter", Dat::MODE_READ);
|
||||
|
||||
// read
|
||||
$member_list = $newsletter_db->get("list") ?? [];
|
||||
|
||||
// close
|
||||
$newsletter_db->close();
|
||||
ignore_user_abort($old_ignore_user_abort);
|
||||
|
||||
|
||||
// RETURN SIZE //
|
||||
return sizeof($member_list);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Send content to one newsletter member.
|
||||
*
|
||||
|
@ -396,6 +421,48 @@
|
|||
|
||||
|
||||
|
||||
/**
|
||||
* Send content to all newsletter members.
|
||||
*
|
||||
* @param string $content_name Name of content to send.
|
||||
*
|
||||
* @return bool Whether sending was successful.
|
||||
*/
|
||||
public static function send_all(string $content_name): bool {
|
||||
// LOAD LIST FROM DATABASE //
|
||||
// open database
|
||||
$old_ignore_user_abort = (bool)ignore_user_abort(true);
|
||||
$newsletter_db = new Dat("./.dat/newsletter", Dat::MODE_READ);
|
||||
|
||||
// read list
|
||||
$member_list = $newsletter_db->get("list") ?? [];
|
||||
|
||||
// close database
|
||||
$newsletter_db->close();
|
||||
|
||||
|
||||
// SEND CONTENT //
|
||||
// read content
|
||||
$content = self::content_file_read($content_name);
|
||||
|
||||
// iterate over all list members
|
||||
$success = true;
|
||||
foreach($member_list as $one_member_mail_address => $one_member_dataset){
|
||||
// send to this member
|
||||
if(!self::send(mail_address: $one_member_mail_address, content: $content, dataset: $one_member_dataset)) $success = false;
|
||||
}
|
||||
|
||||
|
||||
// FINALIZE //
|
||||
// release runlock
|
||||
ignore_user_abort($old_ignore_user_abort);
|
||||
|
||||
// return success status
|
||||
return $success;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* HELPER: Initialize the database with empty values.
|
||||
*
|
||||
|
|
Loading…
Reference in New Issue