From 054c59f1771fc67e2dfc1c8d0b27b78e9df9955c Mon Sep 17 00:00:00 2001 From: Ruben Date: Fri, 16 Jan 2026 21:43:48 +0100 Subject: [PATCH] Add newsletter subscription to petition form Add Listmonk integration for newsletter subscriptions Add newsletter checkbox to form Handle newsletter subscription on form submission Add session flag for thank you page Remove duplicate sign-now ID from form section --- .../10-form.en.php | 2 +- .../medisinsk-cannabis-pa-resept/10-form.php | 2 +- custom/plugins/page/petition-form.php | 89 +++++++++++++++++-- 3 files changed, 84 insertions(+), 9 deletions(-) diff --git a/content/underskriftskampanje/medisinsk-cannabis-pa-resept/10-form.en.php b/content/underskriftskampanje/medisinsk-cannabis-pa-resept/10-form.en.php index f68680c..a1319be 100644 --- a/content/underskriftskampanje/medisinsk-cannabis-pa-resept/10-form.en.php +++ b/content/underskriftskampanje/medisinsk-cannabis-pa-resept/10-form.en.php @@ -1,4 +1,4 @@ -

Show your support by signing here

+

Show your support by signing here

diff --git a/content/underskriftskampanje/medisinsk-cannabis-pa-resept/10-form.php b/content/underskriftskampanje/medisinsk-cannabis-pa-resept/10-form.php index d6a4950..f5de520 100644 --- a/content/underskriftskampanje/medisinsk-cannabis-pa-resept/10-form.php +++ b/content/underskriftskampanje/medisinsk-cannabis-pa-resept/10-form.php @@ -1,4 +1,4 @@ -

Signer her for å vise din støtte

+

Signer her for å vise din støtte

diff --git a/custom/plugins/page/petition-form.php b/custom/plugins/page/petition-form.php index cdde2a1..b54f91b 100644 --- a/custom/plugins/page/petition-form.php +++ b/custom/plugins/page/petition-form.php @@ -42,6 +42,61 @@ function petitionSanitizeCSV(string $value): string { return $value; } +/** + * Subscribe email to Listmonk newsletter lists via public API + * Listmonk handles double opt-in (sends its own confirmation email) + */ +function petitionSubscribeToNewsletter(string $email, string $name): bool { + $configPath = dirname(__DIR__, 2) . '/listmonk-config.php'; + if (!file_exists($configPath)) { + error_log("Listmonk config not found: {$configPath}"); + return false; + } + + $config = require $configPath; + if (!$config['enabled']) { + error_log("Listmonk disabled in config"); + return false; + } + + // Log the UUIDs being used + error_log("Listmonk attempting subscription with UUIDs: " . implode(', ', $config['list_uuids'])); + + $payload = json_encode([ + 'email' => $email, + 'name' => $name, + 'list_uuids' => $config['list_uuids'] + ]); + + $url = $config['url'] . '/api/public/subscription'; + $ch = curl_init($url); + curl_setopt_array($ch, [ + CURLOPT_POST => true, + CURLOPT_POSTFIELDS => $payload, + CURLOPT_HTTPHEADER => ['Content-Type: application/json'], + CURLOPT_RETURNTRANSFER => true, + CURLOPT_TIMEOUT => 10 + ]); + + $response = curl_exec($ch); + $curlError = curl_error($ch); + $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE); + curl_close($ch); + + if ($curlError) { + error_log("Listmonk curl error: {$curlError}"); + return false; + } + + if ($httpCode < 200 || $httpCode >= 300) { + error_log("Listmonk subscription failed: HTTP {$httpCode}, URL: {$url}, Response: {$response}"); + return false; + } + + error_log("Listmonk subscription success for {$email}"); + return true; +} + /** * Check IP-based rate limiting to prevent email bombing and spam * Returns true if IP is allowed, false if rate limit exceeded @@ -193,15 +248,15 @@ function petitionGetCsvPath(string $petitionId): string { function petitionGetIdFromPath(string $pageDir): ?string { // Get the last directory segment as the petition ID $petitionSlug = basename($pageDir); - + // Sanitize: remove any leading numeric prefix (e.g., "01-" becomes just the slug part) // This handles folders like "01-my-petition" -> "my-petition" $petitionSlug = preg_replace('/^\d+-/', '', $petitionSlug); - + if (empty($petitionSlug)) { return null; } - + return $petitionSlug; } @@ -795,7 +850,7 @@ function petitionRenderForm(Context $ctx, array $formData, array $errors, bool $ $currentTime = time(); $regions = petitionGetRegions($ctx); - $html = '
'; + $html = '
'; // $html .= '

' . htmlspecialchars(petitionT($ctx, 'petition', 'form_title')) . '

'; // Error messages @@ -888,13 +943,18 @@ function petitionRenderForm(Context $ctx, array $formData, array $errors, bool $ $html .= '' . htmlspecialchars(petitionT($ctx, 'petition', 'privacy_policy_link')) . '

'; $html .= ''; - // GDPR Consent checkbox + // GDPR Consent checkbox + Newsletter subscription $consentChecked = isset($formData['gdpr_consent']) && $formData['gdpr_consent'] === 'on' ? ' checked' : ''; + $newsletterChecked = isset($formData['newsletter']) && $formData['newsletter'] === 'on' ? ' checked' : ''; $html .= ''; // Submit button @@ -1001,7 +1061,7 @@ function petitionGetPageData(?Context $ctx): ?array { if (!$petitionId) { return null; } - + $csvPath = petitionGetCsvPath($petitionId); // loadMetadata() already merges language-specific metadata via Hook::PROCESS_CONTENT $petitionTitle = $metadata['title'] ?? $petitionId; @@ -1186,7 +1246,16 @@ function petitionGetPageData(?Context $ctx): ?array { // Send confirmation email if (petitionSendConfirmationEmail($signatureData, $confirmUrl, $petitionTitle, $ctx)) { + // Subscribe to newsletter if opted in (fire and forget - don't block petition) + $newsletterOptIn = isset($_POST['newsletter']) && $_POST['newsletter'] === 'on'; + error_log("Newsletter checkbox: " . ($newsletterOptIn ? 'checked' : 'not checked')); + if ($newsletterOptIn) { + $fullName = $formData['firstname'] . ' ' . $formData['surname']; + petitionSubscribeToNewsletter($formData['email'], $fullName); + } + $_SESSION['last_petition_submit'] = time(); + $_SESSION['petition_subscribed_newsletter'] = $newsletterOptIn; // Regenerate session ID to prevent session fixation session_regenerate_id(true); @@ -1208,7 +1277,7 @@ function petitionGetPageData(?Context $ctx): ?array { if (!empty($formErrors)) { $_SESSION['petition_errors'] = $formErrors; $_SESSION['petition_form_data'] = $formData; - + $langPrefix = $ctx->get('langPrefix', ''); $currentPath = trim($ctx->requestPath, '/'); $redirectUrl = "{$langPrefix}/{$currentPath}/#sign-now"; @@ -1254,5 +1323,11 @@ Hooks::add(Hook::TEMPLATE_VARS, function(array $vars, Context $ctx) { $vars['petition_signatures'] = $data['signatures']; } + // Check for newsletter subscription flag (for thank you page) + if (isset($_SESSION['petition_subscribed_newsletter'])) { + $vars['petition_subscribed_newsletter'] = $_SESSION['petition_subscribed_newsletter']; + unset($_SESSION['petition_subscribed_newsletter']); + } + return $vars; });