Add per-form Listmonk list UUIDs to newsletter plugin

Add support for specifying Listmonk list UUIDs per form instance
Update petition form to use metadata-defined UUIDs
Add success confirmation message to newsletter forms
Update documentation with new functionality
This commit is contained in:
Ruben 2026-02-07 15:34:43 +01:00
parent 15a8f97cb2
commit 36591e7438
5 changed files with 47 additions and 17 deletions

View file

@ -12,6 +12,7 @@
* Then in your PHP content file, call the function with your custom text and theme:
* <?= newsletter_signup('Your custom intro text here', 'hero') ?>
* <?= newsletter_signup('Short text here', 'small') ?>
* <?= newsletter_signup('Text', 'small', ['list-uuid-here']) ?>
*
* Available themes:
* - 'hero': Full-width gradient background section (like CTA sections)
@ -57,7 +58,7 @@ function newsletterT(string $key): string {
/**
* Subscribe to newsletter via Listmonk public API
*/
function newsletterSubscribe(string $email, string $name): array {
function newsletterSubscribe(string $email, string $name, array $listUuids = []): array {
$configPath = dirname(__DIR__, 2) . '/listmonk-config.php';
if (!file_exists($configPath)) {
return ['success' => false, 'error' => 'config_missing'];
@ -71,7 +72,7 @@ function newsletterSubscribe(string $email, string $name): array {
$payload = json_encode([
'email' => $email,
'name' => $name,
'list_uuids' => $config['list_uuids']
'list_uuids' => !empty($listUuids) ? $listUuids : $config['list_uuids']
]);
$url = $config['url'] . '/api/public/subscription';
@ -210,12 +211,15 @@ SCRIPT;
/**
* Render the "hero" theme - full-width gradient background section
*/
function newsletterRenderHero(string $introText, string $formId): string {
function newsletterRenderHero(string $introText, string $formId, array $listUuids = []): string {
$csrfToken = $_SESSION['newsletter_csrf_token'];
$nonce = bin2hex(random_bytes(8));
$escapedIntro = htmlspecialchars($introText, ENT_QUOTES, 'UTF-8');
$escapedFormId = htmlspecialchars($formId, ENT_QUOTES, 'UTF-8');
$t = newsletterGetTranslations();
$listUuidsField = !empty($listUuids)
? "\n" . ' <input type="hidden" name="newsletter_list_uuids" value="' . htmlspecialchars(implode(',', $listUuids), ENT_QUOTES, 'UTF-8') . '">'
: '';
$html = <<<HTML
<section class="newsletter-section newsletter-hero escape" id="{$escapedFormId}">
@ -223,7 +227,7 @@ function newsletterRenderHero(string $introText, string $formId): string {
<p class="newsletter-intro">{$escapedIntro}</p>
<form class="newsletter-form" method="post" data-newsletter-form data-success-message="{$t['successMessage']}" data-error-message="{$t['errorMessage']}">
<input type="hidden" name="newsletter_csrf" value="{$csrfToken}">
<input type="hidden" name="newsletter_form_id" value="{$escapedFormId}">
<input type="hidden" name="newsletter_form_id" value="{$escapedFormId}">{$listUuidsField}
<div class="newsletter-fields">
<div class="newsletter-field">
<label for="newsletter_name_{$nonce}" class="visually-hidden">{$t['nameLabel']}</label>
@ -252,19 +256,22 @@ HTML;
/**
* Render the "small" theme - compact inline notice with border
*/
function newsletterRenderSmall(string $introText, string $formId): string {
function newsletterRenderSmall(string $introText, string $formId, array $listUuids = []): string {
$csrfToken = $_SESSION['newsletter_csrf_token'];
$nonce = bin2hex(random_bytes(8));
$escapedIntro = htmlspecialchars($introText, ENT_QUOTES, 'UTF-8');
$escapedFormId = htmlspecialchars($formId, ENT_QUOTES, 'UTF-8');
$t = newsletterGetTranslations();
$listUuidsField = !empty($listUuids)
? "\n" . ' <input type="hidden" name="newsletter_list_uuids" value="' . htmlspecialchars(implode(',', $listUuids), ENT_QUOTES, 'UTF-8') . '">'
: '';
$html = <<<HTML
<aside class="newsletter-section newsletter-small" id="{$escapedFormId}">
<p class="newsletter-intro">{$escapedIntro}</p>
<form class="newsletter-form" method="post" data-newsletter-form data-success-message="{$t['successMessage']}" data-success-confirm="{$t['successConfirm']}" data-error-message="{$t['errorMessage']}">
<input type="hidden" name="newsletter_csrf" value="{$csrfToken}">
<input type="hidden" name="newsletter_form_id" value="{$escapedFormId}">
<input type="hidden" name="newsletter_form_id" value="{$escapedFormId}">{$listUuidsField}
<div class="newsletter-fields">
<div class="newsletter-field">
<label for="newsletter_email_{$nonce}" class="visually-hidden">{$t['emailLabel']}</label>
@ -464,19 +471,20 @@ STYLES;
*
* @param string $introText Custom intro text to display above the form
* @param string $theme Theme to use: 'hero' (default) or 'small'
* @param array $listUuids Optional Listmonk list UUIDs for this form (default: uses global config)
* @param string $formId Optional form ID for the section (default: 'newsletter')
* @return string The complete HTML for the newsletter signup section
*/
function newsletter_signup(string $introText, string $theme = 'hero', string $formId = 'newsletter'): string {
function newsletter_signup(string $introText, string $theme = 'hero', array $listUuids = [], string $formId = 'newsletter'): string {
$html = newsletterGetStyles();
switch ($theme) {
case 'small':
$html .= newsletterRenderSmall($introText, $formId);
$html .= newsletterRenderSmall($introText, $formId, $listUuids);
break;
case 'hero':
default:
$html .= newsletterRenderHero($introText, $formId);
$html .= newsletterRenderHero($introText, $formId, $listUuids);
break;
}
@ -522,8 +530,20 @@ function newsletterHandleSubmission(): void {
exit;
}
// Parse per-form list UUIDs (if provided)
$listUuids = [];
if (!empty($_POST['newsletter_list_uuids'])) {
$raw = explode(',', $_POST['newsletter_list_uuids']);
foreach ($raw as $uuid) {
$uuid = trim($uuid);
if (preg_match('/^[0-9a-f\-]{36}$/i', $uuid)) {
$listUuids[] = $uuid;
}
}
}
// Subscribe
$result = newsletterSubscribe($email, $name);
$result = newsletterSubscribe($email, $name, $listUuids);
if ($result['success']) {
$_SESSION['newsletter_last_submit'] = time();